4 * Copyright 2002 Greg Turner
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 * - figure out whether we *really* got this right
22 * - check for errors and throw exceptions
39 #include "wine/unicode.h"
40 #include "wine/rpcfc.h"
42 #include "wine/debug.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(ole);
46 #define BUFFER_PARANOIA 20
49 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
50 (*((UINT32 *)(pchar)) = (uint32))
52 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
53 (*((UINT32 *)(pchar)))
55 /* these would work for i386 too, but less efficient */
56 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
57 (*(pchar) = LOBYTE(LOWORD(uint32)), \
58 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
59 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
60 *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
61 (uint32)) /* allow as r-value */
63 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
65 MAKEWORD(*(pchar), *((pchar)+1)), \
66 MAKEWORD(*((pchar)+2), *((pchar)+3))))
69 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
70 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
71 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
72 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
73 *(pchar) = HIBYTE(HIWORD(uint32)), \
74 (uint32)) /* allow as r-value */
76 #define BIG_ENDIAN_UINT32_READ(pchar) \
78 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
79 MAKEWORD(*((pchar)+1), *(pchar))))
81 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
82 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
83 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
84 # define NDR_LOCAL_UINT32_READ(pchar) \
85 BIG_ENDIAN_UINT32_READ(pchar)
87 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
88 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
89 # define NDR_LOCAL_UINT32_READ(pchar) \
90 LITTLE_ENDIAN_UINT32_READ(pchar)
93 /* _Align must be the desired alignment,
94 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
95 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
96 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
97 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
98 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
100 #define STD_OVERFLOW_CHECK(_Msg) do { \
101 TRACE("buffer=%d/%ld\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
102 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
103 ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
106 #define NDR_TABLE_SIZE 128
107 #define NDR_TABLE_MASK 127
109 static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
110 static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
111 static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
112 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
113 static unsigned long WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
115 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
117 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
118 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
119 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
120 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
124 NdrPointerMarshall, NdrPointerMarshall,
125 NdrPointerMarshall, NdrPointerMarshall,
127 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
128 NdrConformantStructMarshall, NdrConformantStructMarshall,
129 NdrConformantVaryingStructMarshall,
130 NdrComplexStructMarshall,
132 NdrConformantArrayMarshall,
133 NdrConformantVaryingArrayMarshall,
134 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
135 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
136 NdrComplexArrayMarshall,
138 NdrConformantStringMarshall, 0, 0,
139 NdrConformantStringMarshall,
140 NdrNonConformantStringMarshall, 0, 0, 0,
142 NdrEncapsulatedUnionMarshall,
143 NdrNonEncapsulatedUnionMarshall,
145 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
147 NdrInterfacePointerMarshall,
150 NdrUserMarshalMarshall
152 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
154 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
155 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
156 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
157 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
159 NdrBaseTypeUnmarshall,
161 NdrPointerUnmarshall, NdrPointerUnmarshall,
162 NdrPointerUnmarshall, NdrPointerUnmarshall,
164 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
165 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
166 NdrConformantVaryingStructUnmarshall,
167 NdrComplexStructUnmarshall,
169 NdrConformantArrayUnmarshall,
170 NdrConformantVaryingArrayUnmarshall,
171 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
172 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
173 NdrComplexArrayUnmarshall,
175 NdrConformantStringUnmarshall, 0, 0,
176 NdrConformantStringUnmarshall,
177 NdrNonConformantStringUnmarshall, 0, 0, 0,
179 NdrEncapsulatedUnionUnmarshall,
180 NdrNonEncapsulatedUnionUnmarshall,
182 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
184 NdrInterfacePointerUnmarshall,
187 NdrUserMarshalUnmarshall
189 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
191 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
192 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
193 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
194 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
196 NdrBaseTypeBufferSize,
198 NdrPointerBufferSize, NdrPointerBufferSize,
199 NdrPointerBufferSize, NdrPointerBufferSize,
201 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
202 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
203 NdrConformantVaryingStructBufferSize,
204 NdrComplexStructBufferSize,
206 NdrConformantArrayBufferSize,
207 NdrConformantVaryingArrayBufferSize,
208 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
209 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
210 NdrComplexArrayBufferSize,
212 NdrConformantStringBufferSize, 0, 0,
213 NdrConformantStringBufferSize,
214 NdrNonConformantStringBufferSize, 0, 0, 0,
216 NdrEncapsulatedUnionBufferSize,
217 NdrNonEncapsulatedUnionBufferSize,
219 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
221 NdrInterfacePointerBufferSize,
224 NdrUserMarshalBufferSize
226 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
228 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
229 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
230 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
231 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
233 NdrBaseTypeMemorySize,
235 NdrPointerMemorySize, NdrPointerMemorySize,
236 NdrPointerMemorySize, NdrPointerMemorySize,
238 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
240 NdrComplexStructMemorySize,
242 NdrConformantArrayMemorySize, 0, 0, 0, 0, 0,
243 NdrComplexArrayMemorySize,
245 NdrConformantStringMemorySize, 0, 0,
246 NdrConformantStringMemorySize,
247 NdrNonConformantStringMemorySize, 0, 0, 0,
251 NdrInterfacePointerMemorySize,
254 NdrUserMarshalMemorySize
256 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
258 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
259 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
260 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
261 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
265 NdrPointerFree, NdrPointerFree,
266 NdrPointerFree, NdrPointerFree,
268 NdrSimpleStructFree, NdrSimpleStructFree,
269 NdrConformantStructFree, NdrConformantStructFree,
270 NdrConformantVaryingStructFree,
271 NdrComplexStructFree,
273 NdrConformantArrayFree,
274 NdrConformantVaryingArrayFree,
275 NdrFixedArrayFree, NdrFixedArrayFree,
276 NdrVaryingArrayFree, NdrVaryingArrayFree,
282 NdrEncapsulatedUnionFree,
283 NdrNonEncapsulatedUnionFree,
285 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
287 NdrInterfacePointerFree,
293 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, size_t len)
295 /* hmm, this is probably supposed to do more? */
296 return pStubMsg->pfnAllocate(len);
299 static void WINAPI NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
301 pStubMsg->pfnFree(Pointer);
304 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
306 return (*(const ULONG *)pFormat != -1);
309 PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
311 ALIGN_POINTER(pStubMsg->Buffer, 4);
312 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
313 pStubMsg->Buffer += 4;
314 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
315 if (pStubMsg->fHasNewCorrDesc)
321 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
323 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
325 pStubMsg->Offset = 0;
326 pStubMsg->ActualCount = pStubMsg->MaxCount;
330 ALIGN_POINTER(pStubMsg->Buffer, 4);
331 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
332 pStubMsg->Buffer += 4;
333 TRACE("offset is %ld\n", pStubMsg->Offset);
334 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
335 pStubMsg->Buffer += 4;
336 TRACE("variance is %ld\n", pStubMsg->ActualCount);
339 if (pStubMsg->fHasNewCorrDesc)
345 /* writes the conformance value to the buffer */
346 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
348 ALIGN_POINTER(pStubMsg->Buffer, 4);
349 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
350 pStubMsg->Buffer += 4;
353 /* writes the variance values to the buffer */
354 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
356 ALIGN_POINTER(pStubMsg->Buffer, 4);
357 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
358 pStubMsg->Buffer += 4;
359 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
360 pStubMsg->Buffer += 4;
363 /* requests buffer space for the conformance value */
364 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
366 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
367 pStubMsg->BufferLength += 4;
370 /* requests buffer space for the variance values */
371 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
373 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
374 pStubMsg->BufferLength += 8;
377 PFORMAT_STRING ComputeConformanceOrVariance(
378 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
379 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG *pCount)
381 BYTE dtype = pFormat[0] & 0xf;
382 short ofs = *(short *)&pFormat[2];
386 if (!IsConformanceOrVariancePresent(pFormat)) {
387 /* null descriptor */
392 switch (pFormat[0] & 0xf0) {
393 case RPC_FC_NORMAL_CONFORMANCE:
394 TRACE("normal conformance, ofs=%d\n", ofs);
397 case RPC_FC_POINTER_CONFORMANCE:
398 TRACE("pointer conformance, ofs=%d\n", ofs);
399 ptr = pStubMsg->Memory;
401 case RPC_FC_TOP_LEVEL_CONFORMANCE:
402 TRACE("toplevel conformance, ofs=%d\n", ofs);
403 if (pStubMsg->StackTop) {
404 ptr = pStubMsg->StackTop;
407 /* -Os mode, *pCount is already set */
411 case RPC_FC_CONSTANT_CONFORMANCE:
412 data = ofs | ((DWORD)pFormat[1] << 16);
413 TRACE("constant conformance, val=%ld\n", data);
416 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
417 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
418 if (pStubMsg->StackTop) {
419 ptr = pStubMsg->StackTop;
427 FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);
430 switch (pFormat[1]) {
431 case RPC_FC_DEREFERENCE:
432 ptr = *(LPVOID*)((char *)ptr + ofs);
434 case RPC_FC_CALLBACK:
436 unsigned char *old_stack_top = pStubMsg->StackTop;
437 pStubMsg->StackTop = ptr;
439 /* ofs is index into StubDesc->apfnExprEval */
440 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
441 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
443 pStubMsg->StackTop = old_stack_top;
447 ptr = (char *)ptr + ofs;
460 data = *(USHORT*)ptr;
471 FIXME("unknown conformance data type %x\n", dtype);
474 TRACE("dereferenced data type %x at %p, got %ld\n", dtype, ptr, data);
477 switch (pFormat[1]) {
481 case RPC_FC_DEREFERENCE:
482 /* already handled */
497 FIXME("unknown conformance op %d\n", pFormat[1]);
502 TRACE("resulting conformance is %ld\n", *pCount);
503 if (pStubMsg->fHasNewCorrDesc)
511 * NdrConformantString:
513 * What MS calls a ConformantString is, in DCE terminology,
514 * a Varying-Conformant String.
516 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
517 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
518 * into unmarshalled string)
519 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
521 * data: CHARTYPE[maxlen]
523 * ], where CHARTYPE is the appropriate character type (specified externally)
527 /***********************************************************************
528 * NdrConformantStringMarshall [RPCRT4.@]
530 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
531 unsigned char *pszMessage, PFORMAT_STRING pFormat)
535 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
537 if (*pFormat == RPC_FC_C_CSTRING) {
538 TRACE("string=%s\n", debugstr_a((char*)pszMessage));
539 pStubMsg->ActualCount = strlen((char*)pszMessage)+1;
542 else if (*pFormat == RPC_FC_C_WSTRING) {
543 TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage));
544 pStubMsg->ActualCount = strlenW((LPWSTR)pszMessage)+1;
548 ERR("Unhandled string type: %#x\n", *pFormat);
549 /* FIXME: raise an exception. */
553 if (pFormat[1] == RPC_FC_STRING_SIZED)
554 pFormat = ComputeConformance(pStubMsg, pszMessage, pFormat + 2, 0);
556 pStubMsg->MaxCount = pStubMsg->ActualCount;
557 pStubMsg->Offset = 0;
558 WriteConformance(pStubMsg);
559 WriteVariance(pStubMsg);
561 memcpy(pStubMsg->Buffer, pszMessage, pStubMsg->ActualCount*esize); /* the string itself */
562 pStubMsg->Buffer += pStubMsg->ActualCount*esize;
564 STD_OVERFLOW_CHECK(pStubMsg);
567 return NULL; /* is this always right? */
570 /***********************************************************************
571 * NdrConformantStringBufferSize [RPCRT4.@]
573 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
574 unsigned char* pMemory, PFORMAT_STRING pFormat)
576 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
578 SizeConformance(pStubMsg);
579 SizeVariance(pStubMsg);
581 if (*pFormat == RPC_FC_C_CSTRING) {
582 /* we need + 1 octet for '\0' */
583 TRACE("string=%s\n", debugstr_a((char*)pMemory));
584 pStubMsg->BufferLength += strlen((char*)pMemory) + 1 + BUFFER_PARANOIA;
586 else if (*pFormat == RPC_FC_C_WSTRING) {
587 /* we need + 2 octets for L'\0' */
588 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory));
589 pStubMsg->BufferLength += strlenW((LPWSTR)pMemory)*2 + 2 + BUFFER_PARANOIA;
592 ERR("Unhandled string type: %#x\n", *pFormat);
593 /* FIXME: raise an exception */
597 /************************************************************************
598 * NdrConformantStringMemorySize [RPCRT4.@]
600 unsigned long WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
601 PFORMAT_STRING pFormat )
603 unsigned long rslt = 0;
605 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
607 assert(pStubMsg && pFormat);
609 if (*pFormat == RPC_FC_C_CSTRING) {
610 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); /* maxlen */
612 else if (*pFormat == RPC_FC_C_WSTRING) {
613 rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer)*2; /* maxlen */
616 ERR("Unhandled string type: %#x\n", *pFormat);
617 /* FIXME: raise an exception */
620 if (pFormat[1] != RPC_FC_PAD) {
621 FIXME("sized string format=%d\n", pFormat[1]);
624 TRACE(" --> %lu\n", rslt);
628 /************************************************************************
629 * NdrConformantStringUnmarshall [RPCRT4.@]
631 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
632 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
634 unsigned long len, esize;
636 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
637 pStubMsg, *ppMemory, pFormat, fMustAlloc);
639 assert(pFormat && ppMemory && pStubMsg);
641 ReadConformance(pStubMsg, NULL);
642 ReadVariance(pStubMsg, NULL);
644 if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
645 else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
647 ERR("Unhandled string type: %#x\n", *pFormat);
648 /* FIXME: raise an exception */
652 len = pStubMsg->ActualCount;
654 if (fMustAlloc || !*ppMemory)
655 *ppMemory = NdrAllocate(pStubMsg, len*esize + BUFFER_PARANOIA);
657 memcpy(*ppMemory, pStubMsg->Buffer, len*esize);
659 pStubMsg->Buffer += len*esize;
661 if (*pFormat == RPC_FC_C_CSTRING) {
662 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
664 else if (*pFormat == RPC_FC_C_WSTRING) {
665 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
668 return NULL; /* FIXME: is this always right? */
671 /***********************************************************************
672 * NdrNonConformantStringMarshall [RPCRT4.@]
674 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
675 unsigned char *pMemory,
676 PFORMAT_STRING pFormat)
682 /***********************************************************************
683 * NdrNonConformantStringUnmarshall [RPCRT4.@]
685 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
686 unsigned char **ppMemory,
687 PFORMAT_STRING pFormat,
688 unsigned char fMustAlloc)
694 /***********************************************************************
695 * NdrNonConformantStringBufferSize [RPCRT4.@]
697 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
698 unsigned char *pMemory,
699 PFORMAT_STRING pFormat)
704 /***********************************************************************
705 * NdrNonConformantStringMemorySize [RPCRT4.@]
707 unsigned long WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
708 PFORMAT_STRING pFormat)
714 static inline void dump_pointer_attr(unsigned char attr)
716 if (attr & RPC_FC_P_ALLOCALLNODES)
717 TRACE(" RPC_FC_P_ALLOCALLNODES");
718 if (attr & RPC_FC_P_DONTFREE)
719 TRACE(" RPC_FC_P_DONTFREE");
720 if (attr & RPC_FC_P_ONSTACK)
721 TRACE(" RPC_FC_P_ONSTACK");
722 if (attr & RPC_FC_P_SIMPLEPOINTER)
723 TRACE(" RPC_FC_P_SIMPLEPOINTER");
724 if (attr & RPC_FC_P_DEREF)
725 TRACE(" RPC_FC_P_DEREF");
729 /***********************************************************************
732 void WINAPI PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
733 unsigned char *Buffer,
734 unsigned char *Pointer,
735 PFORMAT_STRING pFormat)
737 unsigned type = pFormat[0], attr = pFormat[1];
741 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
742 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
744 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
745 else desc = pFormat + *(const SHORT*)pFormat;
748 case RPC_FC_RP: /* ref pointer (always non-null) */
749 #if 0 /* this causes problems for InstallShield so is disabled - we need more tests */
751 RpcRaiseException(RPC_X_NULL_REF_POINTER);
754 case RPC_FC_UP: /* unique pointer */
755 case RPC_FC_OP: /* object pointer - same as unique here */
756 TRACE("writing %p to buffer\n", Pointer);
757 NDR_LOCAL_UINT32_WRITE(Buffer, (unsigned long)Pointer);
761 FIXME("unhandled ptr type=%02x\n", type);
762 RpcRaiseException(RPC_X_BAD_STUB_DATA);
765 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
768 if (attr & RPC_FC_P_DEREF) {
769 Pointer = *(unsigned char**)Pointer;
770 TRACE("deref => %p\n", Pointer);
772 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
773 if (m) m(pStubMsg, Pointer, desc);
774 else FIXME("no marshaller for data type=%02x\n", *desc);
777 STD_OVERFLOW_CHECK(pStubMsg);
780 /***********************************************************************
783 void WINAPI PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
784 unsigned char *Buffer,
785 unsigned char **pPointer,
786 PFORMAT_STRING pFormat,
787 unsigned char fMustAlloc)
789 unsigned type = pFormat[0], attr = pFormat[1];
792 DWORD pointer_id = 0;
794 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pFormat, fMustAlloc);
795 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
797 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
798 else desc = pFormat + *(const SHORT*)pFormat;
801 case RPC_FC_RP: /* ref pointer (always non-null) */
804 case RPC_FC_UP: /* unique pointer */
805 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
806 TRACE("pointer_id is 0x%08lx\n", pointer_id);
808 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
809 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
810 TRACE("pointer_id is 0x%08lx\n", pointer_id);
812 FIXME("free object pointer %p\n", *pPointer);
816 FIXME("unhandled ptr type=%02x\n", type);
817 RpcRaiseException(RPC_X_BAD_STUB_DATA);
821 if (attr & RPC_FC_P_DEREF) {
822 if (!*pPointer || fMustAlloc)
823 *pPointer = NdrAllocate(pStubMsg, sizeof(void *));
824 pPointer = *(unsigned char***)pPointer;
825 TRACE("deref => %p\n", pPointer);
827 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
828 if (m) m(pStubMsg, pPointer, desc, fMustAlloc);
829 else FIXME("no unmarshaller for data type=%02x\n", *desc);
832 TRACE("pointer=%p\n", *pPointer);
835 /***********************************************************************
838 void WINAPI PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
839 unsigned char *Pointer,
840 PFORMAT_STRING pFormat)
842 unsigned type = pFormat[0], attr = pFormat[1];
846 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
847 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
849 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
850 else desc = pFormat + *(const SHORT*)pFormat;
853 case RPC_FC_RP: /* ref pointer (always non-null) */
857 /* NULL pointer has no further representation */
863 FIXME("unhandled ptr type=%02x\n", type);
864 RpcRaiseException(RPC_X_BAD_STUB_DATA);
867 if (attr & RPC_FC_P_DEREF) {
868 Pointer = *(unsigned char**)Pointer;
869 TRACE("deref => %p\n", Pointer);
872 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
873 if (m) m(pStubMsg, Pointer, desc);
874 else FIXME("no buffersizer for data type=%02x\n", *desc);
877 /***********************************************************************
878 * PointerMemorySize [RPCRT4.@]
880 unsigned long WINAPI PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
881 unsigned char *Buffer,
882 PFORMAT_STRING pFormat)
884 unsigned type = pFormat[0], attr = pFormat[1];
888 FIXME("(%p,%p,%p): stub\n", pStubMsg, Buffer, pFormat);
889 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
891 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
892 else desc = pFormat + *(const SHORT*)pFormat;
895 case RPC_FC_RP: /* ref pointer (always non-null) */
898 FIXME("unhandled ptr type=%02x\n", type);
899 RpcRaiseException(RPC_X_BAD_STUB_DATA);
902 if (attr & RPC_FC_P_DEREF) {
906 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
907 if (m) m(pStubMsg, desc);
908 else FIXME("no memorysizer for data type=%02x\n", *desc);
913 /***********************************************************************
914 * PointerFree [RPCRT4.@]
916 void WINAPI PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
917 unsigned char *Pointer,
918 PFORMAT_STRING pFormat)
920 unsigned type = pFormat[0], attr = pFormat[1];
924 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
925 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
926 if (attr & RPC_FC_P_DONTFREE) return;
928 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
929 else desc = pFormat + *(const SHORT*)pFormat;
931 if (!Pointer) return;
933 if (attr & RPC_FC_P_DEREF) {
934 Pointer = *(unsigned char**)Pointer;
935 TRACE("deref => %p\n", Pointer);
938 m = NdrFreer[*desc & NDR_TABLE_MASK];
939 if (m) m(pStubMsg, Pointer, desc);
941 /* hmm... is this sensible?
942 * perhaps we should check if the memory comes from NdrAllocate,
943 * and deallocate only if so - checking if the pointer is between
944 * BufferStart and BufferEnd is probably no good since the buffer
945 * may be reallocated when the server wants to marshal the reply */
947 case RPC_FC_BOGUS_STRUCT:
948 case RPC_FC_BOGUS_ARRAY:
949 case RPC_FC_USER_MARSHAL:
954 FIXME("unhandled data type=%02x\n", *desc);
956 case RPC_FC_C_CSTRING:
957 case RPC_FC_C_WSTRING:
958 if (pStubMsg->ReuseBuffer) goto notfree;
964 if (attr & RPC_FC_P_ONSTACK) {
965 TRACE("not freeing stack ptr %p\n", Pointer);
968 TRACE("freeing %p\n", Pointer);
969 NdrFree(pStubMsg, Pointer);
972 TRACE("not freeing %p\n", Pointer);
975 /***********************************************************************
976 * EmbeddedPointerMarshall
978 unsigned char * WINAPI EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
979 unsigned char *pMemory,
980 PFORMAT_STRING pFormat)
982 unsigned char *Mark = pStubMsg->BufferMark;
983 unsigned long Offset = pStubMsg->Offset;
984 unsigned ofs, rep, count, stride, xofs;
987 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
989 if (*pFormat != RPC_FC_PP) return NULL;
992 while (pFormat[0] != RPC_FC_END) {
993 switch (pFormat[0]) {
995 FIXME("unknown repeat type %d\n", pFormat[0]);
996 case RPC_FC_NO_REPEAT:
1004 case RPC_FC_FIXED_REPEAT:
1005 rep = *(const WORD*)&pFormat[2];
1006 stride = *(const WORD*)&pFormat[4];
1007 ofs = *(const WORD*)&pFormat[6];
1008 count = *(const WORD*)&pFormat[8];
1012 case RPC_FC_VARIABLE_REPEAT:
1013 rep = pStubMsg->MaxCount;
1014 stride = *(const WORD*)&pFormat[2];
1015 ofs = *(const WORD*)&pFormat[4];
1016 count = *(const WORD*)&pFormat[6];
1017 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1021 for (i = 0; i < rep; i++) {
1022 PFORMAT_STRING info = pFormat;
1023 unsigned char *membase = pMemory + (i * stride);
1024 unsigned char *bufbase = Mark + (i * stride);
1026 /* ofs doesn't seem to matter in this context */
1027 for (u=0; u<count; u++,info+=8) {
1028 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1029 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1030 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1033 pFormat += 8 * count;
1036 STD_OVERFLOW_CHECK(pStubMsg);
1041 /***********************************************************************
1042 * EmbeddedPointerUnmarshall
1044 unsigned char * WINAPI EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1045 unsigned char **ppMemory,
1046 PFORMAT_STRING pFormat,
1047 unsigned char fMustAlloc)
1049 unsigned char *Mark = pStubMsg->BufferMark;
1050 unsigned long Offset = pStubMsg->Offset;
1051 unsigned ofs, rep, count, stride, xofs;
1054 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1056 if (*pFormat != RPC_FC_PP) return NULL;
1059 while (pFormat[0] != RPC_FC_END) {
1060 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1061 switch (pFormat[0]) {
1063 FIXME("unknown repeat type %d\n", pFormat[0]);
1064 case RPC_FC_NO_REPEAT:
1072 case RPC_FC_FIXED_REPEAT:
1073 rep = *(const WORD*)&pFormat[2];
1074 stride = *(const WORD*)&pFormat[4];
1075 ofs = *(const WORD*)&pFormat[6];
1076 count = *(const WORD*)&pFormat[8];
1080 case RPC_FC_VARIABLE_REPEAT:
1081 rep = pStubMsg->MaxCount;
1082 stride = *(const WORD*)&pFormat[2];
1083 ofs = *(const WORD*)&pFormat[4];
1084 count = *(const WORD*)&pFormat[6];
1085 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1089 /* ofs doesn't seem to matter in this context */
1090 for (i = 0; i < rep; i++) {
1091 PFORMAT_STRING info = pFormat;
1092 unsigned char *membase = *ppMemory + (i * stride);
1093 unsigned char *bufbase = Mark + (i * stride);
1095 for (u=0; u<count; u++,info+=8) {
1096 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1097 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1098 *(void **)memptr = NULL;
1099 PointerUnmarshall(pStubMsg, bufptr, (unsigned char**)memptr, info+4, fMustAlloc);
1102 pFormat += 8 * count;
1108 /***********************************************************************
1109 * EmbeddedPointerBufferSize
1111 void WINAPI EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1112 unsigned char *pMemory,
1113 PFORMAT_STRING pFormat)
1115 unsigned long Offset = pStubMsg->Offset;
1116 unsigned ofs, rep, count, stride, xofs;
1119 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1121 if (pStubMsg->IgnoreEmbeddedPointers) return;
1123 if (*pFormat != RPC_FC_PP) return;
1126 while (pFormat[0] != RPC_FC_END) {
1127 switch (pFormat[0]) {
1129 FIXME("unknown repeat type %d\n", pFormat[0]);
1130 case RPC_FC_NO_REPEAT:
1138 case RPC_FC_FIXED_REPEAT:
1139 rep = *(const WORD*)&pFormat[2];
1140 stride = *(const WORD*)&pFormat[4];
1141 ofs = *(const WORD*)&pFormat[6];
1142 count = *(const WORD*)&pFormat[8];
1146 case RPC_FC_VARIABLE_REPEAT:
1147 rep = pStubMsg->MaxCount;
1148 stride = *(const WORD*)&pFormat[2];
1149 ofs = *(const WORD*)&pFormat[4];
1150 count = *(const WORD*)&pFormat[6];
1151 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1155 /* ofs doesn't seem to matter in this context */
1156 for (i = 0; i < rep; i++) {
1157 PFORMAT_STRING info = pFormat;
1158 unsigned char *membase = pMemory + (i * stride);
1160 for (u=0; u<count; u++,info+=8) {
1161 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1162 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1165 pFormat += 8 * count;
1169 /***********************************************************************
1170 * EmbeddedPointerMemorySize
1172 unsigned long WINAPI EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1173 PFORMAT_STRING pFormat)
1175 unsigned long Offset = pStubMsg->Offset;
1176 unsigned char *Mark = pStubMsg->BufferMark;
1177 unsigned ofs, rep, count, stride, xofs;
1180 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1182 if (*pFormat != RPC_FC_PP) return 0;
1185 while (pFormat[0] != RPC_FC_END) {
1186 switch (pFormat[0]) {
1188 FIXME("unknown repeat type %d\n", pFormat[0]);
1189 case RPC_FC_NO_REPEAT:
1197 case RPC_FC_FIXED_REPEAT:
1198 rep = *(const WORD*)&pFormat[2];
1199 stride = *(const WORD*)&pFormat[4];
1200 ofs = *(const WORD*)&pFormat[6];
1201 count = *(const WORD*)&pFormat[8];
1205 case RPC_FC_VARIABLE_REPEAT:
1206 rep = pStubMsg->MaxCount;
1207 stride = *(const WORD*)&pFormat[2];
1208 ofs = *(const WORD*)&pFormat[4];
1209 count = *(const WORD*)&pFormat[6];
1210 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1214 /* ofs doesn't seem to matter in this context */
1215 for (i = 0; i < rep; i++) {
1216 PFORMAT_STRING info = pFormat;
1217 unsigned char *bufbase = Mark + (i * stride);
1219 for (u=0; u<count; u++,info+=8) {
1220 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1221 PointerMemorySize(pStubMsg, bufptr, info+4);
1224 pFormat += 8 * count;
1230 /***********************************************************************
1231 * EmbeddedPointerFree
1233 void WINAPI EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1234 unsigned char *pMemory,
1235 PFORMAT_STRING pFormat)
1237 unsigned long Offset = pStubMsg->Offset;
1238 unsigned ofs, rep, count, stride, xofs;
1241 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1242 if (*pFormat != RPC_FC_PP) return;
1245 while (pFormat[0] != RPC_FC_END) {
1246 switch (pFormat[0]) {
1248 FIXME("unknown repeat type %d\n", pFormat[0]);
1249 case RPC_FC_NO_REPEAT:
1257 case RPC_FC_FIXED_REPEAT:
1258 rep = *(const WORD*)&pFormat[2];
1259 stride = *(const WORD*)&pFormat[4];
1260 ofs = *(const WORD*)&pFormat[6];
1261 count = *(const WORD*)&pFormat[8];
1265 case RPC_FC_VARIABLE_REPEAT:
1266 rep = pStubMsg->MaxCount;
1267 stride = *(const WORD*)&pFormat[2];
1268 ofs = *(const WORD*)&pFormat[4];
1269 count = *(const WORD*)&pFormat[6];
1270 xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0;
1274 /* ofs doesn't seem to matter in this context */
1275 for (i = 0; i < rep; i++) {
1276 PFORMAT_STRING info = pFormat;
1277 unsigned char *membase = pMemory + (i * stride);
1279 for (u=0; u<count; u++,info+=8) {
1280 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1281 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1284 pFormat += 8 * count;
1288 /***********************************************************************
1289 * NdrPointerMarshall [RPCRT4.@]
1291 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1292 unsigned char *pMemory,
1293 PFORMAT_STRING pFormat)
1295 unsigned char *Buffer;
1297 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1299 /* incremement the buffer here instead of in PointerMarshall,
1300 * as that is used by embedded pointers which already handle the incrementing
1301 * the buffer, and shouldn't write any additional pointer data to the wire */
1302 if (*pFormat != RPC_FC_RP)
1304 ALIGN_POINTER(pStubMsg->Buffer, 4);
1305 Buffer = pStubMsg->Buffer;
1306 pStubMsg->Buffer += 4;
1309 Buffer = pStubMsg->Buffer;
1311 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1313 STD_OVERFLOW_CHECK(pStubMsg);
1318 /***********************************************************************
1319 * NdrPointerUnmarshall [RPCRT4.@]
1321 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1322 unsigned char **ppMemory,
1323 PFORMAT_STRING pFormat,
1324 unsigned char fMustAlloc)
1326 unsigned char *Buffer;
1328 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1330 /* incremement the buffer here instead of in PointerUnmarshall,
1331 * as that is used by embedded pointers which already handle the incrementing
1332 * the buffer, and shouldn't read any additional pointer data from the
1334 if (*pFormat != RPC_FC_RP)
1336 ALIGN_POINTER(pStubMsg->Buffer, 4);
1337 Buffer = pStubMsg->Buffer;
1338 pStubMsg->Buffer += 4;
1341 Buffer = pStubMsg->Buffer;
1343 PointerUnmarshall(pStubMsg, Buffer, ppMemory, pFormat, fMustAlloc);
1348 /***********************************************************************
1349 * NdrPointerBufferSize [RPCRT4.@]
1351 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1352 unsigned char *pMemory,
1353 PFORMAT_STRING pFormat)
1355 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1357 /* incremement the buffer length here instead of in PointerBufferSize,
1358 * as that is used by embedded pointers which already handle the buffer
1359 * length, and shouldn't write anything more to the wire */
1360 if (*pFormat != RPC_FC_RP)
1362 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1363 pStubMsg->BufferLength += 4;
1366 PointerBufferSize(pStubMsg, pMemory, pFormat);
1369 /***********************************************************************
1370 * NdrPointerMemorySize [RPCRT4.@]
1372 unsigned long WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1373 PFORMAT_STRING pFormat)
1375 /* unsigned size = *(LPWORD)(pFormat+2); */
1376 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1377 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1381 /***********************************************************************
1382 * NdrPointerFree [RPCRT4.@]
1384 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1385 unsigned char *pMemory,
1386 PFORMAT_STRING pFormat)
1388 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1389 PointerFree(pStubMsg, pMemory, pFormat);
1392 /***********************************************************************
1393 * NdrSimpleStructMarshall [RPCRT4.@]
1395 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1396 unsigned char *pMemory,
1397 PFORMAT_STRING pFormat)
1399 unsigned size = *(const WORD*)(pFormat+2);
1400 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1402 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1404 memcpy(pStubMsg->Buffer, pMemory, size);
1405 pStubMsg->BufferMark = pStubMsg->Buffer;
1406 pStubMsg->Buffer += size;
1408 if (pFormat[0] != RPC_FC_STRUCT)
1409 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1411 STD_OVERFLOW_CHECK(pStubMsg);
1416 /***********************************************************************
1417 * NdrSimpleStructUnmarshall [RPCRT4.@]
1419 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1420 unsigned char **ppMemory,
1421 PFORMAT_STRING pFormat,
1422 unsigned char fMustAlloc)
1424 unsigned size = *(const WORD*)(pFormat+2);
1425 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1427 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1430 *ppMemory = NdrAllocate(pStubMsg, size);
1431 memcpy(*ppMemory, pStubMsg->Buffer, size);
1433 if (pStubMsg->ReuseBuffer && !*ppMemory)
1434 /* for servers, we may just point straight into the RPC buffer, I think
1435 * (I guess that's what MS does since MIDL code doesn't try to free) */
1436 *ppMemory = pStubMsg->Buffer;
1438 /* for clients, memory should be provided by caller */
1439 memcpy(*ppMemory, pStubMsg->Buffer, size);
1442 pStubMsg->BufferMark = pStubMsg->Buffer;
1443 pStubMsg->Buffer += size;
1445 if (pFormat[0] != RPC_FC_STRUCT)
1446 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat+4, fMustAlloc);
1452 /***********************************************************************
1453 * NdrSimpleStructUnmarshall [RPCRT4.@]
1455 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1456 unsigned char FormatChar )
1462 /***********************************************************************
1463 * NdrSimpleStructUnmarshall [RPCRT4.@]
1465 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1466 unsigned char FormatChar )
1472 /***********************************************************************
1473 * NdrSimpleStructBufferSize [RPCRT4.@]
1475 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1476 unsigned char *pMemory,
1477 PFORMAT_STRING pFormat)
1479 unsigned size = *(const WORD*)(pFormat+2);
1480 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1482 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1484 pStubMsg->BufferLength += size;
1485 if (pFormat[0] != RPC_FC_STRUCT)
1486 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1489 /***********************************************************************
1490 * NdrSimpleStructMemorySize [RPCRT4.@]
1492 unsigned long WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1493 PFORMAT_STRING pFormat)
1495 unsigned short size = *(LPWORD)(pFormat+2);
1497 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1499 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1500 pStubMsg->MemorySize += size;
1501 pStubMsg->Buffer += size;
1503 if (pFormat[0] != RPC_FC_STRUCT)
1504 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1508 /***********************************************************************
1509 * NdrSimpleStructFree [RPCRT4.@]
1511 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1512 unsigned char *pMemory,
1513 PFORMAT_STRING pFormat)
1515 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1516 if (pFormat[0] != RPC_FC_STRUCT)
1517 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1521 unsigned long WINAPI EmbeddedComplexSize(PMIDL_STUB_MESSAGE pStubMsg,
1522 PFORMAT_STRING pFormat)
1526 case RPC_FC_PSTRUCT:
1527 case RPC_FC_CSTRUCT:
1528 case RPC_FC_BOGUS_STRUCT:
1529 return *(const WORD*)&pFormat[2];
1530 case RPC_FC_USER_MARSHAL:
1531 return *(const WORD*)&pFormat[4];
1532 case RPC_FC_NON_ENCAPSULATED_UNION:
1534 if (pStubMsg->fHasNewCorrDesc)
1539 pFormat += *(const SHORT*)pFormat;
1540 return *(const SHORT*)pFormat;
1542 FIXME("unhandled embedded type %02x\n", *pFormat);
1548 unsigned long WINAPI EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1549 PFORMAT_STRING pFormat)
1551 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
1555 FIXME("no memorysizer for data type=%02x\n", *pFormat);
1559 return m(pStubMsg, pFormat);
1563 unsigned char * WINAPI ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1564 unsigned char *pMemory,
1565 PFORMAT_STRING pFormat,
1566 PFORMAT_STRING pPointer)
1568 PFORMAT_STRING desc;
1572 while (*pFormat != RPC_FC_END) {
1576 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
1577 memcpy(pStubMsg->Buffer, pMemory, 2);
1578 pStubMsg->Buffer += 2;
1584 TRACE("long=%ld <= %p\n", *(DWORD*)pMemory, pMemory);
1585 memcpy(pStubMsg->Buffer, pMemory, 4);
1586 pStubMsg->Buffer += 4;
1589 case RPC_FC_POINTER:
1590 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
1591 NdrPointerMarshall(pStubMsg, *(unsigned char**)pMemory, pPointer);
1595 case RPC_FC_ALIGNM4:
1596 ALIGN_POINTER(pMemory, 4);
1598 case RPC_FC_ALIGNM8:
1599 ALIGN_POINTER(pMemory, 8);
1601 case RPC_FC_STRUCTPAD2:
1604 case RPC_FC_EMBEDDED_COMPLEX:
1605 pMemory += pFormat[1];
1607 desc = pFormat + *(const SHORT*)pFormat;
1608 size = EmbeddedComplexSize(pStubMsg, desc);
1609 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
1610 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1611 if (m) m(pStubMsg, pMemory, desc);
1612 else FIXME("no marshaller for embedded type %02x\n", *desc);
1619 FIXME("unhandled format %02x\n", *pFormat);
1627 unsigned char * WINAPI ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1628 unsigned char *pMemory,
1629 PFORMAT_STRING pFormat,
1630 PFORMAT_STRING pPointer,
1631 unsigned char fMustAlloc)
1633 PFORMAT_STRING desc;
1637 while (*pFormat != RPC_FC_END) {
1641 memcpy(pMemory, pStubMsg->Buffer, 2);
1642 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
1643 pStubMsg->Buffer += 2;
1649 memcpy(pMemory, pStubMsg->Buffer, 4);
1650 TRACE("long=%ld => %p\n", *(DWORD*)pMemory, pMemory);
1651 pStubMsg->Buffer += 4;
1654 case RPC_FC_POINTER:
1655 *(unsigned char**)pMemory = NULL;
1656 TRACE("pointer => %p\n", pMemory);
1657 NdrPointerUnmarshall(pStubMsg, (unsigned char**)pMemory, pPointer, fMustAlloc);
1661 case RPC_FC_ALIGNM4:
1662 ALIGN_POINTER(pMemory, 4);
1664 case RPC_FC_ALIGNM8:
1665 ALIGN_POINTER(pMemory, 8);
1667 case RPC_FC_STRUCTPAD2:
1670 case RPC_FC_EMBEDDED_COMPLEX:
1671 pMemory += pFormat[1];
1673 desc = pFormat + *(const SHORT*)pFormat;
1674 size = EmbeddedComplexSize(pStubMsg, desc);
1675 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
1676 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1677 memset(pMemory, 0, size); /* just in case */
1678 if (m) m(pStubMsg, &pMemory, desc, fMustAlloc);
1679 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
1686 FIXME("unhandled format %d\n", *pFormat);
1694 unsigned char * WINAPI ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1695 unsigned char *pMemory,
1696 PFORMAT_STRING pFormat,
1697 PFORMAT_STRING pPointer)
1699 PFORMAT_STRING desc;
1703 while (*pFormat != RPC_FC_END) {
1707 pStubMsg->BufferLength += 2;
1713 pStubMsg->BufferLength += 4;
1716 case RPC_FC_POINTER:
1717 NdrPointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
1721 case RPC_FC_ALIGNM4:
1722 ALIGN_POINTER(pMemory, 4);
1724 case RPC_FC_ALIGNM8:
1725 ALIGN_POINTER(pMemory, 8);
1727 case RPC_FC_STRUCTPAD2:
1730 case RPC_FC_EMBEDDED_COMPLEX:
1731 pMemory += pFormat[1];
1733 desc = pFormat + *(const SHORT*)pFormat;
1734 size = EmbeddedComplexSize(pStubMsg, desc);
1735 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1736 if (m) m(pStubMsg, pMemory, desc);
1737 else FIXME("no buffersizer for embedded type %02x\n", *desc);
1744 FIXME("unhandled format %d\n", *pFormat);
1752 unsigned char * WINAPI ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
1753 unsigned char *pMemory,
1754 PFORMAT_STRING pFormat,
1755 PFORMAT_STRING pPointer)
1757 PFORMAT_STRING desc;
1761 while (*pFormat != RPC_FC_END) {
1772 case RPC_FC_POINTER:
1773 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
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 m = NdrFreer[*desc & NDR_TABLE_MASK];
1792 if (m) m(pStubMsg, pMemory, desc);
1793 else FIXME("no freer for embedded type %02x\n", *desc);
1800 FIXME("unhandled format %d\n", *pFormat);
1808 unsigned long WINAPI ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1809 PFORMAT_STRING pFormat)
1811 PFORMAT_STRING desc;
1812 unsigned long size = 0;
1814 while (*pFormat != RPC_FC_END) {
1819 pStubMsg->Buffer += 2;
1824 pStubMsg->Buffer += 4;
1826 case RPC_FC_POINTER:
1828 pStubMsg->Buffer += 4;
1830 case RPC_FC_ALIGNM4:
1831 ALIGN_LENGTH(size, 4);
1832 ALIGN_POINTER(pStubMsg->Buffer, 4);
1834 case RPC_FC_ALIGNM8:
1835 ALIGN_LENGTH(size, 8);
1836 ALIGN_POINTER(pStubMsg->Buffer, 8);
1838 case RPC_FC_STRUCTPAD2:
1840 pStubMsg->Buffer += 2;
1842 case RPC_FC_EMBEDDED_COMPLEX:
1845 desc = pFormat + *(const SHORT*)pFormat;
1846 size += EmbeddedComplexMemorySize(pStubMsg, desc);
1852 FIXME("unhandled format %d\n", *pFormat);
1860 /***********************************************************************
1861 * NdrComplexStructMarshall [RPCRT4.@]
1863 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1864 unsigned char *pMemory,
1865 PFORMAT_STRING pFormat)
1867 PFORMAT_STRING conf_array = NULL;
1868 PFORMAT_STRING pointer_desc = NULL;
1869 unsigned char *OldMemory = pStubMsg->Memory;
1871 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1873 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1876 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
1878 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
1881 pStubMsg->Memory = pMemory;
1883 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
1886 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
1888 pStubMsg->Memory = OldMemory;
1890 STD_OVERFLOW_CHECK(pStubMsg);
1895 /***********************************************************************
1896 * NdrComplexStructUnmarshall [RPCRT4.@]
1898 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1899 unsigned char **ppMemory,
1900 PFORMAT_STRING pFormat,
1901 unsigned char fMustAlloc)
1903 unsigned size = *(const WORD*)(pFormat+2);
1904 PFORMAT_STRING conf_array = NULL;
1905 PFORMAT_STRING pointer_desc = NULL;
1906 unsigned char *pMemory;
1908 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1910 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1912 if (fMustAlloc || !*ppMemory)
1914 *ppMemory = NdrAllocate(pStubMsg, size);
1915 memset(*ppMemory, 0, size);
1919 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
1921 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
1924 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc);
1927 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
1932 /***********************************************************************
1933 * NdrComplexStructBufferSize [RPCRT4.@]
1935 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1936 unsigned char *pMemory,
1937 PFORMAT_STRING pFormat)
1939 PFORMAT_STRING conf_array = NULL;
1940 PFORMAT_STRING pointer_desc = NULL;
1941 unsigned char *OldMemory = pStubMsg->Memory;
1943 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1945 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1948 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
1950 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
1953 pStubMsg->Memory = pMemory;
1955 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
1958 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
1960 pStubMsg->Memory = OldMemory;
1963 /***********************************************************************
1964 * NdrComplexStructMemorySize [RPCRT4.@]
1966 unsigned long WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1967 PFORMAT_STRING pFormat)
1969 unsigned size = *(const WORD*)(pFormat+2);
1970 PFORMAT_STRING conf_array = NULL;
1971 PFORMAT_STRING pointer_desc = NULL;
1973 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1975 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1978 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
1980 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
1983 ComplexStructMemorySize(pStubMsg, pFormat);
1986 NdrConformantArrayMemorySize(pStubMsg, conf_array);
1991 /***********************************************************************
1992 * NdrComplexStructFree [RPCRT4.@]
1994 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1995 unsigned char *pMemory,
1996 PFORMAT_STRING pFormat)
1998 PFORMAT_STRING conf_array = NULL;
1999 PFORMAT_STRING pointer_desc = NULL;
2000 unsigned char *OldMemory = pStubMsg->Memory;
2002 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2005 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2007 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2010 pStubMsg->Memory = pMemory;
2012 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
2015 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
2017 pStubMsg->Memory = OldMemory;
2020 /***********************************************************************
2021 * NdrConformantArrayMarshall [RPCRT4.@]
2023 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2024 unsigned char *pMemory,
2025 PFORMAT_STRING pFormat)
2027 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2028 unsigned char alignment = pFormat[1] + 1;
2030 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2031 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2033 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2034 size = pStubMsg->MaxCount;
2036 WriteConformance(pStubMsg);
2038 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2040 memcpy(pStubMsg->Buffer, pMemory, size*esize);
2041 pStubMsg->BufferMark = pStubMsg->Buffer;
2042 pStubMsg->Buffer += size*esize;
2044 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2046 STD_OVERFLOW_CHECK(pStubMsg);
2051 /***********************************************************************
2052 * NdrConformantArrayUnmarshall [RPCRT4.@]
2054 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2055 unsigned char **ppMemory,
2056 PFORMAT_STRING pFormat,
2057 unsigned char fMustAlloc)
2059 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2060 unsigned char alignment = pFormat[1] + 1;
2062 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2063 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2065 pFormat = ReadConformance(pStubMsg, pFormat+4);
2066 size = pStubMsg->MaxCount;
2068 if (fMustAlloc || !*ppMemory)
2069 *ppMemory = NdrAllocate(pStubMsg, size*esize);
2071 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2073 memcpy(*ppMemory, pStubMsg->Buffer, size*esize);
2075 pStubMsg->BufferMark = pStubMsg->Buffer;
2076 pStubMsg->Buffer += size*esize;
2078 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2083 /***********************************************************************
2084 * NdrConformantArrayBufferSize [RPCRT4.@]
2086 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2087 unsigned char *pMemory,
2088 PFORMAT_STRING pFormat)
2090 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2091 unsigned char alignment = pFormat[1] + 1;
2093 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2094 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2096 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2097 size = pStubMsg->MaxCount;
2099 SizeConformance(pStubMsg);
2101 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2103 /* conformance value plus array */
2104 pStubMsg->BufferLength += size*esize;
2106 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2109 /***********************************************************************
2110 * NdrConformantArrayMemorySize [RPCRT4.@]
2112 unsigned long WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2113 PFORMAT_STRING pFormat)
2115 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2116 unsigned char *buffer;
2118 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2119 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2121 buffer = pStubMsg->Buffer;
2122 pFormat = ReadConformance(pStubMsg, pFormat+4);
2123 pStubMsg->Buffer = buffer;
2124 size = pStubMsg->MaxCount;
2129 /***********************************************************************
2130 * NdrConformantArrayFree [RPCRT4.@]
2132 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2133 unsigned char *pMemory,
2134 PFORMAT_STRING pFormat)
2136 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2137 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2139 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2143 /***********************************************************************
2144 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2146 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
2147 unsigned char* pMemory,
2148 PFORMAT_STRING pFormat )
2150 unsigned char alignment = pFormat[1] + 1;
2151 DWORD esize = *(const WORD*)(pFormat+2);
2153 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2155 if (pFormat[0] != RPC_FC_CVARRAY)
2157 ERR("invalid format type %x\n", pFormat[0]);
2158 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2162 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2163 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2165 WriteConformance(pStubMsg);
2166 WriteVariance(pStubMsg);
2168 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2170 memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, pStubMsg->ActualCount*esize);
2171 pStubMsg->BufferMark = pStubMsg->Buffer;
2172 pStubMsg->Buffer += pStubMsg->ActualCount*esize;
2174 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2176 STD_OVERFLOW_CHECK(pStubMsg);
2182 /***********************************************************************
2183 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2185 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2186 unsigned char** ppMemory,
2187 PFORMAT_STRING pFormat,
2188 unsigned char fMustAlloc )
2190 unsigned char alignment = pFormat[1] + 1;
2191 DWORD esize = *(const WORD*)(pFormat+2);
2193 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2195 if (pFormat[0] != RPC_FC_CVARRAY)
2197 ERR("invalid format type %x\n", pFormat[0]);
2198 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2202 pFormat = ReadConformance(pStubMsg, pFormat);
2203 pFormat = ReadVariance(pStubMsg, pFormat);
2205 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2207 if (!*ppMemory || fMustAlloc)
2208 *ppMemory = NdrAllocate(pStubMsg, pStubMsg->MaxCount * esize);
2209 memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, pStubMsg->ActualCount * esize);
2210 pStubMsg->Buffer += pStubMsg->ActualCount * esize;
2212 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2218 /***********************************************************************
2219 * NdrConformantVaryingArrayFree [RPCRT4.@]
2221 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
2222 unsigned char* pMemory,
2223 PFORMAT_STRING pFormat )
2225 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2227 if (pFormat[0] != RPC_FC_CVARRAY)
2229 ERR("invalid format type %x\n", pFormat[0]);
2230 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2234 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2235 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2237 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2241 /***********************************************************************
2242 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2244 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
2245 unsigned char* pMemory, PFORMAT_STRING pFormat )
2247 unsigned char alignment = pFormat[1] + 1;
2248 DWORD esize = *(const WORD*)(pFormat+2);
2250 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2252 if (pFormat[0] != RPC_FC_CVARRAY)
2254 ERR("invalid format type %x\n", pFormat[0]);
2255 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2260 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2261 /* compute length */
2262 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2264 SizeConformance(pStubMsg);
2265 SizeVariance(pStubMsg);
2267 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2269 pStubMsg->BufferLength += pStubMsg->ActualCount*esize;
2271 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2275 /***********************************************************************
2276 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2278 unsigned long WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2279 PFORMAT_STRING pFormat )
2286 /***********************************************************************
2287 * NdrComplexArrayMarshall [RPCRT4.@]
2289 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2290 unsigned char *pMemory,
2291 PFORMAT_STRING pFormat)
2293 ULONG i, count, def;
2294 BOOL variance_present;
2295 unsigned char alignment;
2297 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2299 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2301 ERR("invalid format type %x\n", pFormat[0]);
2302 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2306 alignment = pFormat[1] + 1;
2308 def = *(const WORD*)&pFormat[2];
2311 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2312 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2314 variance_present = IsConformanceOrVariancePresent(pFormat);
2315 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2316 TRACE("variance = %ld\n", pStubMsg->ActualCount);
2318 WriteConformance(pStubMsg);
2319 if (variance_present)
2320 WriteVariance(pStubMsg);
2322 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2324 count = pStubMsg->ActualCount;
2325 for (i = 0; i < count; i++)
2326 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
2328 STD_OVERFLOW_CHECK(pStubMsg);
2333 /***********************************************************************
2334 * NdrComplexArrayUnmarshall [RPCRT4.@]
2336 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2337 unsigned char **ppMemory,
2338 PFORMAT_STRING pFormat,
2339 unsigned char fMustAlloc)
2341 ULONG i, count, esize;
2342 unsigned char alignment;
2343 unsigned char *pMemory;
2344 unsigned char *Buffer;
2346 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2348 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2350 ERR("invalid format type %x\n", pFormat[0]);
2351 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2355 alignment = pFormat[1] + 1;
2359 pFormat = ReadConformance(pStubMsg, pFormat);
2360 pFormat = ReadVariance(pStubMsg, pFormat);
2362 Buffer = pStubMsg->Buffer;
2363 esize = ComplexStructMemorySize(pStubMsg, pFormat);
2364 pStubMsg->Buffer = Buffer;
2366 if (fMustAlloc || !*ppMemory)
2368 *ppMemory = NdrAllocate(pStubMsg, pStubMsg->MaxCount * esize);
2369 memset(*ppMemory, 0, pStubMsg->MaxCount * esize);
2372 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2374 pMemory = *ppMemory;
2375 count = pStubMsg->ActualCount;
2376 for (i = 0; i < count; i++)
2377 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
2382 /***********************************************************************
2383 * NdrComplexArrayBufferSize [RPCRT4.@]
2385 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2386 unsigned char *pMemory,
2387 PFORMAT_STRING pFormat)
2389 ULONG i, count, def;
2390 unsigned char alignment;
2391 BOOL variance_present;
2393 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2395 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2397 ERR("invalid format type %x\n", pFormat[0]);
2398 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2402 alignment = pFormat[1] + 1;
2404 def = *(const WORD*)&pFormat[2];
2407 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2408 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2409 SizeConformance(pStubMsg);
2411 variance_present = IsConformanceOrVariancePresent(pFormat);
2412 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2413 TRACE("variance = %ld\n", pStubMsg->ActualCount);
2415 if (variance_present)
2416 SizeVariance(pStubMsg);
2418 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
2420 count = pStubMsg->ActualCount;
2421 for (i = 0; i < count; i++)
2422 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
2425 /***********************************************************************
2426 * NdrComplexArrayMemorySize [RPCRT4.@]
2428 unsigned long WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2429 PFORMAT_STRING pFormat)
2431 ULONG i, count, esize;
2432 unsigned char alignment;
2433 unsigned char *Buffer;
2434 unsigned long SavedMemorySize;
2435 unsigned long MemorySize;
2437 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2439 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2441 ERR("invalid format type %x\n", pFormat[0]);
2442 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2446 alignment = pFormat[1] + 1;
2450 pFormat = ReadConformance(pStubMsg, pFormat);
2451 pFormat = ReadVariance(pStubMsg, pFormat);
2453 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2455 SavedMemorySize = pStubMsg->MemorySize;
2457 Buffer = pStubMsg->Buffer;
2458 esize = ComplexStructMemorySize(pStubMsg, pFormat);
2459 pStubMsg->Buffer = Buffer;
2461 MemorySize = esize * pStubMsg->MaxCount;
2463 count = pStubMsg->ActualCount;
2464 for (i = 0; i < count; i++)
2465 ComplexStructMemorySize(pStubMsg, pFormat);
2467 pStubMsg->MemorySize = SavedMemorySize;
2469 pStubMsg->MemorySize += MemorySize;
2473 /***********************************************************************
2474 * NdrComplexArrayFree [RPCRT4.@]
2476 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
2477 unsigned char *pMemory,
2478 PFORMAT_STRING pFormat)
2480 ULONG i, count, def;
2482 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2484 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
2486 ERR("invalid format type %x\n", pFormat[0]);
2487 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2491 def = *(const WORD*)&pFormat[2];
2494 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
2495 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
2497 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
2498 TRACE("variance = %ld\n", pStubMsg->ActualCount);
2500 count = pStubMsg->ActualCount;
2501 for (i = 0; i < count; i++)
2502 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
2505 unsigned long UserMarshalFlags(PMIDL_STUB_MESSAGE pStubMsg)
2507 return MAKELONG(pStubMsg->dwDestContext,
2508 pStubMsg->RpcMsg->DataRepresentation);
2511 /***********************************************************************
2512 * NdrUserMarshalMarshall [RPCRT4.@]
2514 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2515 unsigned char *pMemory,
2516 PFORMAT_STRING pFormat)
2518 /* unsigned flags = pFormat[1]; */
2519 unsigned index = *(const WORD*)&pFormat[2];
2520 unsigned long uflag = UserMarshalFlags(pStubMsg);
2521 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2522 TRACE("index=%d\n", index);
2525 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
2526 &uflag, pStubMsg->Buffer, pMemory);
2528 STD_OVERFLOW_CHECK(pStubMsg);
2533 /***********************************************************************
2534 * NdrUserMarshalUnmarshall [RPCRT4.@]
2536 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2537 unsigned char **ppMemory,
2538 PFORMAT_STRING pFormat,
2539 unsigned char fMustAlloc)
2541 /* unsigned flags = pFormat[1];*/
2542 unsigned index = *(const WORD*)&pFormat[2];
2543 DWORD memsize = *(const WORD*)&pFormat[4];
2544 unsigned long uflag = UserMarshalFlags(pStubMsg);
2545 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2546 TRACE("index=%d\n", index);
2548 if (fMustAlloc || !*ppMemory)
2549 *ppMemory = NdrAllocate(pStubMsg, memsize);
2552 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
2553 &uflag, pStubMsg->Buffer, *ppMemory);
2558 /***********************************************************************
2559 * NdrUserMarshalBufferSize [RPCRT4.@]
2561 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2562 unsigned char *pMemory,
2563 PFORMAT_STRING pFormat)
2565 /* unsigned flags = pFormat[1];*/
2566 unsigned index = *(const WORD*)&pFormat[2];
2567 DWORD bufsize = *(const WORD*)&pFormat[6];
2568 unsigned long uflag = UserMarshalFlags(pStubMsg);
2569 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2570 TRACE("index=%d\n", index);
2573 TRACE("size=%ld\n", bufsize);
2574 pStubMsg->BufferLength += bufsize;
2578 pStubMsg->BufferLength =
2579 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
2580 &uflag, pStubMsg->BufferLength, pMemory);
2583 /***********************************************************************
2584 * NdrUserMarshalMemorySize [RPCRT4.@]
2586 unsigned long WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2587 PFORMAT_STRING pFormat)
2589 unsigned index = *(const WORD*)&pFormat[2];
2590 /* DWORD memsize = *(const WORD*)&pFormat[4]; */
2591 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
2592 TRACE("index=%d\n", index);
2597 /***********************************************************************
2598 * NdrUserMarshalFree [RPCRT4.@]
2600 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
2601 unsigned char *pMemory,
2602 PFORMAT_STRING pFormat)
2604 /* unsigned flags = pFormat[1]; */
2605 unsigned index = *(const WORD*)&pFormat[2];
2606 unsigned long uflag = UserMarshalFlags(pStubMsg);
2607 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2608 TRACE("index=%d\n", index);
2610 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
2614 /***********************************************************************
2615 * NdrClearOutParameters [RPCRT4.@]
2617 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
2618 PFORMAT_STRING pFormat,
2621 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
2624 /***********************************************************************
2625 * NdrConvert [RPCRT4.@]
2627 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
2629 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
2630 /* FIXME: since this stub doesn't do any converting, the proper behavior
2631 is to raise an exception */
2634 /***********************************************************************
2635 * NdrConvert2 [RPCRT4.@]
2637 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, long NumberParams )
2639 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %ld): stub.\n",
2640 pStubMsg, pFormat, NumberParams);
2641 /* FIXME: since this stub doesn't do any converting, the proper behavior
2642 is to raise an exception */
2645 typedef struct _NDR_CSTRUCT_FORMAT
2648 unsigned char alignment;
2649 unsigned short memory_size;
2650 short offset_to_array_description;
2651 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
2653 /***********************************************************************
2654 * NdrConformantStructMarshall [RPCRT4.@]
2656 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2657 unsigned char *pMemory,
2658 PFORMAT_STRING pFormat)
2660 const NDR_CSTRUCT_FORMAT * pCStructFormat = (NDR_CSTRUCT_FORMAT*)pFormat;
2661 PFORMAT_STRING pCArrayFormat;
2664 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2666 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
2667 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
2669 ERR("invalid format type %x\n", pCStructFormat->type);
2670 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2674 pCArrayFormat = (unsigned char*)&pCStructFormat->offset_to_array_description +
2675 pCStructFormat->offset_to_array_description;
2676 if (*pCArrayFormat != RPC_FC_CARRAY)
2678 ERR("invalid array format type %x\n", pCStructFormat->type);
2679 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2682 esize = *(const WORD*)(pCArrayFormat+2);
2684 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
2685 pCArrayFormat + 4, 0);
2687 WriteConformance(pStubMsg);
2689 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
2691 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
2693 /* copy constant sized part of struct */
2694 pStubMsg->BufferMark = pStubMsg->Buffer;
2695 memcpy(pStubMsg->Buffer, pMemory, pCStructFormat->memory_size + pStubMsg->MaxCount * esize);
2696 pStubMsg->Buffer += pCStructFormat->memory_size + pStubMsg->MaxCount * esize;
2698 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
2699 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2701 STD_OVERFLOW_CHECK(pStubMsg);
2706 /***********************************************************************
2707 * NdrConformantStructUnmarshall [RPCRT4.@]
2709 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2710 unsigned char **ppMemory,
2711 PFORMAT_STRING pFormat,
2712 unsigned char fMustAlloc)
2714 const NDR_CSTRUCT_FORMAT * pCStructFormat = (NDR_CSTRUCT_FORMAT*)pFormat;
2715 PFORMAT_STRING pCArrayFormat;
2718 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2720 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
2721 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
2723 ERR("invalid format type %x\n", pCStructFormat->type);
2724 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2727 pCArrayFormat = (unsigned char*)&pCStructFormat->offset_to_array_description +
2728 pCStructFormat->offset_to_array_description;
2729 if (*pCArrayFormat != RPC_FC_CARRAY)
2731 ERR("invalid array format type %x\n", pCStructFormat->type);
2732 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2735 esize = *(const WORD*)(pCArrayFormat+2);
2737 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
2739 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
2741 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
2743 /* work out how much memory to allocate if we need to do so */
2744 if (!*ppMemory || fMustAlloc)
2746 SIZE_T size = pCStructFormat->memory_size + pStubMsg->MaxCount * esize;
2747 *ppMemory = NdrAllocate(pStubMsg, size);
2750 /* now copy the data */
2751 pStubMsg->BufferMark = pStubMsg->Buffer;
2752 memcpy(*ppMemory, pStubMsg->Buffer, pCStructFormat->memory_size + pStubMsg->MaxCount * esize);
2753 pStubMsg->Buffer += pCStructFormat->memory_size + pStubMsg->MaxCount * esize;
2755 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
2756 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2761 /***********************************************************************
2762 * NdrConformantStructBufferSize [RPCRT4.@]
2764 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2765 unsigned char *pMemory,
2766 PFORMAT_STRING pFormat)
2768 const NDR_CSTRUCT_FORMAT * pCStructFormat = (NDR_CSTRUCT_FORMAT*)pFormat;
2769 PFORMAT_STRING pCArrayFormat;
2772 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2774 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
2775 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
2777 ERR("invalid format type %x\n", pCStructFormat->type);
2778 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2781 pCArrayFormat = (unsigned char*)&pCStructFormat->offset_to_array_description +
2782 pCStructFormat->offset_to_array_description;
2783 if (*pCArrayFormat != RPC_FC_CARRAY)
2785 ERR("invalid array format type %x\n", pCStructFormat->type);
2786 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2789 esize = *(const WORD*)(pCArrayFormat+2);
2791 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
2792 SizeConformance(pStubMsg);
2794 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
2796 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
2798 pStubMsg->BufferLength += pCStructFormat->memory_size + esize * pStubMsg->MaxCount;
2800 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
2801 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
2804 /***********************************************************************
2805 * NdrConformantStructMemorySize [RPCRT4.@]
2807 unsigned long WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2808 PFORMAT_STRING pFormat)
2814 /***********************************************************************
2815 * NdrConformantStructFree [RPCRT4.@]
2817 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2818 unsigned char *pMemory,
2819 PFORMAT_STRING pFormat)
2824 /***********************************************************************
2825 * NdrConformantVaryingStructMarshall [RPCRT4.@]
2827 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2828 unsigned char *pMemory,
2829 PFORMAT_STRING pFormat)
2831 const NDR_CVSTRUCT_FORMAT * pCVStructFormat = (NDR_CVSTRUCT_FORMAT*)pFormat;
2832 PFORMAT_STRING pCVArrayFormat;
2835 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
2837 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
2838 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
2840 ERR("invalid format type %x\n", pCVStructFormat->type);
2841 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2845 pCVArrayFormat = (unsigned char*)&pCVStructFormat->offset_to_array_description +
2846 pCVStructFormat->offset_to_array_description;
2847 switch (*pCVArrayFormat)
2849 case RPC_FC_CVARRAY:
2850 esize = *(const WORD*)(pCVArrayFormat+2);
2852 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
2853 pCVArrayFormat + 4, 0);
2854 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
2857 case RPC_FC_C_CSTRING:
2858 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
2859 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
2860 esize = sizeof(char);
2861 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
2862 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
2863 pCVArrayFormat + 2, 0);
2865 pStubMsg->MaxCount = pStubMsg->ActualCount;
2867 case RPC_FC_C_WSTRING:
2868 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
2869 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
2870 esize = sizeof(WCHAR);
2871 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
2872 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
2873 pCVArrayFormat + 2, 0);
2875 pStubMsg->MaxCount = pStubMsg->ActualCount;
2878 ERR("invalid array format type %x\n", *pCVArrayFormat);
2879 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2883 WriteConformance(pStubMsg);
2885 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
2887 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
2889 /* write constant sized part */
2890 pStubMsg->BufferMark = pStubMsg->Buffer;
2891 memcpy(pStubMsg->Buffer, pMemory, pCVStructFormat->memory_size);
2892 pStubMsg->Buffer += pCVStructFormat->memory_size;
2894 WriteVariance(pStubMsg);
2896 /* write array part */
2897 memcpy(pStubMsg->Buffer, pMemory + pCVStructFormat->memory_size, pStubMsg->ActualCount * esize);
2898 pStubMsg->Buffer += pStubMsg->ActualCount * esize;
2900 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2902 STD_OVERFLOW_CHECK(pStubMsg);
2907 /***********************************************************************
2908 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
2910 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2911 unsigned char **ppMemory,
2912 PFORMAT_STRING pFormat,
2913 unsigned char fMustAlloc)
2915 const NDR_CVSTRUCT_FORMAT * pCVStructFormat = (NDR_CVSTRUCT_FORMAT*)pFormat;
2916 PFORMAT_STRING pCVArrayFormat;
2918 unsigned char cvarray_type;
2920 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2922 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
2923 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
2925 ERR("invalid format type %x\n", pCVStructFormat->type);
2926 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2930 pCVArrayFormat = (unsigned char*)&pCVStructFormat->offset_to_array_description +
2931 pCVStructFormat->offset_to_array_description;
2932 cvarray_type = *pCVArrayFormat;
2933 switch (cvarray_type)
2935 case RPC_FC_CVARRAY:
2936 esize = *(const WORD*)(pCVArrayFormat+2);
2937 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
2939 case RPC_FC_C_CSTRING:
2940 esize = sizeof(char);
2941 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
2942 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
2944 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
2946 case RPC_FC_C_WSTRING:
2947 esize = sizeof(WCHAR);
2948 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
2949 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
2951 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
2954 ERR("invalid array format type %x\n", *pCVArrayFormat);
2955 RpcRaiseException(RPC_S_INTERNAL_ERROR);
2959 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
2961 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
2963 /* work out how much memory to allocate if we need to do so */
2964 if (!*ppMemory || fMustAlloc)
2966 SIZE_T size = pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
2967 *ppMemory = NdrAllocate(pStubMsg, size);
2970 /* copy the constant data */
2971 pStubMsg->BufferMark = pStubMsg->Buffer;
2972 memcpy(*ppMemory, pStubMsg->Buffer, pCVStructFormat->memory_size);
2973 pStubMsg->Buffer += pCVStructFormat->memory_size;
2975 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat);
2977 /* copy the array data */
2978 memcpy(*ppMemory + pCVStructFormat->memory_size, pStubMsg->Buffer,
2979 pStubMsg->ActualCount * esize);
2980 pStubMsg->Buffer += pStubMsg->ActualCount * esize;
2982 if (cvarray_type == RPC_FC_C_CSTRING)
2983 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
2984 else if (cvarray_type == RPC_FC_C_WSTRING)
2985 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
2987 EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
2992 /***********************************************************************
2993 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
2995 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2996 unsigned char *pMemory,
2997 PFORMAT_STRING pFormat)
2999 const NDR_CVSTRUCT_FORMAT * pCVStructFormat = (NDR_CVSTRUCT_FORMAT*)pFormat;
3000 PFORMAT_STRING pCVArrayFormat;
3003 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3005 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3006 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3008 ERR("invalid format type %x\n", pCVStructFormat->type);
3009 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3013 pCVArrayFormat = (unsigned char*)&pCVStructFormat->offset_to_array_description +
3014 pCVStructFormat->offset_to_array_description;
3015 switch (*pCVArrayFormat)
3017 case RPC_FC_CVARRAY:
3018 esize = *(const WORD*)(pCVArrayFormat+2);
3020 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3021 pCVArrayFormat + 4, 0);
3022 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3023 pCVArrayFormat + 4, 0);
3025 case RPC_FC_C_CSTRING:
3026 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3027 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3028 esize = sizeof(char);
3029 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3030 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3031 pCVArrayFormat + 2, 0);
3033 pStubMsg->MaxCount = pStubMsg->ActualCount;
3035 case RPC_FC_C_WSTRING:
3036 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3037 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3038 esize = sizeof(WCHAR);
3039 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3040 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3041 pCVArrayFormat + 2, 0);
3043 pStubMsg->MaxCount = pStubMsg->ActualCount;
3046 ERR("invalid array format type %x\n", *pCVArrayFormat);
3047 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3051 SizeConformance(pStubMsg);
3053 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
3055 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3057 pStubMsg->BufferLength += pCVStructFormat->memory_size;
3058 SizeVariance(pStubMsg);
3059 pStubMsg->BufferLength += esize * pStubMsg->MaxCount;
3061 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3064 /***********************************************************************
3065 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
3067 unsigned long WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3068 PFORMAT_STRING pFormat)
3070 const NDR_CVSTRUCT_FORMAT * pCVStructFormat = (NDR_CVSTRUCT_FORMAT*)pFormat;
3071 PFORMAT_STRING pCVArrayFormat;
3073 unsigned char cvarray_type;
3075 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3077 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3078 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3080 ERR("invalid format type %x\n", pCVStructFormat->type);
3081 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3085 pCVArrayFormat = (unsigned char*)&pCVStructFormat->offset_to_array_description +
3086 pCVStructFormat->offset_to_array_description;
3087 cvarray_type = *pCVArrayFormat;
3088 switch (cvarray_type)
3090 case RPC_FC_CVARRAY:
3091 esize = *(const WORD*)(pCVArrayFormat+2);
3092 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
3094 case RPC_FC_C_CSTRING:
3095 esize = sizeof(char);
3096 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3097 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3099 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3101 case RPC_FC_C_WSTRING:
3102 esize = sizeof(WCHAR);
3103 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3104 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
3106 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
3109 ERR("invalid array format type %x\n", *pCVArrayFormat);
3110 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3114 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
3116 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3118 pStubMsg->Buffer += pCVStructFormat->memory_size;
3119 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat);
3120 pStubMsg->Buffer += pCVStructFormat->memory_size + pStubMsg->ActualCount * esize;
3122 pStubMsg->MemorySize += pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
3124 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3126 return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
3129 /***********************************************************************
3130 * NdrConformantVaryingStructFree [RPCRT4.@]
3132 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3133 unsigned char *pMemory,
3134 PFORMAT_STRING pFormat)
3136 const NDR_CVSTRUCT_FORMAT * pCVStructFormat = (NDR_CVSTRUCT_FORMAT*)pFormat;
3137 PFORMAT_STRING pCVArrayFormat;
3140 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3142 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
3143 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
3145 ERR("invalid format type %x\n", pCVStructFormat->type);
3146 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3150 pCVArrayFormat = (unsigned char*)&pCVStructFormat->offset_to_array_description +
3151 pCVStructFormat->offset_to_array_description;
3152 switch (*pCVArrayFormat)
3154 case RPC_FC_CVARRAY:
3155 esize = *(const WORD*)(pCVArrayFormat+2);
3157 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3158 pCVArrayFormat + 4, 0);
3159 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3162 case RPC_FC_C_CSTRING:
3163 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
3164 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
3165 esize = sizeof(char);
3166 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3167 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3168 pCVArrayFormat + 2, 0);
3170 pStubMsg->MaxCount = pStubMsg->ActualCount;
3172 case RPC_FC_C_WSTRING:
3173 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
3174 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
3175 esize = sizeof(WCHAR);
3176 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
3177 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
3178 pCVArrayFormat + 2, 0);
3180 pStubMsg->MaxCount = pStubMsg->ActualCount;
3183 ERR("invalid array format type %x\n", *pCVArrayFormat);
3184 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3188 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
3190 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3193 /***********************************************************************
3194 * NdrFixedArrayMarshall [RPCRT4.@]
3196 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3197 unsigned char *pMemory,
3198 PFORMAT_STRING pFormat)
3204 /***********************************************************************
3205 * NdrFixedArrayUnmarshall [RPCRT4.@]
3207 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3208 unsigned char **ppMemory,
3209 PFORMAT_STRING pFormat,
3210 unsigned char fMustAlloc)
3216 /***********************************************************************
3217 * NdrFixedArrayBufferSize [RPCRT4.@]
3219 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3220 unsigned char *pMemory,
3221 PFORMAT_STRING pFormat)
3226 /***********************************************************************
3227 * NdrFixedArrayMemorySize [RPCRT4.@]
3229 unsigned long WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3230 PFORMAT_STRING pFormat)
3236 /***********************************************************************
3237 * NdrFixedArrayFree [RPCRT4.@]
3239 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3240 unsigned char *pMemory,
3241 PFORMAT_STRING pFormat)
3246 /***********************************************************************
3247 * NdrVaryingArrayMarshall [RPCRT4.@]
3249 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3250 unsigned char *pMemory,
3251 PFORMAT_STRING pFormat)
3257 /***********************************************************************
3258 * NdrVaryingArrayUnmarshall [RPCRT4.@]
3260 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3261 unsigned char **ppMemory,
3262 PFORMAT_STRING pFormat,
3263 unsigned char fMustAlloc)
3269 /***********************************************************************
3270 * NdrVaryingArrayBufferSize [RPCRT4.@]
3272 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3273 unsigned char *pMemory,
3274 PFORMAT_STRING pFormat)
3279 /***********************************************************************
3280 * NdrVaryingArrayMemorySize [RPCRT4.@]
3282 unsigned long WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3283 PFORMAT_STRING pFormat)
3289 /***********************************************************************
3290 * NdrVaryingArrayFree [RPCRT4.@]
3292 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3293 unsigned char *pMemory,
3294 PFORMAT_STRING pFormat)
3299 /***********************************************************************
3300 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
3302 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3303 unsigned char *pMemory,
3304 PFORMAT_STRING pFormat)
3310 /***********************************************************************
3311 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
3313 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3314 unsigned char **ppMemory,
3315 PFORMAT_STRING pFormat,
3316 unsigned char fMustAlloc)
3322 /***********************************************************************
3323 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
3325 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3326 unsigned char *pMemory,
3327 PFORMAT_STRING pFormat)
3332 /***********************************************************************
3333 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
3335 unsigned long WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3336 PFORMAT_STRING pFormat)
3342 /***********************************************************************
3343 * NdrEncapsulatedUnionFree [RPCRT4.@]
3345 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
3346 unsigned char *pMemory,
3347 PFORMAT_STRING pFormat)
3352 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
3353 unsigned long discriminant,
3354 PFORMAT_STRING pFormat)
3356 unsigned short num_arms, arm, type;
3358 num_arms = *(const SHORT*)pFormat & 0x0fff;
3360 for(arm = 0; arm < num_arms; arm++)
3362 if(discriminant == *(const ULONG*)pFormat)
3370 type = *(const unsigned short*)pFormat;
3371 TRACE("type %04x\n", type);
3372 if(arm == num_arms) /* default arm extras */
3376 FIXME("should raise an exception here\n");
3381 /* Don't marshall any type. FIXME is this correct? */
3388 static PFORMAT_STRING get_non_encapsulated_union_arm(PMIDL_STUB_MESSAGE pStubMsg,
3390 PFORMAT_STRING pFormat)
3392 pFormat += *(const SHORT*)pFormat;
3395 return get_arm_offset_from_union_arm_selector(pStubMsg, value, pFormat);
3398 /***********************************************************************
3399 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
3401 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3402 unsigned char *pMemory,
3403 PFORMAT_STRING pFormat)
3405 unsigned short type;
3406 unsigned char switch_type;
3408 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3411 switch_type = *pFormat;
3414 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
3415 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
3416 /* Marshall discriminant */
3417 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
3419 pFormat = get_non_encapsulated_union_arm(pStubMsg, pStubMsg->MaxCount, pFormat);
3423 type = *(const unsigned short*)pFormat;
3424 if((type & 0xff00) == 0x8000)
3426 unsigned char basetype = LOBYTE(type);
3427 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
3431 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
3432 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
3435 unsigned char *saved_buffer = NULL;
3442 saved_buffer = pStubMsg->Buffer;
3443 pStubMsg->Buffer += 4; /* for pointer ID */
3444 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
3447 m(pStubMsg, pMemory, desc);
3450 else FIXME("no marshaller for embedded type %02x\n", *desc);
3455 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
3456 PFORMAT_STRING *ppFormat)
3458 long discriminant = 0;
3466 discriminant = *(UCHAR *)pStubMsg->Buffer;
3467 pStubMsg->Buffer += sizeof(UCHAR);
3472 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
3473 discriminant = *(USHORT *)pStubMsg->Buffer;
3474 pStubMsg->Buffer += sizeof(USHORT);
3478 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
3479 discriminant = *(ULONG *)pStubMsg->Buffer;
3480 pStubMsg->Buffer += sizeof(ULONG);
3483 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
3487 if (pStubMsg->fHasNewCorrDesc)
3491 return discriminant;
3494 /**********************************************************************
3495 * NdrNonEncapsulatedUnionUnmarshall[RPCRT4.@]
3497 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3498 unsigned char **ppMemory,
3499 PFORMAT_STRING pFormat,
3500 unsigned char fMustAlloc)
3503 unsigned short type, size;
3505 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3508 /* Unmarshall discriminant */
3509 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
3510 TRACE("unmarshalled discriminant %lx\n", discriminant);
3512 pFormat += *(const SHORT*)pFormat;
3514 size = *(const unsigned short*)pFormat;
3517 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
3521 if(!*ppMemory || fMustAlloc)
3522 *ppMemory = NdrAllocate(pStubMsg, size);
3524 type = *(const unsigned short*)pFormat;
3525 if((type & 0xff00) == 0x8000)
3527 unsigned char basetype = LOBYTE(type);
3528 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, fMustAlloc);
3532 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
3533 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
3536 unsigned char *saved_buffer = NULL;
3543 **(void***)ppMemory = NULL;
3544 ALIGN_POINTER(pStubMsg->Buffer, 4);
3545 saved_buffer = pStubMsg->Buffer;
3546 pStubMsg->Buffer += 4; /* for pointer ID */
3547 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, desc, fMustAlloc);
3550 m(pStubMsg, ppMemory, desc, fMustAlloc);
3553 else FIXME("no marshaller for embedded type %02x\n", *desc);
3558 /***********************************************************************
3559 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
3561 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3562 unsigned char *pMemory,
3563 PFORMAT_STRING pFormat)
3565 unsigned short type;
3566 unsigned char switch_type;
3568 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3571 switch_type = *pFormat;
3574 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
3575 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
3576 /* Add discriminant size */
3577 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
3579 pFormat = get_non_encapsulated_union_arm(pStubMsg, pStubMsg->MaxCount, pFormat);
3583 type = *(const unsigned short*)pFormat;
3584 if((type & 0xff00) == 0x8000)
3586 unsigned char basetype = LOBYTE(type);
3587 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
3591 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
3592 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
3601 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
3602 pStubMsg->BufferLength += 4; /* for pointer ID */
3603 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
3606 m(pStubMsg, pMemory, desc);
3609 else FIXME("no buffersizer for embedded type %02x\n", *desc);
3614 /***********************************************************************
3615 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
3617 unsigned long WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3618 PFORMAT_STRING pFormat)
3621 if (pStubMsg->fHasNewCorrDesc)
3626 pFormat += *(const SHORT*)pFormat;
3627 TRACE("size %d\n", *(const SHORT*)pFormat);
3628 return *(const SHORT*)pFormat;
3631 /***********************************************************************
3632 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
3634 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
3635 unsigned char *pMemory,
3636 PFORMAT_STRING pFormat)
3641 /***********************************************************************
3642 * NdrByteCountPointerMarshall [RPCRT4.@]
3644 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3645 unsigned char *pMemory,
3646 PFORMAT_STRING pFormat)
3652 /***********************************************************************
3653 * NdrByteCountPointerUnmarshall [RPCRT4.@]
3655 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3656 unsigned char **ppMemory,
3657 PFORMAT_STRING pFormat,
3658 unsigned char fMustAlloc)
3664 /***********************************************************************
3665 * NdrByteCountPointerBufferSize [RPCRT4.@]
3667 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3668 unsigned char *pMemory,
3669 PFORMAT_STRING pFormat)
3674 /***********************************************************************
3675 * NdrByteCountPointerMemorySize [RPCRT4.@]
3677 unsigned long WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3678 PFORMAT_STRING pFormat)
3684 /***********************************************************************
3685 * NdrByteCountPointerFree [RPCRT4.@]
3687 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
3688 unsigned char *pMemory,
3689 PFORMAT_STRING pFormat)
3694 /***********************************************************************
3695 * NdrXmitOrRepAsMarshall [RPCRT4.@]
3697 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3698 unsigned char *pMemory,
3699 PFORMAT_STRING pFormat)
3705 /***********************************************************************
3706 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
3708 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3709 unsigned char **ppMemory,
3710 PFORMAT_STRING pFormat,
3711 unsigned char fMustAlloc)
3717 /***********************************************************************
3718 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
3720 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3721 unsigned char *pMemory,
3722 PFORMAT_STRING pFormat)
3727 /***********************************************************************
3728 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
3730 unsigned long WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3731 PFORMAT_STRING pFormat)
3737 /***********************************************************************
3738 * NdrXmitOrRepAsFree [RPCRT4.@]
3740 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
3741 unsigned char *pMemory,
3742 PFORMAT_STRING pFormat)
3747 /***********************************************************************
3748 * NdrBaseTypeMarshall [internal]
3750 static unsigned char *WINAPI NdrBaseTypeMarshall(
3751 PMIDL_STUB_MESSAGE pStubMsg,
3752 unsigned char *pMemory,
3753 PFORMAT_STRING pFormat)
3755 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
3763 *(UCHAR *)pStubMsg->Buffer = *(UCHAR *)pMemory;
3764 pStubMsg->Buffer += sizeof(UCHAR);
3765 TRACE("value: 0x%02x\n", *(UCHAR *)pMemory);
3770 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
3771 *(USHORT *)pStubMsg->Buffer = *(USHORT *)pMemory;
3772 pStubMsg->Buffer += sizeof(USHORT);
3773 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
3777 case RPC_FC_ERROR_STATUS_T:
3779 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
3780 *(ULONG *)pStubMsg->Buffer = *(ULONG *)pMemory;
3781 pStubMsg->Buffer += sizeof(ULONG);
3782 TRACE("value: 0x%08lx\n", *(ULONG *)pMemory);
3785 ALIGN_POINTER(pStubMsg->Buffer, sizeof(float));
3786 *(float *)pStubMsg->Buffer = *(float *)pMemory;
3787 pStubMsg->Buffer += sizeof(float);
3790 ALIGN_POINTER(pStubMsg->Buffer, sizeof(double));
3791 *(double *)pStubMsg->Buffer = *(double *)pMemory;
3792 pStubMsg->Buffer += sizeof(double);
3795 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG));
3796 *(ULONGLONG *)pStubMsg->Buffer = *(ULONGLONG *)pMemory;
3797 pStubMsg->Buffer += sizeof(ULONGLONG);
3798 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
3801 /* only 16-bits on the wire, so do a sanity check */
3802 if (*(UINT *)pMemory > USHRT_MAX)
3803 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
3804 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
3805 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
3806 pStubMsg->Buffer += sizeof(USHORT);
3807 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
3810 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
3813 STD_OVERFLOW_CHECK(pStubMsg);
3815 /* FIXME: what is the correct return value? */
3819 /***********************************************************************
3820 * NdrBaseTypeUnmarshall [internal]
3822 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
3823 PMIDL_STUB_MESSAGE pStubMsg,
3824 unsigned char **ppMemory,
3825 PFORMAT_STRING pFormat,
3826 unsigned char fMustAlloc)
3828 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
3830 if (fMustAlloc || !*ppMemory)
3832 unsigned char *Buffer = pStubMsg->Buffer;
3833 *ppMemory = NdrAllocate(pStubMsg, NdrBaseTypeMemorySize(pStubMsg, pFormat));
3834 pStubMsg->Buffer = Buffer;
3837 TRACE("*ppMemory: %p\n", *ppMemory);
3845 **(UCHAR **)ppMemory = *(UCHAR *)pStubMsg->Buffer;
3846 pStubMsg->Buffer += sizeof(UCHAR);
3847 TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
3852 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
3853 **(USHORT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
3854 pStubMsg->Buffer += sizeof(USHORT);
3855 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
3859 case RPC_FC_ERROR_STATUS_T:
3861 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
3862 **(ULONG **)ppMemory = *(ULONG *)pStubMsg->Buffer;
3863 pStubMsg->Buffer += sizeof(ULONG);
3864 TRACE("value: 0x%08lx\n", **(ULONG **)ppMemory);
3867 ALIGN_POINTER(pStubMsg->Buffer, sizeof(float));
3868 **(float **)ppMemory = *(float *)pStubMsg->Buffer;
3869 pStubMsg->Buffer += sizeof(float);
3870 TRACE("value: %f\n", **(float **)ppMemory);
3873 ALIGN_POINTER(pStubMsg->Buffer, sizeof(double));
3874 **(double **)ppMemory = *(double*)pStubMsg->Buffer;
3875 pStubMsg->Buffer += sizeof(double);
3876 TRACE("value: %f\n", **(double **)ppMemory);
3879 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG));
3880 **(ULONGLONG **)ppMemory = *(ULONGLONG *)pStubMsg->Buffer;
3881 pStubMsg->Buffer += sizeof(ULONGLONG);
3882 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
3885 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
3886 /* 16-bits on the wire, but int in memory */
3887 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
3888 pStubMsg->Buffer += sizeof(USHORT);
3889 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
3892 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
3895 /* FIXME: what is the correct return value? */
3900 /***********************************************************************
3901 * NdrBaseTypeBufferSize [internal]
3903 static void WINAPI NdrBaseTypeBufferSize(
3904 PMIDL_STUB_MESSAGE pStubMsg,
3905 unsigned char *pMemory,
3906 PFORMAT_STRING pFormat)
3908 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
3916 pStubMsg->BufferLength += sizeof(UCHAR);
3922 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
3923 pStubMsg->BufferLength += sizeof(USHORT);
3928 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
3929 pStubMsg->BufferLength += sizeof(ULONG);
3932 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
3933 pStubMsg->BufferLength += sizeof(float);
3936 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
3937 pStubMsg->BufferLength += sizeof(double);
3940 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
3941 pStubMsg->BufferLength += sizeof(ULONGLONG);
3943 case RPC_FC_ERROR_STATUS_T:
3944 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
3945 pStubMsg->BufferLength += sizeof(error_status_t);
3948 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
3952 /***********************************************************************
3953 * NdrBaseTypeMemorySize [internal]
3955 static unsigned long WINAPI NdrBaseTypeMemorySize(
3956 PMIDL_STUB_MESSAGE pStubMsg,
3957 PFORMAT_STRING pFormat)
3965 pStubMsg->Buffer += sizeof(UCHAR);
3966 pStubMsg->MemorySize += sizeof(UCHAR);
3967 return sizeof(UCHAR);
3971 pStubMsg->Buffer += sizeof(USHORT);
3972 pStubMsg->MemorySize += sizeof(USHORT);
3973 return sizeof(USHORT);
3976 pStubMsg->Buffer += sizeof(ULONG);
3977 pStubMsg->MemorySize += sizeof(ULONG);
3978 return sizeof(ULONG);
3980 pStubMsg->Buffer += sizeof(float);
3981 pStubMsg->MemorySize += sizeof(float);
3982 return sizeof(float);
3984 pStubMsg->Buffer += sizeof(double);
3985 pStubMsg->MemorySize += sizeof(double);
3986 return sizeof(double);
3988 pStubMsg->Buffer += sizeof(ULONGLONG);
3989 pStubMsg->MemorySize += sizeof(ULONGLONG);
3990 return sizeof(ULONGLONG);
3991 case RPC_FC_ERROR_STATUS_T:
3992 pStubMsg->Buffer += sizeof(error_status_t);
3993 pStubMsg->MemorySize += sizeof(error_status_t);
3994 return sizeof(error_status_t);
3997 pStubMsg->Buffer += sizeof(INT);
3998 pStubMsg->MemorySize += sizeof(INT);
4001 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
4006 /***********************************************************************
4007 * NdrBaseTypeFree [internal]
4009 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
4010 unsigned char *pMemory,
4011 PFORMAT_STRING pFormat)
4013 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
4018 /***********************************************************************
4019 * NdrClientContextMarshall
4021 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4022 NDR_CCONTEXT ContextHandle,
4025 FIXME("(%p, %p, %d): stub\n", pStubMsg, ContextHandle, fCheck);
4028 /***********************************************************************
4029 * NdrClientContextUnmarshall
4031 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4032 NDR_CCONTEXT * pContextHandle,
4033 RPC_BINDING_HANDLE BindHandle)
4035 FIXME("(%p, %p, %p): stub\n", pStubMsg, pContextHandle, BindHandle);
4038 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4039 NDR_SCONTEXT ContextHandle,
4040 NDR_RUNDOWN RundownRoutine )
4042 FIXME("(%p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine);
4045 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
4047 FIXME("(%p): stub\n", pStubMsg);
4051 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
4052 unsigned char* pMemory,
4053 PFORMAT_STRING pFormat)
4055 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
4058 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
4059 PFORMAT_STRING pFormat)
4061 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
4065 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4066 NDR_SCONTEXT ContextHandle,
4067 NDR_RUNDOWN RundownRoutine,
4068 PFORMAT_STRING pFormat)
4070 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
4073 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4074 PFORMAT_STRING pFormat)
4076 FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
4080 RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext)
4082 FIXME("(%p): stub\n", CContext);