4 * Copyright 2002 Greg Turner
5 * Copyright 2003-2006 CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 * - Non-conformant strings
24 * - Encapsulated unions
25 * - Byte count pointers
26 * - transmit_as/represent as
27 * - Multi-dimensional arrays
28 * - Conversion functions (NdrConvert)
29 * - Checks for integer addition overflow
30 * - Checks for out-of-memory conditions
46 #include "wine/unicode.h"
47 #include "wine/rpcfc.h"
49 #include "wine/debug.h"
50 #include "wine/list.h"
52 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
55 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
56 (*((UINT32 *)(pchar)) = (uint32))
58 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
59 (*((UINT32 *)(pchar)))
61 /* these would work for i386 too, but less efficient */
62 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
63 (*(pchar) = LOBYTE(LOWORD(uint32)), \
64 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
65 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
66 *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
67 (uint32)) /* allow as r-value */
69 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
71 MAKEWORD(*(pchar), *((pchar)+1)), \
72 MAKEWORD(*((pchar)+2), *((pchar)+3))))
75 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
76 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
77 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
78 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
79 *(pchar) = HIBYTE(HIWORD(uint32)), \
80 (uint32)) /* allow as r-value */
82 #define BIG_ENDIAN_UINT32_READ(pchar) \
84 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
85 MAKEWORD(*((pchar)+1), *(pchar))))
87 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
88 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
89 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
90 # define NDR_LOCAL_UINT32_READ(pchar) \
91 BIG_ENDIAN_UINT32_READ(pchar)
93 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
94 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
95 # define NDR_LOCAL_UINT32_READ(pchar) \
96 LITTLE_ENDIAN_UINT32_READ(pchar)
99 /* _Align must be the desired alignment,
100 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
101 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
102 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
103 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
104 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
106 #define STD_OVERFLOW_CHECK(_Msg) do { \
107 TRACE("buffer=%d/%d\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
108 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
109 ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
112 #define NDR_TABLE_SIZE 128
113 #define NDR_TABLE_MASK 127
115 static unsigned char *WINAPI
NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
116 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
117 static void WINAPI
NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
118 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
119 static ULONG WINAPI
NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
121 const NDR_MARSHALL NdrMarshaller
[NDR_TABLE_SIZE
] = {
123 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
124 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
125 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
126 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
130 NdrPointerMarshall
, NdrPointerMarshall
,
131 NdrPointerMarshall
, NdrPointerMarshall
,
133 NdrSimpleStructMarshall
, NdrSimpleStructMarshall
,
134 NdrConformantStructMarshall
, NdrConformantStructMarshall
,
135 NdrConformantVaryingStructMarshall
,
136 NdrComplexStructMarshall
,
138 NdrConformantArrayMarshall
,
139 NdrConformantVaryingArrayMarshall
,
140 NdrFixedArrayMarshall
, NdrFixedArrayMarshall
,
141 NdrVaryingArrayMarshall
, NdrVaryingArrayMarshall
,
142 NdrComplexArrayMarshall
,
144 NdrConformantStringMarshall
, 0, 0,
145 NdrConformantStringMarshall
,
146 NdrNonConformantStringMarshall
, 0, 0, 0,
148 NdrEncapsulatedUnionMarshall
,
149 NdrNonEncapsulatedUnionMarshall
,
150 NdrByteCountPointerMarshall
,
151 NdrXmitOrRepAsMarshall
, NdrXmitOrRepAsMarshall
,
153 NdrInterfacePointerMarshall
,
156 NdrUserMarshalMarshall
158 const NDR_UNMARSHALL NdrUnmarshaller
[NDR_TABLE_SIZE
] = {
160 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
161 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
162 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
163 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
165 NdrBaseTypeUnmarshall
,
167 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
168 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
170 NdrSimpleStructUnmarshall
, NdrSimpleStructUnmarshall
,
171 NdrConformantStructUnmarshall
, NdrConformantStructUnmarshall
,
172 NdrConformantVaryingStructUnmarshall
,
173 NdrComplexStructUnmarshall
,
175 NdrConformantArrayUnmarshall
,
176 NdrConformantVaryingArrayUnmarshall
,
177 NdrFixedArrayUnmarshall
, NdrFixedArrayUnmarshall
,
178 NdrVaryingArrayUnmarshall
, NdrVaryingArrayUnmarshall
,
179 NdrComplexArrayUnmarshall
,
181 NdrConformantStringUnmarshall
, 0, 0,
182 NdrConformantStringUnmarshall
,
183 NdrNonConformantStringUnmarshall
, 0, 0, 0,
185 NdrEncapsulatedUnionUnmarshall
,
186 NdrNonEncapsulatedUnionUnmarshall
,
187 NdrByteCountPointerUnmarshall
,
188 NdrXmitOrRepAsUnmarshall
, NdrXmitOrRepAsUnmarshall
,
190 NdrInterfacePointerUnmarshall
,
193 NdrUserMarshalUnmarshall
195 const NDR_BUFFERSIZE NdrBufferSizer
[NDR_TABLE_SIZE
] = {
197 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
198 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
199 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
200 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
202 NdrBaseTypeBufferSize
,
204 NdrPointerBufferSize
, NdrPointerBufferSize
,
205 NdrPointerBufferSize
, NdrPointerBufferSize
,
207 NdrSimpleStructBufferSize
, NdrSimpleStructBufferSize
,
208 NdrConformantStructBufferSize
, NdrConformantStructBufferSize
,
209 NdrConformantVaryingStructBufferSize
,
210 NdrComplexStructBufferSize
,
212 NdrConformantArrayBufferSize
,
213 NdrConformantVaryingArrayBufferSize
,
214 NdrFixedArrayBufferSize
, NdrFixedArrayBufferSize
,
215 NdrVaryingArrayBufferSize
, NdrVaryingArrayBufferSize
,
216 NdrComplexArrayBufferSize
,
218 NdrConformantStringBufferSize
, 0, 0,
219 NdrConformantStringBufferSize
,
220 NdrNonConformantStringBufferSize
, 0, 0, 0,
222 NdrEncapsulatedUnionBufferSize
,
223 NdrNonEncapsulatedUnionBufferSize
,
224 NdrByteCountPointerBufferSize
,
225 NdrXmitOrRepAsBufferSize
, NdrXmitOrRepAsBufferSize
,
227 NdrInterfacePointerBufferSize
,
230 NdrUserMarshalBufferSize
232 const NDR_MEMORYSIZE NdrMemorySizer
[NDR_TABLE_SIZE
] = {
234 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
235 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
236 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
237 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
239 NdrBaseTypeMemorySize
,
241 NdrPointerMemorySize
, NdrPointerMemorySize
,
242 NdrPointerMemorySize
, NdrPointerMemorySize
,
244 NdrSimpleStructMemorySize
, NdrSimpleStructMemorySize
,
245 NdrConformantStructMemorySize
, NdrConformantStructMemorySize
,
246 NdrConformantVaryingStructMemorySize
,
247 NdrComplexStructMemorySize
,
249 NdrConformantArrayMemorySize
,
250 NdrConformantVaryingArrayMemorySize
,
251 NdrFixedArrayMemorySize
, NdrFixedArrayMemorySize
,
252 NdrVaryingArrayMemorySize
, NdrVaryingArrayMemorySize
,
253 NdrComplexArrayMemorySize
,
255 NdrConformantStringMemorySize
, 0, 0,
256 NdrConformantStringMemorySize
,
257 NdrNonConformantStringMemorySize
, 0, 0, 0,
259 NdrEncapsulatedUnionMemorySize
,
260 NdrNonEncapsulatedUnionMemorySize
,
261 NdrByteCountPointerMemorySize
,
262 NdrXmitOrRepAsMemorySize
, NdrXmitOrRepAsMemorySize
,
264 NdrInterfacePointerMemorySize
,
267 NdrUserMarshalMemorySize
269 const NDR_FREE NdrFreer
[NDR_TABLE_SIZE
] = {
271 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
272 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
273 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
274 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
278 NdrPointerFree
, NdrPointerFree
,
279 NdrPointerFree
, NdrPointerFree
,
281 NdrSimpleStructFree
, NdrSimpleStructFree
,
282 NdrConformantStructFree
, NdrConformantStructFree
,
283 NdrConformantVaryingStructFree
,
284 NdrComplexStructFree
,
286 NdrConformantArrayFree
,
287 NdrConformantVaryingArrayFree
,
288 NdrFixedArrayFree
, NdrFixedArrayFree
,
289 NdrVaryingArrayFree
, NdrVaryingArrayFree
,
295 NdrEncapsulatedUnionFree
,
296 NdrNonEncapsulatedUnionFree
,
298 NdrXmitOrRepAsFree
, NdrXmitOrRepAsFree
,
300 NdrInterfacePointerFree
,
306 void * WINAPI
NdrAllocate(MIDL_STUB_MESSAGE
*pStubMsg
, size_t len
)
308 /* hmm, this is probably supposed to do more? */
309 return pStubMsg
->pfnAllocate(len
);
312 static void WINAPI
NdrFree(MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *Pointer
)
314 pStubMsg
->pfnFree(Pointer
);
317 static inline BOOL
IsConformanceOrVariancePresent(PFORMAT_STRING pFormat
)
319 return (*(const ULONG
*)pFormat
!= -1);
322 static PFORMAT_STRING
ReadConformance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
)
324 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
325 pStubMsg
->MaxCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
326 pStubMsg
->Buffer
+= 4;
327 TRACE("unmarshalled conformance is %ld\n", pStubMsg
->MaxCount
);
328 if (pStubMsg
->fHasNewCorrDesc
)
334 static inline PFORMAT_STRING
ReadVariance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
, ULONG MaxValue
)
336 if (pFormat
&& !IsConformanceOrVariancePresent(pFormat
))
338 pStubMsg
->Offset
= 0;
339 pStubMsg
->ActualCount
= pStubMsg
->MaxCount
;
343 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
344 pStubMsg
->Offset
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
345 pStubMsg
->Buffer
+= 4;
346 TRACE("offset is %d\n", pStubMsg
->Offset
);
347 pStubMsg
->ActualCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
348 pStubMsg
->Buffer
+= 4;
349 TRACE("variance is %d\n", pStubMsg
->ActualCount
);
351 if ((pStubMsg
->ActualCount
> MaxValue
) ||
352 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> MaxValue
))
354 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
355 pStubMsg
->ActualCount
, pStubMsg
->Offset
, MaxValue
);
356 RpcRaiseException(RPC_S_INVALID_BOUND
);
361 if (pStubMsg
->fHasNewCorrDesc
)
367 /* writes the conformance value to the buffer */
368 static inline void WriteConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
370 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
371 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->MaxCount
);
372 pStubMsg
->Buffer
+= 4;
375 /* writes the variance values to the buffer */
376 static inline void WriteVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
378 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
379 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->Offset
);
380 pStubMsg
->Buffer
+= 4;
381 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->ActualCount
);
382 pStubMsg
->Buffer
+= 4;
385 /* requests buffer space for the conformance value */
386 static inline void SizeConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
388 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
389 pStubMsg
->BufferLength
+= 4;
392 /* requests buffer space for the variance values */
393 static inline void SizeVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
395 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
396 pStubMsg
->BufferLength
+= 8;
399 PFORMAT_STRING
ComputeConformanceOrVariance(
400 MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *pMemory
,
401 PFORMAT_STRING pFormat
, ULONG_PTR def
, ULONG_PTR
*pCount
)
403 BYTE dtype
= pFormat
[0] & 0xf;
404 short ofs
= *(const short *)&pFormat
[2];
408 if (!IsConformanceOrVariancePresent(pFormat
)) {
409 /* null descriptor */
414 switch (pFormat
[0] & 0xf0) {
415 case RPC_FC_NORMAL_CONFORMANCE
:
416 TRACE("normal conformance, ofs=%d\n", ofs
);
419 case RPC_FC_POINTER_CONFORMANCE
:
420 TRACE("pointer conformance, ofs=%d\n", ofs
);
421 ptr
= pStubMsg
->Memory
;
423 case RPC_FC_TOP_LEVEL_CONFORMANCE
:
424 TRACE("toplevel conformance, ofs=%d\n", ofs
);
425 if (pStubMsg
->StackTop
) {
426 ptr
= pStubMsg
->StackTop
;
429 /* -Os mode, *pCount is already set */
433 case RPC_FC_CONSTANT_CONFORMANCE
:
434 data
= ofs
| ((DWORD
)pFormat
[1] << 16);
435 TRACE("constant conformance, val=%d\n", data
);
438 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE
:
439 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs
);
440 if (pStubMsg
->StackTop
) {
441 ptr
= pStubMsg
->StackTop
;
449 FIXME("unknown conformance type %x\n", pFormat
[0] & 0xf0);
452 switch (pFormat
[1]) {
453 case RPC_FC_DEREFERENCE
:
454 ptr
= *(LPVOID
*)((char *)ptr
+ ofs
);
456 case RPC_FC_CALLBACK
:
458 unsigned char *old_stack_top
= pStubMsg
->StackTop
;
459 pStubMsg
->StackTop
= ptr
;
461 /* ofs is index into StubDesc->apfnExprEval */
462 TRACE("callback conformance into apfnExprEval[%d]\n", ofs
);
463 pStubMsg
->StubDesc
->apfnExprEval
[ofs
](pStubMsg
);
465 pStubMsg
->StackTop
= old_stack_top
;
467 /* the callback function always stores the computed value in MaxCount */
468 *pCount
= pStubMsg
->MaxCount
;
472 ptr
= (char *)ptr
+ ofs
;
485 data
= *(USHORT
*)ptr
;
496 FIXME("unknown conformance data type %x\n", dtype
);
499 TRACE("dereferenced data type %x at %p, got %d\n", dtype
, ptr
, data
);
502 switch (pFormat
[1]) {
503 case RPC_FC_DEREFERENCE
: /* already handled */
520 FIXME("unknown conformance op %d\n", pFormat
[1]);
525 TRACE("resulting conformance is %ld\n", *pCount
);
526 if (pStubMsg
->fHasNewCorrDesc
)
532 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
533 * the result overflows 32-bits */
534 static inline ULONG
safe_multiply(ULONG a
, ULONG b
)
536 ULONGLONG ret
= (ULONGLONG
)a
* b
;
537 if (ret
> 0xffffffff)
539 RpcRaiseException(RPC_S_INVALID_BOUND
);
547 * NdrConformantString:
549 * What MS calls a ConformantString is, in DCE terminology,
550 * a Varying-Conformant String.
552 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
553 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
554 * into unmarshalled string)
555 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
557 * data: CHARTYPE[maxlen]
559 * ], where CHARTYPE is the appropriate character type (specified externally)
563 /***********************************************************************
564 * NdrConformantStringMarshall [RPCRT4.@]
566 unsigned char *WINAPI
NdrConformantStringMarshall(MIDL_STUB_MESSAGE
*pStubMsg
,
567 unsigned char *pszMessage
, PFORMAT_STRING pFormat
)
571 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg
, pszMessage
, pFormat
);
573 if (*pFormat
== RPC_FC_C_CSTRING
) {
574 TRACE("string=%s\n", debugstr_a((char*)pszMessage
));
575 pStubMsg
->ActualCount
= strlen((char*)pszMessage
)+1;
578 else if (*pFormat
== RPC_FC_C_WSTRING
) {
579 TRACE("string=%s\n", debugstr_w((LPWSTR
)pszMessage
));
580 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pszMessage
)+1;
584 ERR("Unhandled string type: %#x\n", *pFormat
);
585 /* FIXME: raise an exception. */
589 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
590 pFormat
= ComputeConformance(pStubMsg
, pszMessage
, pFormat
+ 2, 0);
592 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
593 pStubMsg
->Offset
= 0;
594 WriteConformance(pStubMsg
);
595 WriteVariance(pStubMsg
);
597 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
598 memcpy(pStubMsg
->Buffer
, pszMessage
, size
); /* the string itself */
599 pStubMsg
->Buffer
+= size
;
601 STD_OVERFLOW_CHECK(pStubMsg
);
604 return NULL
; /* is this always right? */
607 /***********************************************************************
608 * NdrConformantStringBufferSize [RPCRT4.@]
610 void WINAPI
NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
611 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
615 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
617 SizeConformance(pStubMsg
);
618 SizeVariance(pStubMsg
);
620 if (*pFormat
== RPC_FC_C_CSTRING
) {
621 TRACE("string=%s\n", debugstr_a((char*)pMemory
));
622 pStubMsg
->ActualCount
= strlen((char*)pMemory
)+1;
625 else if (*pFormat
== RPC_FC_C_WSTRING
) {
626 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
));
627 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
)+1;
631 ERR("Unhandled string type: %#x\n", *pFormat
);
632 /* FIXME: raise an exception */
636 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
637 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
639 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
641 pStubMsg
->BufferLength
+= safe_multiply(esize
, pStubMsg
->ActualCount
);
644 /************************************************************************
645 * NdrConformantStringMemorySize [RPCRT4.@]
647 ULONG WINAPI
NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
648 PFORMAT_STRING pFormat
)
652 FIXME("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
654 assert(pStubMsg
&& pFormat
);
656 if (*pFormat
== RPC_FC_C_CSTRING
) {
657 rslt
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
); /* maxlen */
659 else if (*pFormat
== RPC_FC_C_WSTRING
) {
660 rslt
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
)*2; /* maxlen */
663 ERR("Unhandled string type: %#x\n", *pFormat
);
664 /* FIXME: raise an exception */
667 if (pFormat
[1] != RPC_FC_PAD
) {
668 FIXME("sized string format=%d\n", pFormat
[1]);
671 TRACE(" --> %u\n", rslt
);
675 /************************************************************************
676 * NdrConformantStringUnmarshall [RPCRT4.@]
678 unsigned char *WINAPI
NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
679 unsigned char** ppMemory
, PFORMAT_STRING pFormat
, unsigned char fMustAlloc
)
681 ULONG bufsize
, memsize
, esize
, i
;
683 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
684 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
686 assert(pFormat
&& ppMemory
&& pStubMsg
);
688 ReadConformance(pStubMsg
, NULL
);
689 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
691 if (*pFormat
== RPC_FC_C_CSTRING
) esize
= 1;
692 else if (*pFormat
== RPC_FC_C_WSTRING
) esize
= 2;
694 ERR("Unhandled string type: %#x\n", *pFormat
);
695 /* FIXME: raise an exception */
699 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
700 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
702 /* strings must always have null terminating bytes */
705 ERR("invalid string length of %d\n", pStubMsg
->ActualCount
);
706 RpcRaiseException(RPC_S_INVALID_BOUND
);
709 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
710 if (pStubMsg
->Buffer
[i
] != 0)
712 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
713 i
, pStubMsg
->Buffer
[i
]);
714 RpcRaiseException(RPC_S_INVALID_BOUND
);
718 if (fMustAlloc
|| !*ppMemory
)
719 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
721 memcpy(*ppMemory
, pStubMsg
->Buffer
, bufsize
);
723 pStubMsg
->Buffer
+= bufsize
;
725 if (*pFormat
== RPC_FC_C_CSTRING
) {
726 TRACE("string=%s\n", debugstr_a((char*)*ppMemory
));
728 else if (*pFormat
== RPC_FC_C_WSTRING
) {
729 TRACE("string=%s\n", debugstr_w((LPWSTR
)*ppMemory
));
732 return NULL
; /* FIXME: is this always right? */
735 /***********************************************************************
736 * NdrNonConformantStringMarshall [RPCRT4.@]
738 unsigned char * WINAPI
NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
739 unsigned char *pMemory
,
740 PFORMAT_STRING pFormat
)
746 /***********************************************************************
747 * NdrNonConformantStringUnmarshall [RPCRT4.@]
749 unsigned char * WINAPI
NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
750 unsigned char **ppMemory
,
751 PFORMAT_STRING pFormat
,
752 unsigned char fMustAlloc
)
758 /***********************************************************************
759 * NdrNonConformantStringBufferSize [RPCRT4.@]
761 void WINAPI
NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
762 unsigned char *pMemory
,
763 PFORMAT_STRING pFormat
)
768 /***********************************************************************
769 * NdrNonConformantStringMemorySize [RPCRT4.@]
771 ULONG WINAPI
NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
772 PFORMAT_STRING pFormat
)
778 static inline void dump_pointer_attr(unsigned char attr
)
780 if (attr
& RPC_FC_P_ALLOCALLNODES
)
781 TRACE(" RPC_FC_P_ALLOCALLNODES");
782 if (attr
& RPC_FC_P_DONTFREE
)
783 TRACE(" RPC_FC_P_DONTFREE");
784 if (attr
& RPC_FC_P_ONSTACK
)
785 TRACE(" RPC_FC_P_ONSTACK");
786 if (attr
& RPC_FC_P_SIMPLEPOINTER
)
787 TRACE(" RPC_FC_P_SIMPLEPOINTER");
788 if (attr
& RPC_FC_P_DEREF
)
789 TRACE(" RPC_FC_P_DEREF");
793 /***********************************************************************
794 * PointerMarshall [internal]
796 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
797 unsigned char *Buffer
,
798 unsigned char *Pointer
,
799 PFORMAT_STRING pFormat
)
801 unsigned type
= pFormat
[0], attr
= pFormat
[1];
805 int pointer_needs_marshaling
;
807 TRACE("(%p,%p,%p,%p)\n", pStubMsg
, Buffer
, Pointer
, pFormat
);
808 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
810 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
811 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
814 case RPC_FC_RP
: /* ref pointer (always non-null) */
815 #if 0 /* this causes problems for InstallShield so is disabled - we need more tests */
817 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
819 pointer_needs_marshaling
= 1;
821 case RPC_FC_UP
: /* unique pointer */
822 case RPC_FC_OP
: /* object pointer - same as unique here */
824 pointer_needs_marshaling
= 1;
826 pointer_needs_marshaling
= 0;
827 pointer_id
= (ULONG
)Pointer
;
828 TRACE("writing 0x%08x to buffer\n", pointer_id
);
829 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
832 pointer_needs_marshaling
= !NdrFullPointerQueryPointer(
833 pStubMsg
->FullPtrXlatTables
, Pointer
, 1, &pointer_id
);
834 TRACE("writing 0x%08x to buffer\n", pointer_id
);
835 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
838 FIXME("unhandled ptr type=%02x\n", type
);
839 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
843 TRACE("calling marshaller for type 0x%x\n", (int)*desc
);
845 if (pointer_needs_marshaling
) {
846 if (attr
& RPC_FC_P_DEREF
) {
847 Pointer
= *(unsigned char**)Pointer
;
848 TRACE("deref => %p\n", Pointer
);
850 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
851 if (m
) m(pStubMsg
, Pointer
, desc
);
852 else FIXME("no marshaller for data type=%02x\n", *desc
);
855 STD_OVERFLOW_CHECK(pStubMsg
);
858 /***********************************************************************
859 * PointerUnmarshall [internal]
861 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
862 unsigned char *Buffer
,
863 unsigned char **pPointer
,
864 PFORMAT_STRING pFormat
,
865 unsigned char fMustAlloc
)
867 unsigned type
= pFormat
[0], attr
= pFormat
[1];
870 DWORD pointer_id
= 0;
871 int pointer_needs_unmarshaling
;
873 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg
, Buffer
, pPointer
, pFormat
, fMustAlloc
);
874 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
876 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
877 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
880 case RPC_FC_RP
: /* ref pointer (always non-null) */
881 pointer_needs_unmarshaling
= 1;
883 case RPC_FC_UP
: /* unique pointer */
884 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
885 TRACE("pointer_id is 0x%08x\n", pointer_id
);
887 pointer_needs_unmarshaling
= 1;
890 pointer_needs_unmarshaling
= 0;
893 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
894 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
895 TRACE("pointer_id is 0x%08x\n", pointer_id
);
896 if (!fMustAlloc
&& *pPointer
)
898 FIXME("free object pointer %p\n", *pPointer
);
902 pointer_needs_unmarshaling
= 1;
904 pointer_needs_unmarshaling
= 0;
907 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
908 TRACE("pointer_id is 0x%08x\n", pointer_id
);
909 pointer_needs_unmarshaling
= !NdrFullPointerQueryRefId(
910 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, (void **)pPointer
);
913 FIXME("unhandled ptr type=%02x\n", type
);
914 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
918 if (pointer_needs_unmarshaling
) {
919 if (attr
& RPC_FC_P_DEREF
) {
920 if (!*pPointer
|| fMustAlloc
)
921 *pPointer
= NdrAllocate(pStubMsg
, sizeof(void *));
922 pPointer
= *(unsigned char***)pPointer
;
923 TRACE("deref => %p\n", pPointer
);
925 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
926 if (m
) m(pStubMsg
, pPointer
, desc
, fMustAlloc
);
927 else FIXME("no unmarshaller for data type=%02x\n", *desc
);
929 if (type
== RPC_FC_FP
)
930 NdrFullPointerInsertRefId(pStubMsg
->FullPtrXlatTables
, pointer_id
,
934 TRACE("pointer=%p\n", *pPointer
);
937 /***********************************************************************
938 * PointerBufferSize [internal]
940 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
941 unsigned char *Pointer
,
942 PFORMAT_STRING pFormat
)
944 unsigned type
= pFormat
[0], attr
= pFormat
[1];
947 int pointer_needs_sizing
;
950 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
951 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
953 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
954 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
957 case RPC_FC_RP
: /* ref pointer (always non-null) */
961 /* NULL pointer has no further representation */
966 pointer_needs_sizing
= !NdrFullPointerQueryPointer(
967 pStubMsg
->FullPtrXlatTables
, Pointer
, 0, &pointer_id
);
968 if (!pointer_needs_sizing
)
972 FIXME("unhandled ptr type=%02x\n", type
);
973 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
977 if (attr
& RPC_FC_P_DEREF
) {
978 Pointer
= *(unsigned char**)Pointer
;
979 TRACE("deref => %p\n", Pointer
);
982 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
983 if (m
) m(pStubMsg
, Pointer
, desc
);
984 else FIXME("no buffersizer for data type=%02x\n", *desc
);
987 /***********************************************************************
988 * PointerMemorySize [internal]
990 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
991 unsigned char *Buffer
,
992 PFORMAT_STRING pFormat
)
994 unsigned type
= pFormat
[0], attr
= pFormat
[1];
998 FIXME("(%p,%p,%p): stub\n", pStubMsg
, Buffer
, pFormat
);
999 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1001 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1002 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1005 case RPC_FC_RP
: /* ref pointer (always non-null) */
1008 FIXME("unhandled ptr type=%02x\n", type
);
1009 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1012 if (attr
& RPC_FC_P_DEREF
) {
1016 m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
1017 if (m
) m(pStubMsg
, desc
);
1018 else FIXME("no memorysizer for data type=%02x\n", *desc
);
1023 /***********************************************************************
1024 * PointerFree [internal]
1026 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1027 unsigned char *Pointer
,
1028 PFORMAT_STRING pFormat
)
1030 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1031 PFORMAT_STRING desc
;
1034 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1035 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1036 if (attr
& RPC_FC_P_DONTFREE
) return;
1038 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1039 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1041 if (!Pointer
) return;
1043 if (type
== RPC_FC_FP
) {
1044 int pointer_needs_freeing
= NdrFullPointerFree(
1045 pStubMsg
->FullPtrXlatTables
, Pointer
);
1046 if (!pointer_needs_freeing
)
1050 if (attr
& RPC_FC_P_DEREF
) {
1051 Pointer
= *(unsigned char**)Pointer
;
1052 TRACE("deref => %p\n", Pointer
);
1055 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
1056 if (m
) m(pStubMsg
, Pointer
, desc
);
1058 /* hmm... is this sensible?
1059 * perhaps we should check if the memory comes from NdrAllocate,
1060 * and deallocate only if so - checking if the pointer is between
1061 * BufferStart and BufferEnd is probably no good since the buffer
1062 * may be reallocated when the server wants to marshal the reply */
1064 case RPC_FC_BOGUS_STRUCT
:
1065 case RPC_FC_BOGUS_ARRAY
:
1066 case RPC_FC_USER_MARSHAL
:
1068 case RPC_FC_CVARRAY
:
1071 FIXME("unhandled data type=%02x\n", *desc
);
1073 case RPC_FC_C_CSTRING
:
1074 case RPC_FC_C_WSTRING
:
1075 if (pStubMsg
->ReuseBuffer
) goto notfree
;
1081 if (attr
& RPC_FC_P_ONSTACK
) {
1082 TRACE("not freeing stack ptr %p\n", Pointer
);
1085 TRACE("freeing %p\n", Pointer
);
1086 NdrFree(pStubMsg
, Pointer
);
1089 TRACE("not freeing %p\n", Pointer
);
1092 /***********************************************************************
1093 * EmbeddedPointerMarshall
1095 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1096 unsigned char *pMemory
,
1097 PFORMAT_STRING pFormat
)
1099 unsigned char *Mark
= pStubMsg
->BufferMark
;
1100 unsigned long Offset
= pStubMsg
->Offset
;
1101 unsigned ofs
, rep
, count
, stride
, xofs
;
1104 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1106 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1109 while (pFormat
[0] != RPC_FC_END
) {
1110 switch (pFormat
[0]) {
1112 FIXME("unknown repeat type %d\n", pFormat
[0]);
1113 case RPC_FC_NO_REPEAT
:
1121 case RPC_FC_FIXED_REPEAT
:
1122 rep
= *(const WORD
*)&pFormat
[2];
1123 stride
= *(const WORD
*)&pFormat
[4];
1124 ofs
= *(const WORD
*)&pFormat
[6];
1125 count
= *(const WORD
*)&pFormat
[8];
1129 case RPC_FC_VARIABLE_REPEAT
:
1130 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1131 stride
= *(const WORD
*)&pFormat
[2];
1132 ofs
= *(const WORD
*)&pFormat
[4];
1133 count
= *(const WORD
*)&pFormat
[6];
1134 xofs
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? Offset
* stride
: 0;
1138 for (i
= 0; i
< rep
; i
++) {
1139 PFORMAT_STRING info
= pFormat
;
1140 unsigned char *membase
= pMemory
+ ofs
+ (i
* stride
);
1141 unsigned char *bufbase
= Mark
+ ofs
+ (i
* stride
);
1144 for (u
=0; u
<count
; u
++,info
+=8) {
1145 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1146 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1147 unsigned char *saved_memory
= pStubMsg
->Memory
;
1149 pStubMsg
->Memory
= pMemory
;
1150 PointerMarshall(pStubMsg
, bufptr
, *(unsigned char**)memptr
, info
+4);
1151 pStubMsg
->Memory
= saved_memory
;
1154 pFormat
+= 8 * count
;
1157 STD_OVERFLOW_CHECK(pStubMsg
);
1162 /***********************************************************************
1163 * EmbeddedPointerUnmarshall
1165 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1166 unsigned char **ppMemory
,
1167 PFORMAT_STRING pFormat
,
1168 unsigned char fMustAlloc
)
1170 unsigned char *Mark
= pStubMsg
->BufferMark
;
1171 unsigned long Offset
= pStubMsg
->Offset
;
1172 unsigned ofs
, rep
, count
, stride
, xofs
;
1175 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1177 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1180 while (pFormat
[0] != RPC_FC_END
) {
1181 TRACE("pFormat[0] = 0x%x\n", pFormat
[0]);
1182 switch (pFormat
[0]) {
1184 FIXME("unknown repeat type %d\n", pFormat
[0]);
1185 case RPC_FC_NO_REPEAT
:
1193 case RPC_FC_FIXED_REPEAT
:
1194 rep
= *(const WORD
*)&pFormat
[2];
1195 stride
= *(const WORD
*)&pFormat
[4];
1196 ofs
= *(const WORD
*)&pFormat
[6];
1197 count
= *(const WORD
*)&pFormat
[8];
1201 case RPC_FC_VARIABLE_REPEAT
:
1202 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1203 stride
= *(const WORD
*)&pFormat
[2];
1204 ofs
= *(const WORD
*)&pFormat
[4];
1205 count
= *(const WORD
*)&pFormat
[6];
1206 xofs
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? Offset
* stride
: 0;
1210 /* ofs doesn't seem to matter in this context */
1211 for (i
= 0; i
< rep
; i
++) {
1212 PFORMAT_STRING info
= pFormat
;
1213 unsigned char *membase
= *ppMemory
+ ofs
+ (i
* stride
);
1214 unsigned char *bufbase
= Mark
+ ofs
+ (i
* stride
);
1217 for (u
=0; u
<count
; u
++,info
+=8) {
1218 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1219 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1220 PointerUnmarshall(pStubMsg
, bufptr
, (unsigned char**)memptr
, info
+4, TRUE
);
1223 pFormat
+= 8 * count
;
1229 /***********************************************************************
1230 * EmbeddedPointerBufferSize
1232 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1233 unsigned char *pMemory
,
1234 PFORMAT_STRING pFormat
)
1236 unsigned long Offset
= pStubMsg
->Offset
;
1237 unsigned ofs
, rep
, count
, stride
, xofs
;
1240 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1242 if (pStubMsg
->IgnoreEmbeddedPointers
) return;
1244 if (*pFormat
!= RPC_FC_PP
) return;
1247 while (pFormat
[0] != RPC_FC_END
) {
1248 switch (pFormat
[0]) {
1250 FIXME("unknown repeat type %d\n", pFormat
[0]);
1251 case RPC_FC_NO_REPEAT
:
1259 case RPC_FC_FIXED_REPEAT
:
1260 rep
= *(const WORD
*)&pFormat
[2];
1261 stride
= *(const WORD
*)&pFormat
[4];
1262 ofs
= *(const WORD
*)&pFormat
[6];
1263 count
= *(const WORD
*)&pFormat
[8];
1267 case RPC_FC_VARIABLE_REPEAT
:
1268 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1269 stride
= *(const WORD
*)&pFormat
[2];
1270 ofs
= *(const WORD
*)&pFormat
[4];
1271 count
= *(const WORD
*)&pFormat
[6];
1272 xofs
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? Offset
* stride
: 0;
1276 for (i
= 0; i
< rep
; i
++) {
1277 PFORMAT_STRING info
= pFormat
;
1278 unsigned char *membase
= pMemory
+ ofs
+ (i
* stride
);
1281 for (u
=0; u
<count
; u
++,info
+=8) {
1282 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1283 unsigned char *saved_memory
= pStubMsg
->Memory
;
1285 pStubMsg
->Memory
= pMemory
;
1286 PointerBufferSize(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1287 pStubMsg
->Memory
= saved_memory
;
1290 pFormat
+= 8 * count
;
1294 /***********************************************************************
1295 * EmbeddedPointerMemorySize [internal]
1297 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1298 PFORMAT_STRING pFormat
)
1300 unsigned long Offset
= pStubMsg
->Offset
;
1301 unsigned char *Mark
= pStubMsg
->BufferMark
;
1302 unsigned ofs
, rep
, count
, stride
, xofs
;
1305 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1307 if (*pFormat
!= RPC_FC_PP
) return 0;
1310 while (pFormat
[0] != RPC_FC_END
) {
1311 switch (pFormat
[0]) {
1313 FIXME("unknown repeat type %d\n", pFormat
[0]);
1314 case RPC_FC_NO_REPEAT
:
1322 case RPC_FC_FIXED_REPEAT
:
1323 rep
= *(const WORD
*)&pFormat
[2];
1324 stride
= *(const WORD
*)&pFormat
[4];
1325 ofs
= *(const WORD
*)&pFormat
[6];
1326 count
= *(const WORD
*)&pFormat
[8];
1330 case RPC_FC_VARIABLE_REPEAT
:
1331 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1332 stride
= *(const WORD
*)&pFormat
[2];
1333 ofs
= *(const WORD
*)&pFormat
[4];
1334 count
= *(const WORD
*)&pFormat
[6];
1335 xofs
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? Offset
* stride
: 0;
1339 /* ofs doesn't seem to matter in this context */
1340 for (i
= 0; i
< rep
; i
++) {
1341 PFORMAT_STRING info
= pFormat
;
1342 unsigned char *bufbase
= Mark
+ ofs
+ (i
* stride
);
1344 for (u
=0; u
<count
; u
++,info
+=8) {
1345 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1346 PointerMemorySize(pStubMsg
, bufptr
, info
+4);
1349 pFormat
+= 8 * count
;
1355 /***********************************************************************
1356 * EmbeddedPointerFree [internal]
1358 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1359 unsigned char *pMemory
,
1360 PFORMAT_STRING pFormat
)
1362 unsigned long Offset
= pStubMsg
->Offset
;
1363 unsigned ofs
, rep
, count
, stride
, xofs
;
1366 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1367 if (*pFormat
!= RPC_FC_PP
) return;
1370 while (pFormat
[0] != RPC_FC_END
) {
1371 switch (pFormat
[0]) {
1373 FIXME("unknown repeat type %d\n", pFormat
[0]);
1374 case RPC_FC_NO_REPEAT
:
1382 case RPC_FC_FIXED_REPEAT
:
1383 rep
= *(const WORD
*)&pFormat
[2];
1384 stride
= *(const WORD
*)&pFormat
[4];
1385 ofs
= *(const WORD
*)&pFormat
[6];
1386 count
= *(const WORD
*)&pFormat
[8];
1390 case RPC_FC_VARIABLE_REPEAT
:
1391 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1392 stride
= *(const WORD
*)&pFormat
[2];
1393 ofs
= *(const WORD
*)&pFormat
[4];
1394 count
= *(const WORD
*)&pFormat
[6];
1395 xofs
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? Offset
* stride
: 0;
1399 for (i
= 0; i
< rep
; i
++) {
1400 PFORMAT_STRING info
= pFormat
;
1401 unsigned char *membase
= pMemory
+ (i
* stride
);
1404 for (u
=0; u
<count
; u
++,info
+=8) {
1405 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1406 unsigned char *saved_memory
= pStubMsg
->Memory
;
1408 pStubMsg
->Memory
= pMemory
;
1409 PointerFree(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1410 pStubMsg
->Memory
= saved_memory
;
1413 pFormat
+= 8 * count
;
1417 /***********************************************************************
1418 * NdrPointerMarshall [RPCRT4.@]
1420 unsigned char * WINAPI
NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1421 unsigned char *pMemory
,
1422 PFORMAT_STRING pFormat
)
1424 unsigned char *Buffer
;
1426 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1428 /* incremement the buffer here instead of in PointerMarshall,
1429 * as that is used by embedded pointers which already handle the incrementing
1430 * the buffer, and shouldn't write any additional pointer data to the wire */
1431 if (*pFormat
!= RPC_FC_RP
)
1433 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1434 Buffer
= pStubMsg
->Buffer
;
1435 pStubMsg
->Buffer
+= 4;
1438 Buffer
= pStubMsg
->Buffer
;
1440 PointerMarshall(pStubMsg
, Buffer
, pMemory
, pFormat
);
1442 STD_OVERFLOW_CHECK(pStubMsg
);
1447 /***********************************************************************
1448 * NdrPointerUnmarshall [RPCRT4.@]
1450 unsigned char * WINAPI
NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1451 unsigned char **ppMemory
,
1452 PFORMAT_STRING pFormat
,
1453 unsigned char fMustAlloc
)
1455 unsigned char *Buffer
;
1457 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1459 /* incremement the buffer here instead of in PointerUnmarshall,
1460 * as that is used by embedded pointers which already handle the incrementing
1461 * the buffer, and shouldn't read any additional pointer data from the
1463 if (*pFormat
!= RPC_FC_RP
)
1465 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1466 Buffer
= pStubMsg
->Buffer
;
1467 pStubMsg
->Buffer
+= 4;
1470 Buffer
= pStubMsg
->Buffer
;
1472 PointerUnmarshall(pStubMsg
, Buffer
, ppMemory
, pFormat
, fMustAlloc
);
1477 /***********************************************************************
1478 * NdrPointerBufferSize [RPCRT4.@]
1480 void WINAPI
NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1481 unsigned char *pMemory
,
1482 PFORMAT_STRING pFormat
)
1484 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1486 /* incremement the buffer length here instead of in PointerBufferSize,
1487 * as that is used by embedded pointers which already handle the buffer
1488 * length, and shouldn't write anything more to the wire */
1489 if (*pFormat
!= RPC_FC_RP
)
1491 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
1492 pStubMsg
->BufferLength
+= 4;
1495 PointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1498 /***********************************************************************
1499 * NdrPointerMemorySize [RPCRT4.@]
1501 ULONG WINAPI
NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1502 PFORMAT_STRING pFormat
)
1504 /* unsigned size = *(LPWORD)(pFormat+2); */
1505 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1506 PointerMemorySize(pStubMsg
, pStubMsg
->Buffer
, pFormat
);
1510 /***********************************************************************
1511 * NdrPointerFree [RPCRT4.@]
1513 void WINAPI
NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1514 unsigned char *pMemory
,
1515 PFORMAT_STRING pFormat
)
1517 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1518 PointerFree(pStubMsg
, pMemory
, pFormat
);
1521 /***********************************************************************
1522 * NdrSimpleTypeMarshall [RPCRT4.@]
1524 void WINAPI
NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1525 unsigned char FormatChar
)
1527 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &FormatChar
);
1530 /***********************************************************************
1531 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1533 void WINAPI
NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1534 unsigned char FormatChar
)
1536 NdrBaseTypeUnmarshall(pStubMsg
, &pMemory
, &FormatChar
, 0);
1539 /***********************************************************************
1540 * NdrSimpleStructMarshall [RPCRT4.@]
1542 unsigned char * WINAPI
NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1543 unsigned char *pMemory
,
1544 PFORMAT_STRING pFormat
)
1546 unsigned size
= *(const WORD
*)(pFormat
+2);
1547 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1549 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1551 memcpy(pStubMsg
->Buffer
, pMemory
, size
);
1552 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1553 pStubMsg
->Buffer
+= size
;
1555 if (pFormat
[0] != RPC_FC_STRUCT
)
1556 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
+4);
1558 STD_OVERFLOW_CHECK(pStubMsg
);
1563 /***********************************************************************
1564 * NdrSimpleStructUnmarshall [RPCRT4.@]
1566 unsigned char * WINAPI
NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1567 unsigned char **ppMemory
,
1568 PFORMAT_STRING pFormat
,
1569 unsigned char fMustAlloc
)
1571 unsigned size
= *(const WORD
*)(pFormat
+2);
1572 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1574 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1577 *ppMemory
= NdrAllocate(pStubMsg
, size
);
1578 memcpy(*ppMemory
, pStubMsg
->Buffer
, size
);
1580 if (!pStubMsg
->IsClient
&& !*ppMemory
)
1581 /* for servers, we just point straight into the RPC buffer */
1582 *ppMemory
= pStubMsg
->Buffer
;
1584 /* for clients, memory should be provided by caller */
1585 memcpy(*ppMemory
, pStubMsg
->Buffer
, size
);
1588 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1589 pStubMsg
->Buffer
+= size
;
1591 if (pFormat
[0] != RPC_FC_STRUCT
)
1592 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
+4, fMustAlloc
);
1597 /***********************************************************************
1598 * NdrSimpleStructBufferSize [RPCRT4.@]
1600 void WINAPI
NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1601 unsigned char *pMemory
,
1602 PFORMAT_STRING pFormat
)
1604 unsigned size
= *(const WORD
*)(pFormat
+2);
1605 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1607 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
1609 pStubMsg
->BufferLength
+= size
;
1610 if (pFormat
[0] != RPC_FC_STRUCT
)
1611 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
+4);
1614 /***********************************************************************
1615 * NdrSimpleStructMemorySize [RPCRT4.@]
1617 ULONG WINAPI
NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1618 PFORMAT_STRING pFormat
)
1620 unsigned short size
= *(const WORD
*)(pFormat
+2);
1622 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1624 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1625 pStubMsg
->MemorySize
+= size
;
1626 pStubMsg
->Buffer
+= size
;
1628 if (pFormat
[0] != RPC_FC_STRUCT
)
1629 EmbeddedPointerMemorySize(pStubMsg
, pFormat
+4);
1633 /***********************************************************************
1634 * NdrSimpleStructFree [RPCRT4.@]
1636 void WINAPI
NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
1637 unsigned char *pMemory
,
1638 PFORMAT_STRING pFormat
)
1640 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1641 if (pFormat
[0] != RPC_FC_STRUCT
)
1642 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
+4);
1646 static unsigned long EmbeddedComplexSize(PMIDL_STUB_MESSAGE pStubMsg
,
1647 PFORMAT_STRING pFormat
)
1651 case RPC_FC_PSTRUCT
:
1652 case RPC_FC_CSTRUCT
:
1653 case RPC_FC_BOGUS_STRUCT
:
1654 case RPC_FC_SMFARRAY
:
1655 case RPC_FC_SMVARRAY
:
1656 return *(const WORD
*)&pFormat
[2];
1657 case RPC_FC_USER_MARSHAL
:
1658 return *(const WORD
*)&pFormat
[4];
1659 case RPC_FC_NON_ENCAPSULATED_UNION
:
1661 if (pStubMsg
->fHasNewCorrDesc
)
1666 pFormat
+= *(const SHORT
*)pFormat
;
1667 return *(const SHORT
*)pFormat
;
1669 return sizeof(void *);
1671 FIXME("unhandled embedded type %02x\n", *pFormat
);
1677 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1678 PFORMAT_STRING pFormat
)
1680 NDR_MEMORYSIZE m
= NdrMemorySizer
[*pFormat
& NDR_TABLE_MASK
];
1684 FIXME("no memorysizer for data type=%02x\n", *pFormat
);
1688 return m(pStubMsg
, pFormat
);
1692 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1693 unsigned char *pMemory
,
1694 PFORMAT_STRING pFormat
,
1695 PFORMAT_STRING pPointer
)
1697 PFORMAT_STRING desc
;
1701 while (*pFormat
!= RPC_FC_END
) {
1707 TRACE("byte=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
1708 memcpy(pStubMsg
->Buffer
, pMemory
, 1);
1709 pStubMsg
->Buffer
+= 1;
1715 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
1716 memcpy(pStubMsg
->Buffer
, pMemory
, 2);
1717 pStubMsg
->Buffer
+= 2;
1723 TRACE("long=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
1724 memcpy(pStubMsg
->Buffer
, pMemory
, 4);
1725 pStubMsg
->Buffer
+= 4;
1729 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
1730 memcpy(pStubMsg
->Buffer
, pMemory
, 8);
1731 pStubMsg
->Buffer
+= 8;
1734 case RPC_FC_POINTER
:
1735 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
1736 NdrPointerMarshall(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
1740 case RPC_FC_ALIGNM4
:
1741 ALIGN_POINTER(pMemory
, 4);
1743 case RPC_FC_ALIGNM8
:
1744 ALIGN_POINTER(pMemory
, 8);
1746 case RPC_FC_STRUCTPAD1
:
1747 case RPC_FC_STRUCTPAD2
:
1748 case RPC_FC_STRUCTPAD3
:
1749 case RPC_FC_STRUCTPAD4
:
1750 case RPC_FC_STRUCTPAD5
:
1751 case RPC_FC_STRUCTPAD6
:
1752 case RPC_FC_STRUCTPAD7
:
1753 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
1755 case RPC_FC_EMBEDDED_COMPLEX
:
1756 pMemory
+= pFormat
[1];
1758 desc
= pFormat
+ *(const SHORT
*)pFormat
;
1759 size
= EmbeddedComplexSize(pStubMsg
, desc
);
1760 TRACE("embedded complex (size=%ld) <= %p\n", size
, pMemory
);
1761 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
1762 if (m
) m(pStubMsg
, pMemory
, desc
);
1763 else FIXME("no marshaller for embedded type %02x\n", *desc
);
1770 FIXME("unhandled format 0x%02x\n", *pFormat
);
1778 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1779 unsigned char *pMemory
,
1780 PFORMAT_STRING pFormat
,
1781 PFORMAT_STRING pPointer
)
1783 PFORMAT_STRING desc
;
1787 while (*pFormat
!= RPC_FC_END
) {
1793 memcpy(pMemory
, pStubMsg
->Buffer
, 1);
1794 TRACE("byte=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
1795 pStubMsg
->Buffer
+= 1;
1801 memcpy(pMemory
, pStubMsg
->Buffer
, 2);
1802 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
1803 pStubMsg
->Buffer
+= 2;
1809 memcpy(pMemory
, pStubMsg
->Buffer
, 4);
1810 TRACE("long=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
1811 pStubMsg
->Buffer
+= 4;
1815 memcpy(pMemory
, pStubMsg
->Buffer
, 8);
1816 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
1817 pStubMsg
->Buffer
+= 8;
1820 case RPC_FC_POINTER
:
1821 TRACE("pointer => %p\n", pMemory
);
1822 NdrPointerUnmarshall(pStubMsg
, (unsigned char**)pMemory
, pPointer
, TRUE
);
1826 case RPC_FC_ALIGNM4
:
1827 ALIGN_POINTER(pMemory
, 4);
1829 case RPC_FC_ALIGNM8
:
1830 ALIGN_POINTER(pMemory
, 8);
1832 case RPC_FC_STRUCTPAD1
:
1833 case RPC_FC_STRUCTPAD2
:
1834 case RPC_FC_STRUCTPAD3
:
1835 case RPC_FC_STRUCTPAD4
:
1836 case RPC_FC_STRUCTPAD5
:
1837 case RPC_FC_STRUCTPAD6
:
1838 case RPC_FC_STRUCTPAD7
:
1839 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
1841 case RPC_FC_EMBEDDED_COMPLEX
:
1842 pMemory
+= pFormat
[1];
1844 desc
= pFormat
+ *(const SHORT
*)pFormat
;
1845 size
= EmbeddedComplexSize(pStubMsg
, desc
);
1846 TRACE("embedded complex (size=%ld) => %p\n", size
, pMemory
);
1847 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
1848 memset(pMemory
, 0, size
); /* just in case */
1849 if (m
) m(pStubMsg
, &pMemory
, desc
, FALSE
);
1850 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
1857 FIXME("unhandled format %d\n", *pFormat
);
1865 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1866 unsigned char *pMemory
,
1867 PFORMAT_STRING pFormat
,
1868 PFORMAT_STRING pPointer
)
1870 PFORMAT_STRING desc
;
1874 while (*pFormat
!= RPC_FC_END
) {
1880 pStubMsg
->BufferLength
+= 1;
1886 pStubMsg
->BufferLength
+= 2;
1892 pStubMsg
->BufferLength
+= 4;
1896 pStubMsg
->BufferLength
+= 8;
1899 case RPC_FC_POINTER
:
1900 NdrPointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
1904 case RPC_FC_ALIGNM4
:
1905 ALIGN_POINTER(pMemory
, 4);
1907 case RPC_FC_ALIGNM8
:
1908 ALIGN_POINTER(pMemory
, 8);
1910 case RPC_FC_STRUCTPAD1
:
1911 case RPC_FC_STRUCTPAD2
:
1912 case RPC_FC_STRUCTPAD3
:
1913 case RPC_FC_STRUCTPAD4
:
1914 case RPC_FC_STRUCTPAD5
:
1915 case RPC_FC_STRUCTPAD6
:
1916 case RPC_FC_STRUCTPAD7
:
1917 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
1919 case RPC_FC_EMBEDDED_COMPLEX
:
1920 pMemory
+= pFormat
[1];
1922 desc
= pFormat
+ *(const SHORT
*)pFormat
;
1923 size
= EmbeddedComplexSize(pStubMsg
, desc
);
1924 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
1925 if (m
) m(pStubMsg
, pMemory
, desc
);
1926 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
1933 FIXME("unhandled format 0x%02x\n", *pFormat
);
1941 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
1942 unsigned char *pMemory
,
1943 PFORMAT_STRING pFormat
,
1944 PFORMAT_STRING pPointer
)
1946 PFORMAT_STRING desc
;
1950 while (*pFormat
!= RPC_FC_END
) {
1971 case RPC_FC_POINTER
:
1972 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
1976 case RPC_FC_ALIGNM4
:
1977 ALIGN_POINTER(pMemory
, 4);
1979 case RPC_FC_ALIGNM8
:
1980 ALIGN_POINTER(pMemory
, 8);
1982 case RPC_FC_STRUCTPAD1
:
1983 case RPC_FC_STRUCTPAD2
:
1984 case RPC_FC_STRUCTPAD3
:
1985 case RPC_FC_STRUCTPAD4
:
1986 case RPC_FC_STRUCTPAD5
:
1987 case RPC_FC_STRUCTPAD6
:
1988 case RPC_FC_STRUCTPAD7
:
1989 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
1991 case RPC_FC_EMBEDDED_COMPLEX
:
1992 pMemory
+= pFormat
[1];
1994 desc
= pFormat
+ *(const SHORT
*)pFormat
;
1995 size
= EmbeddedComplexSize(pStubMsg
, desc
);
1996 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
1997 if (m
) m(pStubMsg
, pMemory
, desc
);
1998 else FIXME("no freer for embedded type %02x\n", *desc
);
2005 FIXME("unhandled format 0x%02x\n", *pFormat
);
2013 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2014 PFORMAT_STRING pFormat
)
2016 PFORMAT_STRING desc
;
2017 unsigned long size
= 0;
2019 while (*pFormat
!= RPC_FC_END
) {
2026 pStubMsg
->Buffer
+= 1;
2032 pStubMsg
->Buffer
+= 2;
2038 pStubMsg
->Buffer
+= 4;
2042 pStubMsg
->Buffer
+= 8;
2044 case RPC_FC_POINTER
:
2046 pStubMsg
->Buffer
+= 4;
2048 case RPC_FC_ALIGNM4
:
2049 ALIGN_LENGTH(size
, 4);
2050 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2052 case RPC_FC_ALIGNM8
:
2053 ALIGN_LENGTH(size
, 8);
2054 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
2056 case RPC_FC_STRUCTPAD1
:
2057 case RPC_FC_STRUCTPAD2
:
2058 case RPC_FC_STRUCTPAD3
:
2059 case RPC_FC_STRUCTPAD4
:
2060 case RPC_FC_STRUCTPAD5
:
2061 case RPC_FC_STRUCTPAD6
:
2062 case RPC_FC_STRUCTPAD7
:
2063 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2065 case RPC_FC_EMBEDDED_COMPLEX
:
2068 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2069 size
+= EmbeddedComplexMemorySize(pStubMsg
, desc
);
2075 FIXME("unhandled format 0x%02x\n", *pFormat
);
2083 /***********************************************************************
2084 * NdrComplexStructMarshall [RPCRT4.@]
2086 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2087 unsigned char *pMemory
,
2088 PFORMAT_STRING pFormat
)
2090 PFORMAT_STRING conf_array
= NULL
;
2091 PFORMAT_STRING pointer_desc
= NULL
;
2092 unsigned char *OldMemory
= pStubMsg
->Memory
;
2094 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2096 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2099 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2101 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2104 pStubMsg
->Memory
= pMemory
;
2106 ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2109 NdrConformantArrayMarshall(pStubMsg
, pMemory
, conf_array
);
2111 pStubMsg
->Memory
= OldMemory
;
2113 STD_OVERFLOW_CHECK(pStubMsg
);
2118 /***********************************************************************
2119 * NdrComplexStructUnmarshall [RPCRT4.@]
2121 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2122 unsigned char **ppMemory
,
2123 PFORMAT_STRING pFormat
,
2124 unsigned char fMustAlloc
)
2126 unsigned size
= *(const WORD
*)(pFormat
+2);
2127 PFORMAT_STRING conf_array
= NULL
;
2128 PFORMAT_STRING pointer_desc
= NULL
;
2129 unsigned char *pMemory
;
2131 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2133 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2135 if (fMustAlloc
|| !*ppMemory
)
2137 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2138 memset(*ppMemory
, 0, size
);
2142 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2144 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2147 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
);
2150 NdrConformantArrayUnmarshall(pStubMsg
, &pMemory
, conf_array
, fMustAlloc
);
2155 /***********************************************************************
2156 * NdrComplexStructBufferSize [RPCRT4.@]
2158 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2159 unsigned char *pMemory
,
2160 PFORMAT_STRING pFormat
)
2162 PFORMAT_STRING conf_array
= NULL
;
2163 PFORMAT_STRING pointer_desc
= NULL
;
2164 unsigned char *OldMemory
= pStubMsg
->Memory
;
2166 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2168 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
2171 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2173 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2176 pStubMsg
->Memory
= pMemory
;
2178 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2181 NdrConformantArrayBufferSize(pStubMsg
, pMemory
, conf_array
);
2183 pStubMsg
->Memory
= OldMemory
;
2186 /***********************************************************************
2187 * NdrComplexStructMemorySize [RPCRT4.@]
2189 ULONG WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2190 PFORMAT_STRING pFormat
)
2192 unsigned size
= *(const WORD
*)(pFormat
+2);
2193 PFORMAT_STRING conf_array
= NULL
;
2194 PFORMAT_STRING pointer_desc
= NULL
;
2196 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2198 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2201 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2203 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2206 ComplexStructMemorySize(pStubMsg
, pFormat
);
2209 NdrConformantArrayMemorySize(pStubMsg
, conf_array
);
2214 /***********************************************************************
2215 * NdrComplexStructFree [RPCRT4.@]
2217 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
2218 unsigned char *pMemory
,
2219 PFORMAT_STRING pFormat
)
2221 PFORMAT_STRING conf_array
= NULL
;
2222 PFORMAT_STRING pointer_desc
= NULL
;
2223 unsigned char *OldMemory
= pStubMsg
->Memory
;
2225 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2228 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2230 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2233 pStubMsg
->Memory
= pMemory
;
2235 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2238 NdrConformantArrayFree(pStubMsg
, pMemory
, conf_array
);
2240 pStubMsg
->Memory
= OldMemory
;
2243 /***********************************************************************
2244 * NdrConformantArrayMarshall [RPCRT4.@]
2246 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2247 unsigned char *pMemory
,
2248 PFORMAT_STRING pFormat
)
2250 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
2251 unsigned char alignment
= pFormat
[1] + 1;
2253 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2254 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2256 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2258 WriteConformance(pStubMsg
);
2260 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2262 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2263 memcpy(pStubMsg
->Buffer
, pMemory
, size
);
2264 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2265 pStubMsg
->Buffer
+= size
;
2267 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2269 STD_OVERFLOW_CHECK(pStubMsg
);
2274 /***********************************************************************
2275 * NdrConformantArrayUnmarshall [RPCRT4.@]
2277 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2278 unsigned char **ppMemory
,
2279 PFORMAT_STRING pFormat
,
2280 unsigned char fMustAlloc
)
2282 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
2283 unsigned char alignment
= pFormat
[1] + 1;
2285 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2286 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2288 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2290 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2292 if (fMustAlloc
|| !*ppMemory
)
2293 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2295 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2297 memcpy(*ppMemory
, pStubMsg
->Buffer
, size
);
2299 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2300 pStubMsg
->Buffer
+= size
;
2302 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2307 /***********************************************************************
2308 * NdrConformantArrayBufferSize [RPCRT4.@]
2310 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2311 unsigned char *pMemory
,
2312 PFORMAT_STRING pFormat
)
2314 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
2315 unsigned char alignment
= pFormat
[1] + 1;
2317 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2318 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2320 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2322 SizeConformance(pStubMsg
);
2324 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
2326 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2327 /* conformance value plus array */
2328 pStubMsg
->BufferLength
+= size
;
2330 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
2333 /***********************************************************************
2334 * NdrConformantArrayMemorySize [RPCRT4.@]
2336 ULONG WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2337 PFORMAT_STRING pFormat
)
2339 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
2340 unsigned char alignment
= pFormat
[1] + 1;
2342 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2343 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2345 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2346 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2347 pStubMsg
->MemorySize
+= size
;
2349 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2350 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2351 pStubMsg
->Buffer
+= size
;
2353 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2355 return pStubMsg
->MemorySize
;
2358 /***********************************************************************
2359 * NdrConformantArrayFree [RPCRT4.@]
2361 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
2362 unsigned char *pMemory
,
2363 PFORMAT_STRING pFormat
)
2365 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2366 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2368 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2370 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2374 /***********************************************************************
2375 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2377 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2378 unsigned char* pMemory
,
2379 PFORMAT_STRING pFormat
)
2382 unsigned char alignment
= pFormat
[1] + 1;
2383 DWORD esize
= *(const WORD
*)(pFormat
+2);
2385 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
2387 if (pFormat
[0] != RPC_FC_CVARRAY
)
2389 ERR("invalid format type %x\n", pFormat
[0]);
2390 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2394 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2395 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2397 WriteConformance(pStubMsg
);
2398 WriteVariance(pStubMsg
);
2400 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2402 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2404 memcpy(pStubMsg
->Buffer
, pMemory
+ pStubMsg
->Offset
, bufsize
);
2405 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2406 pStubMsg
->Buffer
+= bufsize
;
2408 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2410 STD_OVERFLOW_CHECK(pStubMsg
);
2416 /***********************************************************************
2417 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2419 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2420 unsigned char** ppMemory
,
2421 PFORMAT_STRING pFormat
,
2422 unsigned char fMustAlloc
)
2424 ULONG bufsize
, memsize
;
2425 unsigned char alignment
= pFormat
[1] + 1;
2426 DWORD esize
= *(const WORD
*)(pFormat
+2);
2428 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2430 if (pFormat
[0] != RPC_FC_CVARRAY
)
2432 ERR("invalid format type %x\n", pFormat
[0]);
2433 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2437 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2438 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2440 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2442 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2443 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2445 if (!*ppMemory
|| fMustAlloc
)
2446 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2447 memcpy(*ppMemory
+ pStubMsg
->Offset
, pStubMsg
->Buffer
, bufsize
);
2448 pStubMsg
->Buffer
+= bufsize
;
2450 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2456 /***********************************************************************
2457 * NdrConformantVaryingArrayFree [RPCRT4.@]
2459 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
2460 unsigned char* pMemory
,
2461 PFORMAT_STRING pFormat
)
2463 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2465 if (pFormat
[0] != RPC_FC_CVARRAY
)
2467 ERR("invalid format type %x\n", pFormat
[0]);
2468 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2472 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2473 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2475 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2479 /***********************************************************************
2480 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2482 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
2483 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
2485 unsigned char alignment
= pFormat
[1] + 1;
2486 DWORD esize
= *(const WORD
*)(pFormat
+2);
2488 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
2490 if (pFormat
[0] != RPC_FC_CVARRAY
)
2492 ERR("invalid format type %x\n", pFormat
[0]);
2493 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2498 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2499 /* compute length */
2500 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2502 SizeConformance(pStubMsg
);
2503 SizeVariance(pStubMsg
);
2505 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
2507 pStubMsg
->BufferLength
+= safe_multiply(esize
, pStubMsg
->ActualCount
);
2509 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
2513 /***********************************************************************
2514 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2516 ULONG WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
2517 PFORMAT_STRING pFormat
)
2524 /***********************************************************************
2525 * NdrComplexArrayMarshall [RPCRT4.@]
2527 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2528 unsigned char *pMemory
,
2529 PFORMAT_STRING pFormat
)
2531 ULONG i
, count
, def
;
2532 BOOL variance_present
;
2533 unsigned char alignment
;
2535 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2537 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
2539 ERR("invalid format type %x\n", pFormat
[0]);
2540 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2544 alignment
= pFormat
[1] + 1;
2546 def
= *(const WORD
*)&pFormat
[2];
2549 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
2550 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
2552 variance_present
= IsConformanceOrVariancePresent(pFormat
);
2553 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
2554 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
2556 WriteConformance(pStubMsg
);
2557 if (variance_present
)
2558 WriteVariance(pStubMsg
);
2560 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2562 count
= pStubMsg
->ActualCount
;
2563 for (i
= 0; i
< count
; i
++)
2564 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
2566 STD_OVERFLOW_CHECK(pStubMsg
);
2571 /***********************************************************************
2572 * NdrComplexArrayUnmarshall [RPCRT4.@]
2574 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2575 unsigned char **ppMemory
,
2576 PFORMAT_STRING pFormat
,
2577 unsigned char fMustAlloc
)
2579 ULONG i
, count
, esize
, memsize
;
2580 unsigned char alignment
;
2581 unsigned char *pMemory
;
2582 unsigned char *Buffer
;
2584 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2586 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
2588 ERR("invalid format type %x\n", pFormat
[0]);
2589 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2593 alignment
= pFormat
[1] + 1;
2597 pFormat
= ReadConformance(pStubMsg
, pFormat
);
2598 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2600 Buffer
= pStubMsg
->Buffer
;
2601 pStubMsg
->MemorySize
= 0;
2602 esize
= ComplexStructMemorySize(pStubMsg
, pFormat
);
2603 pStubMsg
->Buffer
= Buffer
;
2605 /* do multiply here instead of inside if block to verify MaxCount */
2606 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2607 if (fMustAlloc
|| !*ppMemory
)
2609 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2610 memset(*ppMemory
, 0, memsize
);
2613 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2615 pMemory
= *ppMemory
;
2616 count
= pStubMsg
->ActualCount
;
2617 for (i
= 0; i
< count
; i
++)
2618 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
2623 /***********************************************************************
2624 * NdrComplexArrayBufferSize [RPCRT4.@]
2626 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2627 unsigned char *pMemory
,
2628 PFORMAT_STRING pFormat
)
2630 ULONG i
, count
, def
;
2631 unsigned char alignment
;
2632 BOOL variance_present
;
2634 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2636 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
2638 ERR("invalid format type %x\n", pFormat
[0]);
2639 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2643 alignment
= pFormat
[1] + 1;
2645 def
= *(const WORD
*)&pFormat
[2];
2648 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
2649 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
2650 SizeConformance(pStubMsg
);
2652 variance_present
= IsConformanceOrVariancePresent(pFormat
);
2653 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
2654 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
2656 if (variance_present
)
2657 SizeVariance(pStubMsg
);
2659 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
2661 count
= pStubMsg
->ActualCount
;
2662 for (i
= 0; i
< count
; i
++)
2663 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
2666 /***********************************************************************
2667 * NdrComplexArrayMemorySize [RPCRT4.@]
2669 ULONG WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2670 PFORMAT_STRING pFormat
)
2672 ULONG i
, count
, esize
, SavedMemorySize
, MemorySize
;
2673 unsigned char alignment
;
2674 unsigned char *Buffer
;
2676 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2678 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
2680 ERR("invalid format type %x\n", pFormat
[0]);
2681 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2685 alignment
= pFormat
[1] + 1;
2689 pFormat
= ReadConformance(pStubMsg
, pFormat
);
2690 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2692 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2694 SavedMemorySize
= pStubMsg
->MemorySize
;
2696 Buffer
= pStubMsg
->Buffer
;
2697 pStubMsg
->MemorySize
= 0;
2698 esize
= ComplexStructMemorySize(pStubMsg
, pFormat
);
2699 pStubMsg
->Buffer
= Buffer
;
2701 MemorySize
= safe_multiply(pStubMsg
->MaxCount
, esize
);
2703 count
= pStubMsg
->ActualCount
;
2704 for (i
= 0; i
< count
; i
++)
2705 ComplexStructMemorySize(pStubMsg
, pFormat
);
2707 pStubMsg
->MemorySize
= SavedMemorySize
;
2709 pStubMsg
->MemorySize
+= MemorySize
;
2713 /***********************************************************************
2714 * NdrComplexArrayFree [RPCRT4.@]
2716 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
2717 unsigned char *pMemory
,
2718 PFORMAT_STRING pFormat
)
2720 ULONG i
, count
, def
;
2722 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2724 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
2726 ERR("invalid format type %x\n", pFormat
[0]);
2727 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2731 def
= *(const WORD
*)&pFormat
[2];
2734 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
2735 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
2737 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
2738 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
2740 count
= pStubMsg
->ActualCount
;
2741 for (i
= 0; i
< count
; i
++)
2742 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
2745 static ULONG
UserMarshalFlags(PMIDL_STUB_MESSAGE pStubMsg
)
2747 return MAKELONG(pStubMsg
->dwDestContext
,
2748 pStubMsg
->RpcMsg
->DataRepresentation
);
2751 #define USER_MARSHAL_PTR_PREFIX \
2752 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
2753 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
2755 /***********************************************************************
2756 * NdrUserMarshalMarshall [RPCRT4.@]
2758 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2759 unsigned char *pMemory
,
2760 PFORMAT_STRING pFormat
)
2762 unsigned flags
= pFormat
[1];
2763 unsigned index
= *(const WORD
*)&pFormat
[2];
2764 ULONG uflag
= UserMarshalFlags(pStubMsg
);
2765 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2766 TRACE("index=%d\n", index
);
2768 if (flags
& USER_MARSHAL_POINTER
)
2770 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2771 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, USER_MARSHAL_PTR_PREFIX
);
2772 pStubMsg
->Buffer
+= 4;
2773 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
2776 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
2779 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
2780 &uflag
, pStubMsg
->Buffer
, pMemory
);
2782 STD_OVERFLOW_CHECK(pStubMsg
);
2787 /***********************************************************************
2788 * NdrUserMarshalUnmarshall [RPCRT4.@]
2790 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2791 unsigned char **ppMemory
,
2792 PFORMAT_STRING pFormat
,
2793 unsigned char fMustAlloc
)
2795 unsigned flags
= pFormat
[1];
2796 unsigned index
= *(const WORD
*)&pFormat
[2];
2797 DWORD memsize
= *(const WORD
*)&pFormat
[4];
2798 ULONG uflag
= UserMarshalFlags(pStubMsg
);
2799 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2800 TRACE("index=%d\n", index
);
2802 if (flags
& USER_MARSHAL_POINTER
)
2804 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2805 /* skip pointer prefix */
2806 pStubMsg
->Buffer
+= 4;
2807 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
2810 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
2812 if (fMustAlloc
|| !*ppMemory
)
2813 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2816 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
2817 &uflag
, pStubMsg
->Buffer
, *ppMemory
);
2822 /***********************************************************************
2823 * NdrUserMarshalBufferSize [RPCRT4.@]
2825 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2826 unsigned char *pMemory
,
2827 PFORMAT_STRING pFormat
)
2829 unsigned flags
= pFormat
[1];
2830 unsigned index
= *(const WORD
*)&pFormat
[2];
2831 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
2832 ULONG uflag
= UserMarshalFlags(pStubMsg
);
2833 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2834 TRACE("index=%d\n", index
);
2836 if (flags
& USER_MARSHAL_POINTER
)
2838 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
2839 /* skip pointer prefix */
2840 pStubMsg
->BufferLength
+= 4;
2841 ALIGN_LENGTH(pStubMsg
->BufferLength
, 8);
2844 ALIGN_LENGTH(pStubMsg
->BufferLength
, (flags
& 0xf) + 1);
2847 TRACE("size=%d\n", bufsize
);
2848 pStubMsg
->BufferLength
+= bufsize
;
2852 pStubMsg
->BufferLength
=
2853 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
2854 &uflag
, pStubMsg
->BufferLength
, pMemory
);
2857 /***********************************************************************
2858 * NdrUserMarshalMemorySize [RPCRT4.@]
2860 ULONG WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2861 PFORMAT_STRING pFormat
)
2863 unsigned flags
= pFormat
[1];
2864 unsigned index
= *(const WORD
*)&pFormat
[2];
2865 DWORD memsize
= *(const WORD
*)&pFormat
[4];
2866 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
2868 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2869 TRACE("index=%d\n", index
);
2871 pStubMsg
->MemorySize
+= memsize
;
2873 if (flags
& USER_MARSHAL_POINTER
)
2875 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2876 /* skip pointer prefix */
2877 pStubMsg
->Buffer
+= 4;
2878 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
2881 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
2883 pStubMsg
->Buffer
+= bufsize
;
2885 return pStubMsg
->MemorySize
;
2888 /***********************************************************************
2889 * NdrUserMarshalFree [RPCRT4.@]
2891 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
2892 unsigned char *pMemory
,
2893 PFORMAT_STRING pFormat
)
2895 /* unsigned flags = pFormat[1]; */
2896 unsigned index
= *(const WORD
*)&pFormat
[2];
2897 ULONG uflag
= UserMarshalFlags(pStubMsg
);
2898 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2899 TRACE("index=%d\n", index
);
2901 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
2905 /***********************************************************************
2906 * NdrClearOutParameters [RPCRT4.@]
2908 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
2909 PFORMAT_STRING pFormat
,
2912 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
2915 /***********************************************************************
2916 * NdrConvert [RPCRT4.@]
2918 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
2920 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
2921 /* FIXME: since this stub doesn't do any converting, the proper behavior
2922 is to raise an exception */
2925 /***********************************************************************
2926 * NdrConvert2 [RPCRT4.@]
2928 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, LONG NumberParams
)
2930 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
2931 pStubMsg
, pFormat
, NumberParams
);
2932 /* FIXME: since this stub doesn't do any converting, the proper behavior
2933 is to raise an exception */
2936 #include "pshpack1.h"
2937 typedef struct _NDR_CSTRUCT_FORMAT
2940 unsigned char alignment
;
2941 unsigned short memory_size
;
2942 short offset_to_array_description
;
2943 } NDR_CSTRUCT_FORMAT
, NDR_CVSTRUCT_FORMAT
;
2944 #include "poppack.h"
2946 /***********************************************************************
2947 * NdrConformantStructMarshall [RPCRT4.@]
2949 unsigned char * WINAPI
NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2950 unsigned char *pMemory
,
2951 PFORMAT_STRING pFormat
)
2953 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
2954 PFORMAT_STRING pCArrayFormat
;
2955 ULONG esize
, bufsize
;
2957 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
2959 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
2960 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
2962 ERR("invalid format type %x\n", pCStructFormat
->type
);
2963 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2967 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
2968 pCStructFormat
->offset_to_array_description
;
2969 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
2971 ERR("invalid array format type %x\n", pCStructFormat
->type
);
2972 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2975 esize
= *(const WORD
*)(pCArrayFormat
+2);
2977 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
2978 pCArrayFormat
+ 4, 0);
2980 WriteConformance(pStubMsg
);
2982 ALIGN_POINTER(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
2984 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
2986 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2987 /* copy constant sized part of struct */
2988 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2989 memcpy(pStubMsg
->Buffer
, pMemory
, pCStructFormat
->memory_size
+ bufsize
);
2990 pStubMsg
->Buffer
+= pCStructFormat
->memory_size
+ bufsize
;
2992 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
2993 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2995 STD_OVERFLOW_CHECK(pStubMsg
);
3000 /***********************************************************************
3001 * NdrConformantStructUnmarshall [RPCRT4.@]
3003 unsigned char * WINAPI
NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3004 unsigned char **ppMemory
,
3005 PFORMAT_STRING pFormat
,
3006 unsigned char fMustAlloc
)
3008 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3009 PFORMAT_STRING pCArrayFormat
;
3010 ULONG esize
, bufsize
;
3012 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3014 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3015 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3017 ERR("invalid format type %x\n", pCStructFormat
->type
);
3018 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3021 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3022 pCStructFormat
->offset_to_array_description
;
3023 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3025 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3026 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3029 esize
= *(const WORD
*)(pCArrayFormat
+2);
3031 pCArrayFormat
= ReadConformance(pStubMsg
, pCArrayFormat
+ 4);
3033 ALIGN_POINTER(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
3035 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3037 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3038 /* work out how much memory to allocate if we need to do so */
3039 if (!*ppMemory
|| fMustAlloc
)
3041 SIZE_T size
= pCStructFormat
->memory_size
+ bufsize
;
3042 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3045 /* now copy the data */
3046 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3047 memcpy(*ppMemory
, pStubMsg
->Buffer
, pCStructFormat
->memory_size
+ bufsize
);
3048 pStubMsg
->Buffer
+= pCStructFormat
->memory_size
+ bufsize
;
3050 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3051 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3056 /***********************************************************************
3057 * NdrConformantStructBufferSize [RPCRT4.@]
3059 void WINAPI
NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3060 unsigned char *pMemory
,
3061 PFORMAT_STRING pFormat
)
3063 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3064 PFORMAT_STRING pCArrayFormat
;
3067 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3069 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3070 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3072 ERR("invalid format type %x\n", pCStructFormat
->type
);
3073 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3076 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3077 pCStructFormat
->offset_to_array_description
;
3078 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3080 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3081 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3084 esize
= *(const WORD
*)(pCArrayFormat
+2);
3086 pCArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
, pCArrayFormat
+4, 0);
3087 SizeConformance(pStubMsg
);
3089 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCStructFormat
->alignment
+ 1);
3091 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3093 pStubMsg
->BufferLength
+= pCStructFormat
->memory_size
+
3094 safe_multiply(pStubMsg
->MaxCount
, esize
);
3096 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3097 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3100 /***********************************************************************
3101 * NdrConformantStructMemorySize [RPCRT4.@]
3103 ULONG WINAPI
NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3104 PFORMAT_STRING pFormat
)
3110 /***********************************************************************
3111 * NdrConformantStructFree [RPCRT4.@]
3113 void WINAPI
NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3114 unsigned char *pMemory
,
3115 PFORMAT_STRING pFormat
)
3120 /***********************************************************************
3121 * NdrConformantVaryingStructMarshall [RPCRT4.@]
3123 unsigned char * WINAPI
NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3124 unsigned char *pMemory
,
3125 PFORMAT_STRING pFormat
)
3127 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3128 PFORMAT_STRING pCVArrayFormat
;
3129 ULONG esize
, bufsize
;
3131 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3133 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3134 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3136 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3137 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3141 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3142 pCVStructFormat
->offset_to_array_description
;
3143 switch (*pCVArrayFormat
)
3145 case RPC_FC_CVARRAY
:
3146 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3148 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3149 pCVArrayFormat
+ 4, 0);
3150 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3153 case RPC_FC_C_CSTRING
:
3154 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
3155 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
3156 esize
= sizeof(char);
3157 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3158 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3159 pCVArrayFormat
+ 2, 0);
3161 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3163 case RPC_FC_C_WSTRING
:
3164 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
3165 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
3166 esize
= sizeof(WCHAR
);
3167 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3168 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3169 pCVArrayFormat
+ 2, 0);
3171 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3174 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3175 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3179 WriteConformance(pStubMsg
);
3181 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
3183 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3185 /* write constant sized part */
3186 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3187 memcpy(pStubMsg
->Buffer
, pMemory
, pCVStructFormat
->memory_size
);
3188 pStubMsg
->Buffer
+= pCVStructFormat
->memory_size
;
3190 WriteVariance(pStubMsg
);
3192 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3194 /* write array part */
3195 memcpy(pStubMsg
->Buffer
, pMemory
+ pCVStructFormat
->memory_size
, bufsize
);
3196 pStubMsg
->Buffer
+= bufsize
;
3198 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3200 STD_OVERFLOW_CHECK(pStubMsg
);
3205 /***********************************************************************
3206 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3208 unsigned char * WINAPI
NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3209 unsigned char **ppMemory
,
3210 PFORMAT_STRING pFormat
,
3211 unsigned char fMustAlloc
)
3213 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3214 PFORMAT_STRING pCVArrayFormat
;
3215 ULONG esize
, bufsize
;
3216 unsigned char cvarray_type
;
3218 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3220 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3221 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3223 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3224 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3228 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3229 pCVStructFormat
->offset_to_array_description
;
3230 cvarray_type
= *pCVArrayFormat
;
3231 switch (cvarray_type
)
3233 case RPC_FC_CVARRAY
:
3234 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3235 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 4);
3237 case RPC_FC_C_CSTRING
:
3238 esize
= sizeof(char);
3239 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3240 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3242 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3244 case RPC_FC_C_WSTRING
:
3245 esize
= sizeof(WCHAR
);
3246 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3247 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3249 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3252 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3253 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3257 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
3259 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3261 /* work out how much memory to allocate if we need to do so */
3262 if (!*ppMemory
|| fMustAlloc
)
3264 SIZE_T size
= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->MaxCount
);
3265 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3268 /* copy the constant data */
3269 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3270 memcpy(*ppMemory
, pStubMsg
->Buffer
, pCVStructFormat
->memory_size
);
3271 pStubMsg
->Buffer
+= pCVStructFormat
->memory_size
;
3273 pCVArrayFormat
= ReadVariance(pStubMsg
, pCVArrayFormat
, pStubMsg
->MaxCount
);
3275 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3277 if ((cvarray_type
== RPC_FC_C_CSTRING
) ||
3278 (cvarray_type
== RPC_FC_C_WSTRING
))
3281 /* strings must always have null terminating bytes */
3282 if (bufsize
< esize
)
3284 ERR("invalid string length of %d\n", pStubMsg
->ActualCount
);
3285 RpcRaiseException(RPC_S_INVALID_BOUND
);
3288 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
3289 if (pStubMsg
->Buffer
[i
] != 0)
3291 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
3292 i
, pStubMsg
->Buffer
[i
]);
3293 RpcRaiseException(RPC_S_INVALID_BOUND
);
3298 /* copy the array data */
3299 memcpy(*ppMemory
+ pCVStructFormat
->memory_size
, pStubMsg
->Buffer
,
3301 pStubMsg
->Buffer
+= bufsize
;
3303 if (cvarray_type
== RPC_FC_C_CSTRING
)
3304 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory
+ pCVStructFormat
->memory_size
)));
3305 else if (cvarray_type
== RPC_FC_C_WSTRING
)
3306 TRACE("string=%s\n", debugstr_w((WCHAR
*)(*ppMemory
+ pCVStructFormat
->memory_size
)));
3308 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3313 /***********************************************************************
3314 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3316 void WINAPI
NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3317 unsigned char *pMemory
,
3318 PFORMAT_STRING pFormat
)
3320 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3321 PFORMAT_STRING pCVArrayFormat
;
3324 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3326 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3327 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3329 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3330 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3334 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3335 pCVStructFormat
->offset_to_array_description
;
3336 switch (*pCVArrayFormat
)
3338 case RPC_FC_CVARRAY
:
3339 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3341 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3342 pCVArrayFormat
+ 4, 0);
3343 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3346 case RPC_FC_C_CSTRING
:
3347 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
3348 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
3349 esize
= sizeof(char);
3350 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3351 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3352 pCVArrayFormat
+ 2, 0);
3354 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3356 case RPC_FC_C_WSTRING
:
3357 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
3358 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
3359 esize
= sizeof(WCHAR
);
3360 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3361 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3362 pCVArrayFormat
+ 2, 0);
3364 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3367 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3368 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3372 SizeConformance(pStubMsg
);
3374 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCVStructFormat
->alignment
+ 1);
3376 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3378 pStubMsg
->BufferLength
+= pCVStructFormat
->memory_size
;
3379 SizeVariance(pStubMsg
);
3380 pStubMsg
->BufferLength
+= safe_multiply(pStubMsg
->MaxCount
, esize
);
3382 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3385 /***********************************************************************
3386 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
3388 ULONG WINAPI
NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3389 PFORMAT_STRING pFormat
)
3391 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3392 PFORMAT_STRING pCVArrayFormat
;
3394 unsigned char cvarray_type
;
3396 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
3398 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3399 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3401 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3402 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3406 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3407 pCVStructFormat
->offset_to_array_description
;
3408 cvarray_type
= *pCVArrayFormat
;
3409 switch (cvarray_type
)
3411 case RPC_FC_CVARRAY
:
3412 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3413 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 4);
3415 case RPC_FC_C_CSTRING
:
3416 esize
= sizeof(char);
3417 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3418 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3420 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3422 case RPC_FC_C_WSTRING
:
3423 esize
= sizeof(WCHAR
);
3424 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3425 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3427 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3430 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3431 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3435 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
3437 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3439 pStubMsg
->Buffer
+= pCVStructFormat
->memory_size
;
3440 pCVArrayFormat
= ReadVariance(pStubMsg
, pCVArrayFormat
, pStubMsg
->MaxCount
);
3441 pStubMsg
->Buffer
+= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->ActualCount
);
3443 pStubMsg
->MemorySize
+= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->MaxCount
);
3445 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
3447 return pCVStructFormat
->memory_size
+ pStubMsg
->MaxCount
* esize
;
3450 /***********************************************************************
3451 * NdrConformantVaryingStructFree [RPCRT4.@]
3453 void WINAPI
NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3454 unsigned char *pMemory
,
3455 PFORMAT_STRING pFormat
)
3457 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3458 PFORMAT_STRING pCVArrayFormat
;
3461 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3463 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3464 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3466 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3467 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3471 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3472 pCVStructFormat
->offset_to_array_description
;
3473 switch (*pCVArrayFormat
)
3475 case RPC_FC_CVARRAY
:
3476 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3478 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3479 pCVArrayFormat
+ 4, 0);
3480 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3483 case RPC_FC_C_CSTRING
:
3484 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
3485 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
3486 esize
= sizeof(char);
3487 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3488 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3489 pCVArrayFormat
+ 2, 0);
3491 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3493 case RPC_FC_C_WSTRING
:
3494 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
3495 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
3496 esize
= sizeof(WCHAR
);
3497 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3498 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3499 pCVArrayFormat
+ 2, 0);
3501 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3504 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3505 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3509 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3511 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
3514 #include "pshpack1.h"
3518 unsigned char alignment
;
3519 unsigned short total_size
;
3520 } NDR_SMFARRAY_FORMAT
;
3525 unsigned char alignment
;
3526 unsigned long total_size
;
3527 } NDR_LGFARRAY_FORMAT
;
3528 #include "poppack.h"
3530 /***********************************************************************
3531 * NdrFixedArrayMarshall [RPCRT4.@]
3533 unsigned char * WINAPI
NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3534 unsigned char *pMemory
,
3535 PFORMAT_STRING pFormat
)
3537 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
3538 unsigned long total_size
;
3540 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3542 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
3543 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
3545 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
3546 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3550 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
3552 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
3554 total_size
= pSmFArrayFormat
->total_size
;
3555 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
3559 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
3560 total_size
= pLgFArrayFormat
->total_size
;
3561 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
3564 memcpy(pStubMsg
->Buffer
, pMemory
, total_size
);
3565 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3566 pStubMsg
->Buffer
+= total_size
;
3568 pFormat
= EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3573 /***********************************************************************
3574 * NdrFixedArrayUnmarshall [RPCRT4.@]
3576 unsigned char * WINAPI
NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3577 unsigned char **ppMemory
,
3578 PFORMAT_STRING pFormat
,
3579 unsigned char fMustAlloc
)
3581 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
3582 unsigned long total_size
;
3584 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3586 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
3587 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
3589 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
3590 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3594 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
3596 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
3598 total_size
= pSmFArrayFormat
->total_size
;
3599 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
3603 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
3604 total_size
= pLgFArrayFormat
->total_size
;
3605 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
3608 if (fMustAlloc
|| !*ppMemory
)
3609 *ppMemory
= NdrAllocate(pStubMsg
, total_size
);
3610 memcpy(*ppMemory
, pStubMsg
->Buffer
, total_size
);
3611 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3612 pStubMsg
->Buffer
+= total_size
;
3614 pFormat
= EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3619 /***********************************************************************
3620 * NdrFixedArrayBufferSize [RPCRT4.@]
3622 void WINAPI
NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3623 unsigned char *pMemory
,
3624 PFORMAT_STRING pFormat
)
3626 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
3627 unsigned long total_size
;
3629 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3631 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
3632 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
3634 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
3635 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3639 ALIGN_LENGTH(pStubMsg
->BufferLength
, pSmFArrayFormat
->alignment
+ 1);
3641 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
3643 total_size
= pSmFArrayFormat
->total_size
;
3644 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
3648 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
3649 total_size
= pLgFArrayFormat
->total_size
;
3650 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
3652 pStubMsg
->BufferLength
+= total_size
;
3654 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3657 /***********************************************************************
3658 * NdrFixedArrayMemorySize [RPCRT4.@]
3660 ULONG WINAPI
NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3661 PFORMAT_STRING pFormat
)
3663 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
3666 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
3668 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
3669 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
3671 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
3672 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3676 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
3678 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
3680 total_size
= pSmFArrayFormat
->total_size
;
3681 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
3685 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
3686 total_size
= pLgFArrayFormat
->total_size
;
3687 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
3689 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3690 pStubMsg
->Buffer
+= total_size
;
3691 pStubMsg
->MemorySize
+= total_size
;
3693 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
3698 /***********************************************************************
3699 * NdrFixedArrayFree [RPCRT4.@]
3701 void WINAPI
NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3702 unsigned char *pMemory
,
3703 PFORMAT_STRING pFormat
)
3705 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
3707 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3709 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
3710 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
3712 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
3713 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3717 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
3718 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
3721 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
3722 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
3725 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
3728 /***********************************************************************
3729 * NdrVaryingArrayMarshall [RPCRT4.@]
3731 unsigned char * WINAPI
NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3732 unsigned char *pMemory
,
3733 PFORMAT_STRING pFormat
)
3735 unsigned char alignment
;
3736 DWORD elements
, esize
;
3739 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3741 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
3742 (pFormat
[0] != RPC_FC_LGVARRAY
))
3744 ERR("invalid format type %x\n", pFormat
[0]);
3745 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3749 alignment
= pFormat
[1] + 1;
3751 if (pFormat
[0] == RPC_FC_SMVARRAY
)
3754 pFormat
+= sizeof(WORD
);
3755 elements
= *(const WORD
*)pFormat
;
3756 pFormat
+= sizeof(WORD
);
3761 pFormat
+= sizeof(DWORD
);
3762 elements
= *(const DWORD
*)pFormat
;
3763 pFormat
+= sizeof(DWORD
);
3766 esize
= *(const WORD
*)pFormat
;
3767 pFormat
+= sizeof(WORD
);
3769 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
3770 if ((pStubMsg
->ActualCount
> elements
) ||
3771 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
3773 RpcRaiseException(RPC_S_INVALID_BOUND
);
3777 WriteVariance(pStubMsg
);
3779 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3781 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3782 memcpy(pStubMsg
->Buffer
, pMemory
+ pStubMsg
->Offset
, bufsize
);
3783 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3784 pStubMsg
->Buffer
+= bufsize
;
3786 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3788 STD_OVERFLOW_CHECK(pStubMsg
);
3793 /***********************************************************************
3794 * NdrVaryingArrayUnmarshall [RPCRT4.@]
3796 unsigned char * WINAPI
NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3797 unsigned char **ppMemory
,
3798 PFORMAT_STRING pFormat
,
3799 unsigned char fMustAlloc
)
3801 unsigned char alignment
;
3802 DWORD size
, elements
, esize
;
3805 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3807 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
3808 (pFormat
[0] != RPC_FC_LGVARRAY
))
3810 ERR("invalid format type %x\n", pFormat
[0]);
3811 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3815 alignment
= pFormat
[1] + 1;
3817 if (pFormat
[0] == RPC_FC_SMVARRAY
)
3820 size
= *(const WORD
*)pFormat
;
3821 pFormat
+= sizeof(WORD
);
3822 elements
= *(const WORD
*)pFormat
;
3823 pFormat
+= sizeof(WORD
);
3828 size
= *(const DWORD
*)pFormat
;
3829 pFormat
+= sizeof(DWORD
);
3830 elements
= *(const DWORD
*)pFormat
;
3831 pFormat
+= sizeof(DWORD
);
3834 esize
= *(const WORD
*)pFormat
;
3835 pFormat
+= sizeof(WORD
);
3837 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
3839 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3841 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3843 if (!*ppMemory
|| fMustAlloc
)
3844 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3845 memcpy(*ppMemory
+ pStubMsg
->Offset
, pStubMsg
->Buffer
, bufsize
);
3846 pStubMsg
->Buffer
+= bufsize
;
3848 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3853 /***********************************************************************
3854 * NdrVaryingArrayBufferSize [RPCRT4.@]
3856 void WINAPI
NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3857 unsigned char *pMemory
,
3858 PFORMAT_STRING pFormat
)
3860 unsigned char alignment
;
3861 DWORD elements
, esize
;
3863 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3865 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
3866 (pFormat
[0] != RPC_FC_LGVARRAY
))
3868 ERR("invalid format type %x\n", pFormat
[0]);
3869 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3873 alignment
= pFormat
[1] + 1;
3875 if (pFormat
[0] == RPC_FC_SMVARRAY
)
3878 pFormat
+= sizeof(WORD
);
3879 elements
= *(const WORD
*)pFormat
;
3880 pFormat
+= sizeof(WORD
);
3885 pFormat
+= sizeof(DWORD
);
3886 elements
= *(const DWORD
*)pFormat
;
3887 pFormat
+= sizeof(DWORD
);
3890 esize
= *(const WORD
*)pFormat
;
3891 pFormat
+= sizeof(WORD
);
3893 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
3894 if ((pStubMsg
->ActualCount
> elements
) ||
3895 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
3897 RpcRaiseException(RPC_S_INVALID_BOUND
);
3901 SizeVariance(pStubMsg
);
3903 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
3905 pStubMsg
->BufferLength
+= safe_multiply(esize
, pStubMsg
->ActualCount
);
3907 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3910 /***********************************************************************
3911 * NdrVaryingArrayMemorySize [RPCRT4.@]
3913 ULONG WINAPI
NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3914 PFORMAT_STRING pFormat
)
3916 unsigned char alignment
;
3917 DWORD size
, elements
, esize
;
3919 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
3921 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
3922 (pFormat
[0] != RPC_FC_LGVARRAY
))
3924 ERR("invalid format type %x\n", pFormat
[0]);
3925 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3929 alignment
= pFormat
[1] + 1;
3931 if (pFormat
[0] == RPC_FC_SMVARRAY
)
3934 size
= *(const WORD
*)pFormat
;
3935 pFormat
+= sizeof(WORD
);
3936 elements
= *(const WORD
*)pFormat
;
3937 pFormat
+= sizeof(WORD
);
3942 size
= *(const DWORD
*)pFormat
;
3943 pFormat
+= sizeof(DWORD
);
3944 elements
= *(const DWORD
*)pFormat
;
3945 pFormat
+= sizeof(DWORD
);
3948 esize
= *(const WORD
*)pFormat
;
3949 pFormat
+= sizeof(WORD
);
3951 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
3953 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3955 pStubMsg
->Buffer
+= safe_multiply(esize
, pStubMsg
->ActualCount
);
3956 pStubMsg
->MemorySize
+= size
;
3958 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
3960 return pStubMsg
->MemorySize
;
3963 /***********************************************************************
3964 * NdrVaryingArrayFree [RPCRT4.@]
3966 void WINAPI
NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3967 unsigned char *pMemory
,
3968 PFORMAT_STRING pFormat
)
3970 unsigned char alignment
;
3973 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3975 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
3976 (pFormat
[0] != RPC_FC_LGVARRAY
))
3978 ERR("invalid format type %x\n", pFormat
[0]);
3979 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3983 alignment
= pFormat
[1] + 1;
3985 if (pFormat
[0] == RPC_FC_SMVARRAY
)
3988 pFormat
+= sizeof(WORD
);
3989 elements
= *(const WORD
*)pFormat
;
3990 pFormat
+= sizeof(WORD
);
3995 pFormat
+= sizeof(DWORD
);
3996 elements
= *(const DWORD
*)pFormat
;
3997 pFormat
+= sizeof(DWORD
);
4000 pFormat
+= sizeof(WORD
);
4002 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4003 if ((pStubMsg
->ActualCount
> elements
) ||
4004 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4006 RpcRaiseException(RPC_S_INVALID_BOUND
);
4010 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4013 static ULONG
get_discriminant(unsigned char fc
, unsigned char *pMemory
)
4021 return *(UCHAR
*)pMemory
;
4025 return *(USHORT
*)pMemory
;
4028 return *(ULONG
*)pMemory
;
4030 FIXME("Unhandled base type: 0x%02x\n", fc
);
4035 static PFORMAT_STRING
get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg
,
4036 unsigned long discriminant
,
4037 PFORMAT_STRING pFormat
)
4039 unsigned short num_arms
, arm
, type
;
4041 num_arms
= *(const SHORT
*)pFormat
& 0x0fff;
4043 for(arm
= 0; arm
< num_arms
; arm
++)
4045 if(discriminant
== *(const ULONG
*)pFormat
)
4053 type
= *(const unsigned short*)pFormat
;
4054 TRACE("type %04x\n", type
);
4055 if(arm
== num_arms
) /* default arm extras */
4059 ERR("no arm for 0x%lx and no default case\n", discriminant
);
4060 RpcRaiseException(RPC_S_INVALID_TAG
);
4065 TRACE("falling back to empty default case for 0x%lx\n", discriminant
);
4072 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
, ULONG discriminant
, PFORMAT_STRING pFormat
)
4074 unsigned short type
;
4078 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4082 type
= *(const unsigned short*)pFormat
;
4083 if((type
& 0xff00) == 0x8000)
4085 unsigned char basetype
= LOBYTE(type
);
4086 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &basetype
);
4090 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4091 NDR_MARSHALL m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
4094 unsigned char *saved_buffer
= NULL
;
4101 saved_buffer
= pStubMsg
->Buffer
;
4102 pStubMsg
->Buffer
+= 4; /* for pointer ID */
4103 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char **)pMemory
, desc
);
4106 m(pStubMsg
, pMemory
, desc
);
4109 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4114 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4115 unsigned char **ppMemory
,
4117 PFORMAT_STRING pFormat
,
4118 unsigned char fMustAlloc
)
4120 unsigned short type
;
4124 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4128 type
= *(const unsigned short*)pFormat
;
4129 if((type
& 0xff00) == 0x8000)
4131 unsigned char basetype
= LOBYTE(type
);
4132 return NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &basetype
, fMustAlloc
);
4136 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4137 NDR_UNMARSHALL m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
4140 unsigned char *saved_buffer
= NULL
;
4147 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4148 saved_buffer
= pStubMsg
->Buffer
;
4149 pStubMsg
->Buffer
+= 4; /* for pointer ID */
4150 PointerUnmarshall(pStubMsg
, saved_buffer
, *(unsigned char ***)ppMemory
, desc
, TRUE
);
4153 m(pStubMsg
, ppMemory
, desc
, fMustAlloc
);
4156 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4161 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg
,
4162 unsigned char *pMemory
,
4164 PFORMAT_STRING pFormat
)
4166 unsigned short type
;
4170 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4174 type
= *(const unsigned short*)pFormat
;
4175 if((type
& 0xff00) == 0x8000)
4177 unsigned char basetype
= LOBYTE(type
);
4178 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &basetype
);
4182 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4183 NDR_BUFFERSIZE m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
4192 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
4193 pStubMsg
->BufferLength
+= 4; /* for pointer ID */
4194 PointerBufferSize(pStubMsg
, *(unsigned char **)pMemory
, desc
);
4197 m(pStubMsg
, pMemory
, desc
);
4200 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
4204 static ULONG
union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg
,
4206 PFORMAT_STRING pFormat
)
4208 unsigned short type
, size
;
4210 size
= *(const unsigned short*)pFormat
;
4211 pStubMsg
->Memory
+= size
;
4214 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4218 type
= *(const unsigned short*)pFormat
;
4219 if((type
& 0xff00) == 0x8000)
4221 return NdrBaseTypeMemorySize(pStubMsg
, pFormat
);
4225 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4226 NDR_MEMORYSIZE m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
4227 unsigned char *saved_buffer
;
4236 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4237 saved_buffer
= pStubMsg
->Buffer
;
4238 pStubMsg
->Buffer
+= 4;
4239 ALIGN_LENGTH(pStubMsg
->MemorySize
, 4);
4240 pStubMsg
->MemorySize
+= 4;
4241 PointerMemorySize(pStubMsg
, saved_buffer
, pFormat
);
4244 return m(pStubMsg
, desc
);
4247 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4250 TRACE("size %d\n", size
);
4254 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg
,
4255 unsigned char *pMemory
,
4257 PFORMAT_STRING pFormat
)
4259 unsigned short type
;
4263 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4267 type
= *(const unsigned short*)pFormat
;
4268 if((type
& 0xff00) != 0x8000)
4270 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4271 NDR_FREE m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
4280 PointerFree(pStubMsg
, *(unsigned char **)pMemory
, desc
);
4283 m(pStubMsg
, pMemory
, desc
);
4286 else FIXME("no freer for embedded type %02x\n", *desc
);
4290 /***********************************************************************
4291 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
4293 unsigned char * WINAPI
NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4294 unsigned char *pMemory
,
4295 PFORMAT_STRING pFormat
)
4297 unsigned char switch_type
;
4298 unsigned char increment
;
4301 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4304 switch_type
= *pFormat
& 0xf;
4305 increment
= (*pFormat
& 0xf0) >> 4;
4308 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
4310 switch_value
= get_discriminant(switch_type
, pMemory
);
4311 TRACE("got switch value 0x%x\n", switch_value
);
4313 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &switch_type
);
4314 pMemory
+= increment
;
4316 return union_arm_marshall(pStubMsg
, pMemory
, switch_value
, pFormat
);
4319 /***********************************************************************
4320 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
4322 unsigned char * WINAPI
NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4323 unsigned char **ppMemory
,
4324 PFORMAT_STRING pFormat
,
4325 unsigned char fMustAlloc
)
4327 unsigned char switch_type
;
4328 unsigned char increment
;
4330 unsigned short size
;
4331 unsigned char *pMemoryArm
;
4333 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4336 switch_type
= *pFormat
& 0xf;
4337 increment
= (*pFormat
& 0xf0) >> 4;
4340 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
4341 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
4342 TRACE("got switch value 0x%x\n", switch_value
);
4344 size
= *(const unsigned short*)pFormat
+ increment
;
4345 if(!*ppMemory
|| fMustAlloc
)
4346 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4348 NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &switch_type
, FALSE
);
4349 pMemoryArm
= *ppMemory
+ increment
;
4351 return union_arm_unmarshall(pStubMsg
, &pMemoryArm
, switch_value
, pFormat
, fMustAlloc
);
4354 /***********************************************************************
4355 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
4357 void WINAPI
NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4358 unsigned char *pMemory
,
4359 PFORMAT_STRING pFormat
)
4361 unsigned char switch_type
;
4362 unsigned char increment
;
4365 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4368 switch_type
= *pFormat
& 0xf;
4369 increment
= (*pFormat
& 0xf0) >> 4;
4372 ALIGN_LENGTH(pStubMsg
->BufferLength
, increment
);
4373 switch_value
= get_discriminant(switch_type
, pMemory
);
4374 TRACE("got switch value 0x%x\n", switch_value
);
4376 /* Add discriminant size */
4377 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&switch_value
, &switch_type
);
4378 pMemory
+= increment
;
4380 union_arm_buffer_size(pStubMsg
, pMemory
, switch_value
, pFormat
);
4383 /***********************************************************************
4384 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
4386 ULONG WINAPI
NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4387 PFORMAT_STRING pFormat
)
4389 unsigned char switch_type
;
4390 unsigned char increment
;
4393 switch_type
= *pFormat
& 0xf;
4394 increment
= (*pFormat
& 0xf0) >> 4;
4397 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
4398 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
4399 TRACE("got switch value 0x%x\n", switch_value
);
4401 pStubMsg
->Memory
+= increment
;
4403 return increment
+ union_arm_memory_size(pStubMsg
, switch_value
, pFormat
+ *(const SHORT
*)pFormat
);
4406 /***********************************************************************
4407 * NdrEncapsulatedUnionFree [RPCRT4.@]
4409 void WINAPI
NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
4410 unsigned char *pMemory
,
4411 PFORMAT_STRING pFormat
)
4413 unsigned char switch_type
;
4414 unsigned char increment
;
4417 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4420 switch_type
= *pFormat
& 0xf;
4421 increment
= (*pFormat
& 0xf0) >> 4;
4424 switch_value
= get_discriminant(switch_type
, pMemory
);
4425 TRACE("got switch value 0x%x\n", switch_value
);
4427 pMemory
+= increment
;
4429 return union_arm_free(pStubMsg
, pMemory
, switch_value
, pFormat
);
4432 /***********************************************************************
4433 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
4435 unsigned char * WINAPI
NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4436 unsigned char *pMemory
,
4437 PFORMAT_STRING pFormat
)
4439 unsigned char switch_type
;
4441 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4444 switch_type
= *pFormat
;
4447 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
4448 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
4449 /* Marshall discriminant */
4450 NdrBaseTypeMarshall(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
4452 return union_arm_marshall(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
4455 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg
,
4456 PFORMAT_STRING
*ppFormat
)
4458 long discriminant
= 0;
4466 discriminant
= *(UCHAR
*)pStubMsg
->Buffer
;
4467 pStubMsg
->Buffer
+= sizeof(UCHAR
);
4472 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
4473 discriminant
= *(USHORT
*)pStubMsg
->Buffer
;
4474 pStubMsg
->Buffer
+= sizeof(USHORT
);
4478 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
4479 discriminant
= *(ULONG
*)pStubMsg
->Buffer
;
4480 pStubMsg
->Buffer
+= sizeof(ULONG
);
4483 FIXME("Unhandled base type: 0x%02x\n", **ppFormat
);
4487 if (pStubMsg
->fHasNewCorrDesc
)
4491 return discriminant
;
4494 /**********************************************************************
4495 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
4497 unsigned char * WINAPI
NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4498 unsigned char **ppMemory
,
4499 PFORMAT_STRING pFormat
,
4500 unsigned char fMustAlloc
)
4503 unsigned short size
;
4505 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4508 /* Unmarshall discriminant */
4509 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
4510 TRACE("unmarshalled discriminant %lx\n", discriminant
);
4512 pFormat
+= *(const SHORT
*)pFormat
;
4514 size
= *(const unsigned short*)pFormat
;
4516 if(!*ppMemory
|| fMustAlloc
)
4517 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4519 return union_arm_unmarshall(pStubMsg
, ppMemory
, discriminant
, pFormat
, fMustAlloc
);
4522 /***********************************************************************
4523 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
4525 void WINAPI
NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4526 unsigned char *pMemory
,
4527 PFORMAT_STRING pFormat
)
4529 unsigned char switch_type
;
4531 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4534 switch_type
= *pFormat
;
4537 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
4538 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
4539 /* Add discriminant size */
4540 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
4542 union_arm_buffer_size(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
4545 /***********************************************************************
4546 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
4548 ULONG WINAPI
NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4549 PFORMAT_STRING pFormat
)
4554 /* Unmarshall discriminant */
4555 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
4556 TRACE("unmarshalled discriminant 0x%x\n", discriminant
);
4558 return union_arm_memory_size(pStubMsg
, discriminant
, pFormat
+ *(const SHORT
*)pFormat
);
4561 /***********************************************************************
4562 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
4564 void WINAPI
NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
4565 unsigned char *pMemory
,
4566 PFORMAT_STRING pFormat
)
4568 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4572 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
4573 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
4575 return union_arm_free(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
4578 /***********************************************************************
4579 * NdrByteCountPointerMarshall [RPCRT4.@]
4581 unsigned char * WINAPI
NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4582 unsigned char *pMemory
,
4583 PFORMAT_STRING pFormat
)
4589 /***********************************************************************
4590 * NdrByteCountPointerUnmarshall [RPCRT4.@]
4592 unsigned char * WINAPI
NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4593 unsigned char **ppMemory
,
4594 PFORMAT_STRING pFormat
,
4595 unsigned char fMustAlloc
)
4601 /***********************************************************************
4602 * NdrByteCountPointerBufferSize [RPCRT4.@]
4604 void WINAPI
NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4605 unsigned char *pMemory
,
4606 PFORMAT_STRING pFormat
)
4611 /***********************************************************************
4612 * NdrByteCountPointerMemorySize [RPCRT4.@]
4614 ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4615 PFORMAT_STRING pFormat
)
4621 /***********************************************************************
4622 * NdrByteCountPointerFree [RPCRT4.@]
4624 void WINAPI
NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
4625 unsigned char *pMemory
,
4626 PFORMAT_STRING pFormat
)
4631 /***********************************************************************
4632 * NdrXmitOrRepAsMarshall [RPCRT4.@]
4634 unsigned char * WINAPI
NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4635 unsigned char *pMemory
,
4636 PFORMAT_STRING pFormat
)
4642 /***********************************************************************
4643 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
4645 unsigned char * WINAPI
NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4646 unsigned char **ppMemory
,
4647 PFORMAT_STRING pFormat
,
4648 unsigned char fMustAlloc
)
4654 /***********************************************************************
4655 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
4657 void WINAPI
NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4658 unsigned char *pMemory
,
4659 PFORMAT_STRING pFormat
)
4664 /***********************************************************************
4665 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
4667 ULONG WINAPI
NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4668 PFORMAT_STRING pFormat
)
4674 /***********************************************************************
4675 * NdrXmitOrRepAsFree [RPCRT4.@]
4677 void WINAPI
NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg
,
4678 unsigned char *pMemory
,
4679 PFORMAT_STRING pFormat
)
4684 /***********************************************************************
4685 * NdrBaseTypeMarshall [internal]
4687 static unsigned char *WINAPI
NdrBaseTypeMarshall(
4688 PMIDL_STUB_MESSAGE pStubMsg
,
4689 unsigned char *pMemory
,
4690 PFORMAT_STRING pFormat
)
4692 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
4700 *(UCHAR
*)pStubMsg
->Buffer
= *(UCHAR
*)pMemory
;
4701 pStubMsg
->Buffer
+= sizeof(UCHAR
);
4702 TRACE("value: 0x%02x\n", *(UCHAR
*)pMemory
);
4707 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
4708 *(USHORT
*)pStubMsg
->Buffer
= *(USHORT
*)pMemory
;
4709 pStubMsg
->Buffer
+= sizeof(USHORT
);
4710 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
4714 case RPC_FC_ERROR_STATUS_T
:
4716 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
4717 *(ULONG
*)pStubMsg
->Buffer
= *(ULONG
*)pMemory
;
4718 pStubMsg
->Buffer
+= sizeof(ULONG
);
4719 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
4722 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(float));
4723 *(float *)pStubMsg
->Buffer
= *(float *)pMemory
;
4724 pStubMsg
->Buffer
+= sizeof(float);
4727 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(double));
4728 *(double *)pStubMsg
->Buffer
= *(double *)pMemory
;
4729 pStubMsg
->Buffer
+= sizeof(double);
4732 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONGLONG
));
4733 *(ULONGLONG
*)pStubMsg
->Buffer
= *(ULONGLONG
*)pMemory
;
4734 pStubMsg
->Buffer
+= sizeof(ULONGLONG
);
4735 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
4738 /* only 16-bits on the wire, so do a sanity check */
4739 if (*(UINT
*)pMemory
> USHRT_MAX
)
4740 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
4741 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
4742 *(USHORT
*)pStubMsg
->Buffer
= *(UINT
*)pMemory
;
4743 pStubMsg
->Buffer
+= sizeof(USHORT
);
4744 TRACE("value: 0x%04x\n", *(UINT
*)pMemory
);
4747 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
4750 STD_OVERFLOW_CHECK(pStubMsg
);
4752 /* FIXME: what is the correct return value? */
4756 /***********************************************************************
4757 * NdrBaseTypeUnmarshall [internal]
4759 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(
4760 PMIDL_STUB_MESSAGE pStubMsg
,
4761 unsigned char **ppMemory
,
4762 PFORMAT_STRING pFormat
,
4763 unsigned char fMustAlloc
)
4765 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
4767 #define BASE_TYPE_UNMARSHALL(type) \
4768 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
4769 if (fMustAlloc || !*ppMemory) \
4770 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
4771 TRACE("*ppMemory: %p\n", *ppMemory); \
4772 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
4773 pStubMsg->Buffer += sizeof(type);
4781 BASE_TYPE_UNMARSHALL(UCHAR
);
4782 TRACE("value: 0x%02x\n", **(UCHAR
**)ppMemory
);
4787 BASE_TYPE_UNMARSHALL(USHORT
);
4788 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
4792 case RPC_FC_ERROR_STATUS_T
:
4794 BASE_TYPE_UNMARSHALL(ULONG
);
4795 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
4798 BASE_TYPE_UNMARSHALL(float);
4799 TRACE("value: %f\n", **(float **)ppMemory
);
4802 BASE_TYPE_UNMARSHALL(double);
4803 TRACE("value: %f\n", **(double **)ppMemory
);
4806 BASE_TYPE_UNMARSHALL(ULONGLONG
);
4807 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG
**)ppMemory
));
4810 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
4811 if (fMustAlloc
|| !*ppMemory
)
4812 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT
));
4813 TRACE("*ppMemory: %p\n", *ppMemory
);
4814 /* 16-bits on the wire, but int in memory */
4815 **(UINT
**)ppMemory
= *(USHORT
*)pStubMsg
->Buffer
;
4816 pStubMsg
->Buffer
+= sizeof(USHORT
);
4817 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
4820 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
4822 #undef BASE_TYPE_UNMARSHALL
4824 /* FIXME: what is the correct return value? */
4829 /***********************************************************************
4830 * NdrBaseTypeBufferSize [internal]
4832 static void WINAPI
NdrBaseTypeBufferSize(
4833 PMIDL_STUB_MESSAGE pStubMsg
,
4834 unsigned char *pMemory
,
4835 PFORMAT_STRING pFormat
)
4837 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
4845 pStubMsg
->BufferLength
+= sizeof(UCHAR
);
4851 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(USHORT
));
4852 pStubMsg
->BufferLength
+= sizeof(USHORT
);
4857 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONG
));
4858 pStubMsg
->BufferLength
+= sizeof(ULONG
);
4861 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(float));
4862 pStubMsg
->BufferLength
+= sizeof(float);
4865 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(double));
4866 pStubMsg
->BufferLength
+= sizeof(double);
4869 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONGLONG
));
4870 pStubMsg
->BufferLength
+= sizeof(ULONGLONG
);
4872 case RPC_FC_ERROR_STATUS_T
:
4873 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(error_status_t
));
4874 pStubMsg
->BufferLength
+= sizeof(error_status_t
);
4877 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
4881 /***********************************************************************
4882 * NdrBaseTypeMemorySize [internal]
4884 static ULONG WINAPI
NdrBaseTypeMemorySize(
4885 PMIDL_STUB_MESSAGE pStubMsg
,
4886 PFORMAT_STRING pFormat
)
4894 pStubMsg
->Buffer
+= sizeof(UCHAR
);
4895 pStubMsg
->MemorySize
+= sizeof(UCHAR
);
4896 return sizeof(UCHAR
);
4900 pStubMsg
->Buffer
+= sizeof(USHORT
);
4901 pStubMsg
->MemorySize
+= sizeof(USHORT
);
4902 return sizeof(USHORT
);
4905 pStubMsg
->Buffer
+= sizeof(ULONG
);
4906 pStubMsg
->MemorySize
+= sizeof(ULONG
);
4907 return sizeof(ULONG
);
4909 pStubMsg
->Buffer
+= sizeof(float);
4910 pStubMsg
->MemorySize
+= sizeof(float);
4911 return sizeof(float);
4913 pStubMsg
->Buffer
+= sizeof(double);
4914 pStubMsg
->MemorySize
+= sizeof(double);
4915 return sizeof(double);
4917 pStubMsg
->Buffer
+= sizeof(ULONGLONG
);
4918 pStubMsg
->MemorySize
+= sizeof(ULONGLONG
);
4919 return sizeof(ULONGLONG
);
4920 case RPC_FC_ERROR_STATUS_T
:
4921 pStubMsg
->Buffer
+= sizeof(error_status_t
);
4922 pStubMsg
->MemorySize
+= sizeof(error_status_t
);
4923 return sizeof(error_status_t
);
4926 pStubMsg
->Buffer
+= sizeof(INT
);
4927 pStubMsg
->MemorySize
+= sizeof(INT
);
4930 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
4935 /***********************************************************************
4936 * NdrBaseTypeFree [internal]
4938 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg
,
4939 unsigned char *pMemory
,
4940 PFORMAT_STRING pFormat
)
4942 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
4947 /***********************************************************************
4948 * NdrClientContextMarshall [RPCRT4.@]
4950 void WINAPI
NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4951 NDR_CCONTEXT ContextHandle
,
4954 TRACE("(%p, %p, %d)\n", pStubMsg
, ContextHandle
, fCheck
);
4956 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4958 /* FIXME: what does fCheck do? */
4959 NDRCContextMarshall(ContextHandle
,
4962 pStubMsg
->Buffer
+= cbNDRContext
;
4965 /***********************************************************************
4966 * NdrClientContextUnmarshall [RPCRT4.@]
4968 void WINAPI
NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4969 NDR_CCONTEXT
* pContextHandle
,
4970 RPC_BINDING_HANDLE BindHandle
)
4972 TRACE("(%p, %p, %p)\n", pStubMsg
, pContextHandle
, BindHandle
);
4974 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4976 NDRCContextUnmarshall(pContextHandle
,
4979 pStubMsg
->RpcMsg
->DataRepresentation
);
4981 pStubMsg
->Buffer
+= cbNDRContext
;
4984 void WINAPI
NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4985 NDR_SCONTEXT ContextHandle
,
4986 NDR_RUNDOWN RundownRoutine
)
4988 FIXME("(%p, %p, %p): stub\n", pStubMsg
, ContextHandle
, RundownRoutine
);
4991 NDR_SCONTEXT WINAPI
NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
)
4993 FIXME("(%p): stub\n", pStubMsg
);
4997 void WINAPI
NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg
,
4998 unsigned char* pMemory
,
4999 PFORMAT_STRING pFormat
)
5001 FIXME("(%p, %p, %p): stub\n", pStubMsg
, pMemory
, pFormat
);
5004 NDR_SCONTEXT WINAPI
NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg
,
5005 PFORMAT_STRING pFormat
)
5007 FIXME("(%p, %p): stub\n", pStubMsg
, pFormat
);
5011 void WINAPI
NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5012 NDR_SCONTEXT ContextHandle
,
5013 NDR_RUNDOWN RundownRoutine
,
5014 PFORMAT_STRING pFormat
)
5016 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg
, ContextHandle
, RundownRoutine
, pFormat
);
5019 NDR_SCONTEXT WINAPI
NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5020 PFORMAT_STRING pFormat
)
5022 FIXME("(%p, %p): stub\n", pStubMsg
, pFormat
);
5026 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
5028 typedef struct ndr_context_handle
5032 } ndr_context_handle
;
5034 struct context_handle_entry
5038 RPC_BINDING_HANDLE handle
;
5039 ndr_context_handle wire_data
;
5042 static struct list context_handle_list
= LIST_INIT(context_handle_list
);
5044 static CRITICAL_SECTION ndr_context_cs
;
5045 static CRITICAL_SECTION_DEBUG ndr_context_debug
=
5047 0, 0, &ndr_context_cs
,
5048 { &ndr_context_debug
.ProcessLocksList
, &ndr_context_debug
.ProcessLocksList
},
5049 0, 0, { (DWORD_PTR
)(__FILE__
": ndr_context") }
5051 static CRITICAL_SECTION ndr_context_cs
= { &ndr_context_debug
, -1, 0, 0, 0, 0 };
5053 static struct context_handle_entry
*get_context_entry(NDR_CCONTEXT CContext
)
5055 struct context_handle_entry
*che
= (struct context_handle_entry
*) CContext
;
5057 if (che
->magic
!= NDR_CONTEXT_HANDLE_MAGIC
)
5062 static struct context_handle_entry
*context_entry_from_guid(LPGUID uuid
)
5064 struct context_handle_entry
*che
;
5065 LIST_FOR_EACH_ENTRY(che
, &context_handle_list
, struct context_handle_entry
, entry
)
5066 if (IsEqualGUID(&che
->wire_data
.uuid
, uuid
))
5071 RPC_BINDING_HANDLE WINAPI
NDRCContextBinding(NDR_CCONTEXT CContext
)
5073 struct context_handle_entry
*che
;
5074 RPC_BINDING_HANDLE handle
= NULL
;
5076 TRACE("%p\n", CContext
);
5078 EnterCriticalSection(&ndr_context_cs
);
5079 che
= get_context_entry(CContext
);
5081 handle
= che
->handle
;
5082 LeaveCriticalSection(&ndr_context_cs
);
5085 RpcRaiseException(ERROR_INVALID_HANDLE
);
5089 void WINAPI
NDRCContextMarshall(NDR_CCONTEXT CContext
, void *pBuff
)
5091 struct context_handle_entry
*che
;
5093 TRACE("%p %p\n", CContext
, pBuff
);
5097 EnterCriticalSection(&ndr_context_cs
);
5098 che
= get_context_entry(CContext
);
5099 memcpy(pBuff
, &che
->wire_data
, sizeof (ndr_context_handle
));
5100 LeaveCriticalSection(&ndr_context_cs
);
5104 ndr_context_handle
*wire_data
= (ndr_context_handle
*)pBuff
;
5105 wire_data
->attributes
= 0;
5106 wire_data
->uuid
= GUID_NULL
;
5110 static UINT
ndr_update_context_handle(NDR_CCONTEXT
*CContext
,
5111 RPC_BINDING_HANDLE hBinding
,
5112 ndr_context_handle
*chi
)
5114 struct context_handle_entry
*che
= NULL
;
5116 /* a null UUID means we should free the context handle */
5117 if (IsEqualGUID(&chi
->uuid
, &GUID_NULL
))
5121 che
= get_context_entry(*CContext
);
5123 return ERROR_INVALID_HANDLE
;
5124 list_remove(&che
->entry
);
5125 RpcBindingFree(&che
->handle
);
5126 HeapFree(GetProcessHeap(), 0, che
);
5130 /* if there's no existing entry matching the GUID, allocate one */
5131 else if (!(che
= context_entry_from_guid(&chi
->uuid
)))
5133 che
= HeapAlloc(GetProcessHeap(), 0, sizeof *che
);
5135 return ERROR_NOT_ENOUGH_MEMORY
;
5136 che
->magic
= NDR_CONTEXT_HANDLE_MAGIC
;
5137 RpcBindingCopy(hBinding
, &che
->handle
);
5138 list_add_tail(&context_handle_list
, &che
->entry
);
5139 memcpy(&che
->wire_data
, chi
, sizeof *chi
);
5144 return ERROR_SUCCESS
;
5147 /***********************************************************************
5148 * NDRCContextUnmarshall [RPCRT4.@]
5150 void WINAPI
NDRCContextUnmarshall(NDR_CCONTEXT
*CContext
,
5151 RPC_BINDING_HANDLE hBinding
,
5152 void *pBuff
, ULONG DataRepresentation
)
5156 TRACE("*%p=(%p) %p %p %08x\n",
5157 CContext
, *CContext
, hBinding
, pBuff
, DataRepresentation
);
5159 EnterCriticalSection(&ndr_context_cs
);
5160 r
= ndr_update_context_handle(CContext
, hBinding
, pBuff
);
5161 LeaveCriticalSection(&ndr_context_cs
);
5163 RpcRaiseException(r
);
5166 /***********************************************************************
5167 * NDRSContextMarshall [RPCRT4.@]
5169 void WINAPI
NDRSContextMarshall(NDR_SCONTEXT CContext
,
5171 NDR_RUNDOWN userRunDownIn
)
5173 FIXME("(%p %p %p): stub\n", CContext
, pBuff
, userRunDownIn
);
5176 /***********************************************************************
5177 * NDRSContextMarshallEx [RPCRT4.@]
5179 void WINAPI
NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding
,
5180 NDR_SCONTEXT CContext
,
5182 NDR_RUNDOWN userRunDownIn
)
5184 FIXME("(%p %p %p %p): stub\n", hBinding
, CContext
, pBuff
, userRunDownIn
);
5187 /***********************************************************************
5188 * NDRSContextMarshall2 [RPCRT4.@]
5190 void WINAPI
NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding
,
5191 NDR_SCONTEXT CContext
,
5193 NDR_RUNDOWN userRunDownIn
,
5194 void *CtxGuard
, ULONG Flags
)
5196 FIXME("(%p %p %p %p %p %u): stub\n",
5197 hBinding
, CContext
, pBuff
, userRunDownIn
, CtxGuard
, Flags
);
5200 /***********************************************************************
5201 * NDRSContextUnmarshall [RPCRT4.@]
5203 NDR_SCONTEXT WINAPI
NDRSContextUnmarshall(void *pBuff
,
5204 ULONG DataRepresentation
)
5206 FIXME("(%p %08x): stub\n", pBuff
, DataRepresentation
);
5210 /***********************************************************************
5211 * NDRSContextUnmarshallEx [RPCRT4.@]
5213 NDR_SCONTEXT WINAPI
NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding
,
5215 ULONG DataRepresentation
)
5217 FIXME("(%p %p %08x): stub\n", hBinding
, pBuff
, DataRepresentation
);
5221 /***********************************************************************
5222 * NDRSContextUnmarshall2 [RPCRT4.@]
5224 NDR_SCONTEXT WINAPI
NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding
,
5226 ULONG DataRepresentation
,
5227 void *CtxGuard
, ULONG Flags
)
5229 FIXME("(%p %p %08x %p %u): stub\n",
5230 hBinding
, pBuff
, DataRepresentation
, CtxGuard
, Flags
);