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 * - Byte count pointers
25 * - transmit_as/represent as
26 * - Multi-dimensional arrays
27 * - Conversion functions (NdrConvert)
28 * - Checks for integer addition overflow
29 * - Checks for out-of-memory conditions
45 #include "wine/unicode.h"
46 #include "wine/rpcfc.h"
48 #include "wine/debug.h"
49 #include "wine/list.h"
51 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
54 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
55 (*((UINT32 *)(pchar)) = (uint32))
57 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
58 (*((UINT32 *)(pchar)))
60 /* these would work for i386 too, but less efficient */
61 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
62 (*(pchar) = LOBYTE(LOWORD(uint32)), \
63 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
64 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
65 *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
66 (uint32)) /* allow as r-value */
68 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
70 MAKEWORD(*(pchar), *((pchar)+1)), \
71 MAKEWORD(*((pchar)+2), *((pchar)+3))))
74 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
75 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
76 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
77 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
78 *(pchar) = HIBYTE(HIWORD(uint32)), \
79 (uint32)) /* allow as r-value */
81 #define BIG_ENDIAN_UINT32_READ(pchar) \
83 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
84 MAKEWORD(*((pchar)+1), *(pchar))))
86 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
87 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
88 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
89 # define NDR_LOCAL_UINT32_READ(pchar) \
90 BIG_ENDIAN_UINT32_READ(pchar)
92 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
93 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
94 # define NDR_LOCAL_UINT32_READ(pchar) \
95 LITTLE_ENDIAN_UINT32_READ(pchar)
98 /* _Align must be the desired alignment,
99 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
100 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
101 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
102 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
103 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
105 #define STD_OVERFLOW_CHECK(_Msg) do { \
106 TRACE("buffer=%d/%d\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
107 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
108 ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
111 #define NDR_TABLE_SIZE 128
112 #define NDR_TABLE_MASK 127
114 static unsigned char *WINAPI
NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
115 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
116 static void WINAPI
NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
117 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
118 static ULONG WINAPI
NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
120 static unsigned char *WINAPI
NdrContextHandleMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
121 static void WINAPI
NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
122 static unsigned char *WINAPI
NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
124 const NDR_MARSHALL NdrMarshaller
[NDR_TABLE_SIZE
] = {
126 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
127 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
128 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
129 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
133 NdrPointerMarshall
, NdrPointerMarshall
,
134 NdrPointerMarshall
, NdrPointerMarshall
,
136 NdrSimpleStructMarshall
, NdrSimpleStructMarshall
,
137 NdrConformantStructMarshall
, NdrConformantStructMarshall
,
138 NdrConformantVaryingStructMarshall
,
139 NdrComplexStructMarshall
,
141 NdrConformantArrayMarshall
,
142 NdrConformantVaryingArrayMarshall
,
143 NdrFixedArrayMarshall
, NdrFixedArrayMarshall
,
144 NdrVaryingArrayMarshall
, NdrVaryingArrayMarshall
,
145 NdrComplexArrayMarshall
,
147 NdrConformantStringMarshall
, 0, 0,
148 NdrConformantStringMarshall
,
149 NdrNonConformantStringMarshall
, 0, 0, 0,
151 NdrEncapsulatedUnionMarshall
,
152 NdrNonEncapsulatedUnionMarshall
,
153 NdrByteCountPointerMarshall
,
154 NdrXmitOrRepAsMarshall
, NdrXmitOrRepAsMarshall
,
156 NdrInterfacePointerMarshall
,
158 NdrContextHandleMarshall
,
161 NdrUserMarshalMarshall
,
166 const NDR_UNMARSHALL NdrUnmarshaller
[NDR_TABLE_SIZE
] = {
168 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
169 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
170 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
171 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
173 NdrBaseTypeUnmarshall
,
175 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
176 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
178 NdrSimpleStructUnmarshall
, NdrSimpleStructUnmarshall
,
179 NdrConformantStructUnmarshall
, NdrConformantStructUnmarshall
,
180 NdrConformantVaryingStructUnmarshall
,
181 NdrComplexStructUnmarshall
,
183 NdrConformantArrayUnmarshall
,
184 NdrConformantVaryingArrayUnmarshall
,
185 NdrFixedArrayUnmarshall
, NdrFixedArrayUnmarshall
,
186 NdrVaryingArrayUnmarshall
, NdrVaryingArrayUnmarshall
,
187 NdrComplexArrayUnmarshall
,
189 NdrConformantStringUnmarshall
, 0, 0,
190 NdrConformantStringUnmarshall
,
191 NdrNonConformantStringUnmarshall
, 0, 0, 0,
193 NdrEncapsulatedUnionUnmarshall
,
194 NdrNonEncapsulatedUnionUnmarshall
,
195 NdrByteCountPointerUnmarshall
,
196 NdrXmitOrRepAsUnmarshall
, NdrXmitOrRepAsUnmarshall
,
198 NdrInterfacePointerUnmarshall
,
200 NdrContextHandleUnmarshall
,
203 NdrUserMarshalUnmarshall
,
208 const NDR_BUFFERSIZE NdrBufferSizer
[NDR_TABLE_SIZE
] = {
210 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
211 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
212 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
213 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
215 NdrBaseTypeBufferSize
,
217 NdrPointerBufferSize
, NdrPointerBufferSize
,
218 NdrPointerBufferSize
, NdrPointerBufferSize
,
220 NdrSimpleStructBufferSize
, NdrSimpleStructBufferSize
,
221 NdrConformantStructBufferSize
, NdrConformantStructBufferSize
,
222 NdrConformantVaryingStructBufferSize
,
223 NdrComplexStructBufferSize
,
225 NdrConformantArrayBufferSize
,
226 NdrConformantVaryingArrayBufferSize
,
227 NdrFixedArrayBufferSize
, NdrFixedArrayBufferSize
,
228 NdrVaryingArrayBufferSize
, NdrVaryingArrayBufferSize
,
229 NdrComplexArrayBufferSize
,
231 NdrConformantStringBufferSize
, 0, 0,
232 NdrConformantStringBufferSize
,
233 NdrNonConformantStringBufferSize
, 0, 0, 0,
235 NdrEncapsulatedUnionBufferSize
,
236 NdrNonEncapsulatedUnionBufferSize
,
237 NdrByteCountPointerBufferSize
,
238 NdrXmitOrRepAsBufferSize
, NdrXmitOrRepAsBufferSize
,
240 NdrInterfacePointerBufferSize
,
242 NdrContextHandleBufferSize
,
245 NdrUserMarshalBufferSize
,
250 const NDR_MEMORYSIZE NdrMemorySizer
[NDR_TABLE_SIZE
] = {
252 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
253 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
254 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
255 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
257 NdrBaseTypeMemorySize
,
259 NdrPointerMemorySize
, NdrPointerMemorySize
,
260 NdrPointerMemorySize
, NdrPointerMemorySize
,
262 NdrSimpleStructMemorySize
, NdrSimpleStructMemorySize
,
263 NdrConformantStructMemorySize
, NdrConformantStructMemorySize
,
264 NdrConformantVaryingStructMemorySize
,
265 NdrComplexStructMemorySize
,
267 NdrConformantArrayMemorySize
,
268 NdrConformantVaryingArrayMemorySize
,
269 NdrFixedArrayMemorySize
, NdrFixedArrayMemorySize
,
270 NdrVaryingArrayMemorySize
, NdrVaryingArrayMemorySize
,
271 NdrComplexArrayMemorySize
,
273 NdrConformantStringMemorySize
, 0, 0,
274 NdrConformantStringMemorySize
,
275 NdrNonConformantStringMemorySize
, 0, 0, 0,
277 NdrEncapsulatedUnionMemorySize
,
278 NdrNonEncapsulatedUnionMemorySize
,
279 NdrByteCountPointerMemorySize
,
280 NdrXmitOrRepAsMemorySize
, NdrXmitOrRepAsMemorySize
,
282 NdrInterfacePointerMemorySize
,
287 NdrUserMarshalMemorySize
,
292 const NDR_FREE NdrFreer
[NDR_TABLE_SIZE
] = {
294 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
295 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
296 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
297 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
301 NdrPointerFree
, NdrPointerFree
,
302 NdrPointerFree
, NdrPointerFree
,
304 NdrSimpleStructFree
, NdrSimpleStructFree
,
305 NdrConformantStructFree
, NdrConformantStructFree
,
306 NdrConformantVaryingStructFree
,
307 NdrComplexStructFree
,
309 NdrConformantArrayFree
,
310 NdrConformantVaryingArrayFree
,
311 NdrFixedArrayFree
, NdrFixedArrayFree
,
312 NdrVaryingArrayFree
, NdrVaryingArrayFree
,
318 NdrEncapsulatedUnionFree
,
319 NdrNonEncapsulatedUnionFree
,
321 NdrXmitOrRepAsFree
, NdrXmitOrRepAsFree
,
323 NdrInterfacePointerFree
,
334 void * WINAPI
NdrAllocate(MIDL_STUB_MESSAGE
*pStubMsg
, size_t len
)
336 /* hmm, this is probably supposed to do more? */
337 return pStubMsg
->pfnAllocate(len
);
340 static void WINAPI
NdrFree(MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *Pointer
)
342 pStubMsg
->pfnFree(Pointer
);
345 static inline BOOL
IsConformanceOrVariancePresent(PFORMAT_STRING pFormat
)
347 return (*(const ULONG
*)pFormat
!= -1);
350 static PFORMAT_STRING
ReadConformance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
)
352 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
353 if (pStubMsg
->Buffer
+ 4 > pStubMsg
->BufferEnd
)
354 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
355 pStubMsg
->MaxCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
356 pStubMsg
->Buffer
+= 4;
357 TRACE("unmarshalled conformance is %ld\n", pStubMsg
->MaxCount
);
358 if (pStubMsg
->fHasNewCorrDesc
)
364 static inline PFORMAT_STRING
ReadVariance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
, ULONG MaxValue
)
366 if (pFormat
&& !IsConformanceOrVariancePresent(pFormat
))
368 pStubMsg
->Offset
= 0;
369 pStubMsg
->ActualCount
= pStubMsg
->MaxCount
;
373 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
374 if (pStubMsg
->Buffer
+ 8 > pStubMsg
->BufferEnd
)
375 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
376 pStubMsg
->Offset
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
377 pStubMsg
->Buffer
+= 4;
378 TRACE("offset is %d\n", pStubMsg
->Offset
);
379 pStubMsg
->ActualCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
380 pStubMsg
->Buffer
+= 4;
381 TRACE("variance is %d\n", pStubMsg
->ActualCount
);
383 if ((pStubMsg
->ActualCount
> MaxValue
) ||
384 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> MaxValue
))
386 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
387 pStubMsg
->ActualCount
, pStubMsg
->Offset
, MaxValue
);
388 RpcRaiseException(RPC_S_INVALID_BOUND
);
393 if (pStubMsg
->fHasNewCorrDesc
)
399 /* writes the conformance value to the buffer */
400 static inline void WriteConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
402 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
403 if (pStubMsg
->Buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
404 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
405 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->MaxCount
);
406 pStubMsg
->Buffer
+= 4;
409 /* writes the variance values to the buffer */
410 static inline void WriteVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
412 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
413 if (pStubMsg
->Buffer
+ 8 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
414 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
415 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->Offset
);
416 pStubMsg
->Buffer
+= 4;
417 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->ActualCount
);
418 pStubMsg
->Buffer
+= 4;
421 /* requests buffer space for the conformance value */
422 static inline void SizeConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
424 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
425 if (pStubMsg
->BufferLength
+ 4 < pStubMsg
->BufferLength
)
426 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
427 pStubMsg
->BufferLength
+= 4;
430 /* requests buffer space for the variance values */
431 static inline void SizeVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
433 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
434 if (pStubMsg
->BufferLength
+ 8 < pStubMsg
->BufferLength
)
435 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
436 pStubMsg
->BufferLength
+= 8;
439 PFORMAT_STRING
ComputeConformanceOrVariance(
440 MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *pMemory
,
441 PFORMAT_STRING pFormat
, ULONG_PTR def
, ULONG_PTR
*pCount
)
443 BYTE dtype
= pFormat
[0] & 0xf;
444 short ofs
= *(const short *)&pFormat
[2];
448 if (!IsConformanceOrVariancePresent(pFormat
)) {
449 /* null descriptor */
454 switch (pFormat
[0] & 0xf0) {
455 case RPC_FC_NORMAL_CONFORMANCE
:
456 TRACE("normal conformance, ofs=%d\n", ofs
);
459 case RPC_FC_POINTER_CONFORMANCE
:
460 TRACE("pointer conformance, ofs=%d\n", ofs
);
461 ptr
= pStubMsg
->Memory
;
463 case RPC_FC_TOP_LEVEL_CONFORMANCE
:
464 TRACE("toplevel conformance, ofs=%d\n", ofs
);
465 if (pStubMsg
->StackTop
) {
466 ptr
= pStubMsg
->StackTop
;
469 /* -Os mode, *pCount is already set */
473 case RPC_FC_CONSTANT_CONFORMANCE
:
474 data
= ofs
| ((DWORD
)pFormat
[1] << 16);
475 TRACE("constant conformance, val=%d\n", data
);
478 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE
:
479 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs
);
480 if (pStubMsg
->StackTop
) {
481 ptr
= pStubMsg
->StackTop
;
489 FIXME("unknown conformance type %x\n", pFormat
[0] & 0xf0);
492 switch (pFormat
[1]) {
493 case RPC_FC_DEREFERENCE
:
494 ptr
= *(LPVOID
*)((char *)ptr
+ ofs
);
496 case RPC_FC_CALLBACK
:
498 unsigned char *old_stack_top
= pStubMsg
->StackTop
;
499 pStubMsg
->StackTop
= ptr
;
501 /* ofs is index into StubDesc->apfnExprEval */
502 TRACE("callback conformance into apfnExprEval[%d]\n", ofs
);
503 pStubMsg
->StubDesc
->apfnExprEval
[ofs
](pStubMsg
);
505 pStubMsg
->StackTop
= old_stack_top
;
507 /* the callback function always stores the computed value in MaxCount */
508 *pCount
= pStubMsg
->MaxCount
;
512 ptr
= (char *)ptr
+ ofs
;
525 data
= *(USHORT
*)ptr
;
536 FIXME("unknown conformance data type %x\n", dtype
);
539 TRACE("dereferenced data type %x at %p, got %d\n", dtype
, ptr
, data
);
542 switch (pFormat
[1]) {
543 case RPC_FC_DEREFERENCE
: /* already handled */
560 FIXME("unknown conformance op %d\n", pFormat
[1]);
565 TRACE("resulting conformance is %ld\n", *pCount
);
566 if (pStubMsg
->fHasNewCorrDesc
)
572 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
573 * the result overflows 32-bits */
574 static inline ULONG
safe_multiply(ULONG a
, ULONG b
)
576 ULONGLONG ret
= (ULONGLONG
)a
* b
;
577 if (ret
> 0xffffffff)
579 RpcRaiseException(RPC_S_INVALID_BOUND
);
585 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
587 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
588 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
589 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
590 pStubMsg
->Buffer
+= size
;
593 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
595 if (pStubMsg
->BufferLength
+ size
< pStubMsg
->BufferLength
) /* integer overflow of pStubMsg->BufferSize */
597 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
598 pStubMsg
->BufferLength
, size
);
599 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
601 pStubMsg
->BufferLength
+= size
;
604 /* copies data from the buffer, checking that there is enough data in the buffer
606 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, void *p
, ULONG size
)
608 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
609 (pStubMsg
->Buffer
+ size
> pStubMsg
->BufferEnd
))
610 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
611 memcpy(p
, pStubMsg
->Buffer
, size
);
612 pStubMsg
->Buffer
+= size
;
615 /* copies data to the buffer, checking that there is enough space to do so */
616 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, const void *p
, ULONG size
)
618 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
619 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
621 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
622 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
,
624 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
626 memcpy(pStubMsg
->Buffer
, p
, size
);
627 pStubMsg
->Buffer
+= size
;
631 * NdrConformantString:
633 * What MS calls a ConformantString is, in DCE terminology,
634 * a Varying-Conformant String.
636 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
637 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
638 * into unmarshalled string)
639 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
641 * data: CHARTYPE[maxlen]
643 * ], where CHARTYPE is the appropriate character type (specified externally)
647 /***********************************************************************
648 * NdrConformantStringMarshall [RPCRT4.@]
650 unsigned char *WINAPI
NdrConformantStringMarshall(MIDL_STUB_MESSAGE
*pStubMsg
,
651 unsigned char *pszMessage
, PFORMAT_STRING pFormat
)
655 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg
, pszMessage
, pFormat
);
657 if (*pFormat
== RPC_FC_C_CSTRING
) {
658 TRACE("string=%s\n", debugstr_a((char*)pszMessage
));
659 pStubMsg
->ActualCount
= strlen((char*)pszMessage
)+1;
662 else if (*pFormat
== RPC_FC_C_WSTRING
) {
663 TRACE("string=%s\n", debugstr_w((LPWSTR
)pszMessage
));
664 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pszMessage
)+1;
668 ERR("Unhandled string type: %#x\n", *pFormat
);
669 /* FIXME: raise an exception. */
673 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
674 pFormat
= ComputeConformance(pStubMsg
, pszMessage
, pFormat
+ 2, 0);
676 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
677 pStubMsg
->Offset
= 0;
678 WriteConformance(pStubMsg
);
679 WriteVariance(pStubMsg
);
681 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
682 safe_copy_to_buffer(pStubMsg
, pszMessage
, size
); /* the string itself */
685 return NULL
; /* is this always right? */
688 /***********************************************************************
689 * NdrConformantStringBufferSize [RPCRT4.@]
691 void WINAPI
NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
692 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
696 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
698 SizeConformance(pStubMsg
);
699 SizeVariance(pStubMsg
);
701 if (*pFormat
== RPC_FC_C_CSTRING
) {
702 TRACE("string=%s\n", debugstr_a((char*)pMemory
));
703 pStubMsg
->ActualCount
= strlen((char*)pMemory
)+1;
706 else if (*pFormat
== RPC_FC_C_WSTRING
) {
707 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
));
708 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
)+1;
712 ERR("Unhandled string type: %#x\n", *pFormat
);
713 /* FIXME: raise an exception */
717 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
718 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
720 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
722 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
725 /************************************************************************
726 * NdrConformantStringMemorySize [RPCRT4.@]
728 ULONG WINAPI
NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
729 PFORMAT_STRING pFormat
)
733 FIXME("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
735 assert(pStubMsg
&& pFormat
);
737 if (*pFormat
== RPC_FC_C_CSTRING
) {
738 rslt
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
); /* maxlen */
740 else if (*pFormat
== RPC_FC_C_WSTRING
) {
741 rslt
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
)*2; /* maxlen */
744 ERR("Unhandled string type: %#x\n", *pFormat
);
745 /* FIXME: raise an exception */
748 if (pFormat
[1] != RPC_FC_PAD
) {
749 FIXME("sized string format=%d\n", pFormat
[1]);
752 TRACE(" --> %u\n", rslt
);
756 /************************************************************************
757 * NdrConformantStringUnmarshall [RPCRT4.@]
759 unsigned char *WINAPI
NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
760 unsigned char** ppMemory
, PFORMAT_STRING pFormat
, unsigned char fMustAlloc
)
762 ULONG bufsize
, memsize
, esize
, i
;
764 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
765 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
767 assert(pFormat
&& ppMemory
&& pStubMsg
);
769 ReadConformance(pStubMsg
, NULL
);
770 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
772 if (*pFormat
== RPC_FC_C_CSTRING
) esize
= 1;
773 else if (*pFormat
== RPC_FC_C_WSTRING
) esize
= 2;
775 ERR("Unhandled string type: %#x\n", *pFormat
);
776 /* FIXME: raise an exception */
780 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
781 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
783 /* strings must always have null terminating bytes */
786 ERR("invalid string length of %d\n", pStubMsg
->ActualCount
);
787 RpcRaiseException(RPC_S_INVALID_BOUND
);
791 /* verify the buffer is safe to access */
792 if ((pStubMsg
->Buffer
+ bufsize
< pStubMsg
->Buffer
) ||
793 (pStubMsg
->Buffer
+ bufsize
> pStubMsg
->BufferEnd
))
795 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize
,
796 pStubMsg
->BufferEnd
, pStubMsg
->Buffer
);
797 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
801 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
802 if (pStubMsg
->Buffer
[i
] != 0)
804 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
805 i
, pStubMsg
->Buffer
[i
]);
806 RpcRaiseException(RPC_S_INVALID_BOUND
);
810 if (fMustAlloc
|| !*ppMemory
)
811 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
813 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
815 if (*pFormat
== RPC_FC_C_CSTRING
) {
816 TRACE("string=%s\n", debugstr_a((char*)*ppMemory
));
818 else if (*pFormat
== RPC_FC_C_WSTRING
) {
819 TRACE("string=%s\n", debugstr_w((LPWSTR
)*ppMemory
));
822 return NULL
; /* FIXME: is this always right? */
825 /***********************************************************************
826 * NdrNonConformantStringMarshall [RPCRT4.@]
828 unsigned char * WINAPI
NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
829 unsigned char *pMemory
,
830 PFORMAT_STRING pFormat
)
836 /***********************************************************************
837 * NdrNonConformantStringUnmarshall [RPCRT4.@]
839 unsigned char * WINAPI
NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
840 unsigned char **ppMemory
,
841 PFORMAT_STRING pFormat
,
842 unsigned char fMustAlloc
)
848 /***********************************************************************
849 * NdrNonConformantStringBufferSize [RPCRT4.@]
851 void WINAPI
NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
852 unsigned char *pMemory
,
853 PFORMAT_STRING pFormat
)
858 /***********************************************************************
859 * NdrNonConformantStringMemorySize [RPCRT4.@]
861 ULONG WINAPI
NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
862 PFORMAT_STRING pFormat
)
868 static inline void dump_pointer_attr(unsigned char attr
)
870 if (attr
& RPC_FC_P_ALLOCALLNODES
)
871 TRACE(" RPC_FC_P_ALLOCALLNODES");
872 if (attr
& RPC_FC_P_DONTFREE
)
873 TRACE(" RPC_FC_P_DONTFREE");
874 if (attr
& RPC_FC_P_ONSTACK
)
875 TRACE(" RPC_FC_P_ONSTACK");
876 if (attr
& RPC_FC_P_SIMPLEPOINTER
)
877 TRACE(" RPC_FC_P_SIMPLEPOINTER");
878 if (attr
& RPC_FC_P_DEREF
)
879 TRACE(" RPC_FC_P_DEREF");
883 /***********************************************************************
884 * PointerMarshall [internal]
886 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
887 unsigned char *Buffer
,
888 unsigned char *Pointer
,
889 PFORMAT_STRING pFormat
)
891 unsigned type
= pFormat
[0], attr
= pFormat
[1];
895 int pointer_needs_marshaling
;
897 TRACE("(%p,%p,%p,%p)\n", pStubMsg
, Buffer
, Pointer
, pFormat
);
898 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
900 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
901 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
904 case RPC_FC_RP
: /* ref pointer (always non-null) */
907 ERR("NULL ref pointer is not allowed\n");
908 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
910 pointer_needs_marshaling
= 1;
912 case RPC_FC_UP
: /* unique pointer */
913 case RPC_FC_OP
: /* object pointer - same as unique here */
915 pointer_needs_marshaling
= 1;
917 pointer_needs_marshaling
= 0;
918 pointer_id
= (ULONG
)Pointer
;
919 TRACE("writing 0x%08x to buffer\n", pointer_id
);
920 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
923 pointer_needs_marshaling
= !NdrFullPointerQueryPointer(
924 pStubMsg
->FullPtrXlatTables
, Pointer
, 1, &pointer_id
);
925 TRACE("writing 0x%08x to buffer\n", pointer_id
);
926 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
929 FIXME("unhandled ptr type=%02x\n", type
);
930 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
934 TRACE("calling marshaller for type 0x%x\n", (int)*desc
);
936 if (pointer_needs_marshaling
) {
937 if (attr
& RPC_FC_P_DEREF
) {
938 Pointer
= *(unsigned char**)Pointer
;
939 TRACE("deref => %p\n", Pointer
);
941 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
942 if (m
) m(pStubMsg
, Pointer
, desc
);
943 else FIXME("no marshaller for data type=%02x\n", *desc
);
946 STD_OVERFLOW_CHECK(pStubMsg
);
949 /***********************************************************************
950 * PointerUnmarshall [internal]
952 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
953 unsigned char *Buffer
,
954 unsigned char **pPointer
,
955 unsigned char *pSrcPointer
,
956 PFORMAT_STRING pFormat
,
957 unsigned char fMustAlloc
)
959 unsigned type
= pFormat
[0], attr
= pFormat
[1];
962 DWORD pointer_id
= 0;
963 int pointer_needs_unmarshaling
;
965 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg
, Buffer
, pPointer
, pSrcPointer
, pFormat
, fMustAlloc
);
966 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
968 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
969 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
972 case RPC_FC_RP
: /* ref pointer (always non-null) */
973 pointer_needs_unmarshaling
= 1;
975 case RPC_FC_UP
: /* unique pointer */
976 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
977 TRACE("pointer_id is 0x%08x\n", pointer_id
);
979 pointer_needs_unmarshaling
= 1;
982 pointer_needs_unmarshaling
= 0;
985 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
986 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
987 TRACE("pointer_id is 0x%08x\n", pointer_id
);
988 if (!fMustAlloc
&& pSrcPointer
)
990 FIXME("free object pointer %p\n", pSrcPointer
);
994 pointer_needs_unmarshaling
= 1;
996 pointer_needs_unmarshaling
= 0;
999 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1000 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1001 pointer_needs_unmarshaling
= !NdrFullPointerQueryRefId(
1002 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, (void **)pPointer
);
1005 FIXME("unhandled ptr type=%02x\n", type
);
1006 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1010 if (pointer_needs_unmarshaling
) {
1011 unsigned char *base_ptr_val
= *pPointer
;
1012 unsigned char **current_ptr
= pPointer
;
1013 if (pStubMsg
->IsClient
) {
1015 /* if we aren't forcing allocation of memory then try to use the existing
1016 * (source) pointer to unmarshall the data into so that [in,out]
1017 * parameters behave correctly. it doesn't matter if the parameter is
1018 * [out] only since in that case the pointer will be NULL. we force
1019 * allocation when the source pointer is NULL here instead of in the type
1020 * unmarshalling routine for the benefit of the deref code below */
1023 TRACE("pSrcPointer = %p\n", pSrcPointer
);
1024 base_ptr_val
= pSrcPointer
;
1030 /* the memory in a stub is never initialised, so we have to work out here
1031 * whether we have to initialise it so we can use the optimisation of
1032 * setting the pointer to the buffer, if possible, or set fMustAlloc to
1033 * TRUE. As there is no space used in the buffer for pointers when using
1034 * reference pointers we must allocate memory in this case */
1035 if (type
== RPC_FC_RP
|| attr
& RPC_FC_P_DEREF
) {
1037 base_ptr_val
= NULL
;
1039 base_ptr_val
= NULL
;
1040 *current_ptr
= NULL
;
1044 if (attr
& RPC_FC_P_DEREF
) {
1046 base_ptr_val
= NdrAllocate(pStubMsg
, sizeof(void *));
1047 current_ptr
= (unsigned char **)base_ptr_val
;
1049 current_ptr
= *(unsigned char***)current_ptr
;
1050 TRACE("deref => %p\n", current_ptr
);
1051 if (!fMustAlloc
&& !*current_ptr
) fMustAlloc
= TRUE
;
1053 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
1054 if (m
) m(pStubMsg
, current_ptr
, desc
, fMustAlloc
);
1055 else FIXME("no unmarshaller for data type=%02x\n", *desc
);
1057 if (type
== RPC_FC_FP
)
1058 NdrFullPointerInsertRefId(pStubMsg
->FullPtrXlatTables
, pointer_id
,
1061 /* this must be done after the call to the unmarshaller, since when we are
1062 * unmarshalling reference pointers on the server side *pPointer will be
1063 * pointing to valid data */
1064 if ((!fMustAlloc
|| attr
& RPC_FC_P_DEREF
) && base_ptr_val
)
1065 *pPointer
= base_ptr_val
;
1068 TRACE("pointer=%p\n", *pPointer
);
1071 /***********************************************************************
1072 * PointerBufferSize [internal]
1074 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1075 unsigned char *Pointer
,
1076 PFORMAT_STRING pFormat
)
1078 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1079 PFORMAT_STRING desc
;
1081 int pointer_needs_sizing
;
1084 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1085 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1087 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1088 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1091 case RPC_FC_RP
: /* ref pointer (always non-null) */
1094 ERR("NULL ref pointer is not allowed\n");
1095 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
1100 /* NULL pointer has no further representation */
1105 pointer_needs_sizing
= !NdrFullPointerQueryPointer(
1106 pStubMsg
->FullPtrXlatTables
, Pointer
, 0, &pointer_id
);
1107 if (!pointer_needs_sizing
)
1111 FIXME("unhandled ptr type=%02x\n", type
);
1112 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1116 if (attr
& RPC_FC_P_DEREF
) {
1117 Pointer
= *(unsigned char**)Pointer
;
1118 TRACE("deref => %p\n", Pointer
);
1121 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
1122 if (m
) m(pStubMsg
, Pointer
, desc
);
1123 else FIXME("no buffersizer for data type=%02x\n", *desc
);
1126 /***********************************************************************
1127 * PointerMemorySize [internal]
1129 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1130 unsigned char *Buffer
,
1131 PFORMAT_STRING pFormat
)
1133 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1134 PFORMAT_STRING desc
;
1137 FIXME("(%p,%p,%p): stub\n", pStubMsg
, Buffer
, pFormat
);
1138 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1140 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1141 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1144 case RPC_FC_RP
: /* ref pointer (always non-null) */
1147 FIXME("unhandled ptr type=%02x\n", type
);
1148 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1151 if (attr
& RPC_FC_P_DEREF
) {
1155 m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
1156 if (m
) m(pStubMsg
, desc
);
1157 else FIXME("no memorysizer for data type=%02x\n", *desc
);
1162 /***********************************************************************
1163 * PointerFree [internal]
1165 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1166 unsigned char *Pointer
,
1167 PFORMAT_STRING pFormat
)
1169 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1170 PFORMAT_STRING desc
;
1173 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1174 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1175 if (attr
& RPC_FC_P_DONTFREE
) return;
1177 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1178 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1180 if (!Pointer
) return;
1182 if (type
== RPC_FC_FP
) {
1183 int pointer_needs_freeing
= NdrFullPointerFree(
1184 pStubMsg
->FullPtrXlatTables
, Pointer
);
1185 if (!pointer_needs_freeing
)
1189 if (attr
& RPC_FC_P_DEREF
) {
1190 Pointer
= *(unsigned char**)Pointer
;
1191 TRACE("deref => %p\n", Pointer
);
1194 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
1195 if (m
) m(pStubMsg
, Pointer
, desc
);
1197 /* hmm... is this sensible?
1198 * perhaps we should check if the memory comes from NdrAllocate,
1199 * and deallocate only if so - checking if the pointer is between
1200 * BufferStart and BufferEnd is probably no good since the buffer
1201 * may be reallocated when the server wants to marshal the reply */
1203 case RPC_FC_BOGUS_STRUCT
:
1204 case RPC_FC_BOGUS_ARRAY
:
1205 case RPC_FC_USER_MARSHAL
:
1207 case RPC_FC_CVARRAY
:
1210 FIXME("unhandled data type=%02x\n", *desc
);
1212 case RPC_FC_C_CSTRING
:
1213 case RPC_FC_C_WSTRING
:
1214 if (pStubMsg
->ReuseBuffer
) goto notfree
;
1220 if (attr
& RPC_FC_P_ONSTACK
) {
1221 TRACE("not freeing stack ptr %p\n", Pointer
);
1224 TRACE("freeing %p\n", Pointer
);
1225 NdrFree(pStubMsg
, Pointer
);
1228 TRACE("not freeing %p\n", Pointer
);
1231 /***********************************************************************
1232 * EmbeddedPointerMarshall
1234 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1235 unsigned char *pMemory
,
1236 PFORMAT_STRING pFormat
)
1238 unsigned char *Mark
= pStubMsg
->BufferMark
;
1239 unsigned rep
, count
, stride
;
1241 unsigned char *saved_buffer
= NULL
;
1243 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1245 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1248 if (pStubMsg
->PointerBufferMark
)
1250 saved_buffer
= pStubMsg
->Buffer
;
1251 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1252 pStubMsg
->PointerBufferMark
= NULL
;
1255 while (pFormat
[0] != RPC_FC_END
) {
1256 switch (pFormat
[0]) {
1258 FIXME("unknown repeat type %d\n", pFormat
[0]);
1259 case RPC_FC_NO_REPEAT
:
1265 case RPC_FC_FIXED_REPEAT
:
1266 rep
= *(const WORD
*)&pFormat
[2];
1267 stride
= *(const WORD
*)&pFormat
[4];
1268 count
= *(const WORD
*)&pFormat
[8];
1271 case RPC_FC_VARIABLE_REPEAT
:
1272 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1273 stride
= *(const WORD
*)&pFormat
[2];
1274 count
= *(const WORD
*)&pFormat
[6];
1278 for (i
= 0; i
< rep
; i
++) {
1279 PFORMAT_STRING info
= pFormat
;
1280 unsigned char *membase
= pMemory
+ (i
* stride
);
1281 unsigned char *bufbase
= Mark
+ (i
* stride
);
1284 for (u
=0; u
<count
; u
++,info
+=8) {
1285 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1286 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1287 unsigned char *saved_memory
= pStubMsg
->Memory
;
1289 pStubMsg
->Memory
= pMemory
;
1290 PointerMarshall(pStubMsg
, bufptr
, *(unsigned char**)memptr
, info
+4);
1291 pStubMsg
->Memory
= saved_memory
;
1294 pFormat
+= 8 * count
;
1299 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1300 pStubMsg
->Buffer
= saved_buffer
;
1303 STD_OVERFLOW_CHECK(pStubMsg
);
1308 /***********************************************************************
1309 * EmbeddedPointerUnmarshall
1311 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1312 unsigned char *pDstMemoryPtrs
,
1313 unsigned char *pSrcMemoryPtrs
,
1314 PFORMAT_STRING pFormat
,
1315 unsigned char fMustAlloc
)
1317 unsigned char *Mark
= pStubMsg
->BufferMark
;
1318 unsigned rep
, count
, stride
;
1320 unsigned char *saved_buffer
= NULL
;
1322 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg
, pDstMemoryPtrs
, pSrcMemoryPtrs
, pFormat
, fMustAlloc
);
1324 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1327 if (pStubMsg
->PointerBufferMark
)
1329 saved_buffer
= pStubMsg
->Buffer
;
1330 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1331 pStubMsg
->PointerBufferMark
= NULL
;
1334 while (pFormat
[0] != RPC_FC_END
) {
1335 TRACE("pFormat[0] = 0x%x\n", pFormat
[0]);
1336 switch (pFormat
[0]) {
1338 FIXME("unknown repeat type %d\n", pFormat
[0]);
1339 case RPC_FC_NO_REPEAT
:
1345 case RPC_FC_FIXED_REPEAT
:
1346 rep
= *(const WORD
*)&pFormat
[2];
1347 stride
= *(const WORD
*)&pFormat
[4];
1348 count
= *(const WORD
*)&pFormat
[8];
1351 case RPC_FC_VARIABLE_REPEAT
:
1352 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1353 stride
= *(const WORD
*)&pFormat
[2];
1354 count
= *(const WORD
*)&pFormat
[6];
1358 for (i
= 0; i
< rep
; i
++) {
1359 PFORMAT_STRING info
= pFormat
;
1360 unsigned char *memdstbase
= pDstMemoryPtrs
+ (i
* stride
);
1361 unsigned char *memsrcbase
= pSrcMemoryPtrs
+ (i
* stride
);
1362 unsigned char *bufbase
= Mark
+ (i
* stride
);
1365 for (u
=0; u
<count
; u
++,info
+=8) {
1366 unsigned char **memdstptr
= (unsigned char **)(memdstbase
+ *(const SHORT
*)&info
[0]);
1367 unsigned char **memsrcptr
= (unsigned char **)(memsrcbase
+ *(const SHORT
*)&info
[0]);
1368 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1369 PointerUnmarshall(pStubMsg
, bufptr
, memdstptr
, *memsrcptr
, info
+4, fMustAlloc
);
1372 pFormat
+= 8 * count
;
1377 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1378 pStubMsg
->Buffer
= saved_buffer
;
1384 /***********************************************************************
1385 * EmbeddedPointerBufferSize
1387 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1388 unsigned char *pMemory
,
1389 PFORMAT_STRING pFormat
)
1391 unsigned rep
, count
, stride
;
1393 ULONG saved_buffer_length
= 0;
1395 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1397 if (pStubMsg
->IgnoreEmbeddedPointers
) return;
1399 if (*pFormat
!= RPC_FC_PP
) return;
1402 if (pStubMsg
->PointerLength
)
1404 saved_buffer_length
= pStubMsg
->BufferLength
;
1405 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
1406 pStubMsg
->PointerLength
= 0;
1409 while (pFormat
[0] != RPC_FC_END
) {
1410 switch (pFormat
[0]) {
1412 FIXME("unknown repeat type %d\n", pFormat
[0]);
1413 case RPC_FC_NO_REPEAT
:
1419 case RPC_FC_FIXED_REPEAT
:
1420 rep
= *(const WORD
*)&pFormat
[2];
1421 stride
= *(const WORD
*)&pFormat
[4];
1422 count
= *(const WORD
*)&pFormat
[8];
1425 case RPC_FC_VARIABLE_REPEAT
:
1426 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1427 stride
= *(const WORD
*)&pFormat
[2];
1428 count
= *(const WORD
*)&pFormat
[6];
1432 for (i
= 0; i
< rep
; i
++) {
1433 PFORMAT_STRING info
= pFormat
;
1434 unsigned char *membase
= pMemory
+ (i
* stride
);
1437 for (u
=0; u
<count
; u
++,info
+=8) {
1438 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1439 unsigned char *saved_memory
= pStubMsg
->Memory
;
1441 pStubMsg
->Memory
= pMemory
;
1442 PointerBufferSize(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1443 pStubMsg
->Memory
= saved_memory
;
1446 pFormat
+= 8 * count
;
1449 if (saved_buffer_length
)
1451 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
1452 pStubMsg
->BufferLength
= saved_buffer_length
;
1456 /***********************************************************************
1457 * EmbeddedPointerMemorySize [internal]
1459 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1460 PFORMAT_STRING pFormat
)
1462 unsigned char *Mark
= pStubMsg
->BufferMark
;
1463 unsigned rep
, count
, stride
;
1466 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1468 if (pStubMsg
->IgnoreEmbeddedPointers
) return 0;
1470 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1472 if (*pFormat
!= RPC_FC_PP
) return 0;
1475 while (pFormat
[0] != RPC_FC_END
) {
1476 switch (pFormat
[0]) {
1478 FIXME("unknown repeat type %d\n", pFormat
[0]);
1479 case RPC_FC_NO_REPEAT
:
1485 case RPC_FC_FIXED_REPEAT
:
1486 rep
= *(const WORD
*)&pFormat
[2];
1487 stride
= *(const WORD
*)&pFormat
[4];
1488 count
= *(const WORD
*)&pFormat
[8];
1491 case RPC_FC_VARIABLE_REPEAT
:
1492 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1493 stride
= *(const WORD
*)&pFormat
[2];
1494 count
= *(const WORD
*)&pFormat
[6];
1498 for (i
= 0; i
< rep
; i
++) {
1499 PFORMAT_STRING info
= pFormat
;
1500 unsigned char *bufbase
= Mark
+ (i
* stride
);
1502 for (u
=0; u
<count
; u
++,info
+=8) {
1503 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1504 PointerMemorySize(pStubMsg
, bufptr
, info
+4);
1507 pFormat
+= 8 * count
;
1513 /***********************************************************************
1514 * EmbeddedPointerFree [internal]
1516 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1517 unsigned char *pMemory
,
1518 PFORMAT_STRING pFormat
)
1520 unsigned rep
, count
, stride
;
1523 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1524 if (*pFormat
!= RPC_FC_PP
) return;
1527 while (pFormat
[0] != RPC_FC_END
) {
1528 switch (pFormat
[0]) {
1530 FIXME("unknown repeat type %d\n", pFormat
[0]);
1531 case RPC_FC_NO_REPEAT
:
1537 case RPC_FC_FIXED_REPEAT
:
1538 rep
= *(const WORD
*)&pFormat
[2];
1539 stride
= *(const WORD
*)&pFormat
[4];
1540 count
= *(const WORD
*)&pFormat
[8];
1543 case RPC_FC_VARIABLE_REPEAT
:
1544 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1545 stride
= *(const WORD
*)&pFormat
[2];
1546 count
= *(const WORD
*)&pFormat
[6];
1550 for (i
= 0; i
< rep
; i
++) {
1551 PFORMAT_STRING info
= pFormat
;
1552 unsigned char *membase
= pMemory
+ (i
* stride
);
1555 for (u
=0; u
<count
; u
++,info
+=8) {
1556 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1557 unsigned char *saved_memory
= pStubMsg
->Memory
;
1559 pStubMsg
->Memory
= pMemory
;
1560 PointerFree(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1561 pStubMsg
->Memory
= saved_memory
;
1564 pFormat
+= 8 * count
;
1568 /***********************************************************************
1569 * NdrPointerMarshall [RPCRT4.@]
1571 unsigned char * WINAPI
NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1572 unsigned char *pMemory
,
1573 PFORMAT_STRING pFormat
)
1575 unsigned char *Buffer
;
1577 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1579 /* incremement the buffer here instead of in PointerMarshall,
1580 * as that is used by embedded pointers which already handle the incrementing
1581 * the buffer, and shouldn't write any additional pointer data to the wire */
1582 if (*pFormat
!= RPC_FC_RP
)
1584 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1585 Buffer
= pStubMsg
->Buffer
;
1586 safe_buffer_increment(pStubMsg
, 4);
1589 Buffer
= pStubMsg
->Buffer
;
1591 PointerMarshall(pStubMsg
, Buffer
, pMemory
, pFormat
);
1596 /***********************************************************************
1597 * NdrPointerUnmarshall [RPCRT4.@]
1599 unsigned char * WINAPI
NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1600 unsigned char **ppMemory
,
1601 PFORMAT_STRING pFormat
,
1602 unsigned char fMustAlloc
)
1604 unsigned char *Buffer
;
1606 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1608 /* incremement the buffer here instead of in PointerUnmarshall,
1609 * as that is used by embedded pointers which already handle the incrementing
1610 * the buffer, and shouldn't read any additional pointer data from the
1612 if (*pFormat
!= RPC_FC_RP
)
1614 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1615 Buffer
= pStubMsg
->Buffer
;
1616 safe_buffer_increment(pStubMsg
, 4);
1619 Buffer
= pStubMsg
->Buffer
;
1621 PointerUnmarshall(pStubMsg
, Buffer
, ppMemory
, *ppMemory
, pFormat
, fMustAlloc
);
1626 /***********************************************************************
1627 * NdrPointerBufferSize [RPCRT4.@]
1629 void WINAPI
NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1630 unsigned char *pMemory
,
1631 PFORMAT_STRING pFormat
)
1633 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1635 /* incremement the buffer length here instead of in PointerBufferSize,
1636 * as that is used by embedded pointers which already handle the buffer
1637 * length, and shouldn't write anything more to the wire */
1638 if (*pFormat
!= RPC_FC_RP
)
1640 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
1641 safe_buffer_length_increment(pStubMsg
, 4);
1644 PointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1647 /***********************************************************************
1648 * NdrPointerMemorySize [RPCRT4.@]
1650 ULONG WINAPI
NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1651 PFORMAT_STRING pFormat
)
1653 /* unsigned size = *(LPWORD)(pFormat+2); */
1654 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1655 PointerMemorySize(pStubMsg
, pStubMsg
->Buffer
, pFormat
);
1659 /***********************************************************************
1660 * NdrPointerFree [RPCRT4.@]
1662 void WINAPI
NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1663 unsigned char *pMemory
,
1664 PFORMAT_STRING pFormat
)
1666 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1667 PointerFree(pStubMsg
, pMemory
, pFormat
);
1670 /***********************************************************************
1671 * NdrSimpleTypeMarshall [RPCRT4.@]
1673 void WINAPI
NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1674 unsigned char FormatChar
)
1676 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &FormatChar
);
1679 /***********************************************************************
1680 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1682 void WINAPI
NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1683 unsigned char FormatChar
)
1685 NdrBaseTypeUnmarshall(pStubMsg
, &pMemory
, &FormatChar
, 0);
1688 /***********************************************************************
1689 * NdrSimpleStructMarshall [RPCRT4.@]
1691 unsigned char * WINAPI
NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1692 unsigned char *pMemory
,
1693 PFORMAT_STRING pFormat
)
1695 unsigned size
= *(const WORD
*)(pFormat
+2);
1696 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1698 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1700 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1701 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
1703 if (pFormat
[0] != RPC_FC_STRUCT
)
1704 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
+4);
1709 /***********************************************************************
1710 * NdrSimpleStructUnmarshall [RPCRT4.@]
1712 unsigned char * WINAPI
NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1713 unsigned char **ppMemory
,
1714 PFORMAT_STRING pFormat
,
1715 unsigned char fMustAlloc
)
1717 unsigned size
= *(const WORD
*)(pFormat
+2);
1718 unsigned char *saved_buffer
;
1719 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1721 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1724 *ppMemory
= NdrAllocate(pStubMsg
, size
);
1727 if (!pStubMsg
->IsClient
&& !*ppMemory
)
1728 /* for servers, we just point straight into the RPC buffer */
1729 *ppMemory
= pStubMsg
->Buffer
;
1732 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1733 safe_buffer_increment(pStubMsg
, size
);
1734 if (pFormat
[0] == RPC_FC_PSTRUCT
)
1735 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
+4, fMustAlloc
);
1737 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
1738 if (*ppMemory
!= saved_buffer
)
1739 memcpy(*ppMemory
, saved_buffer
, size
);
1744 /***********************************************************************
1745 * NdrSimpleStructBufferSize [RPCRT4.@]
1747 void WINAPI
NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1748 unsigned char *pMemory
,
1749 PFORMAT_STRING pFormat
)
1751 unsigned size
= *(const WORD
*)(pFormat
+2);
1752 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1754 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
1756 safe_buffer_length_increment(pStubMsg
, size
);
1757 if (pFormat
[0] != RPC_FC_STRUCT
)
1758 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
+4);
1761 /***********************************************************************
1762 * NdrSimpleStructMemorySize [RPCRT4.@]
1764 ULONG WINAPI
NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1765 PFORMAT_STRING pFormat
)
1767 unsigned short size
= *(const WORD
*)(pFormat
+2);
1769 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1771 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1772 pStubMsg
->MemorySize
+= size
;
1773 safe_buffer_increment(pStubMsg
, size
);
1775 if (pFormat
[0] != RPC_FC_STRUCT
)
1776 EmbeddedPointerMemorySize(pStubMsg
, pFormat
+4);
1780 /***********************************************************************
1781 * NdrSimpleStructFree [RPCRT4.@]
1783 void WINAPI
NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
1784 unsigned char *pMemory
,
1785 PFORMAT_STRING pFormat
)
1787 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1788 if (pFormat
[0] != RPC_FC_STRUCT
)
1789 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
+4);
1793 static unsigned long EmbeddedComplexSize(const MIDL_STUB_MESSAGE
*pStubMsg
,
1794 PFORMAT_STRING pFormat
)
1798 case RPC_FC_PSTRUCT
:
1799 case RPC_FC_CSTRUCT
:
1800 case RPC_FC_BOGUS_STRUCT
:
1801 case RPC_FC_SMFARRAY
:
1802 case RPC_FC_SMVARRAY
:
1803 return *(const WORD
*)&pFormat
[2];
1804 case RPC_FC_USER_MARSHAL
:
1805 return *(const WORD
*)&pFormat
[4];
1806 case RPC_FC_NON_ENCAPSULATED_UNION
:
1808 if (pStubMsg
->fHasNewCorrDesc
)
1813 pFormat
+= *(const SHORT
*)pFormat
;
1814 return *(const SHORT
*)pFormat
;
1816 return sizeof(void *);
1818 FIXME("unhandled embedded type %02x\n", *pFormat
);
1824 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1825 PFORMAT_STRING pFormat
)
1827 NDR_MEMORYSIZE m
= NdrMemorySizer
[*pFormat
& NDR_TABLE_MASK
];
1831 FIXME("no memorysizer for data type=%02x\n", *pFormat
);
1835 return m(pStubMsg
, pFormat
);
1839 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1840 unsigned char *pMemory
,
1841 PFORMAT_STRING pFormat
,
1842 PFORMAT_STRING pPointer
)
1844 PFORMAT_STRING desc
;
1848 while (*pFormat
!= RPC_FC_END
) {
1854 TRACE("byte=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
1855 safe_copy_to_buffer(pStubMsg
, pMemory
, 1);
1861 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
1862 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
1868 TRACE("long=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
1869 safe_copy_to_buffer(pStubMsg
, pMemory
, 4);
1873 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
1874 safe_copy_to_buffer(pStubMsg
, pMemory
, 8);
1877 case RPC_FC_POINTER
:
1879 unsigned char *saved_buffer
;
1880 int pointer_buffer_mark_set
= 0;
1881 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
1882 saved_buffer
= pStubMsg
->Buffer
;
1883 if (pStubMsg
->PointerBufferMark
)
1885 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1886 pStubMsg
->PointerBufferMark
= NULL
;
1887 pointer_buffer_mark_set
= 1;
1890 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
1891 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char**)pMemory
, pPointer
);
1892 if (pointer_buffer_mark_set
)
1894 STD_OVERFLOW_CHECK(pStubMsg
);
1895 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1896 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
1898 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
1899 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
1900 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1902 pStubMsg
->Buffer
= saved_buffer
+ 4;
1908 case RPC_FC_ALIGNM4
:
1909 ALIGN_POINTER(pMemory
, 4);
1911 case RPC_FC_ALIGNM8
:
1912 ALIGN_POINTER(pMemory
, 8);
1914 case RPC_FC_STRUCTPAD1
:
1915 case RPC_FC_STRUCTPAD2
:
1916 case RPC_FC_STRUCTPAD3
:
1917 case RPC_FC_STRUCTPAD4
:
1918 case RPC_FC_STRUCTPAD5
:
1919 case RPC_FC_STRUCTPAD6
:
1920 case RPC_FC_STRUCTPAD7
:
1921 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
1923 case RPC_FC_EMBEDDED_COMPLEX
:
1924 pMemory
+= pFormat
[1];
1926 desc
= pFormat
+ *(const SHORT
*)pFormat
;
1927 size
= EmbeddedComplexSize(pStubMsg
, desc
);
1928 TRACE("embedded complex (size=%ld) <= %p\n", size
, pMemory
);
1929 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
1932 /* for some reason interface pointers aren't generated as
1933 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
1934 * they still need the derefencing treatment that pointers are
1936 if (*desc
== RPC_FC_IP
)
1937 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
1939 m(pStubMsg
, pMemory
, desc
);
1941 else FIXME("no marshaller for embedded type %02x\n", *desc
);
1948 FIXME("unhandled format 0x%02x\n", *pFormat
);
1956 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1957 unsigned char *pMemory
,
1958 PFORMAT_STRING pFormat
,
1959 PFORMAT_STRING pPointer
)
1961 PFORMAT_STRING desc
;
1965 while (*pFormat
!= RPC_FC_END
) {
1971 safe_copy_from_buffer(pStubMsg
, pMemory
, 1);
1972 TRACE("byte=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
1978 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
1979 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
1985 safe_copy_from_buffer(pStubMsg
, pMemory
, 4);
1986 TRACE("long=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
1990 safe_copy_from_buffer(pStubMsg
, pMemory
, 8);
1991 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
1994 case RPC_FC_POINTER
:
1996 unsigned char *saved_buffer
;
1997 int pointer_buffer_mark_set
= 0;
1998 TRACE("pointer => %p\n", pMemory
);
1999 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2000 saved_buffer
= pStubMsg
->Buffer
;
2001 if (pStubMsg
->PointerBufferMark
)
2003 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2004 pStubMsg
->PointerBufferMark
= NULL
;
2005 pointer_buffer_mark_set
= 1;
2008 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2010 PointerUnmarshall(pStubMsg
, saved_buffer
, (unsigned char**)pMemory
, *(unsigned char**)pMemory
, pPointer
, TRUE
);
2011 if (pointer_buffer_mark_set
)
2013 STD_OVERFLOW_CHECK(pStubMsg
);
2014 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2015 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
2017 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2018 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
2019 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2021 pStubMsg
->Buffer
= saved_buffer
+ 4;
2027 case RPC_FC_ALIGNM4
:
2028 ALIGN_POINTER(pMemory
, 4);
2030 case RPC_FC_ALIGNM8
:
2031 ALIGN_POINTER(pMemory
, 8);
2033 case RPC_FC_STRUCTPAD1
:
2034 case RPC_FC_STRUCTPAD2
:
2035 case RPC_FC_STRUCTPAD3
:
2036 case RPC_FC_STRUCTPAD4
:
2037 case RPC_FC_STRUCTPAD5
:
2038 case RPC_FC_STRUCTPAD6
:
2039 case RPC_FC_STRUCTPAD7
:
2040 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2042 case RPC_FC_EMBEDDED_COMPLEX
:
2043 pMemory
+= pFormat
[1];
2045 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2046 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2047 TRACE("embedded complex (size=%ld) => %p\n", size
, pMemory
);
2048 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
2049 memset(pMemory
, 0, size
); /* just in case */
2052 /* for some reason interface pointers aren't generated as
2053 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2054 * they still need the derefencing treatment that pointers are
2056 if (*desc
== RPC_FC_IP
)
2057 m(pStubMsg
, (unsigned char **)pMemory
, desc
, FALSE
);
2059 m(pStubMsg
, &pMemory
, desc
, FALSE
);
2061 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
2068 FIXME("unhandled format %d\n", *pFormat
);
2076 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2077 unsigned char *pMemory
,
2078 PFORMAT_STRING pFormat
,
2079 PFORMAT_STRING pPointer
)
2081 PFORMAT_STRING desc
;
2085 while (*pFormat
!= RPC_FC_END
) {
2091 safe_buffer_length_increment(pStubMsg
, 1);
2097 safe_buffer_length_increment(pStubMsg
, 2);
2103 safe_buffer_length_increment(pStubMsg
, 4);
2107 safe_buffer_length_increment(pStubMsg
, 8);
2110 case RPC_FC_POINTER
:
2111 if (!pStubMsg
->IgnoreEmbeddedPointers
)
2113 int saved_buffer_length
= pStubMsg
->BufferLength
;
2114 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2115 pStubMsg
->PointerLength
= 0;
2116 if(!pStubMsg
->BufferLength
)
2117 ERR("BufferLength == 0??\n");
2118 PointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
2119 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2120 pStubMsg
->BufferLength
= saved_buffer_length
;
2122 safe_buffer_length_increment(pStubMsg
, 4);
2126 case RPC_FC_ALIGNM4
:
2127 ALIGN_POINTER(pMemory
, 4);
2129 case RPC_FC_ALIGNM8
:
2130 ALIGN_POINTER(pMemory
, 8);
2132 case RPC_FC_STRUCTPAD1
:
2133 case RPC_FC_STRUCTPAD2
:
2134 case RPC_FC_STRUCTPAD3
:
2135 case RPC_FC_STRUCTPAD4
:
2136 case RPC_FC_STRUCTPAD5
:
2137 case RPC_FC_STRUCTPAD6
:
2138 case RPC_FC_STRUCTPAD7
:
2139 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2141 case RPC_FC_EMBEDDED_COMPLEX
:
2142 pMemory
+= pFormat
[1];
2144 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2145 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2146 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
2149 /* for some reason interface pointers aren't generated as
2150 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2151 * they still need the derefencing treatment that pointers are
2153 if (*desc
== RPC_FC_IP
)
2154 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2156 m(pStubMsg
, pMemory
, desc
);
2158 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
2165 FIXME("unhandled format 0x%02x\n", *pFormat
);
2173 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
2174 unsigned char *pMemory
,
2175 PFORMAT_STRING pFormat
,
2176 PFORMAT_STRING pPointer
)
2178 PFORMAT_STRING desc
;
2182 while (*pFormat
!= RPC_FC_END
) {
2203 case RPC_FC_POINTER
:
2204 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
2208 case RPC_FC_ALIGNM4
:
2209 ALIGN_POINTER(pMemory
, 4);
2211 case RPC_FC_ALIGNM8
:
2212 ALIGN_POINTER(pMemory
, 8);
2214 case RPC_FC_STRUCTPAD1
:
2215 case RPC_FC_STRUCTPAD2
:
2216 case RPC_FC_STRUCTPAD3
:
2217 case RPC_FC_STRUCTPAD4
:
2218 case RPC_FC_STRUCTPAD5
:
2219 case RPC_FC_STRUCTPAD6
:
2220 case RPC_FC_STRUCTPAD7
:
2221 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2223 case RPC_FC_EMBEDDED_COMPLEX
:
2224 pMemory
+= pFormat
[1];
2226 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2227 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2228 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
2231 /* for some reason interface pointers aren't generated as
2232 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2233 * they still need the derefencing treatment that pointers are
2235 if (*desc
== RPC_FC_IP
)
2236 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2238 m(pStubMsg
, pMemory
, desc
);
2240 else FIXME("no freer for embedded type %02x\n", *desc
);
2247 FIXME("unhandled format 0x%02x\n", *pFormat
);
2255 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2256 PFORMAT_STRING pFormat
)
2258 PFORMAT_STRING desc
;
2259 unsigned long size
= 0;
2261 while (*pFormat
!= RPC_FC_END
) {
2268 safe_buffer_increment(pStubMsg
, 1);
2274 safe_buffer_increment(pStubMsg
, 2);
2280 safe_buffer_increment(pStubMsg
, 4);
2284 safe_buffer_increment(pStubMsg
, 8);
2286 case RPC_FC_POINTER
:
2288 safe_buffer_increment(pStubMsg
, 4);
2289 if (!pStubMsg
->IgnoreEmbeddedPointers
)
2290 FIXME("embedded pointers\n");
2292 case RPC_FC_ALIGNM4
:
2293 ALIGN_LENGTH(size
, 4);
2294 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2296 case RPC_FC_ALIGNM8
:
2297 ALIGN_LENGTH(size
, 8);
2298 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
2300 case RPC_FC_STRUCTPAD1
:
2301 case RPC_FC_STRUCTPAD2
:
2302 case RPC_FC_STRUCTPAD3
:
2303 case RPC_FC_STRUCTPAD4
:
2304 case RPC_FC_STRUCTPAD5
:
2305 case RPC_FC_STRUCTPAD6
:
2306 case RPC_FC_STRUCTPAD7
:
2307 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2309 case RPC_FC_EMBEDDED_COMPLEX
:
2312 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2313 size
+= EmbeddedComplexMemorySize(pStubMsg
, desc
);
2319 FIXME("unhandled format 0x%02x\n", *pFormat
);
2327 /***********************************************************************
2328 * NdrComplexStructMarshall [RPCRT4.@]
2330 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2331 unsigned char *pMemory
,
2332 PFORMAT_STRING pFormat
)
2334 PFORMAT_STRING conf_array
= NULL
;
2335 PFORMAT_STRING pointer_desc
= NULL
;
2336 unsigned char *OldMemory
= pStubMsg
->Memory
;
2337 int pointer_buffer_mark_set
= 0;
2339 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2341 if (!pStubMsg
->PointerBufferMark
)
2343 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2344 /* save buffer length */
2345 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2347 /* get the buffer pointer after complex array data, but before
2349 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- pStubMsg
->BufferStart
;
2350 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2351 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
2352 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2354 /* save it for use by embedded pointer code later */
2355 pStubMsg
->PointerBufferMark
= pStubMsg
->BufferStart
+ pStubMsg
->BufferLength
;
2356 TRACE("difference = 0x%x\n", pStubMsg
->PointerBufferMark
- pStubMsg
->Buffer
);
2357 pointer_buffer_mark_set
= 1;
2359 /* restore the original buffer length */
2360 pStubMsg
->BufferLength
= saved_buffer_length
;
2363 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2366 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2368 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2371 pStubMsg
->Memory
= pMemory
;
2373 ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2376 NdrConformantArrayMarshall(pStubMsg
, pMemory
, conf_array
);
2378 pStubMsg
->Memory
= OldMemory
;
2380 if (pointer_buffer_mark_set
)
2382 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2383 pStubMsg
->PointerBufferMark
= NULL
;
2386 STD_OVERFLOW_CHECK(pStubMsg
);
2391 /***********************************************************************
2392 * NdrComplexStructUnmarshall [RPCRT4.@]
2394 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2395 unsigned char **ppMemory
,
2396 PFORMAT_STRING pFormat
,
2397 unsigned char fMustAlloc
)
2399 unsigned size
= *(const WORD
*)(pFormat
+2);
2400 PFORMAT_STRING conf_array
= NULL
;
2401 PFORMAT_STRING pointer_desc
= NULL
;
2402 unsigned char *pMemory
;
2403 int pointer_buffer_mark_set
= 0;
2405 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2407 if (!pStubMsg
->PointerBufferMark
)
2409 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2410 /* save buffer pointer */
2411 unsigned char *saved_buffer
= pStubMsg
->Buffer
;
2413 /* get the buffer pointer after complex array data, but before
2415 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2416 NdrComplexStructMemorySize(pStubMsg
, pFormat
);
2417 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2419 /* save it for use by embedded pointer code later */
2420 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2421 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->PointerBufferMark
- saved_buffer
));
2422 pointer_buffer_mark_set
= 1;
2424 /* restore the original buffer */
2425 pStubMsg
->Buffer
= saved_buffer
;
2428 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2430 if (fMustAlloc
|| !*ppMemory
)
2432 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2433 memset(*ppMemory
, 0, size
);
2437 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2439 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2442 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
);
2445 NdrConformantArrayUnmarshall(pStubMsg
, &pMemory
, conf_array
, fMustAlloc
);
2447 if (pointer_buffer_mark_set
)
2449 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2450 pStubMsg
->PointerBufferMark
= NULL
;
2456 /***********************************************************************
2457 * NdrComplexStructBufferSize [RPCRT4.@]
2459 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2460 unsigned char *pMemory
,
2461 PFORMAT_STRING pFormat
)
2463 PFORMAT_STRING conf_array
= NULL
;
2464 PFORMAT_STRING pointer_desc
= NULL
;
2465 unsigned char *OldMemory
= pStubMsg
->Memory
;
2466 int pointer_length_set
= 0;
2468 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2470 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
2472 if(!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
2474 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2475 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2477 /* get the buffer length after complex struct data, but before
2479 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2480 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
2481 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2483 /* save it for use by embedded pointer code later */
2484 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2485 pointer_length_set
= 1;
2486 TRACE("difference = 0x%lx\n", pStubMsg
->PointerLength
- saved_buffer_length
);
2488 /* restore the original buffer length */
2489 pStubMsg
->BufferLength
= saved_buffer_length
;
2493 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2495 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2498 pStubMsg
->Memory
= pMemory
;
2500 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2503 NdrConformantArrayBufferSize(pStubMsg
, pMemory
, conf_array
);
2505 pStubMsg
->Memory
= OldMemory
;
2507 if(pointer_length_set
)
2509 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2510 pStubMsg
->PointerLength
= 0;
2515 /***********************************************************************
2516 * NdrComplexStructMemorySize [RPCRT4.@]
2518 ULONG WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2519 PFORMAT_STRING pFormat
)
2521 unsigned size
= *(const WORD
*)(pFormat
+2);
2522 PFORMAT_STRING conf_array
= NULL
;
2523 PFORMAT_STRING pointer_desc
= NULL
;
2525 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2527 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2530 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2532 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2535 ComplexStructMemorySize(pStubMsg
, pFormat
);
2538 NdrConformantArrayMemorySize(pStubMsg
, conf_array
);
2543 /***********************************************************************
2544 * NdrComplexStructFree [RPCRT4.@]
2546 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
2547 unsigned char *pMemory
,
2548 PFORMAT_STRING pFormat
)
2550 PFORMAT_STRING conf_array
= NULL
;
2551 PFORMAT_STRING pointer_desc
= NULL
;
2552 unsigned char *OldMemory
= pStubMsg
->Memory
;
2554 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2557 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2559 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2562 pStubMsg
->Memory
= pMemory
;
2564 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2567 NdrConformantArrayFree(pStubMsg
, pMemory
, conf_array
);
2569 pStubMsg
->Memory
= OldMemory
;
2572 /***********************************************************************
2573 * NdrConformantArrayMarshall [RPCRT4.@]
2575 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2576 unsigned char *pMemory
,
2577 PFORMAT_STRING pFormat
)
2579 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
2580 unsigned char alignment
= pFormat
[1] + 1;
2582 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2583 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2585 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2587 WriteConformance(pStubMsg
);
2589 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2591 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2592 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2593 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
2595 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2600 /***********************************************************************
2601 * NdrConformantArrayUnmarshall [RPCRT4.@]
2603 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2604 unsigned char **ppMemory
,
2605 PFORMAT_STRING pFormat
,
2606 unsigned char fMustAlloc
)
2608 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
2609 unsigned char alignment
= pFormat
[1] + 1;
2611 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2612 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2614 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2616 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2618 if (fMustAlloc
|| !*ppMemory
)
2619 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2621 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2623 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2624 safe_copy_from_buffer(pStubMsg
, *ppMemory
, size
);
2626 EmbeddedPointerUnmarshall(pStubMsg
, *ppMemory
, *ppMemory
, pFormat
, TRUE
/* FIXME */);
2631 /***********************************************************************
2632 * NdrConformantArrayBufferSize [RPCRT4.@]
2634 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2635 unsigned char *pMemory
,
2636 PFORMAT_STRING pFormat
)
2638 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
2639 unsigned char alignment
= pFormat
[1] + 1;
2641 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2642 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2644 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2646 SizeConformance(pStubMsg
);
2648 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
2650 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2651 /* conformance value plus array */
2652 safe_buffer_length_increment(pStubMsg
, size
);
2654 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
2657 /***********************************************************************
2658 * NdrConformantArrayMemorySize [RPCRT4.@]
2660 ULONG WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2661 PFORMAT_STRING pFormat
)
2663 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
2664 unsigned char alignment
= pFormat
[1] + 1;
2666 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2667 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2669 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2670 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2671 pStubMsg
->MemorySize
+= size
;
2673 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2674 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2675 safe_buffer_increment(pStubMsg
, size
);
2677 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2679 return pStubMsg
->MemorySize
;
2682 /***********************************************************************
2683 * NdrConformantArrayFree [RPCRT4.@]
2685 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
2686 unsigned char *pMemory
,
2687 PFORMAT_STRING pFormat
)
2689 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2690 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2692 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2694 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2698 /***********************************************************************
2699 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2701 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2702 unsigned char* pMemory
,
2703 PFORMAT_STRING pFormat
)
2706 unsigned char alignment
= pFormat
[1] + 1;
2707 DWORD esize
= *(const WORD
*)(pFormat
+2);
2709 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
2711 if (pFormat
[0] != RPC_FC_CVARRAY
)
2713 ERR("invalid format type %x\n", pFormat
[0]);
2714 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2718 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2719 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2721 WriteConformance(pStubMsg
);
2722 WriteVariance(pStubMsg
);
2724 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2726 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2728 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2729 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
2731 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2737 /***********************************************************************
2738 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2740 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2741 unsigned char** ppMemory
,
2742 PFORMAT_STRING pFormat
,
2743 unsigned char fMustAlloc
)
2745 ULONG bufsize
, memsize
;
2746 unsigned char alignment
= pFormat
[1] + 1;
2747 DWORD esize
= *(const WORD
*)(pFormat
+2);
2749 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2751 if (pFormat
[0] != RPC_FC_CVARRAY
)
2753 ERR("invalid format type %x\n", pFormat
[0]);
2754 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2758 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2759 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2761 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2763 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2764 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2766 if (!*ppMemory
|| fMustAlloc
)
2767 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2768 safe_copy_from_buffer(pStubMsg
, *ppMemory
+ pStubMsg
->Offset
, bufsize
);
2770 EmbeddedPointerUnmarshall(pStubMsg
, *ppMemory
, *ppMemory
, pFormat
, TRUE
/* FIXME */);
2776 /***********************************************************************
2777 * NdrConformantVaryingArrayFree [RPCRT4.@]
2779 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
2780 unsigned char* pMemory
,
2781 PFORMAT_STRING pFormat
)
2783 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2785 if (pFormat
[0] != RPC_FC_CVARRAY
)
2787 ERR("invalid format type %x\n", pFormat
[0]);
2788 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2792 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2793 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2795 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2799 /***********************************************************************
2800 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2802 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
2803 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
2805 unsigned char alignment
= pFormat
[1] + 1;
2806 DWORD esize
= *(const WORD
*)(pFormat
+2);
2808 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
2810 if (pFormat
[0] != RPC_FC_CVARRAY
)
2812 ERR("invalid format type %x\n", pFormat
[0]);
2813 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2818 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2819 /* compute length */
2820 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2822 SizeConformance(pStubMsg
);
2823 SizeVariance(pStubMsg
);
2825 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
2827 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
2829 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
2833 /***********************************************************************
2834 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2836 ULONG WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
2837 PFORMAT_STRING pFormat
)
2844 /***********************************************************************
2845 * NdrComplexArrayMarshall [RPCRT4.@]
2847 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2848 unsigned char *pMemory
,
2849 PFORMAT_STRING pFormat
)
2851 ULONG i
, count
, def
;
2852 BOOL variance_present
;
2853 unsigned char alignment
;
2854 int pointer_buffer_mark_set
= 0;
2856 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2858 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
2860 ERR("invalid format type %x\n", pFormat
[0]);
2861 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2865 alignment
= pFormat
[1] + 1;
2867 if (!pStubMsg
->PointerBufferMark
)
2869 /* save buffer fields that may be changed by buffer sizer functions
2870 * and that may be needed later on */
2871 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2872 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2873 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
2874 unsigned long saved_offset
= pStubMsg
->Offset
;
2875 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
2877 /* get the buffer pointer after complex array data, but before
2879 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- pStubMsg
->BufferStart
;
2880 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2881 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
2882 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2884 /* save it for use by embedded pointer code later */
2885 pStubMsg
->PointerBufferMark
= pStubMsg
->BufferStart
+ pStubMsg
->BufferLength
;
2886 TRACE("difference = 0x%x\n", pStubMsg
->Buffer
- pStubMsg
->BufferStart
);
2887 pointer_buffer_mark_set
= 1;
2889 /* restore fields */
2890 pStubMsg
->ActualCount
= saved_actual_count
;
2891 pStubMsg
->Offset
= saved_offset
;
2892 pStubMsg
->MaxCount
= saved_max_count
;
2893 pStubMsg
->BufferLength
= saved_buffer_length
;
2896 def
= *(const WORD
*)&pFormat
[2];
2899 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
2900 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
2902 variance_present
= IsConformanceOrVariancePresent(pFormat
);
2903 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
2904 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
2906 WriteConformance(pStubMsg
);
2907 if (variance_present
)
2908 WriteVariance(pStubMsg
);
2910 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2912 count
= pStubMsg
->ActualCount
;
2913 for (i
= 0; i
< count
; i
++)
2914 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
2916 STD_OVERFLOW_CHECK(pStubMsg
);
2918 if (pointer_buffer_mark_set
)
2920 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2921 pStubMsg
->PointerBufferMark
= NULL
;
2927 /***********************************************************************
2928 * NdrComplexArrayUnmarshall [RPCRT4.@]
2930 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2931 unsigned char **ppMemory
,
2932 PFORMAT_STRING pFormat
,
2933 unsigned char fMustAlloc
)
2935 ULONG i
, count
, size
;
2936 unsigned char alignment
;
2937 unsigned char *pMemory
;
2938 unsigned char *saved_buffer
;
2939 int pointer_buffer_mark_set
= 0;
2940 int saved_ignore_embedded
;
2942 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2944 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
2946 ERR("invalid format type %x\n", pFormat
[0]);
2947 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2951 alignment
= pFormat
[1] + 1;
2953 saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2954 /* save buffer pointer */
2955 saved_buffer
= pStubMsg
->Buffer
;
2956 /* get the buffer pointer after complex array data, but before
2958 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2959 pStubMsg
->MemorySize
= 0;
2960 NdrComplexArrayMemorySize(pStubMsg
, pFormat
);
2961 size
= pStubMsg
->MemorySize
;
2962 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2964 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->Buffer
- saved_buffer
));
2965 if (!pStubMsg
->PointerBufferMark
)
2967 /* save it for use by embedded pointer code later */
2968 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2969 pointer_buffer_mark_set
= 1;
2971 /* restore the original buffer */
2972 pStubMsg
->Buffer
= saved_buffer
;
2976 pFormat
= ReadConformance(pStubMsg
, pFormat
);
2977 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2979 if (fMustAlloc
|| !*ppMemory
)
2981 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2982 memset(*ppMemory
, 0, size
);
2985 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2987 pMemory
= *ppMemory
;
2988 count
= pStubMsg
->ActualCount
;
2989 for (i
= 0; i
< count
; i
++)
2990 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
2992 if (pointer_buffer_mark_set
)
2994 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2995 pStubMsg
->PointerBufferMark
= NULL
;
3001 /***********************************************************************
3002 * NdrComplexArrayBufferSize [RPCRT4.@]
3004 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3005 unsigned char *pMemory
,
3006 PFORMAT_STRING pFormat
)
3008 ULONG i
, count
, def
;
3009 unsigned char alignment
;
3010 BOOL variance_present
;
3011 int pointer_length_set
= 0;
3013 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3015 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3017 ERR("invalid format type %x\n", pFormat
[0]);
3018 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3022 alignment
= pFormat
[1] + 1;
3024 if (!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
3026 /* save buffer fields that may be changed by buffer sizer functions
3027 * and that may be needed later on */
3028 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3029 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
3030 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
3031 unsigned long saved_offset
= pStubMsg
->Offset
;
3032 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
3034 /* get the buffer pointer after complex array data, but before
3036 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3037 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
3038 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3040 /* save it for use by embedded pointer code later */
3041 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3042 pointer_length_set
= 1;
3044 /* restore fields */
3045 pStubMsg
->ActualCount
= saved_actual_count
;
3046 pStubMsg
->Offset
= saved_offset
;
3047 pStubMsg
->MaxCount
= saved_max_count
;
3048 pStubMsg
->BufferLength
= saved_buffer_length
;
3050 def
= *(const WORD
*)&pFormat
[2];
3053 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3054 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3055 SizeConformance(pStubMsg
);
3057 variance_present
= IsConformanceOrVariancePresent(pFormat
);
3058 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3059 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3061 if (variance_present
)
3062 SizeVariance(pStubMsg
);
3064 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
3066 count
= pStubMsg
->ActualCount
;
3067 for (i
= 0; i
< count
; i
++)
3068 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
3070 if(pointer_length_set
)
3072 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3073 pStubMsg
->PointerLength
= 0;
3077 /***********************************************************************
3078 * NdrComplexArrayMemorySize [RPCRT4.@]
3080 ULONG WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3081 PFORMAT_STRING pFormat
)
3083 ULONG i
, count
, esize
, SavedMemorySize
, MemorySize
;
3084 unsigned char alignment
;
3085 unsigned char *Buffer
;
3087 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3089 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3091 ERR("invalid format type %x\n", pFormat
[0]);
3092 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3096 alignment
= pFormat
[1] + 1;
3100 pFormat
= ReadConformance(pStubMsg
, pFormat
);
3101 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3103 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3105 SavedMemorySize
= pStubMsg
->MemorySize
;
3107 Buffer
= pStubMsg
->Buffer
;
3108 pStubMsg
->MemorySize
= 0;
3109 esize
= ComplexStructMemorySize(pStubMsg
, pFormat
);
3110 pStubMsg
->Buffer
= Buffer
;
3112 MemorySize
= safe_multiply(pStubMsg
->MaxCount
, esize
);
3114 count
= pStubMsg
->ActualCount
;
3115 for (i
= 0; i
< count
; i
++)
3116 ComplexStructMemorySize(pStubMsg
, pFormat
);
3118 pStubMsg
->MemorySize
= SavedMemorySize
;
3120 pStubMsg
->MemorySize
+= MemorySize
;
3124 /***********************************************************************
3125 * NdrComplexArrayFree [RPCRT4.@]
3127 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3128 unsigned char *pMemory
,
3129 PFORMAT_STRING pFormat
)
3131 ULONG i
, count
, def
;
3133 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3135 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3137 ERR("invalid format type %x\n", pFormat
[0]);
3138 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3142 def
= *(const WORD
*)&pFormat
[2];
3145 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3146 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3148 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3149 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3151 count
= pStubMsg
->ActualCount
;
3152 for (i
= 0; i
< count
; i
++)
3153 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
3156 static ULONG
UserMarshalFlags(const MIDL_STUB_MESSAGE
*pStubMsg
)
3158 return MAKELONG(pStubMsg
->dwDestContext
,
3159 pStubMsg
->RpcMsg
->DataRepresentation
);
3162 #define USER_MARSHAL_PTR_PREFIX \
3163 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3164 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3166 /***********************************************************************
3167 * NdrUserMarshalMarshall [RPCRT4.@]
3169 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3170 unsigned char *pMemory
,
3171 PFORMAT_STRING pFormat
)
3173 unsigned flags
= pFormat
[1];
3174 unsigned index
= *(const WORD
*)&pFormat
[2];
3175 unsigned char *saved_buffer
= NULL
;
3176 ULONG uflag
= UserMarshalFlags(pStubMsg
);
3177 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3178 TRACE("index=%d\n", index
);
3180 if (flags
& USER_MARSHAL_POINTER
)
3182 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3183 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, USER_MARSHAL_PTR_PREFIX
);
3184 pStubMsg
->Buffer
+= 4;
3185 if (pStubMsg
->PointerBufferMark
)
3187 saved_buffer
= pStubMsg
->Buffer
;
3188 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3189 pStubMsg
->PointerBufferMark
= NULL
;
3191 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3194 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3197 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
3198 &uflag
, pStubMsg
->Buffer
, pMemory
);
3202 STD_OVERFLOW_CHECK(pStubMsg
);
3203 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3204 pStubMsg
->Buffer
= saved_buffer
;
3207 STD_OVERFLOW_CHECK(pStubMsg
);
3212 /***********************************************************************
3213 * NdrUserMarshalUnmarshall [RPCRT4.@]
3215 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3216 unsigned char **ppMemory
,
3217 PFORMAT_STRING pFormat
,
3218 unsigned char fMustAlloc
)
3220 unsigned flags
= pFormat
[1];
3221 unsigned index
= *(const WORD
*)&pFormat
[2];
3222 DWORD memsize
= *(const WORD
*)&pFormat
[4];
3223 unsigned char *saved_buffer
= NULL
;
3224 ULONG uflag
= UserMarshalFlags(pStubMsg
);
3225 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3226 TRACE("index=%d\n", index
);
3228 if (flags
& USER_MARSHAL_POINTER
)
3230 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3231 /* skip pointer prefix */
3232 pStubMsg
->Buffer
+= 4;
3233 if (pStubMsg
->PointerBufferMark
)
3235 saved_buffer
= pStubMsg
->Buffer
;
3236 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3237 pStubMsg
->PointerBufferMark
= NULL
;
3239 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3242 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3244 if (fMustAlloc
|| !*ppMemory
)
3245 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
3248 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
3249 &uflag
, pStubMsg
->Buffer
, *ppMemory
);
3253 STD_OVERFLOW_CHECK(pStubMsg
);
3254 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3255 pStubMsg
->Buffer
= saved_buffer
;
3261 /***********************************************************************
3262 * NdrUserMarshalBufferSize [RPCRT4.@]
3264 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3265 unsigned char *pMemory
,
3266 PFORMAT_STRING pFormat
)
3268 unsigned flags
= pFormat
[1];
3269 unsigned index
= *(const WORD
*)&pFormat
[2];
3270 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
3271 ULONG uflag
= UserMarshalFlags(pStubMsg
);
3272 unsigned long saved_buffer_length
= 0;
3273 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3274 TRACE("index=%d\n", index
);
3276 if (flags
& USER_MARSHAL_POINTER
)
3278 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
3279 /* skip pointer prefix */
3280 safe_buffer_length_increment(pStubMsg
, 4);
3281 if (pStubMsg
->IgnoreEmbeddedPointers
)
3283 if (pStubMsg
->PointerLength
)
3285 saved_buffer_length
= pStubMsg
->BufferLength
;
3286 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3287 pStubMsg
->PointerLength
= 0;
3289 ALIGN_LENGTH(pStubMsg
->BufferLength
, 8);
3292 ALIGN_LENGTH(pStubMsg
->BufferLength
, (flags
& 0xf) + 1);
3295 TRACE("size=%d\n", bufsize
);
3296 safe_buffer_length_increment(pStubMsg
, bufsize
);
3299 pStubMsg
->BufferLength
=
3300 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
3301 &uflag
, pStubMsg
->BufferLength
, pMemory
);
3303 if (saved_buffer_length
)
3305 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3306 pStubMsg
->BufferLength
= saved_buffer_length
;
3311 /***********************************************************************
3312 * NdrUserMarshalMemorySize [RPCRT4.@]
3314 ULONG WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3315 PFORMAT_STRING pFormat
)
3317 unsigned flags
= pFormat
[1];
3318 unsigned index
= *(const WORD
*)&pFormat
[2];
3319 DWORD memsize
= *(const WORD
*)&pFormat
[4];
3320 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
3322 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3323 TRACE("index=%d\n", index
);
3325 pStubMsg
->MemorySize
+= memsize
;
3327 if (flags
& USER_MARSHAL_POINTER
)
3329 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3330 /* skip pointer prefix */
3331 pStubMsg
->Buffer
+= 4;
3332 if (pStubMsg
->IgnoreEmbeddedPointers
)
3333 return pStubMsg
->MemorySize
;
3334 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3337 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3340 FIXME("not implemented for varying buffer size\n");
3342 pStubMsg
->Buffer
+= bufsize
;
3344 return pStubMsg
->MemorySize
;
3347 /***********************************************************************
3348 * NdrUserMarshalFree [RPCRT4.@]
3350 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
3351 unsigned char *pMemory
,
3352 PFORMAT_STRING pFormat
)
3354 /* unsigned flags = pFormat[1]; */
3355 unsigned index
= *(const WORD
*)&pFormat
[2];
3356 ULONG uflag
= UserMarshalFlags(pStubMsg
);
3357 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3358 TRACE("index=%d\n", index
);
3360 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
3364 /***********************************************************************
3365 * NdrClearOutParameters [RPCRT4.@]
3367 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
3368 PFORMAT_STRING pFormat
,
3371 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
3374 /***********************************************************************
3375 * NdrConvert [RPCRT4.@]
3377 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
3379 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
3380 /* FIXME: since this stub doesn't do any converting, the proper behavior
3381 is to raise an exception */
3384 /***********************************************************************
3385 * NdrConvert2 [RPCRT4.@]
3387 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, LONG NumberParams
)
3389 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3390 pStubMsg
, pFormat
, NumberParams
);
3391 /* FIXME: since this stub doesn't do any converting, the proper behavior
3392 is to raise an exception */
3395 #include "pshpack1.h"
3396 typedef struct _NDR_CSTRUCT_FORMAT
3399 unsigned char alignment
;
3400 unsigned short memory_size
;
3401 short offset_to_array_description
;
3402 } NDR_CSTRUCT_FORMAT
, NDR_CVSTRUCT_FORMAT
;
3403 #include "poppack.h"
3405 /***********************************************************************
3406 * NdrConformantStructMarshall [RPCRT4.@]
3408 unsigned char * WINAPI
NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3409 unsigned char *pMemory
,
3410 PFORMAT_STRING pFormat
)
3412 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3413 PFORMAT_STRING pCArrayFormat
;
3414 ULONG esize
, bufsize
;
3416 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3418 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3419 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3421 ERR("invalid format type %x\n", pCStructFormat
->type
);
3422 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3426 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3427 pCStructFormat
->offset_to_array_description
;
3428 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3430 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3431 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3434 esize
= *(const WORD
*)(pCArrayFormat
+2);
3436 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
3437 pCArrayFormat
+ 4, 0);
3439 WriteConformance(pStubMsg
);
3441 ALIGN_POINTER(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
3443 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3445 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3446 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
3448 ERR("integer overflow of memory_size %u with bufsize %u\n",
3449 pCStructFormat
->memory_size
, bufsize
);
3450 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3452 /* copy constant sized part of struct */
3453 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3454 safe_copy_to_buffer(pStubMsg
, pMemory
, pCStructFormat
->memory_size
+ bufsize
);
3456 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3457 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3462 /***********************************************************************
3463 * NdrConformantStructUnmarshall [RPCRT4.@]
3465 unsigned char * WINAPI
NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3466 unsigned char **ppMemory
,
3467 PFORMAT_STRING pFormat
,
3468 unsigned char fMustAlloc
)
3470 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3471 PFORMAT_STRING pCArrayFormat
;
3472 ULONG esize
, bufsize
;
3474 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3476 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3477 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3479 ERR("invalid format type %x\n", pCStructFormat
->type
);
3480 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3483 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3484 pCStructFormat
->offset_to_array_description
;
3485 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3487 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3488 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3491 esize
= *(const WORD
*)(pCArrayFormat
+2);
3493 pCArrayFormat
= ReadConformance(pStubMsg
, pCArrayFormat
+ 4);
3495 ALIGN_POINTER(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
3497 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3499 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3500 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
3502 ERR("integer overflow of memory_size %u with bufsize %u\n",
3503 pCStructFormat
->memory_size
, bufsize
);
3504 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3506 /* work out how much memory to allocate if we need to do so */
3507 if (!*ppMemory
|| fMustAlloc
)
3509 SIZE_T size
= pCStructFormat
->memory_size
+ bufsize
;
3510 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3513 /* now copy the data */
3514 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3515 safe_copy_from_buffer(pStubMsg
, *ppMemory
, pCStructFormat
->memory_size
+ bufsize
);
3517 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3518 EmbeddedPointerUnmarshall(pStubMsg
, *ppMemory
, *ppMemory
, pFormat
, TRUE
/* FIXME */);
3523 /***********************************************************************
3524 * NdrConformantStructBufferSize [RPCRT4.@]
3526 void WINAPI
NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3527 unsigned char *pMemory
,
3528 PFORMAT_STRING pFormat
)
3530 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3531 PFORMAT_STRING pCArrayFormat
;
3534 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3536 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3537 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3539 ERR("invalid format type %x\n", pCStructFormat
->type
);
3540 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3543 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3544 pCStructFormat
->offset_to_array_description
;
3545 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3547 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3548 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3551 esize
= *(const WORD
*)(pCArrayFormat
+2);
3553 pCArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
, pCArrayFormat
+4, 0);
3554 SizeConformance(pStubMsg
);
3556 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCStructFormat
->alignment
+ 1);
3558 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3560 safe_buffer_length_increment(pStubMsg
, pCStructFormat
->memory_size
);
3561 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
3563 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3564 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3567 /***********************************************************************
3568 * NdrConformantStructMemorySize [RPCRT4.@]
3570 ULONG WINAPI
NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3571 PFORMAT_STRING pFormat
)
3577 /***********************************************************************
3578 * NdrConformantStructFree [RPCRT4.@]
3580 void WINAPI
NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3581 unsigned char *pMemory
,
3582 PFORMAT_STRING pFormat
)
3587 /***********************************************************************
3588 * NdrConformantVaryingStructMarshall [RPCRT4.@]
3590 unsigned char * WINAPI
NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3591 unsigned char *pMemory
,
3592 PFORMAT_STRING pFormat
)
3594 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3595 PFORMAT_STRING pCVArrayFormat
;
3596 ULONG esize
, bufsize
;
3598 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3600 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3601 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3603 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3604 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3608 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3609 pCVStructFormat
->offset_to_array_description
;
3610 switch (*pCVArrayFormat
)
3612 case RPC_FC_CVARRAY
:
3613 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3615 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3616 pCVArrayFormat
+ 4, 0);
3617 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3620 case RPC_FC_C_CSTRING
:
3621 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
3622 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
3623 esize
= sizeof(char);
3624 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3625 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3626 pCVArrayFormat
+ 2, 0);
3628 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3630 case RPC_FC_C_WSTRING
:
3631 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
3632 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
3633 esize
= sizeof(WCHAR
);
3634 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3635 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3636 pCVArrayFormat
+ 2, 0);
3638 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3641 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3642 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3646 WriteConformance(pStubMsg
);
3648 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
3650 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3652 /* write constant sized part */
3653 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3654 safe_copy_to_buffer(pStubMsg
, pMemory
, pCVStructFormat
->memory_size
);
3656 WriteVariance(pStubMsg
);
3658 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3660 /* write array part */
3661 safe_copy_to_buffer(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
, bufsize
);
3663 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3668 /***********************************************************************
3669 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3671 unsigned char * WINAPI
NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3672 unsigned char **ppMemory
,
3673 PFORMAT_STRING pFormat
,
3674 unsigned char fMustAlloc
)
3676 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3677 PFORMAT_STRING pCVArrayFormat
;
3678 ULONG esize
, bufsize
;
3679 unsigned char cvarray_type
;
3681 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3683 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3684 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3686 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3687 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3691 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3692 pCVStructFormat
->offset_to_array_description
;
3693 cvarray_type
= *pCVArrayFormat
;
3694 switch (cvarray_type
)
3696 case RPC_FC_CVARRAY
:
3697 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3698 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 4);
3700 case RPC_FC_C_CSTRING
:
3701 esize
= sizeof(char);
3702 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3703 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3705 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3707 case RPC_FC_C_WSTRING
:
3708 esize
= sizeof(WCHAR
);
3709 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3710 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3712 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3715 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3716 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3720 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
3722 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3724 /* work out how much memory to allocate if we need to do so */
3725 if (!*ppMemory
|| fMustAlloc
)
3727 SIZE_T size
= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->MaxCount
);
3728 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3731 /* copy the constant data */
3732 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3733 safe_copy_from_buffer(pStubMsg
, *ppMemory
, pCVStructFormat
->memory_size
);
3735 pCVArrayFormat
= ReadVariance(pStubMsg
, pCVArrayFormat
, pStubMsg
->MaxCount
);
3737 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3739 if ((cvarray_type
== RPC_FC_C_CSTRING
) ||
3740 (cvarray_type
== RPC_FC_C_WSTRING
))
3743 /* strings must always have null terminating bytes */
3744 if (bufsize
< esize
)
3746 ERR("invalid string length of %d\n", pStubMsg
->ActualCount
);
3747 RpcRaiseException(RPC_S_INVALID_BOUND
);
3750 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
3751 if (pStubMsg
->Buffer
[i
] != 0)
3753 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
3754 i
, pStubMsg
->Buffer
[i
]);
3755 RpcRaiseException(RPC_S_INVALID_BOUND
);
3760 /* copy the array data */
3761 safe_copy_from_buffer(pStubMsg
, *ppMemory
+ pCVStructFormat
->memory_size
, bufsize
);
3763 if (cvarray_type
== RPC_FC_C_CSTRING
)
3764 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory
+ pCVStructFormat
->memory_size
)));
3765 else if (cvarray_type
== RPC_FC_C_WSTRING
)
3766 TRACE("string=%s\n", debugstr_w((WCHAR
*)(*ppMemory
+ pCVStructFormat
->memory_size
)));
3768 EmbeddedPointerUnmarshall(pStubMsg
, *ppMemory
, *ppMemory
, pFormat
, TRUE
/* FIXME */);
3773 /***********************************************************************
3774 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3776 void WINAPI
NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3777 unsigned char *pMemory
,
3778 PFORMAT_STRING pFormat
)
3780 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3781 PFORMAT_STRING pCVArrayFormat
;
3784 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3786 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3787 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3789 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3790 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3794 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3795 pCVStructFormat
->offset_to_array_description
;
3796 switch (*pCVArrayFormat
)
3798 case RPC_FC_CVARRAY
:
3799 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3801 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3802 pCVArrayFormat
+ 4, 0);
3803 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3806 case RPC_FC_C_CSTRING
:
3807 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
3808 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
3809 esize
= sizeof(char);
3810 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3811 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3812 pCVArrayFormat
+ 2, 0);
3814 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3816 case RPC_FC_C_WSTRING
:
3817 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
3818 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
3819 esize
= sizeof(WCHAR
);
3820 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3821 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3822 pCVArrayFormat
+ 2, 0);
3824 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3827 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3828 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3832 SizeConformance(pStubMsg
);
3834 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCVStructFormat
->alignment
+ 1);
3836 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3838 safe_buffer_length_increment(pStubMsg
, pCVStructFormat
->memory_size
);
3839 SizeVariance(pStubMsg
);
3840 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
3842 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3845 /***********************************************************************
3846 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
3848 ULONG WINAPI
NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3849 PFORMAT_STRING pFormat
)
3851 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3852 PFORMAT_STRING pCVArrayFormat
;
3854 unsigned char cvarray_type
;
3856 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
3858 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3859 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3861 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3862 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3866 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3867 pCVStructFormat
->offset_to_array_description
;
3868 cvarray_type
= *pCVArrayFormat
;
3869 switch (cvarray_type
)
3871 case RPC_FC_CVARRAY
:
3872 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3873 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 4);
3875 case RPC_FC_C_CSTRING
:
3876 esize
= sizeof(char);
3877 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3878 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3880 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3882 case RPC_FC_C_WSTRING
:
3883 esize
= sizeof(WCHAR
);
3884 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3885 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3887 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3890 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3891 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3895 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
3897 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3899 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
3900 pCVArrayFormat
= ReadVariance(pStubMsg
, pCVArrayFormat
, pStubMsg
->MaxCount
);
3901 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
3903 pStubMsg
->MemorySize
+= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->MaxCount
);
3905 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
3907 return pCVStructFormat
->memory_size
+ pStubMsg
->MaxCount
* esize
;
3910 /***********************************************************************
3911 * NdrConformantVaryingStructFree [RPCRT4.@]
3913 void WINAPI
NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3914 unsigned char *pMemory
,
3915 PFORMAT_STRING pFormat
)
3917 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3918 PFORMAT_STRING pCVArrayFormat
;
3921 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3923 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3924 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3926 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3927 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3931 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3932 pCVStructFormat
->offset_to_array_description
;
3933 switch (*pCVArrayFormat
)
3935 case RPC_FC_CVARRAY
:
3936 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3938 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3939 pCVArrayFormat
+ 4, 0);
3940 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3943 case RPC_FC_C_CSTRING
:
3944 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
3945 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
3946 esize
= sizeof(char);
3947 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3948 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3949 pCVArrayFormat
+ 2, 0);
3951 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3953 case RPC_FC_C_WSTRING
:
3954 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
3955 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
3956 esize
= sizeof(WCHAR
);
3957 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3958 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3959 pCVArrayFormat
+ 2, 0);
3961 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3964 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3965 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3969 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3971 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
3974 #include "pshpack1.h"
3978 unsigned char alignment
;
3979 unsigned short total_size
;
3980 } NDR_SMFARRAY_FORMAT
;
3985 unsigned char alignment
;
3986 unsigned long total_size
;
3987 } NDR_LGFARRAY_FORMAT
;
3988 #include "poppack.h"
3990 /***********************************************************************
3991 * NdrFixedArrayMarshall [RPCRT4.@]
3993 unsigned char * WINAPI
NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3994 unsigned char *pMemory
,
3995 PFORMAT_STRING pFormat
)
3997 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
3998 unsigned long total_size
;
4000 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4002 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4003 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4005 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4006 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4010 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4012 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4014 total_size
= pSmFArrayFormat
->total_size
;
4015 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4019 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4020 total_size
= pLgFArrayFormat
->total_size
;
4021 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4024 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4025 safe_copy_to_buffer(pStubMsg
, pMemory
, total_size
);
4027 pFormat
= EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4032 /***********************************************************************
4033 * NdrFixedArrayUnmarshall [RPCRT4.@]
4035 unsigned char * WINAPI
NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4036 unsigned char **ppMemory
,
4037 PFORMAT_STRING pFormat
,
4038 unsigned char fMustAlloc
)
4040 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4041 unsigned long total_size
;
4043 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4045 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4046 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4048 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4049 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4053 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4055 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4057 total_size
= pSmFArrayFormat
->total_size
;
4058 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4062 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4063 total_size
= pLgFArrayFormat
->total_size
;
4064 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4067 if (fMustAlloc
|| !*ppMemory
)
4068 *ppMemory
= NdrAllocate(pStubMsg
, total_size
);
4069 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4070 safe_copy_from_buffer(pStubMsg
, *ppMemory
, total_size
);
4072 pFormat
= EmbeddedPointerUnmarshall(pStubMsg
, *ppMemory
, *ppMemory
, pFormat
, TRUE
/* FIXME */);
4077 /***********************************************************************
4078 * NdrFixedArrayBufferSize [RPCRT4.@]
4080 void WINAPI
NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4081 unsigned char *pMemory
,
4082 PFORMAT_STRING pFormat
)
4084 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4085 unsigned long total_size
;
4087 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4089 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4090 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4092 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4093 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4097 ALIGN_LENGTH(pStubMsg
->BufferLength
, pSmFArrayFormat
->alignment
+ 1);
4099 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4101 total_size
= pSmFArrayFormat
->total_size
;
4102 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4106 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4107 total_size
= pLgFArrayFormat
->total_size
;
4108 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4110 safe_buffer_length_increment(pStubMsg
, total_size
);
4112 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4115 /***********************************************************************
4116 * NdrFixedArrayMemorySize [RPCRT4.@]
4118 ULONG WINAPI
NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4119 PFORMAT_STRING pFormat
)
4121 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4124 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4126 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4127 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4129 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4130 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4134 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4136 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4138 total_size
= pSmFArrayFormat
->total_size
;
4139 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4143 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4144 total_size
= pLgFArrayFormat
->total_size
;
4145 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4147 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4148 safe_buffer_increment(pStubMsg
, total_size
);
4149 pStubMsg
->MemorySize
+= total_size
;
4151 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4156 /***********************************************************************
4157 * NdrFixedArrayFree [RPCRT4.@]
4159 void WINAPI
NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4160 unsigned char *pMemory
,
4161 PFORMAT_STRING pFormat
)
4163 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4165 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4167 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4168 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4170 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4171 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4175 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4176 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4179 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4180 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4183 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4186 /***********************************************************************
4187 * NdrVaryingArrayMarshall [RPCRT4.@]
4189 unsigned char * WINAPI
NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4190 unsigned char *pMemory
,
4191 PFORMAT_STRING pFormat
)
4193 unsigned char alignment
;
4194 DWORD elements
, esize
;
4197 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4199 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4200 (pFormat
[0] != RPC_FC_LGVARRAY
))
4202 ERR("invalid format type %x\n", pFormat
[0]);
4203 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4207 alignment
= pFormat
[1] + 1;
4209 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4212 pFormat
+= sizeof(WORD
);
4213 elements
= *(const WORD
*)pFormat
;
4214 pFormat
+= sizeof(WORD
);
4219 pFormat
+= sizeof(DWORD
);
4220 elements
= *(const DWORD
*)pFormat
;
4221 pFormat
+= sizeof(DWORD
);
4224 esize
= *(const WORD
*)pFormat
;
4225 pFormat
+= sizeof(WORD
);
4227 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4228 if ((pStubMsg
->ActualCount
> elements
) ||
4229 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4231 RpcRaiseException(RPC_S_INVALID_BOUND
);
4235 WriteVariance(pStubMsg
);
4237 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4239 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4240 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4241 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
4243 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4248 /***********************************************************************
4249 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4251 unsigned char * WINAPI
NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4252 unsigned char **ppMemory
,
4253 PFORMAT_STRING pFormat
,
4254 unsigned char fMustAlloc
)
4256 unsigned char alignment
;
4257 DWORD size
, elements
, esize
;
4260 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4262 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4263 (pFormat
[0] != RPC_FC_LGVARRAY
))
4265 ERR("invalid format type %x\n", pFormat
[0]);
4266 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4270 alignment
= pFormat
[1] + 1;
4272 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4275 size
= *(const WORD
*)pFormat
;
4276 pFormat
+= sizeof(WORD
);
4277 elements
= *(const WORD
*)pFormat
;
4278 pFormat
+= sizeof(WORD
);
4283 size
= *(const DWORD
*)pFormat
;
4284 pFormat
+= sizeof(DWORD
);
4285 elements
= *(const DWORD
*)pFormat
;
4286 pFormat
+= sizeof(DWORD
);
4289 esize
= *(const WORD
*)pFormat
;
4290 pFormat
+= sizeof(WORD
);
4292 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
4294 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4296 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4298 if (!*ppMemory
|| fMustAlloc
)
4299 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4300 safe_copy_from_buffer(pStubMsg
, *ppMemory
+ pStubMsg
->Offset
, bufsize
);
4302 EmbeddedPointerUnmarshall(pStubMsg
, *ppMemory
, *ppMemory
, pFormat
, TRUE
/* FIXME */);
4307 /***********************************************************************
4308 * NdrVaryingArrayBufferSize [RPCRT4.@]
4310 void WINAPI
NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4311 unsigned char *pMemory
,
4312 PFORMAT_STRING pFormat
)
4314 unsigned char alignment
;
4315 DWORD elements
, esize
;
4317 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4319 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4320 (pFormat
[0] != RPC_FC_LGVARRAY
))
4322 ERR("invalid format type %x\n", pFormat
[0]);
4323 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4327 alignment
= pFormat
[1] + 1;
4329 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4332 pFormat
+= sizeof(WORD
);
4333 elements
= *(const WORD
*)pFormat
;
4334 pFormat
+= sizeof(WORD
);
4339 pFormat
+= sizeof(DWORD
);
4340 elements
= *(const DWORD
*)pFormat
;
4341 pFormat
+= sizeof(DWORD
);
4344 esize
= *(const WORD
*)pFormat
;
4345 pFormat
+= sizeof(WORD
);
4347 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4348 if ((pStubMsg
->ActualCount
> elements
) ||
4349 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4351 RpcRaiseException(RPC_S_INVALID_BOUND
);
4355 SizeVariance(pStubMsg
);
4357 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
4359 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
4361 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4364 /***********************************************************************
4365 * NdrVaryingArrayMemorySize [RPCRT4.@]
4367 ULONG WINAPI
NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4368 PFORMAT_STRING pFormat
)
4370 unsigned char alignment
;
4371 DWORD size
, elements
, esize
;
4373 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4375 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4376 (pFormat
[0] != RPC_FC_LGVARRAY
))
4378 ERR("invalid format type %x\n", pFormat
[0]);
4379 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4383 alignment
= pFormat
[1] + 1;
4385 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4388 size
= *(const WORD
*)pFormat
;
4389 pFormat
+= sizeof(WORD
);
4390 elements
= *(const WORD
*)pFormat
;
4391 pFormat
+= sizeof(WORD
);
4396 size
= *(const DWORD
*)pFormat
;
4397 pFormat
+= sizeof(DWORD
);
4398 elements
= *(const DWORD
*)pFormat
;
4399 pFormat
+= sizeof(DWORD
);
4402 esize
= *(const WORD
*)pFormat
;
4403 pFormat
+= sizeof(WORD
);
4405 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
4407 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4409 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
4410 pStubMsg
->MemorySize
+= size
;
4412 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4414 return pStubMsg
->MemorySize
;
4417 /***********************************************************************
4418 * NdrVaryingArrayFree [RPCRT4.@]
4420 void WINAPI
NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4421 unsigned char *pMemory
,
4422 PFORMAT_STRING pFormat
)
4424 unsigned char alignment
;
4427 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4429 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4430 (pFormat
[0] != RPC_FC_LGVARRAY
))
4432 ERR("invalid format type %x\n", pFormat
[0]);
4433 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4437 alignment
= pFormat
[1] + 1;
4439 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4442 pFormat
+= sizeof(WORD
);
4443 elements
= *(const WORD
*)pFormat
;
4444 pFormat
+= sizeof(WORD
);
4449 pFormat
+= sizeof(DWORD
);
4450 elements
= *(const DWORD
*)pFormat
;
4451 pFormat
+= sizeof(DWORD
);
4454 pFormat
+= sizeof(WORD
);
4456 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4457 if ((pStubMsg
->ActualCount
> elements
) ||
4458 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4460 RpcRaiseException(RPC_S_INVALID_BOUND
);
4464 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4467 static ULONG
get_discriminant(unsigned char fc
, const unsigned char *pMemory
)
4475 return *(const UCHAR
*)pMemory
;
4480 return *(const USHORT
*)pMemory
;
4484 return *(const ULONG
*)pMemory
;
4486 FIXME("Unhandled base type: 0x%02x\n", fc
);
4491 static PFORMAT_STRING
get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg
,
4492 unsigned long discriminant
,
4493 PFORMAT_STRING pFormat
)
4495 unsigned short num_arms
, arm
, type
;
4497 num_arms
= *(const SHORT
*)pFormat
& 0x0fff;
4499 for(arm
= 0; arm
< num_arms
; arm
++)
4501 if(discriminant
== *(const ULONG
*)pFormat
)
4509 type
= *(const unsigned short*)pFormat
;
4510 TRACE("type %04x\n", type
);
4511 if(arm
== num_arms
) /* default arm extras */
4515 ERR("no arm for 0x%lx and no default case\n", discriminant
);
4516 RpcRaiseException(RPC_S_INVALID_TAG
);
4521 TRACE("falling back to empty default case for 0x%lx\n", discriminant
);
4528 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
, ULONG discriminant
, PFORMAT_STRING pFormat
)
4530 unsigned short type
;
4534 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4538 type
= *(const unsigned short*)pFormat
;
4539 if((type
& 0xff00) == 0x8000)
4541 unsigned char basetype
= LOBYTE(type
);
4542 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &basetype
);
4546 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4547 NDR_MARSHALL m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
4550 unsigned char *saved_buffer
= NULL
;
4551 int pointer_buffer_mark_set
= 0;
4558 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4559 saved_buffer
= pStubMsg
->Buffer
;
4560 if (pStubMsg
->PointerBufferMark
)
4562 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4563 pStubMsg
->PointerBufferMark
= NULL
;
4564 pointer_buffer_mark_set
= 1;
4567 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
4569 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char **)pMemory
, desc
);
4570 if (pointer_buffer_mark_set
)
4572 STD_OVERFLOW_CHECK(pStubMsg
);
4573 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4574 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
4576 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
4577 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
4578 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4580 pStubMsg
->Buffer
= saved_buffer
+ 4;
4584 m(pStubMsg
, pMemory
, desc
);
4587 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4592 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4593 unsigned char **ppMemory
,
4595 PFORMAT_STRING pFormat
,
4596 unsigned char fMustAlloc
)
4598 unsigned short type
;
4602 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4606 type
= *(const unsigned short*)pFormat
;
4607 if((type
& 0xff00) == 0x8000)
4609 unsigned char basetype
= LOBYTE(type
);
4610 return NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &basetype
, FALSE
);
4614 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4615 NDR_UNMARSHALL m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
4618 unsigned char *saved_buffer
= NULL
;
4619 int pointer_buffer_mark_set
= 0;
4626 **(void***)ppMemory
= NULL
;
4627 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4628 saved_buffer
= pStubMsg
->Buffer
;
4629 if (pStubMsg
->PointerBufferMark
)
4631 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4632 pStubMsg
->PointerBufferMark
= NULL
;
4633 pointer_buffer_mark_set
= 1;
4636 pStubMsg
->Buffer
+= 4; /* for pointer ID */
4638 if (saved_buffer
+ 4 > pStubMsg
->BufferEnd
)
4640 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
4641 saved_buffer
, pStubMsg
->BufferEnd
);
4642 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4645 PointerUnmarshall(pStubMsg
, saved_buffer
, *(unsigned char ***)ppMemory
, **(unsigned char ***)ppMemory
, desc
, fMustAlloc
);
4646 if (pointer_buffer_mark_set
)
4648 STD_OVERFLOW_CHECK(pStubMsg
);
4649 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4650 pStubMsg
->Buffer
= saved_buffer
+ 4;
4654 m(pStubMsg
, ppMemory
, desc
, fMustAlloc
);
4657 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4662 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg
,
4663 unsigned char *pMemory
,
4665 PFORMAT_STRING pFormat
)
4667 unsigned short type
;
4671 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4675 type
= *(const unsigned short*)pFormat
;
4676 if((type
& 0xff00) == 0x8000)
4678 unsigned char basetype
= LOBYTE(type
);
4679 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &basetype
);
4683 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4684 NDR_BUFFERSIZE m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
4693 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
4694 safe_buffer_length_increment(pStubMsg
, 4); /* for pointer ID */
4695 if (!pStubMsg
->IgnoreEmbeddedPointers
)
4697 int saved_buffer_length
= pStubMsg
->BufferLength
;
4698 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4699 pStubMsg
->PointerLength
= 0;
4700 if(!pStubMsg
->BufferLength
)
4701 ERR("BufferLength == 0??\n");
4702 PointerBufferSize(pStubMsg
, *(unsigned char **)pMemory
, desc
);
4703 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4704 pStubMsg
->BufferLength
= saved_buffer_length
;
4708 m(pStubMsg
, pMemory
, desc
);
4711 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
4715 static ULONG
union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg
,
4717 PFORMAT_STRING pFormat
)
4719 unsigned short type
, size
;
4721 size
= *(const unsigned short*)pFormat
;
4722 pStubMsg
->Memory
+= size
;
4725 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4729 type
= *(const unsigned short*)pFormat
;
4730 if((type
& 0xff00) == 0x8000)
4732 return NdrBaseTypeMemorySize(pStubMsg
, pFormat
);
4736 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4737 NDR_MEMORYSIZE m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
4738 unsigned char *saved_buffer
;
4747 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4748 saved_buffer
= pStubMsg
->Buffer
;
4749 safe_buffer_increment(pStubMsg
, 4);
4750 ALIGN_LENGTH(pStubMsg
->MemorySize
, 4);
4751 pStubMsg
->MemorySize
+= 4;
4752 if (!pStubMsg
->IgnoreEmbeddedPointers
)
4753 PointerMemorySize(pStubMsg
, saved_buffer
, pFormat
);
4756 return m(pStubMsg
, desc
);
4759 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4762 TRACE("size %d\n", size
);
4766 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg
,
4767 unsigned char *pMemory
,
4769 PFORMAT_STRING pFormat
)
4771 unsigned short type
;
4775 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4779 type
= *(const unsigned short*)pFormat
;
4780 if((type
& 0xff00) != 0x8000)
4782 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4783 NDR_FREE m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
4792 PointerFree(pStubMsg
, *(unsigned char **)pMemory
, desc
);
4795 m(pStubMsg
, pMemory
, desc
);
4798 else FIXME("no freer for embedded type %02x\n", *desc
);
4802 /***********************************************************************
4803 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
4805 unsigned char * WINAPI
NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4806 unsigned char *pMemory
,
4807 PFORMAT_STRING pFormat
)
4809 unsigned char switch_type
;
4810 unsigned char increment
;
4813 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4816 switch_type
= *pFormat
& 0xf;
4817 increment
= (*pFormat
& 0xf0) >> 4;
4820 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
4822 switch_value
= get_discriminant(switch_type
, pMemory
);
4823 TRACE("got switch value 0x%x\n", switch_value
);
4825 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &switch_type
);
4826 pMemory
+= increment
;
4828 return union_arm_marshall(pStubMsg
, pMemory
, switch_value
, pFormat
);
4831 /***********************************************************************
4832 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
4834 unsigned char * WINAPI
NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4835 unsigned char **ppMemory
,
4836 PFORMAT_STRING pFormat
,
4837 unsigned char fMustAlloc
)
4839 unsigned char switch_type
;
4840 unsigned char increment
;
4842 unsigned short size
;
4843 unsigned char *pMemoryArm
;
4845 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4848 switch_type
= *pFormat
& 0xf;
4849 increment
= (*pFormat
& 0xf0) >> 4;
4852 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
4853 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
4854 TRACE("got switch value 0x%x\n", switch_value
);
4856 size
= *(const unsigned short*)pFormat
+ increment
;
4857 if(!*ppMemory
|| fMustAlloc
)
4858 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4860 NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &switch_type
, FALSE
);
4861 pMemoryArm
= *ppMemory
+ increment
;
4863 return union_arm_unmarshall(pStubMsg
, &pMemoryArm
, switch_value
, pFormat
, fMustAlloc
);
4866 /***********************************************************************
4867 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
4869 void WINAPI
NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4870 unsigned char *pMemory
,
4871 PFORMAT_STRING pFormat
)
4873 unsigned char switch_type
;
4874 unsigned char increment
;
4877 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4880 switch_type
= *pFormat
& 0xf;
4881 increment
= (*pFormat
& 0xf0) >> 4;
4884 ALIGN_LENGTH(pStubMsg
->BufferLength
, increment
);
4885 switch_value
= get_discriminant(switch_type
, pMemory
);
4886 TRACE("got switch value 0x%x\n", switch_value
);
4888 /* Add discriminant size */
4889 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&switch_value
, &switch_type
);
4890 pMemory
+= increment
;
4892 union_arm_buffer_size(pStubMsg
, pMemory
, switch_value
, pFormat
);
4895 /***********************************************************************
4896 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
4898 ULONG WINAPI
NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4899 PFORMAT_STRING pFormat
)
4901 unsigned char switch_type
;
4902 unsigned char increment
;
4905 switch_type
= *pFormat
& 0xf;
4906 increment
= (*pFormat
& 0xf0) >> 4;
4909 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
4910 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
4911 TRACE("got switch value 0x%x\n", switch_value
);
4913 pStubMsg
->Memory
+= increment
;
4915 return increment
+ union_arm_memory_size(pStubMsg
, switch_value
, pFormat
+ *(const SHORT
*)pFormat
);
4918 /***********************************************************************
4919 * NdrEncapsulatedUnionFree [RPCRT4.@]
4921 void WINAPI
NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
4922 unsigned char *pMemory
,
4923 PFORMAT_STRING pFormat
)
4925 unsigned char switch_type
;
4926 unsigned char increment
;
4929 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4932 switch_type
= *pFormat
& 0xf;
4933 increment
= (*pFormat
& 0xf0) >> 4;
4936 switch_value
= get_discriminant(switch_type
, pMemory
);
4937 TRACE("got switch value 0x%x\n", switch_value
);
4939 pMemory
+= increment
;
4941 return union_arm_free(pStubMsg
, pMemory
, switch_value
, pFormat
);
4944 /***********************************************************************
4945 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
4947 unsigned char * WINAPI
NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4948 unsigned char *pMemory
,
4949 PFORMAT_STRING pFormat
)
4951 unsigned char switch_type
;
4953 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4956 switch_type
= *pFormat
;
4959 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
4960 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
4961 /* Marshall discriminant */
4962 NdrBaseTypeMarshall(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
4964 return union_arm_marshall(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
4967 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg
,
4968 PFORMAT_STRING
*ppFormat
)
4970 long discriminant
= 0;
4980 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
4989 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
4990 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
4998 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
4999 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5004 FIXME("Unhandled base type: 0x%02x\n", **ppFormat
);
5008 if (pStubMsg
->fHasNewCorrDesc
)
5012 return discriminant
;
5015 /**********************************************************************
5016 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5018 unsigned char * WINAPI
NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5019 unsigned char **ppMemory
,
5020 PFORMAT_STRING pFormat
,
5021 unsigned char fMustAlloc
)
5024 unsigned short size
;
5026 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5029 /* Unmarshall discriminant */
5030 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
5031 TRACE("unmarshalled discriminant %lx\n", discriminant
);
5033 pFormat
+= *(const SHORT
*)pFormat
;
5035 size
= *(const unsigned short*)pFormat
;
5037 if(!*ppMemory
|| fMustAlloc
)
5038 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5040 return union_arm_unmarshall(pStubMsg
, ppMemory
, discriminant
, pFormat
, fMustAlloc
);
5043 /***********************************************************************
5044 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5046 void WINAPI
NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5047 unsigned char *pMemory
,
5048 PFORMAT_STRING pFormat
)
5050 unsigned char switch_type
;
5052 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5055 switch_type
= *pFormat
;
5058 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5059 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5060 /* Add discriminant size */
5061 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
5063 union_arm_buffer_size(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5066 /***********************************************************************
5067 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5069 ULONG WINAPI
NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5070 PFORMAT_STRING pFormat
)
5075 /* Unmarshall discriminant */
5076 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
5077 TRACE("unmarshalled discriminant 0x%x\n", discriminant
);
5079 return union_arm_memory_size(pStubMsg
, discriminant
, pFormat
+ *(const SHORT
*)pFormat
);
5082 /***********************************************************************
5083 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5085 void WINAPI
NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
5086 unsigned char *pMemory
,
5087 PFORMAT_STRING pFormat
)
5089 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5093 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5094 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5096 return union_arm_free(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5099 /***********************************************************************
5100 * NdrByteCountPointerMarshall [RPCRT4.@]
5102 unsigned char * WINAPI
NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5103 unsigned char *pMemory
,
5104 PFORMAT_STRING pFormat
)
5110 /***********************************************************************
5111 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5113 unsigned char * WINAPI
NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5114 unsigned char **ppMemory
,
5115 PFORMAT_STRING pFormat
,
5116 unsigned char fMustAlloc
)
5122 /***********************************************************************
5123 * NdrByteCountPointerBufferSize [RPCRT4.@]
5125 void WINAPI
NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5126 unsigned char *pMemory
,
5127 PFORMAT_STRING pFormat
)
5132 /***********************************************************************
5133 * NdrByteCountPointerMemorySize [RPCRT4.@]
5135 ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5136 PFORMAT_STRING pFormat
)
5142 /***********************************************************************
5143 * NdrByteCountPointerFree [RPCRT4.@]
5145 void WINAPI
NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
5146 unsigned char *pMemory
,
5147 PFORMAT_STRING pFormat
)
5152 /***********************************************************************
5153 * NdrXmitOrRepAsMarshall [RPCRT4.@]
5155 unsigned char * WINAPI
NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5156 unsigned char *pMemory
,
5157 PFORMAT_STRING pFormat
)
5163 /***********************************************************************
5164 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
5166 unsigned char * WINAPI
NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5167 unsigned char **ppMemory
,
5168 PFORMAT_STRING pFormat
,
5169 unsigned char fMustAlloc
)
5175 /***********************************************************************
5176 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
5178 void WINAPI
NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5179 unsigned char *pMemory
,
5180 PFORMAT_STRING pFormat
)
5185 /***********************************************************************
5186 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
5188 ULONG WINAPI
NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5189 PFORMAT_STRING pFormat
)
5195 /***********************************************************************
5196 * NdrXmitOrRepAsFree [RPCRT4.@]
5198 void WINAPI
NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg
,
5199 unsigned char *pMemory
,
5200 PFORMAT_STRING pFormat
)
5205 #include "pshpack1.h"
5209 unsigned char flags_type
; /* flags in upper nibble, type in lower nibble */
5213 #include "poppack.h"
5215 /***********************************************************************
5216 * NdrRangeMarshall [internal]
5218 unsigned char *WINAPI
NdrRangeMarshall(
5219 PMIDL_STUB_MESSAGE pStubMsg
,
5220 unsigned char *pMemory
,
5221 PFORMAT_STRING pFormat
)
5223 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5224 unsigned char base_type
;
5226 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5228 if (pRange
->type
!= RPC_FC_RANGE
)
5230 ERR("invalid format type %x\n", pRange
->type
);
5231 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5235 base_type
= pRange
->flags_type
& 0xf;
5237 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &base_type
);
5240 /***********************************************************************
5241 * NdrRangeUnmarshall
5243 unsigned char *WINAPI
NdrRangeUnmarshall(
5244 PMIDL_STUB_MESSAGE pStubMsg
,
5245 unsigned char **ppMemory
,
5246 PFORMAT_STRING pFormat
,
5247 unsigned char fMustAlloc
)
5249 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5250 unsigned char base_type
;
5252 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
5254 if (pRange
->type
!= RPC_FC_RANGE
)
5256 ERR("invalid format type %x\n", pRange
->type
);
5257 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5260 base_type
= pRange
->flags_type
& 0xf;
5262 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5263 base_type
, pRange
->low_value
, pRange
->high_value
);
5265 #define RANGE_UNMARSHALL(type, format_spec) \
5268 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5269 if (fMustAlloc || !*ppMemory) \
5270 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5271 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
5273 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
5274 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
5275 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
5277 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5278 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5280 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5281 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5282 (type)pRange->high_value); \
5283 RpcRaiseException(RPC_S_INVALID_BOUND); \
5286 TRACE("*ppMemory: %p\n", *ppMemory); \
5287 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5288 pStubMsg->Buffer += sizeof(type); \
5295 RANGE_UNMARSHALL(UCHAR
, "%d");
5296 TRACE("value: 0x%02x\n", **(UCHAR
**)ppMemory
);
5300 RANGE_UNMARSHALL(CHAR
, "%u");
5301 TRACE("value: 0x%02x\n", **(UCHAR
**)ppMemory
);
5303 case RPC_FC_WCHAR
: /* FIXME: valid? */
5305 RANGE_UNMARSHALL(USHORT
, "%u");
5306 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5309 RANGE_UNMARSHALL(SHORT
, "%d");
5310 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5313 RANGE_UNMARSHALL(LONG
, "%d");
5314 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5317 RANGE_UNMARSHALL(ULONG
, "%u");
5318 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5322 FIXME("Unhandled enum type\n");
5324 case RPC_FC_ERROR_STATUS_T
: /* FIXME: valid? */
5329 ERR("invalid range base type: 0x%02x\n", base_type
);
5330 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5336 /***********************************************************************
5337 * NdrRangeBufferSize [internal]
5339 void WINAPI
NdrRangeBufferSize(
5340 PMIDL_STUB_MESSAGE pStubMsg
,
5341 unsigned char *pMemory
,
5342 PFORMAT_STRING pFormat
)
5344 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5345 unsigned char base_type
;
5347 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5349 if (pRange
->type
!= RPC_FC_RANGE
)
5351 ERR("invalid format type %x\n", pRange
->type
);
5352 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5354 base_type
= pRange
->flags_type
& 0xf;
5356 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &base_type
);
5359 /***********************************************************************
5360 * NdrRangeMemorySize [internal]
5362 ULONG WINAPI
NdrRangeMemorySize(
5363 PMIDL_STUB_MESSAGE pStubMsg
,
5364 PFORMAT_STRING pFormat
)
5366 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5367 unsigned char base_type
;
5369 if (pRange
->type
!= RPC_FC_RANGE
)
5371 ERR("invalid format type %x\n", pRange
->type
);
5372 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5375 base_type
= pRange
->flags_type
& 0xf;
5377 return NdrBaseTypeMemorySize(pStubMsg
, &base_type
);
5380 /***********************************************************************
5381 * NdrRangeFree [internal]
5383 void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg
,
5384 unsigned char *pMemory
,
5385 PFORMAT_STRING pFormat
)
5387 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5392 /***********************************************************************
5393 * NdrBaseTypeMarshall [internal]
5395 static unsigned char *WINAPI
NdrBaseTypeMarshall(
5396 PMIDL_STUB_MESSAGE pStubMsg
,
5397 unsigned char *pMemory
,
5398 PFORMAT_STRING pFormat
)
5400 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5408 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(UCHAR
));
5409 TRACE("value: 0x%02x\n", *(UCHAR
*)pMemory
);
5414 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5415 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(USHORT
));
5416 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
5420 case RPC_FC_ERROR_STATUS_T
:
5422 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
5423 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONG
));
5424 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
5427 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(float));
5428 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
5431 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(double));
5432 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
5435 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONGLONG
));
5436 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONGLONG
));
5437 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
5440 /* only 16-bits on the wire, so do a sanity check */
5441 if (*(UINT
*)pMemory
> SHRT_MAX
)
5442 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
5443 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5444 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5445 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5446 *(USHORT
*)pStubMsg
->Buffer
= *(UINT
*)pMemory
;
5447 pStubMsg
->Buffer
+= sizeof(USHORT
);
5448 TRACE("value: 0x%04x\n", *(UINT
*)pMemory
);
5453 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5456 /* FIXME: what is the correct return value? */
5460 /***********************************************************************
5461 * NdrBaseTypeUnmarshall [internal]
5463 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(
5464 PMIDL_STUB_MESSAGE pStubMsg
,
5465 unsigned char **ppMemory
,
5466 PFORMAT_STRING pFormat
,
5467 unsigned char fMustAlloc
)
5469 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
5471 #define BASE_TYPE_UNMARSHALL(type) \
5472 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5473 if (fMustAlloc || !*ppMemory) \
5474 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5475 TRACE("*ppMemory: %p\n", *ppMemory); \
5476 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5477 pStubMsg->Buffer += sizeof(type);
5485 BASE_TYPE_UNMARSHALL(UCHAR
);
5486 TRACE("value: 0x%02x\n", **(UCHAR
**)ppMemory
);
5491 BASE_TYPE_UNMARSHALL(USHORT
);
5492 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5496 case RPC_FC_ERROR_STATUS_T
:
5498 BASE_TYPE_UNMARSHALL(ULONG
);
5499 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5502 BASE_TYPE_UNMARSHALL(float);
5503 TRACE("value: %f\n", **(float **)ppMemory
);
5506 BASE_TYPE_UNMARSHALL(double);
5507 TRACE("value: %f\n", **(double **)ppMemory
);
5510 BASE_TYPE_UNMARSHALL(ULONGLONG
);
5511 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG
**)ppMemory
));
5514 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5515 if (fMustAlloc
|| !*ppMemory
)
5516 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT
));
5517 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > pStubMsg
->BufferEnd
)
5518 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5519 TRACE("*ppMemory: %p\n", *ppMemory
);
5520 /* 16-bits on the wire, but int in memory */
5521 **(UINT
**)ppMemory
= *(USHORT
*)pStubMsg
->Buffer
;
5522 pStubMsg
->Buffer
+= sizeof(USHORT
);
5523 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
5528 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5530 #undef BASE_TYPE_UNMARSHALL
5532 /* FIXME: what is the correct return value? */
5537 /***********************************************************************
5538 * NdrBaseTypeBufferSize [internal]
5540 static void WINAPI
NdrBaseTypeBufferSize(
5541 PMIDL_STUB_MESSAGE pStubMsg
,
5542 unsigned char *pMemory
,
5543 PFORMAT_STRING pFormat
)
5545 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5553 safe_buffer_length_increment(pStubMsg
, sizeof(UCHAR
));
5559 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(USHORT
));
5560 safe_buffer_length_increment(pStubMsg
, sizeof(USHORT
));
5565 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONG
));
5566 safe_buffer_length_increment(pStubMsg
, sizeof(ULONG
));
5569 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(float));
5570 safe_buffer_length_increment(pStubMsg
, sizeof(float));
5573 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(double));
5574 safe_buffer_length_increment(pStubMsg
, sizeof(double));
5577 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONGLONG
));
5578 safe_buffer_length_increment(pStubMsg
, sizeof(ULONGLONG
));
5580 case RPC_FC_ERROR_STATUS_T
:
5581 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(error_status_t
));
5582 safe_buffer_length_increment(pStubMsg
, sizeof(error_status_t
));
5587 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5591 /***********************************************************************
5592 * NdrBaseTypeMemorySize [internal]
5594 static ULONG WINAPI
NdrBaseTypeMemorySize(
5595 PMIDL_STUB_MESSAGE pStubMsg
,
5596 PFORMAT_STRING pFormat
)
5604 safe_buffer_increment(pStubMsg
, sizeof(UCHAR
));
5605 pStubMsg
->MemorySize
+= sizeof(UCHAR
);
5606 return sizeof(UCHAR
);
5610 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
5611 pStubMsg
->MemorySize
+= sizeof(USHORT
);
5612 return sizeof(USHORT
);
5616 safe_buffer_increment(pStubMsg
, sizeof(ULONG
));
5617 pStubMsg
->MemorySize
+= sizeof(ULONG
);
5618 return sizeof(ULONG
);
5620 safe_buffer_increment(pStubMsg
, sizeof(float));
5621 pStubMsg
->MemorySize
+= sizeof(float);
5622 return sizeof(float);
5624 safe_buffer_increment(pStubMsg
, sizeof(double));
5625 pStubMsg
->MemorySize
+= sizeof(double);
5626 return sizeof(double);
5628 safe_buffer_increment(pStubMsg
, sizeof(ULONGLONG
));
5629 pStubMsg
->MemorySize
+= sizeof(ULONGLONG
);
5630 return sizeof(ULONGLONG
);
5631 case RPC_FC_ERROR_STATUS_T
:
5632 safe_buffer_increment(pStubMsg
, sizeof(error_status_t
));
5633 pStubMsg
->MemorySize
+= sizeof(error_status_t
);
5634 return sizeof(error_status_t
);
5636 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
5637 pStubMsg
->MemorySize
+= sizeof(UINT
);
5638 return sizeof(UINT
);
5640 pStubMsg
->MemorySize
+= sizeof(void *);
5641 return sizeof(void *);
5643 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5648 /***********************************************************************
5649 * NdrBaseTypeFree [internal]
5651 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg
,
5652 unsigned char *pMemory
,
5653 PFORMAT_STRING pFormat
)
5655 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5660 /***********************************************************************
5661 * NdrContextHandleBufferSize [internal]
5663 static void WINAPI
NdrContextHandleBufferSize(
5664 PMIDL_STUB_MESSAGE pStubMsg
,
5665 unsigned char *pMemory
,
5666 PFORMAT_STRING pFormat
)
5668 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5670 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
5672 ERR("invalid format type %x\n", *pFormat
);
5673 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5675 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
5676 safe_buffer_length_increment(pStubMsg
, cbNDRContext
);
5679 /***********************************************************************
5680 * NdrContextHandleMarshall [internal]
5682 static unsigned char *WINAPI
NdrContextHandleMarshall(
5683 PMIDL_STUB_MESSAGE pStubMsg
,
5684 unsigned char *pMemory
,
5685 PFORMAT_STRING pFormat
)
5687 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5689 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
5691 ERR("invalid format type %x\n", *pFormat
);
5692 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5695 if (pFormat
[1] & 0x80)
5696 NdrClientContextMarshall(pStubMsg
, *(NDR_CCONTEXT
**)pMemory
, FALSE
);
5698 NdrClientContextMarshall(pStubMsg
, (NDR_CCONTEXT
*)pMemory
, FALSE
);
5703 /***********************************************************************
5704 * NdrContextHandleUnmarshall [internal]
5706 static unsigned char *WINAPI
NdrContextHandleUnmarshall(
5707 PMIDL_STUB_MESSAGE pStubMsg
,
5708 unsigned char **ppMemory
,
5709 PFORMAT_STRING pFormat
,
5710 unsigned char fMustAlloc
)
5712 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
5714 ERR("invalid format type %x\n", *pFormat
);
5715 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5718 **(NDR_CCONTEXT
**)ppMemory
= NULL
;
5719 NdrClientContextUnmarshall(pStubMsg
, *(NDR_CCONTEXT
**)ppMemory
, pStubMsg
->RpcMsg
->Handle
);
5724 /***********************************************************************
5725 * NdrClientContextMarshall [RPCRT4.@]
5727 void WINAPI
NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5728 NDR_CCONTEXT ContextHandle
,
5731 TRACE("(%p, %p, %d)\n", pStubMsg
, ContextHandle
, fCheck
);
5733 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5735 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5737 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
5738 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
5739 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5742 /* FIXME: what does fCheck do? */
5743 NDRCContextMarshall(ContextHandle
,
5746 pStubMsg
->Buffer
+= cbNDRContext
;
5749 /***********************************************************************
5750 * NdrClientContextUnmarshall [RPCRT4.@]
5752 void WINAPI
NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5753 NDR_CCONTEXT
* pContextHandle
,
5754 RPC_BINDING_HANDLE BindHandle
)
5756 TRACE("(%p, %p, %p)\n", pStubMsg
, pContextHandle
, BindHandle
);
5758 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5760 if (pStubMsg
->Buffer
+ cbNDRContext
> pStubMsg
->BufferEnd
)
5761 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5763 NDRCContextUnmarshall(pContextHandle
,
5766 pStubMsg
->RpcMsg
->DataRepresentation
);
5768 pStubMsg
->Buffer
+= cbNDRContext
;
5771 void WINAPI
NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5772 NDR_SCONTEXT ContextHandle
,
5773 NDR_RUNDOWN RundownRoutine
)
5775 FIXME("(%p, %p, %p): stub\n", pStubMsg
, ContextHandle
, RundownRoutine
);
5778 NDR_SCONTEXT WINAPI
NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
)
5780 FIXME("(%p): stub\n", pStubMsg
);
5784 void WINAPI
NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg
,
5785 unsigned char* pMemory
,
5786 PFORMAT_STRING pFormat
)
5788 FIXME("(%p, %p, %p): stub\n", pStubMsg
, pMemory
, pFormat
);
5791 NDR_SCONTEXT WINAPI
NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg
,
5792 PFORMAT_STRING pFormat
)
5794 FIXME("(%p, %p): stub\n", pStubMsg
, pFormat
);
5798 void WINAPI
NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5799 NDR_SCONTEXT ContextHandle
,
5800 NDR_RUNDOWN RundownRoutine
,
5801 PFORMAT_STRING pFormat
)
5803 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg
, ContextHandle
, RundownRoutine
, pFormat
);
5806 NDR_SCONTEXT WINAPI
NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5807 PFORMAT_STRING pFormat
)
5809 FIXME("(%p, %p): stub\n", pStubMsg
, pFormat
);
5813 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
5815 typedef struct ndr_context_handle
5819 } ndr_context_handle
;
5821 struct context_handle_entry
5825 RPC_BINDING_HANDLE handle
;
5826 ndr_context_handle wire_data
;
5829 static struct list context_handle_list
= LIST_INIT(context_handle_list
);
5831 static CRITICAL_SECTION ndr_context_cs
;
5832 static CRITICAL_SECTION_DEBUG ndr_context_debug
=
5834 0, 0, &ndr_context_cs
,
5835 { &ndr_context_debug
.ProcessLocksList
, &ndr_context_debug
.ProcessLocksList
},
5836 0, 0, { (DWORD_PTR
)(__FILE__
": ndr_context") }
5838 static CRITICAL_SECTION ndr_context_cs
= { &ndr_context_debug
, -1, 0, 0, 0, 0 };
5840 static struct context_handle_entry
*get_context_entry(NDR_CCONTEXT CContext
)
5842 struct context_handle_entry
*che
= (struct context_handle_entry
*) CContext
;
5844 if (che
->magic
!= NDR_CONTEXT_HANDLE_MAGIC
)
5849 static struct context_handle_entry
*context_entry_from_guid(LPCGUID uuid
)
5851 struct context_handle_entry
*che
;
5852 LIST_FOR_EACH_ENTRY(che
, &context_handle_list
, struct context_handle_entry
, entry
)
5853 if (IsEqualGUID(&che
->wire_data
.uuid
, uuid
))
5858 RPC_BINDING_HANDLE WINAPI
NDRCContextBinding(NDR_CCONTEXT CContext
)
5860 struct context_handle_entry
*che
;
5861 RPC_BINDING_HANDLE handle
= NULL
;
5863 TRACE("%p\n", CContext
);
5865 EnterCriticalSection(&ndr_context_cs
);
5866 che
= get_context_entry(CContext
);
5868 handle
= che
->handle
;
5869 LeaveCriticalSection(&ndr_context_cs
);
5872 RpcRaiseException(ERROR_INVALID_HANDLE
);
5876 void WINAPI
NDRCContextMarshall(NDR_CCONTEXT CContext
, void *pBuff
)
5878 struct context_handle_entry
*che
;
5880 TRACE("%p %p\n", CContext
, pBuff
);
5884 EnterCriticalSection(&ndr_context_cs
);
5885 che
= get_context_entry(CContext
);
5886 memcpy(pBuff
, &che
->wire_data
, sizeof (ndr_context_handle
));
5887 LeaveCriticalSection(&ndr_context_cs
);
5891 ndr_context_handle
*wire_data
= (ndr_context_handle
*)pBuff
;
5892 wire_data
->attributes
= 0;
5893 wire_data
->uuid
= GUID_NULL
;
5897 /***********************************************************************
5898 * RpcSmDestroyClientContext [RPCRT4.@]
5900 RPC_STATUS WINAPI
RpcSmDestroyClientContext(void **ContextHandle
)
5902 RPC_STATUS status
= RPC_X_SS_CONTEXT_MISMATCH
;
5903 struct context_handle_entry
*che
= NULL
;
5905 TRACE("(%p)\n", ContextHandle
);
5907 EnterCriticalSection(&ndr_context_cs
);
5908 che
= get_context_entry(*ContextHandle
);
5909 *ContextHandle
= NULL
;
5913 list_remove(&che
->entry
);
5916 LeaveCriticalSection(&ndr_context_cs
);
5920 RpcBindingFree(&che
->handle
);
5921 HeapFree(GetProcessHeap(), 0, che
);
5927 /***********************************************************************
5928 * RpcSsDestroyClientContext [RPCRT4.@]
5930 void WINAPI
RpcSsDestroyClientContext(void **ContextHandle
)
5932 RPC_STATUS status
= RpcSmDestroyClientContext(ContextHandle
);
5933 if (status
!= RPC_S_OK
)
5934 RpcRaiseException(status
);
5937 static UINT
ndr_update_context_handle(NDR_CCONTEXT
*CContext
,
5938 RPC_BINDING_HANDLE hBinding
,
5939 const ndr_context_handle
*chi
)
5941 struct context_handle_entry
*che
= NULL
;
5943 /* a null UUID means we should free the context handle */
5944 if (IsEqualGUID(&chi
->uuid
, &GUID_NULL
))
5948 che
= get_context_entry(*CContext
);
5950 return ERROR_INVALID_HANDLE
;
5951 list_remove(&che
->entry
);
5952 RpcBindingFree(&che
->handle
);
5953 HeapFree(GetProcessHeap(), 0, che
);
5957 /* if there's no existing entry matching the GUID, allocate one */
5958 else if (!(che
= context_entry_from_guid(&chi
->uuid
)))
5960 che
= HeapAlloc(GetProcessHeap(), 0, sizeof *che
);
5962 return ERROR_NOT_ENOUGH_MEMORY
;
5963 che
->magic
= NDR_CONTEXT_HANDLE_MAGIC
;
5964 RpcBindingCopy(hBinding
, &che
->handle
);
5965 list_add_tail(&context_handle_list
, &che
->entry
);
5966 memcpy(&che
->wire_data
, chi
, sizeof *chi
);
5971 return ERROR_SUCCESS
;
5974 /***********************************************************************
5975 * NDRCContextUnmarshall [RPCRT4.@]
5977 void WINAPI
NDRCContextUnmarshall(NDR_CCONTEXT
*CContext
,
5978 RPC_BINDING_HANDLE hBinding
,
5979 void *pBuff
, ULONG DataRepresentation
)
5983 TRACE("*%p=(%p) %p %p %08x\n",
5984 CContext
, *CContext
, hBinding
, pBuff
, DataRepresentation
);
5986 EnterCriticalSection(&ndr_context_cs
);
5987 r
= ndr_update_context_handle(CContext
, hBinding
, pBuff
);
5988 LeaveCriticalSection(&ndr_context_cs
);
5990 RpcRaiseException(r
);
5993 /***********************************************************************
5994 * NDRSContextMarshall [RPCRT4.@]
5996 void WINAPI
NDRSContextMarshall(NDR_SCONTEXT CContext
,
5998 NDR_RUNDOWN userRunDownIn
)
6000 FIXME("(%p %p %p): stub\n", CContext
, pBuff
, userRunDownIn
);
6003 /***********************************************************************
6004 * NDRSContextMarshallEx [RPCRT4.@]
6006 void WINAPI
NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding
,
6007 NDR_SCONTEXT CContext
,
6009 NDR_RUNDOWN userRunDownIn
)
6011 FIXME("(%p %p %p %p): stub\n", hBinding
, CContext
, pBuff
, userRunDownIn
);
6014 /***********************************************************************
6015 * NDRSContextMarshall2 [RPCRT4.@]
6017 void WINAPI
NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding
,
6018 NDR_SCONTEXT CContext
,
6020 NDR_RUNDOWN userRunDownIn
,
6021 void *CtxGuard
, ULONG Flags
)
6023 FIXME("(%p %p %p %p %p %u): stub\n",
6024 hBinding
, CContext
, pBuff
, userRunDownIn
, CtxGuard
, Flags
);
6027 /***********************************************************************
6028 * NDRSContextUnmarshall [RPCRT4.@]
6030 NDR_SCONTEXT WINAPI
NDRSContextUnmarshall(void *pBuff
,
6031 ULONG DataRepresentation
)
6033 FIXME("(%p %08x): stub\n", pBuff
, DataRepresentation
);
6037 /***********************************************************************
6038 * NDRSContextUnmarshallEx [RPCRT4.@]
6040 NDR_SCONTEXT WINAPI
NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding
,
6042 ULONG DataRepresentation
)
6044 FIXME("(%p %p %08x): stub\n", hBinding
, pBuff
, DataRepresentation
);
6048 /***********************************************************************
6049 * NDRSContextUnmarshall2 [RPCRT4.@]
6051 NDR_SCONTEXT WINAPI
NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding
,
6053 ULONG DataRepresentation
,
6054 void *CtxGuard
, ULONG Flags
)
6056 FIXME("(%p %p %08x %p %u): stub\n",
6057 hBinding
, pBuff
, DataRepresentation
, CtxGuard
, Flags
);