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("setting *pPointer to %p\n", pSrcPointer
);
1024 *pPointer
= 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
1034 if (attr
& RPC_FC_P_DEREF
) {
1037 base_ptr_val
= NULL
;
1038 *current_ptr
= NULL
;
1042 if (attr
& RPC_FC_P_DEREF
) {
1044 base_ptr_val
= NdrAllocate(pStubMsg
, sizeof(void *));
1045 *pPointer
= base_ptr_val
;
1046 current_ptr
= (unsigned char **)base_ptr_val
;
1048 current_ptr
= *(unsigned char***)current_ptr
;
1049 TRACE("deref => %p\n", current_ptr
);
1050 if (!fMustAlloc
&& !*current_ptr
) fMustAlloc
= TRUE
;
1052 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
1053 if (m
) m(pStubMsg
, current_ptr
, desc
, fMustAlloc
);
1054 else FIXME("no unmarshaller for data type=%02x\n", *desc
);
1056 if (type
== RPC_FC_FP
)
1057 NdrFullPointerInsertRefId(pStubMsg
->FullPtrXlatTables
, pointer_id
,
1061 TRACE("pointer=%p\n", *pPointer
);
1064 /***********************************************************************
1065 * PointerBufferSize [internal]
1067 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1068 unsigned char *Pointer
,
1069 PFORMAT_STRING pFormat
)
1071 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1072 PFORMAT_STRING desc
;
1074 int pointer_needs_sizing
;
1077 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1078 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1080 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1081 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1084 case RPC_FC_RP
: /* ref pointer (always non-null) */
1087 ERR("NULL ref pointer is not allowed\n");
1088 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
1093 /* NULL pointer has no further representation */
1098 pointer_needs_sizing
= !NdrFullPointerQueryPointer(
1099 pStubMsg
->FullPtrXlatTables
, Pointer
, 0, &pointer_id
);
1100 if (!pointer_needs_sizing
)
1104 FIXME("unhandled ptr type=%02x\n", type
);
1105 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1109 if (attr
& RPC_FC_P_DEREF
) {
1110 Pointer
= *(unsigned char**)Pointer
;
1111 TRACE("deref => %p\n", Pointer
);
1114 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
1115 if (m
) m(pStubMsg
, Pointer
, desc
);
1116 else FIXME("no buffersizer for data type=%02x\n", *desc
);
1119 /***********************************************************************
1120 * PointerMemorySize [internal]
1122 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1123 unsigned char *Buffer
,
1124 PFORMAT_STRING pFormat
)
1126 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1127 PFORMAT_STRING desc
;
1130 FIXME("(%p,%p,%p): stub\n", pStubMsg
, Buffer
, pFormat
);
1131 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1133 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1134 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1137 case RPC_FC_RP
: /* ref pointer (always non-null) */
1140 FIXME("unhandled ptr type=%02x\n", type
);
1141 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1144 if (attr
& RPC_FC_P_DEREF
) {
1148 m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
1149 if (m
) m(pStubMsg
, desc
);
1150 else FIXME("no memorysizer for data type=%02x\n", *desc
);
1155 /***********************************************************************
1156 * PointerFree [internal]
1158 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1159 unsigned char *Pointer
,
1160 PFORMAT_STRING pFormat
)
1162 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1163 PFORMAT_STRING desc
;
1166 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1167 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1168 if (attr
& RPC_FC_P_DONTFREE
) return;
1170 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1171 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1173 if (!Pointer
) return;
1175 if (type
== RPC_FC_FP
) {
1176 int pointer_needs_freeing
= NdrFullPointerFree(
1177 pStubMsg
->FullPtrXlatTables
, Pointer
);
1178 if (!pointer_needs_freeing
)
1182 if (attr
& RPC_FC_P_DEREF
) {
1183 Pointer
= *(unsigned char**)Pointer
;
1184 TRACE("deref => %p\n", Pointer
);
1187 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
1188 if (m
) m(pStubMsg
, Pointer
, desc
);
1190 /* we should check if the memory comes from NdrAllocate,
1191 * and deallocate only if so - checking if the pointer is between
1192 * BufferStart and BufferEnd will not always work since the buffer
1193 * may be reallocated when the server wants to marshal the reply */
1194 if (Pointer
>= (unsigned char *)pStubMsg
->RpcMsg
->Buffer
||
1195 Pointer
<= (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
1198 if (attr
& RPC_FC_P_ONSTACK
) {
1199 TRACE("not freeing stack ptr %p\n", Pointer
);
1202 TRACE("freeing %p\n", Pointer
);
1203 NdrFree(pStubMsg
, Pointer
);
1206 TRACE("not freeing %p\n", Pointer
);
1209 /***********************************************************************
1210 * EmbeddedPointerMarshall
1212 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1213 unsigned char *pMemory
,
1214 PFORMAT_STRING pFormat
)
1216 unsigned char *Mark
= pStubMsg
->BufferMark
;
1217 unsigned rep
, count
, stride
;
1219 unsigned char *saved_buffer
= NULL
;
1221 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1223 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1226 if (pStubMsg
->PointerBufferMark
)
1228 saved_buffer
= pStubMsg
->Buffer
;
1229 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1230 pStubMsg
->PointerBufferMark
= NULL
;
1233 while (pFormat
[0] != RPC_FC_END
) {
1234 switch (pFormat
[0]) {
1236 FIXME("unknown repeat type %d\n", pFormat
[0]);
1237 case RPC_FC_NO_REPEAT
:
1243 case RPC_FC_FIXED_REPEAT
:
1244 rep
= *(const WORD
*)&pFormat
[2];
1245 stride
= *(const WORD
*)&pFormat
[4];
1246 count
= *(const WORD
*)&pFormat
[8];
1249 case RPC_FC_VARIABLE_REPEAT
:
1250 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1251 stride
= *(const WORD
*)&pFormat
[2];
1252 count
= *(const WORD
*)&pFormat
[6];
1256 for (i
= 0; i
< rep
; i
++) {
1257 PFORMAT_STRING info
= pFormat
;
1258 unsigned char *membase
= pMemory
+ (i
* stride
);
1259 unsigned char *bufbase
= Mark
+ (i
* stride
);
1262 for (u
=0; u
<count
; u
++,info
+=8) {
1263 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1264 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1265 unsigned char *saved_memory
= pStubMsg
->Memory
;
1267 pStubMsg
->Memory
= pMemory
;
1268 PointerMarshall(pStubMsg
, bufptr
, *(unsigned char**)memptr
, info
+4);
1269 pStubMsg
->Memory
= saved_memory
;
1272 pFormat
+= 8 * count
;
1277 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1278 pStubMsg
->Buffer
= saved_buffer
;
1281 STD_OVERFLOW_CHECK(pStubMsg
);
1286 /***********************************************************************
1287 * EmbeddedPointerUnmarshall
1289 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1290 unsigned char *pDstMemoryPtrs
,
1291 unsigned char *pSrcMemoryPtrs
,
1292 PFORMAT_STRING pFormat
,
1293 unsigned char fMustAlloc
)
1295 unsigned char *Mark
= pStubMsg
->BufferMark
;
1296 unsigned rep
, count
, stride
;
1298 unsigned char *saved_buffer
= NULL
;
1300 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg
, pDstMemoryPtrs
, pSrcMemoryPtrs
, pFormat
, fMustAlloc
);
1302 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1305 if (pStubMsg
->PointerBufferMark
)
1307 saved_buffer
= pStubMsg
->Buffer
;
1308 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1309 pStubMsg
->PointerBufferMark
= NULL
;
1312 while (pFormat
[0] != RPC_FC_END
) {
1313 TRACE("pFormat[0] = 0x%x\n", pFormat
[0]);
1314 switch (pFormat
[0]) {
1316 FIXME("unknown repeat type %d\n", pFormat
[0]);
1317 case RPC_FC_NO_REPEAT
:
1323 case RPC_FC_FIXED_REPEAT
:
1324 rep
= *(const WORD
*)&pFormat
[2];
1325 stride
= *(const WORD
*)&pFormat
[4];
1326 count
= *(const WORD
*)&pFormat
[8];
1329 case RPC_FC_VARIABLE_REPEAT
:
1330 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1331 stride
= *(const WORD
*)&pFormat
[2];
1332 count
= *(const WORD
*)&pFormat
[6];
1336 for (i
= 0; i
< rep
; i
++) {
1337 PFORMAT_STRING info
= pFormat
;
1338 unsigned char *memdstbase
= pDstMemoryPtrs
+ (i
* stride
);
1339 unsigned char *memsrcbase
= pSrcMemoryPtrs
+ (i
* stride
);
1340 unsigned char *bufbase
= Mark
+ (i
* stride
);
1343 for (u
=0; u
<count
; u
++,info
+=8) {
1344 unsigned char **memdstptr
= (unsigned char **)(memdstbase
+ *(const SHORT
*)&info
[0]);
1345 unsigned char **memsrcptr
= (unsigned char **)(memsrcbase
+ *(const SHORT
*)&info
[0]);
1346 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1347 PointerUnmarshall(pStubMsg
, bufptr
, memdstptr
, *memsrcptr
, info
+4, fMustAlloc
);
1350 pFormat
+= 8 * count
;
1355 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1356 pStubMsg
->Buffer
= saved_buffer
;
1362 /***********************************************************************
1363 * EmbeddedPointerBufferSize
1365 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1366 unsigned char *pMemory
,
1367 PFORMAT_STRING pFormat
)
1369 unsigned rep
, count
, stride
;
1371 ULONG saved_buffer_length
= 0;
1373 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1375 if (pStubMsg
->IgnoreEmbeddedPointers
) return;
1377 if (*pFormat
!= RPC_FC_PP
) return;
1380 if (pStubMsg
->PointerLength
)
1382 saved_buffer_length
= pStubMsg
->BufferLength
;
1383 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
1384 pStubMsg
->PointerLength
= 0;
1387 while (pFormat
[0] != RPC_FC_END
) {
1388 switch (pFormat
[0]) {
1390 FIXME("unknown repeat type %d\n", pFormat
[0]);
1391 case RPC_FC_NO_REPEAT
:
1397 case RPC_FC_FIXED_REPEAT
:
1398 rep
= *(const WORD
*)&pFormat
[2];
1399 stride
= *(const WORD
*)&pFormat
[4];
1400 count
= *(const WORD
*)&pFormat
[8];
1403 case RPC_FC_VARIABLE_REPEAT
:
1404 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1405 stride
= *(const WORD
*)&pFormat
[2];
1406 count
= *(const WORD
*)&pFormat
[6];
1410 for (i
= 0; i
< rep
; i
++) {
1411 PFORMAT_STRING info
= pFormat
;
1412 unsigned char *membase
= pMemory
+ (i
* stride
);
1415 for (u
=0; u
<count
; u
++,info
+=8) {
1416 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1417 unsigned char *saved_memory
= pStubMsg
->Memory
;
1419 pStubMsg
->Memory
= pMemory
;
1420 PointerBufferSize(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1421 pStubMsg
->Memory
= saved_memory
;
1424 pFormat
+= 8 * count
;
1427 if (saved_buffer_length
)
1429 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
1430 pStubMsg
->BufferLength
= saved_buffer_length
;
1434 /***********************************************************************
1435 * EmbeddedPointerMemorySize [internal]
1437 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1438 PFORMAT_STRING pFormat
)
1440 unsigned char *Mark
= pStubMsg
->BufferMark
;
1441 unsigned rep
, count
, stride
;
1444 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1446 if (pStubMsg
->IgnoreEmbeddedPointers
) return 0;
1448 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1450 if (*pFormat
!= RPC_FC_PP
) return 0;
1453 while (pFormat
[0] != RPC_FC_END
) {
1454 switch (pFormat
[0]) {
1456 FIXME("unknown repeat type %d\n", pFormat
[0]);
1457 case RPC_FC_NO_REPEAT
:
1463 case RPC_FC_FIXED_REPEAT
:
1464 rep
= *(const WORD
*)&pFormat
[2];
1465 stride
= *(const WORD
*)&pFormat
[4];
1466 count
= *(const WORD
*)&pFormat
[8];
1469 case RPC_FC_VARIABLE_REPEAT
:
1470 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1471 stride
= *(const WORD
*)&pFormat
[2];
1472 count
= *(const WORD
*)&pFormat
[6];
1476 for (i
= 0; i
< rep
; i
++) {
1477 PFORMAT_STRING info
= pFormat
;
1478 unsigned char *bufbase
= Mark
+ (i
* stride
);
1480 for (u
=0; u
<count
; u
++,info
+=8) {
1481 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1482 PointerMemorySize(pStubMsg
, bufptr
, info
+4);
1485 pFormat
+= 8 * count
;
1491 /***********************************************************************
1492 * EmbeddedPointerFree [internal]
1494 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1495 unsigned char *pMemory
,
1496 PFORMAT_STRING pFormat
)
1498 unsigned rep
, count
, stride
;
1501 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1502 if (*pFormat
!= RPC_FC_PP
) return;
1505 while (pFormat
[0] != RPC_FC_END
) {
1506 switch (pFormat
[0]) {
1508 FIXME("unknown repeat type %d\n", pFormat
[0]);
1509 case RPC_FC_NO_REPEAT
:
1515 case RPC_FC_FIXED_REPEAT
:
1516 rep
= *(const WORD
*)&pFormat
[2];
1517 stride
= *(const WORD
*)&pFormat
[4];
1518 count
= *(const WORD
*)&pFormat
[8];
1521 case RPC_FC_VARIABLE_REPEAT
:
1522 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1523 stride
= *(const WORD
*)&pFormat
[2];
1524 count
= *(const WORD
*)&pFormat
[6];
1528 for (i
= 0; i
< rep
; i
++) {
1529 PFORMAT_STRING info
= pFormat
;
1530 unsigned char *membase
= pMemory
+ (i
* stride
);
1533 for (u
=0; u
<count
; u
++,info
+=8) {
1534 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1535 unsigned char *saved_memory
= pStubMsg
->Memory
;
1537 pStubMsg
->Memory
= pMemory
;
1538 PointerFree(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1539 pStubMsg
->Memory
= saved_memory
;
1542 pFormat
+= 8 * count
;
1546 /***********************************************************************
1547 * NdrPointerMarshall [RPCRT4.@]
1549 unsigned char * WINAPI
NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1550 unsigned char *pMemory
,
1551 PFORMAT_STRING pFormat
)
1553 unsigned char *Buffer
;
1555 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1557 /* incremement the buffer here instead of in PointerMarshall,
1558 * as that is used by embedded pointers which already handle the incrementing
1559 * the buffer, and shouldn't write any additional pointer data to the wire */
1560 if (*pFormat
!= RPC_FC_RP
)
1562 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1563 Buffer
= pStubMsg
->Buffer
;
1564 safe_buffer_increment(pStubMsg
, 4);
1567 Buffer
= pStubMsg
->Buffer
;
1569 PointerMarshall(pStubMsg
, Buffer
, pMemory
, pFormat
);
1574 /***********************************************************************
1575 * NdrPointerUnmarshall [RPCRT4.@]
1577 unsigned char * WINAPI
NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1578 unsigned char **ppMemory
,
1579 PFORMAT_STRING pFormat
,
1580 unsigned char fMustAlloc
)
1582 unsigned char *Buffer
;
1584 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1586 /* incremement the buffer here instead of in PointerUnmarshall,
1587 * as that is used by embedded pointers which already handle the incrementing
1588 * the buffer, and shouldn't read any additional pointer data from the
1590 if (*pFormat
!= RPC_FC_RP
)
1592 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1593 Buffer
= pStubMsg
->Buffer
;
1594 safe_buffer_increment(pStubMsg
, 4);
1597 Buffer
= pStubMsg
->Buffer
;
1599 PointerUnmarshall(pStubMsg
, Buffer
, ppMemory
, *ppMemory
, pFormat
, fMustAlloc
);
1604 /***********************************************************************
1605 * NdrPointerBufferSize [RPCRT4.@]
1607 void WINAPI
NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1608 unsigned char *pMemory
,
1609 PFORMAT_STRING pFormat
)
1611 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1613 /* incremement the buffer length here instead of in PointerBufferSize,
1614 * as that is used by embedded pointers which already handle the buffer
1615 * length, and shouldn't write anything more to the wire */
1616 if (*pFormat
!= RPC_FC_RP
)
1618 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
1619 safe_buffer_length_increment(pStubMsg
, 4);
1622 PointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1625 /***********************************************************************
1626 * NdrPointerMemorySize [RPCRT4.@]
1628 ULONG WINAPI
NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1629 PFORMAT_STRING pFormat
)
1631 /* unsigned size = *(LPWORD)(pFormat+2); */
1632 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1633 PointerMemorySize(pStubMsg
, pStubMsg
->Buffer
, pFormat
);
1637 /***********************************************************************
1638 * NdrPointerFree [RPCRT4.@]
1640 void WINAPI
NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1641 unsigned char *pMemory
,
1642 PFORMAT_STRING pFormat
)
1644 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1645 PointerFree(pStubMsg
, pMemory
, pFormat
);
1648 /***********************************************************************
1649 * NdrSimpleTypeMarshall [RPCRT4.@]
1651 void WINAPI
NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1652 unsigned char FormatChar
)
1654 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &FormatChar
);
1657 /***********************************************************************
1658 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1660 void WINAPI
NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1661 unsigned char FormatChar
)
1663 NdrBaseTypeUnmarshall(pStubMsg
, &pMemory
, &FormatChar
, 0);
1666 /***********************************************************************
1667 * NdrSimpleStructMarshall [RPCRT4.@]
1669 unsigned char * WINAPI
NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1670 unsigned char *pMemory
,
1671 PFORMAT_STRING pFormat
)
1673 unsigned size
= *(const WORD
*)(pFormat
+2);
1674 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1676 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1678 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1679 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
1681 if (pFormat
[0] != RPC_FC_STRUCT
)
1682 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
+4);
1687 /***********************************************************************
1688 * NdrSimpleStructUnmarshall [RPCRT4.@]
1690 unsigned char * WINAPI
NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1691 unsigned char **ppMemory
,
1692 PFORMAT_STRING pFormat
,
1693 unsigned char fMustAlloc
)
1695 unsigned size
= *(const WORD
*)(pFormat
+2);
1696 unsigned char *saved_buffer
;
1697 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1699 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1702 *ppMemory
= NdrAllocate(pStubMsg
, size
);
1705 if (!pStubMsg
->IsClient
&& !*ppMemory
)
1706 /* for servers, we just point straight into the RPC buffer */
1707 *ppMemory
= pStubMsg
->Buffer
;
1710 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1711 safe_buffer_increment(pStubMsg
, size
);
1712 if (pFormat
[0] == RPC_FC_PSTRUCT
)
1713 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
+4, fMustAlloc
);
1715 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
1716 if (*ppMemory
!= saved_buffer
)
1717 memcpy(*ppMemory
, saved_buffer
, size
);
1722 /***********************************************************************
1723 * NdrSimpleStructBufferSize [RPCRT4.@]
1725 void WINAPI
NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1726 unsigned char *pMemory
,
1727 PFORMAT_STRING pFormat
)
1729 unsigned size
= *(const WORD
*)(pFormat
+2);
1730 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1732 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
1734 safe_buffer_length_increment(pStubMsg
, size
);
1735 if (pFormat
[0] != RPC_FC_STRUCT
)
1736 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
+4);
1739 /***********************************************************************
1740 * NdrSimpleStructMemorySize [RPCRT4.@]
1742 ULONG WINAPI
NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1743 PFORMAT_STRING pFormat
)
1745 unsigned short size
= *(const WORD
*)(pFormat
+2);
1747 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1749 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1750 pStubMsg
->MemorySize
+= size
;
1751 safe_buffer_increment(pStubMsg
, size
);
1753 if (pFormat
[0] != RPC_FC_STRUCT
)
1754 EmbeddedPointerMemorySize(pStubMsg
, pFormat
+4);
1758 /***********************************************************************
1759 * NdrSimpleStructFree [RPCRT4.@]
1761 void WINAPI
NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
1762 unsigned char *pMemory
,
1763 PFORMAT_STRING pFormat
)
1765 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1766 if (pFormat
[0] != RPC_FC_STRUCT
)
1767 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
+4);
1771 static unsigned long EmbeddedComplexSize(const MIDL_STUB_MESSAGE
*pStubMsg
,
1772 PFORMAT_STRING pFormat
)
1776 case RPC_FC_PSTRUCT
:
1777 case RPC_FC_CSTRUCT
:
1778 case RPC_FC_BOGUS_STRUCT
:
1779 case RPC_FC_SMFARRAY
:
1780 case RPC_FC_SMVARRAY
:
1781 return *(const WORD
*)&pFormat
[2];
1782 case RPC_FC_USER_MARSHAL
:
1783 return *(const WORD
*)&pFormat
[4];
1784 case RPC_FC_NON_ENCAPSULATED_UNION
:
1786 if (pStubMsg
->fHasNewCorrDesc
)
1791 pFormat
+= *(const SHORT
*)pFormat
;
1792 return *(const SHORT
*)pFormat
;
1794 return sizeof(void *);
1796 FIXME("unhandled embedded type %02x\n", *pFormat
);
1802 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1803 PFORMAT_STRING pFormat
)
1805 NDR_MEMORYSIZE m
= NdrMemorySizer
[*pFormat
& NDR_TABLE_MASK
];
1809 FIXME("no memorysizer for data type=%02x\n", *pFormat
);
1813 return m(pStubMsg
, pFormat
);
1817 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1818 unsigned char *pMemory
,
1819 PFORMAT_STRING pFormat
,
1820 PFORMAT_STRING pPointer
)
1822 PFORMAT_STRING desc
;
1826 while (*pFormat
!= RPC_FC_END
) {
1832 TRACE("byte=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
1833 safe_copy_to_buffer(pStubMsg
, pMemory
, 1);
1839 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
1840 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
1846 TRACE("long=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
1847 safe_copy_to_buffer(pStubMsg
, pMemory
, 4);
1851 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
1852 safe_copy_to_buffer(pStubMsg
, pMemory
, 8);
1855 case RPC_FC_POINTER
:
1857 unsigned char *saved_buffer
;
1858 int pointer_buffer_mark_set
= 0;
1859 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
1860 saved_buffer
= pStubMsg
->Buffer
;
1861 if (pStubMsg
->PointerBufferMark
)
1863 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1864 pStubMsg
->PointerBufferMark
= NULL
;
1865 pointer_buffer_mark_set
= 1;
1868 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
1869 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char**)pMemory
, pPointer
);
1870 if (pointer_buffer_mark_set
)
1872 STD_OVERFLOW_CHECK(pStubMsg
);
1873 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1874 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
1876 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
1877 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
1878 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1880 pStubMsg
->Buffer
= saved_buffer
+ 4;
1886 case RPC_FC_ALIGNM4
:
1887 ALIGN_POINTER(pMemory
, 4);
1889 case RPC_FC_ALIGNM8
:
1890 ALIGN_POINTER(pMemory
, 8);
1892 case RPC_FC_STRUCTPAD1
:
1893 case RPC_FC_STRUCTPAD2
:
1894 case RPC_FC_STRUCTPAD3
:
1895 case RPC_FC_STRUCTPAD4
:
1896 case RPC_FC_STRUCTPAD5
:
1897 case RPC_FC_STRUCTPAD6
:
1898 case RPC_FC_STRUCTPAD7
:
1899 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
1901 case RPC_FC_EMBEDDED_COMPLEX
:
1902 pMemory
+= pFormat
[1];
1904 desc
= pFormat
+ *(const SHORT
*)pFormat
;
1905 size
= EmbeddedComplexSize(pStubMsg
, desc
);
1906 TRACE("embedded complex (size=%ld) <= %p\n", size
, pMemory
);
1907 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
1910 /* for some reason interface pointers aren't generated as
1911 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
1912 * they still need the derefencing treatment that pointers are
1914 if (*desc
== RPC_FC_IP
)
1915 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
1917 m(pStubMsg
, pMemory
, desc
);
1919 else FIXME("no marshaller for embedded type %02x\n", *desc
);
1926 FIXME("unhandled format 0x%02x\n", *pFormat
);
1934 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1935 unsigned char *pMemory
,
1936 PFORMAT_STRING pFormat
,
1937 PFORMAT_STRING pPointer
)
1939 PFORMAT_STRING desc
;
1943 while (*pFormat
!= RPC_FC_END
) {
1949 safe_copy_from_buffer(pStubMsg
, pMemory
, 1);
1950 TRACE("byte=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
1956 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
1957 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
1963 safe_copy_from_buffer(pStubMsg
, pMemory
, 4);
1964 TRACE("long=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
1968 safe_copy_from_buffer(pStubMsg
, pMemory
, 8);
1969 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
1972 case RPC_FC_POINTER
:
1974 unsigned char *saved_buffer
;
1975 int pointer_buffer_mark_set
= 0;
1976 TRACE("pointer => %p\n", pMemory
);
1977 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1978 saved_buffer
= pStubMsg
->Buffer
;
1979 if (pStubMsg
->PointerBufferMark
)
1981 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1982 pStubMsg
->PointerBufferMark
= NULL
;
1983 pointer_buffer_mark_set
= 1;
1986 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
1988 PointerUnmarshall(pStubMsg
, saved_buffer
, (unsigned char**)pMemory
, *(unsigned char**)pMemory
, pPointer
, TRUE
);
1989 if (pointer_buffer_mark_set
)
1991 STD_OVERFLOW_CHECK(pStubMsg
);
1992 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1993 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
1995 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
1996 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
1997 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1999 pStubMsg
->Buffer
= saved_buffer
+ 4;
2005 case RPC_FC_ALIGNM4
:
2006 ALIGN_POINTER(pMemory
, 4);
2008 case RPC_FC_ALIGNM8
:
2009 ALIGN_POINTER(pMemory
, 8);
2011 case RPC_FC_STRUCTPAD1
:
2012 case RPC_FC_STRUCTPAD2
:
2013 case RPC_FC_STRUCTPAD3
:
2014 case RPC_FC_STRUCTPAD4
:
2015 case RPC_FC_STRUCTPAD5
:
2016 case RPC_FC_STRUCTPAD6
:
2017 case RPC_FC_STRUCTPAD7
:
2018 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2020 case RPC_FC_EMBEDDED_COMPLEX
:
2021 pMemory
+= pFormat
[1];
2023 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2024 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2025 TRACE("embedded complex (size=%ld) => %p\n", size
, pMemory
);
2026 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
2027 memset(pMemory
, 0, size
); /* just in case */
2030 /* for some reason interface pointers aren't generated as
2031 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2032 * they still need the derefencing treatment that pointers are
2034 if (*desc
== RPC_FC_IP
)
2035 m(pStubMsg
, (unsigned char **)pMemory
, desc
, FALSE
);
2037 m(pStubMsg
, &pMemory
, desc
, FALSE
);
2039 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
2046 FIXME("unhandled format %d\n", *pFormat
);
2054 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2055 unsigned char *pMemory
,
2056 PFORMAT_STRING pFormat
,
2057 PFORMAT_STRING pPointer
)
2059 PFORMAT_STRING desc
;
2063 while (*pFormat
!= RPC_FC_END
) {
2069 safe_buffer_length_increment(pStubMsg
, 1);
2075 safe_buffer_length_increment(pStubMsg
, 2);
2081 safe_buffer_length_increment(pStubMsg
, 4);
2085 safe_buffer_length_increment(pStubMsg
, 8);
2088 case RPC_FC_POINTER
:
2089 if (!pStubMsg
->IgnoreEmbeddedPointers
)
2091 int saved_buffer_length
= pStubMsg
->BufferLength
;
2092 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2093 pStubMsg
->PointerLength
= 0;
2094 if(!pStubMsg
->BufferLength
)
2095 ERR("BufferLength == 0??\n");
2096 PointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
2097 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2098 pStubMsg
->BufferLength
= saved_buffer_length
;
2100 safe_buffer_length_increment(pStubMsg
, 4);
2104 case RPC_FC_ALIGNM4
:
2105 ALIGN_POINTER(pMemory
, 4);
2107 case RPC_FC_ALIGNM8
:
2108 ALIGN_POINTER(pMemory
, 8);
2110 case RPC_FC_STRUCTPAD1
:
2111 case RPC_FC_STRUCTPAD2
:
2112 case RPC_FC_STRUCTPAD3
:
2113 case RPC_FC_STRUCTPAD4
:
2114 case RPC_FC_STRUCTPAD5
:
2115 case RPC_FC_STRUCTPAD6
:
2116 case RPC_FC_STRUCTPAD7
:
2117 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2119 case RPC_FC_EMBEDDED_COMPLEX
:
2120 pMemory
+= pFormat
[1];
2122 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2123 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2124 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
2127 /* for some reason interface pointers aren't generated as
2128 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2129 * they still need the derefencing treatment that pointers are
2131 if (*desc
== RPC_FC_IP
)
2132 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2134 m(pStubMsg
, pMemory
, desc
);
2136 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
2143 FIXME("unhandled format 0x%02x\n", *pFormat
);
2151 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
2152 unsigned char *pMemory
,
2153 PFORMAT_STRING pFormat
,
2154 PFORMAT_STRING pPointer
)
2156 PFORMAT_STRING desc
;
2160 while (*pFormat
!= RPC_FC_END
) {
2181 case RPC_FC_POINTER
:
2182 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
2186 case RPC_FC_ALIGNM4
:
2187 ALIGN_POINTER(pMemory
, 4);
2189 case RPC_FC_ALIGNM8
:
2190 ALIGN_POINTER(pMemory
, 8);
2192 case RPC_FC_STRUCTPAD1
:
2193 case RPC_FC_STRUCTPAD2
:
2194 case RPC_FC_STRUCTPAD3
:
2195 case RPC_FC_STRUCTPAD4
:
2196 case RPC_FC_STRUCTPAD5
:
2197 case RPC_FC_STRUCTPAD6
:
2198 case RPC_FC_STRUCTPAD7
:
2199 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2201 case RPC_FC_EMBEDDED_COMPLEX
:
2202 pMemory
+= pFormat
[1];
2204 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2205 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2206 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
2209 /* for some reason interface pointers aren't generated as
2210 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2211 * they still need the derefencing treatment that pointers are
2213 if (*desc
== RPC_FC_IP
)
2214 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2216 m(pStubMsg
, pMemory
, desc
);
2218 else FIXME("no freer for embedded type %02x\n", *desc
);
2225 FIXME("unhandled format 0x%02x\n", *pFormat
);
2233 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2234 PFORMAT_STRING pFormat
)
2236 PFORMAT_STRING desc
;
2237 unsigned long size
= 0;
2239 while (*pFormat
!= RPC_FC_END
) {
2246 safe_buffer_increment(pStubMsg
, 1);
2252 safe_buffer_increment(pStubMsg
, 2);
2258 safe_buffer_increment(pStubMsg
, 4);
2262 safe_buffer_increment(pStubMsg
, 8);
2264 case RPC_FC_POINTER
:
2266 safe_buffer_increment(pStubMsg
, 4);
2267 if (!pStubMsg
->IgnoreEmbeddedPointers
)
2268 FIXME("embedded pointers\n");
2270 case RPC_FC_ALIGNM4
:
2271 ALIGN_LENGTH(size
, 4);
2272 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2274 case RPC_FC_ALIGNM8
:
2275 ALIGN_LENGTH(size
, 8);
2276 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
2278 case RPC_FC_STRUCTPAD1
:
2279 case RPC_FC_STRUCTPAD2
:
2280 case RPC_FC_STRUCTPAD3
:
2281 case RPC_FC_STRUCTPAD4
:
2282 case RPC_FC_STRUCTPAD5
:
2283 case RPC_FC_STRUCTPAD6
:
2284 case RPC_FC_STRUCTPAD7
:
2285 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2287 case RPC_FC_EMBEDDED_COMPLEX
:
2290 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2291 size
+= EmbeddedComplexMemorySize(pStubMsg
, desc
);
2297 FIXME("unhandled format 0x%02x\n", *pFormat
);
2305 /***********************************************************************
2306 * NdrComplexStructMarshall [RPCRT4.@]
2308 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2309 unsigned char *pMemory
,
2310 PFORMAT_STRING pFormat
)
2312 PFORMAT_STRING conf_array
= NULL
;
2313 PFORMAT_STRING pointer_desc
= NULL
;
2314 unsigned char *OldMemory
= pStubMsg
->Memory
;
2315 int pointer_buffer_mark_set
= 0;
2317 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2319 if (!pStubMsg
->PointerBufferMark
)
2321 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2322 /* save buffer length */
2323 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2325 /* get the buffer pointer after complex array data, but before
2327 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- pStubMsg
->BufferStart
;
2328 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2329 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
2330 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2332 /* save it for use by embedded pointer code later */
2333 pStubMsg
->PointerBufferMark
= pStubMsg
->BufferStart
+ pStubMsg
->BufferLength
;
2334 TRACE("difference = 0x%x\n", pStubMsg
->PointerBufferMark
- pStubMsg
->Buffer
);
2335 pointer_buffer_mark_set
= 1;
2337 /* restore the original buffer length */
2338 pStubMsg
->BufferLength
= saved_buffer_length
;
2341 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2344 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2346 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2349 pStubMsg
->Memory
= pMemory
;
2351 ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2354 NdrConformantArrayMarshall(pStubMsg
, pMemory
, conf_array
);
2356 pStubMsg
->Memory
= OldMemory
;
2358 if (pointer_buffer_mark_set
)
2360 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2361 pStubMsg
->PointerBufferMark
= NULL
;
2364 STD_OVERFLOW_CHECK(pStubMsg
);
2369 /***********************************************************************
2370 * NdrComplexStructUnmarshall [RPCRT4.@]
2372 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2373 unsigned char **ppMemory
,
2374 PFORMAT_STRING pFormat
,
2375 unsigned char fMustAlloc
)
2377 unsigned size
= *(const WORD
*)(pFormat
+2);
2378 PFORMAT_STRING conf_array
= NULL
;
2379 PFORMAT_STRING pointer_desc
= NULL
;
2380 unsigned char *pMemory
;
2381 int pointer_buffer_mark_set
= 0;
2383 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2385 if (!pStubMsg
->PointerBufferMark
)
2387 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2388 /* save buffer pointer */
2389 unsigned char *saved_buffer
= pStubMsg
->Buffer
;
2391 /* get the buffer pointer after complex array data, but before
2393 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2394 NdrComplexStructMemorySize(pStubMsg
, pFormat
);
2395 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2397 /* save it for use by embedded pointer code later */
2398 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2399 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->PointerBufferMark
- saved_buffer
));
2400 pointer_buffer_mark_set
= 1;
2402 /* restore the original buffer */
2403 pStubMsg
->Buffer
= saved_buffer
;
2406 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2408 if (fMustAlloc
|| !*ppMemory
)
2410 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2411 memset(*ppMemory
, 0, size
);
2415 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2417 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2420 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
);
2423 NdrConformantArrayUnmarshall(pStubMsg
, &pMemory
, conf_array
, fMustAlloc
);
2425 if (pointer_buffer_mark_set
)
2427 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2428 pStubMsg
->PointerBufferMark
= NULL
;
2434 /***********************************************************************
2435 * NdrComplexStructBufferSize [RPCRT4.@]
2437 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2438 unsigned char *pMemory
,
2439 PFORMAT_STRING pFormat
)
2441 PFORMAT_STRING conf_array
= NULL
;
2442 PFORMAT_STRING pointer_desc
= NULL
;
2443 unsigned char *OldMemory
= pStubMsg
->Memory
;
2444 int pointer_length_set
= 0;
2446 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2448 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
2450 if(!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
2452 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2453 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2455 /* get the buffer length after complex struct data, but before
2457 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2458 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
2459 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2461 /* save it for use by embedded pointer code later */
2462 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2463 pointer_length_set
= 1;
2464 TRACE("difference = 0x%lx\n", pStubMsg
->PointerLength
- saved_buffer_length
);
2466 /* restore the original buffer length */
2467 pStubMsg
->BufferLength
= saved_buffer_length
;
2471 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2473 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2476 pStubMsg
->Memory
= pMemory
;
2478 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2481 NdrConformantArrayBufferSize(pStubMsg
, pMemory
, conf_array
);
2483 pStubMsg
->Memory
= OldMemory
;
2485 if(pointer_length_set
)
2487 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2488 pStubMsg
->PointerLength
= 0;
2493 /***********************************************************************
2494 * NdrComplexStructMemorySize [RPCRT4.@]
2496 ULONG WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2497 PFORMAT_STRING pFormat
)
2499 unsigned size
= *(const WORD
*)(pFormat
+2);
2500 PFORMAT_STRING conf_array
= NULL
;
2501 PFORMAT_STRING pointer_desc
= NULL
;
2503 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2505 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2508 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2510 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2513 ComplexStructMemorySize(pStubMsg
, pFormat
);
2516 NdrConformantArrayMemorySize(pStubMsg
, conf_array
);
2521 /***********************************************************************
2522 * NdrComplexStructFree [RPCRT4.@]
2524 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
2525 unsigned char *pMemory
,
2526 PFORMAT_STRING pFormat
)
2528 PFORMAT_STRING conf_array
= NULL
;
2529 PFORMAT_STRING pointer_desc
= NULL
;
2530 unsigned char *OldMemory
= pStubMsg
->Memory
;
2532 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2535 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2537 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2540 pStubMsg
->Memory
= pMemory
;
2542 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2545 NdrConformantArrayFree(pStubMsg
, pMemory
, conf_array
);
2547 pStubMsg
->Memory
= OldMemory
;
2550 /***********************************************************************
2551 * NdrConformantArrayMarshall [RPCRT4.@]
2553 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2554 unsigned char *pMemory
,
2555 PFORMAT_STRING pFormat
)
2557 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
2558 unsigned char alignment
= pFormat
[1] + 1;
2560 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2561 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2563 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2565 WriteConformance(pStubMsg
);
2567 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2569 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2570 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2571 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
2573 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2578 /***********************************************************************
2579 * NdrConformantArrayUnmarshall [RPCRT4.@]
2581 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2582 unsigned char **ppMemory
,
2583 PFORMAT_STRING pFormat
,
2584 unsigned char fMustAlloc
)
2586 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
2587 unsigned char alignment
= pFormat
[1] + 1;
2588 unsigned char *saved_buffer
;
2590 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2591 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2593 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2595 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2596 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2599 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2602 if (!pStubMsg
->IsClient
&& !*ppMemory
)
2603 /* for servers, we just point straight into the RPC buffer */
2604 *ppMemory
= pStubMsg
->Buffer
;
2607 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2608 safe_buffer_increment(pStubMsg
, size
);
2609 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
2611 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
2612 if (*ppMemory
!= saved_buffer
)
2613 memcpy(*ppMemory
, saved_buffer
, size
);
2618 /***********************************************************************
2619 * NdrConformantArrayBufferSize [RPCRT4.@]
2621 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2622 unsigned char *pMemory
,
2623 PFORMAT_STRING pFormat
)
2625 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
2626 unsigned char alignment
= pFormat
[1] + 1;
2628 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2629 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2631 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2633 SizeConformance(pStubMsg
);
2635 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
2637 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2638 /* conformance value plus array */
2639 safe_buffer_length_increment(pStubMsg
, size
);
2641 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
2644 /***********************************************************************
2645 * NdrConformantArrayMemorySize [RPCRT4.@]
2647 ULONG WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2648 PFORMAT_STRING pFormat
)
2650 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
2651 unsigned char alignment
= pFormat
[1] + 1;
2653 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2654 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2656 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2657 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2658 pStubMsg
->MemorySize
+= size
;
2660 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2661 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2662 safe_buffer_increment(pStubMsg
, size
);
2664 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2666 return pStubMsg
->MemorySize
;
2669 /***********************************************************************
2670 * NdrConformantArrayFree [RPCRT4.@]
2672 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
2673 unsigned char *pMemory
,
2674 PFORMAT_STRING pFormat
)
2676 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2677 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2679 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2681 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2685 /***********************************************************************
2686 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2688 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2689 unsigned char* pMemory
,
2690 PFORMAT_STRING pFormat
)
2693 unsigned char alignment
= pFormat
[1] + 1;
2694 DWORD esize
= *(const WORD
*)(pFormat
+2);
2696 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
2698 if (pFormat
[0] != RPC_FC_CVARRAY
)
2700 ERR("invalid format type %x\n", pFormat
[0]);
2701 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2705 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2706 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2708 WriteConformance(pStubMsg
);
2709 WriteVariance(pStubMsg
);
2711 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2713 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2715 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2716 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
2718 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2724 /***********************************************************************
2725 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2727 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2728 unsigned char** ppMemory
,
2729 PFORMAT_STRING pFormat
,
2730 unsigned char fMustAlloc
)
2732 ULONG bufsize
, memsize
;
2733 unsigned char alignment
= pFormat
[1] + 1;
2734 DWORD esize
= *(const WORD
*)(pFormat
+2);
2736 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2738 if (pFormat
[0] != RPC_FC_CVARRAY
)
2740 ERR("invalid format type %x\n", pFormat
[0]);
2741 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2745 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2746 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2748 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2750 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2751 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2753 if (!*ppMemory
|| fMustAlloc
)
2754 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2755 safe_copy_from_buffer(pStubMsg
, *ppMemory
+ pStubMsg
->Offset
, bufsize
);
2757 EmbeddedPointerUnmarshall(pStubMsg
, *ppMemory
, *ppMemory
, pFormat
, TRUE
/* FIXME */);
2763 /***********************************************************************
2764 * NdrConformantVaryingArrayFree [RPCRT4.@]
2766 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
2767 unsigned char* pMemory
,
2768 PFORMAT_STRING pFormat
)
2770 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2772 if (pFormat
[0] != RPC_FC_CVARRAY
)
2774 ERR("invalid format type %x\n", pFormat
[0]);
2775 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2779 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2780 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2782 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2786 /***********************************************************************
2787 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2789 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
2790 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
2792 unsigned char alignment
= pFormat
[1] + 1;
2793 DWORD esize
= *(const WORD
*)(pFormat
+2);
2795 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
2797 if (pFormat
[0] != RPC_FC_CVARRAY
)
2799 ERR("invalid format type %x\n", pFormat
[0]);
2800 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2805 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2806 /* compute length */
2807 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2809 SizeConformance(pStubMsg
);
2810 SizeVariance(pStubMsg
);
2812 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
2814 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
2816 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
2820 /***********************************************************************
2821 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2823 ULONG WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
2824 PFORMAT_STRING pFormat
)
2831 /***********************************************************************
2832 * NdrComplexArrayMarshall [RPCRT4.@]
2834 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2835 unsigned char *pMemory
,
2836 PFORMAT_STRING pFormat
)
2838 ULONG i
, count
, def
;
2839 BOOL variance_present
;
2840 unsigned char alignment
;
2841 int pointer_buffer_mark_set
= 0;
2843 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2845 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
2847 ERR("invalid format type %x\n", pFormat
[0]);
2848 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2852 alignment
= pFormat
[1] + 1;
2854 if (!pStubMsg
->PointerBufferMark
)
2856 /* save buffer fields that may be changed by buffer sizer functions
2857 * and that may be needed later on */
2858 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2859 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2860 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
2861 unsigned long saved_offset
= pStubMsg
->Offset
;
2862 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
2864 /* get the buffer pointer after complex array data, but before
2866 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- pStubMsg
->BufferStart
;
2867 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2868 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
2869 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2871 /* save it for use by embedded pointer code later */
2872 pStubMsg
->PointerBufferMark
= pStubMsg
->BufferStart
+ pStubMsg
->BufferLength
;
2873 TRACE("difference = 0x%x\n", pStubMsg
->Buffer
- pStubMsg
->BufferStart
);
2874 pointer_buffer_mark_set
= 1;
2876 /* restore fields */
2877 pStubMsg
->ActualCount
= saved_actual_count
;
2878 pStubMsg
->Offset
= saved_offset
;
2879 pStubMsg
->MaxCount
= saved_max_count
;
2880 pStubMsg
->BufferLength
= saved_buffer_length
;
2883 def
= *(const WORD
*)&pFormat
[2];
2886 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
2887 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
2889 variance_present
= IsConformanceOrVariancePresent(pFormat
);
2890 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
2891 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
2893 WriteConformance(pStubMsg
);
2894 if (variance_present
)
2895 WriteVariance(pStubMsg
);
2897 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2899 count
= pStubMsg
->ActualCount
;
2900 for (i
= 0; i
< count
; i
++)
2901 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
2903 STD_OVERFLOW_CHECK(pStubMsg
);
2905 if (pointer_buffer_mark_set
)
2907 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2908 pStubMsg
->PointerBufferMark
= NULL
;
2914 /***********************************************************************
2915 * NdrComplexArrayUnmarshall [RPCRT4.@]
2917 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2918 unsigned char **ppMemory
,
2919 PFORMAT_STRING pFormat
,
2920 unsigned char fMustAlloc
)
2922 ULONG i
, count
, size
;
2923 unsigned char alignment
;
2924 unsigned char *pMemory
;
2925 unsigned char *saved_buffer
;
2926 int pointer_buffer_mark_set
= 0;
2927 int saved_ignore_embedded
;
2929 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2931 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
2933 ERR("invalid format type %x\n", pFormat
[0]);
2934 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2938 alignment
= pFormat
[1] + 1;
2940 saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2941 /* save buffer pointer */
2942 saved_buffer
= pStubMsg
->Buffer
;
2943 /* get the buffer pointer after complex array data, but before
2945 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2946 pStubMsg
->MemorySize
= 0;
2947 NdrComplexArrayMemorySize(pStubMsg
, pFormat
);
2948 size
= pStubMsg
->MemorySize
;
2949 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2951 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->Buffer
- saved_buffer
));
2952 if (!pStubMsg
->PointerBufferMark
)
2954 /* save it for use by embedded pointer code later */
2955 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2956 pointer_buffer_mark_set
= 1;
2958 /* restore the original buffer */
2959 pStubMsg
->Buffer
= saved_buffer
;
2963 pFormat
= ReadConformance(pStubMsg
, pFormat
);
2964 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2966 if (fMustAlloc
|| !*ppMemory
)
2968 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2969 memset(*ppMemory
, 0, size
);
2972 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2974 pMemory
= *ppMemory
;
2975 count
= pStubMsg
->ActualCount
;
2976 for (i
= 0; i
< count
; i
++)
2977 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
2979 if (pointer_buffer_mark_set
)
2981 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2982 pStubMsg
->PointerBufferMark
= NULL
;
2988 /***********************************************************************
2989 * NdrComplexArrayBufferSize [RPCRT4.@]
2991 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2992 unsigned char *pMemory
,
2993 PFORMAT_STRING pFormat
)
2995 ULONG i
, count
, def
;
2996 unsigned char alignment
;
2997 BOOL variance_present
;
2998 int pointer_length_set
= 0;
3000 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3002 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3004 ERR("invalid format type %x\n", pFormat
[0]);
3005 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3009 alignment
= pFormat
[1] + 1;
3011 if (!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
3013 /* save buffer fields that may be changed by buffer sizer functions
3014 * and that may be needed later on */
3015 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3016 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
3017 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
3018 unsigned long saved_offset
= pStubMsg
->Offset
;
3019 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
3021 /* get the buffer pointer after complex array data, but before
3023 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3024 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
3025 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3027 /* save it for use by embedded pointer code later */
3028 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3029 pointer_length_set
= 1;
3031 /* restore fields */
3032 pStubMsg
->ActualCount
= saved_actual_count
;
3033 pStubMsg
->Offset
= saved_offset
;
3034 pStubMsg
->MaxCount
= saved_max_count
;
3035 pStubMsg
->BufferLength
= saved_buffer_length
;
3037 def
= *(const WORD
*)&pFormat
[2];
3040 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3041 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3042 SizeConformance(pStubMsg
);
3044 variance_present
= IsConformanceOrVariancePresent(pFormat
);
3045 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3046 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3048 if (variance_present
)
3049 SizeVariance(pStubMsg
);
3051 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
3053 count
= pStubMsg
->ActualCount
;
3054 for (i
= 0; i
< count
; i
++)
3055 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
3057 if(pointer_length_set
)
3059 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3060 pStubMsg
->PointerLength
= 0;
3064 /***********************************************************************
3065 * NdrComplexArrayMemorySize [RPCRT4.@]
3067 ULONG WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3068 PFORMAT_STRING pFormat
)
3070 ULONG i
, count
, esize
, SavedMemorySize
, MemorySize
;
3071 unsigned char alignment
;
3072 unsigned char *Buffer
;
3074 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3076 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3078 ERR("invalid format type %x\n", pFormat
[0]);
3079 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3083 alignment
= pFormat
[1] + 1;
3087 pFormat
= ReadConformance(pStubMsg
, pFormat
);
3088 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3090 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3092 SavedMemorySize
= pStubMsg
->MemorySize
;
3094 Buffer
= pStubMsg
->Buffer
;
3095 pStubMsg
->MemorySize
= 0;
3096 esize
= ComplexStructMemorySize(pStubMsg
, pFormat
);
3097 pStubMsg
->Buffer
= Buffer
;
3099 MemorySize
= safe_multiply(pStubMsg
->MaxCount
, esize
);
3101 count
= pStubMsg
->ActualCount
;
3102 for (i
= 0; i
< count
; i
++)
3103 ComplexStructMemorySize(pStubMsg
, pFormat
);
3105 pStubMsg
->MemorySize
= SavedMemorySize
;
3107 pStubMsg
->MemorySize
+= MemorySize
;
3111 /***********************************************************************
3112 * NdrComplexArrayFree [RPCRT4.@]
3114 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3115 unsigned char *pMemory
,
3116 PFORMAT_STRING pFormat
)
3118 ULONG i
, count
, def
;
3120 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3122 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3124 ERR("invalid format type %x\n", pFormat
[0]);
3125 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3129 def
= *(const WORD
*)&pFormat
[2];
3132 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3133 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3135 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3136 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3138 count
= pStubMsg
->ActualCount
;
3139 for (i
= 0; i
< count
; i
++)
3140 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
3143 static ULONG
UserMarshalFlags(const MIDL_STUB_MESSAGE
*pStubMsg
)
3145 return MAKELONG(pStubMsg
->dwDestContext
,
3146 pStubMsg
->RpcMsg
->DataRepresentation
);
3149 #define USER_MARSHAL_PTR_PREFIX \
3150 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3151 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3153 /***********************************************************************
3154 * NdrUserMarshalMarshall [RPCRT4.@]
3156 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3157 unsigned char *pMemory
,
3158 PFORMAT_STRING pFormat
)
3160 unsigned flags
= pFormat
[1];
3161 unsigned index
= *(const WORD
*)&pFormat
[2];
3162 unsigned char *saved_buffer
= NULL
;
3163 ULONG uflag
= UserMarshalFlags(pStubMsg
);
3164 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3165 TRACE("index=%d\n", index
);
3167 if (flags
& USER_MARSHAL_POINTER
)
3169 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3170 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, USER_MARSHAL_PTR_PREFIX
);
3171 pStubMsg
->Buffer
+= 4;
3172 if (pStubMsg
->PointerBufferMark
)
3174 saved_buffer
= pStubMsg
->Buffer
;
3175 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3176 pStubMsg
->PointerBufferMark
= NULL
;
3178 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3181 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3184 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
3185 &uflag
, pStubMsg
->Buffer
, pMemory
);
3189 STD_OVERFLOW_CHECK(pStubMsg
);
3190 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3191 pStubMsg
->Buffer
= saved_buffer
;
3194 STD_OVERFLOW_CHECK(pStubMsg
);
3199 /***********************************************************************
3200 * NdrUserMarshalUnmarshall [RPCRT4.@]
3202 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3203 unsigned char **ppMemory
,
3204 PFORMAT_STRING pFormat
,
3205 unsigned char fMustAlloc
)
3207 unsigned flags
= pFormat
[1];
3208 unsigned index
= *(const WORD
*)&pFormat
[2];
3209 DWORD memsize
= *(const WORD
*)&pFormat
[4];
3210 unsigned char *saved_buffer
= NULL
;
3211 ULONG uflag
= UserMarshalFlags(pStubMsg
);
3212 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3213 TRACE("index=%d\n", index
);
3215 if (flags
& USER_MARSHAL_POINTER
)
3217 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3218 /* skip pointer prefix */
3219 pStubMsg
->Buffer
+= 4;
3220 if (pStubMsg
->PointerBufferMark
)
3222 saved_buffer
= pStubMsg
->Buffer
;
3223 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3224 pStubMsg
->PointerBufferMark
= NULL
;
3226 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3229 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3231 if (fMustAlloc
|| !*ppMemory
)
3232 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
3235 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
3236 &uflag
, pStubMsg
->Buffer
, *ppMemory
);
3240 STD_OVERFLOW_CHECK(pStubMsg
);
3241 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3242 pStubMsg
->Buffer
= saved_buffer
;
3248 /***********************************************************************
3249 * NdrUserMarshalBufferSize [RPCRT4.@]
3251 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3252 unsigned char *pMemory
,
3253 PFORMAT_STRING pFormat
)
3255 unsigned flags
= pFormat
[1];
3256 unsigned index
= *(const WORD
*)&pFormat
[2];
3257 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
3258 ULONG uflag
= UserMarshalFlags(pStubMsg
);
3259 unsigned long saved_buffer_length
= 0;
3260 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3261 TRACE("index=%d\n", index
);
3263 if (flags
& USER_MARSHAL_POINTER
)
3265 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
3266 /* skip pointer prefix */
3267 safe_buffer_length_increment(pStubMsg
, 4);
3268 if (pStubMsg
->IgnoreEmbeddedPointers
)
3270 if (pStubMsg
->PointerLength
)
3272 saved_buffer_length
= pStubMsg
->BufferLength
;
3273 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3274 pStubMsg
->PointerLength
= 0;
3276 ALIGN_LENGTH(pStubMsg
->BufferLength
, 8);
3279 ALIGN_LENGTH(pStubMsg
->BufferLength
, (flags
& 0xf) + 1);
3282 TRACE("size=%d\n", bufsize
);
3283 safe_buffer_length_increment(pStubMsg
, bufsize
);
3286 pStubMsg
->BufferLength
=
3287 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
3288 &uflag
, pStubMsg
->BufferLength
, pMemory
);
3290 if (saved_buffer_length
)
3292 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3293 pStubMsg
->BufferLength
= saved_buffer_length
;
3298 /***********************************************************************
3299 * NdrUserMarshalMemorySize [RPCRT4.@]
3301 ULONG WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3302 PFORMAT_STRING pFormat
)
3304 unsigned flags
= pFormat
[1];
3305 unsigned index
= *(const WORD
*)&pFormat
[2];
3306 DWORD memsize
= *(const WORD
*)&pFormat
[4];
3307 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
3309 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3310 TRACE("index=%d\n", index
);
3312 pStubMsg
->MemorySize
+= memsize
;
3314 if (flags
& USER_MARSHAL_POINTER
)
3316 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3317 /* skip pointer prefix */
3318 pStubMsg
->Buffer
+= 4;
3319 if (pStubMsg
->IgnoreEmbeddedPointers
)
3320 return pStubMsg
->MemorySize
;
3321 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3324 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3327 FIXME("not implemented for varying buffer size\n");
3329 pStubMsg
->Buffer
+= bufsize
;
3331 return pStubMsg
->MemorySize
;
3334 /***********************************************************************
3335 * NdrUserMarshalFree [RPCRT4.@]
3337 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
3338 unsigned char *pMemory
,
3339 PFORMAT_STRING pFormat
)
3341 /* unsigned flags = pFormat[1]; */
3342 unsigned index
= *(const WORD
*)&pFormat
[2];
3343 ULONG uflag
= UserMarshalFlags(pStubMsg
);
3344 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3345 TRACE("index=%d\n", index
);
3347 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
3351 /***********************************************************************
3352 * NdrClearOutParameters [RPCRT4.@]
3354 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
3355 PFORMAT_STRING pFormat
,
3358 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
3361 /***********************************************************************
3362 * NdrConvert [RPCRT4.@]
3364 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
3366 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
3367 /* FIXME: since this stub doesn't do any converting, the proper behavior
3368 is to raise an exception */
3371 /***********************************************************************
3372 * NdrConvert2 [RPCRT4.@]
3374 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, LONG NumberParams
)
3376 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3377 pStubMsg
, pFormat
, NumberParams
);
3378 /* FIXME: since this stub doesn't do any converting, the proper behavior
3379 is to raise an exception */
3382 #include "pshpack1.h"
3383 typedef struct _NDR_CSTRUCT_FORMAT
3386 unsigned char alignment
;
3387 unsigned short memory_size
;
3388 short offset_to_array_description
;
3389 } NDR_CSTRUCT_FORMAT
, NDR_CVSTRUCT_FORMAT
;
3390 #include "poppack.h"
3392 /***********************************************************************
3393 * NdrConformantStructMarshall [RPCRT4.@]
3395 unsigned char * WINAPI
NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3396 unsigned char *pMemory
,
3397 PFORMAT_STRING pFormat
)
3399 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3400 PFORMAT_STRING pCArrayFormat
;
3401 ULONG esize
, bufsize
;
3403 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3405 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3406 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3408 ERR("invalid format type %x\n", pCStructFormat
->type
);
3409 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3413 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3414 pCStructFormat
->offset_to_array_description
;
3415 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3417 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3418 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3421 esize
= *(const WORD
*)(pCArrayFormat
+2);
3423 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
3424 pCArrayFormat
+ 4, 0);
3426 WriteConformance(pStubMsg
);
3428 ALIGN_POINTER(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
3430 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3432 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3433 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
3435 ERR("integer overflow of memory_size %u with bufsize %u\n",
3436 pCStructFormat
->memory_size
, bufsize
);
3437 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3439 /* copy constant sized part of struct */
3440 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3441 safe_copy_to_buffer(pStubMsg
, pMemory
, pCStructFormat
->memory_size
+ bufsize
);
3443 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3444 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3449 /***********************************************************************
3450 * NdrConformantStructUnmarshall [RPCRT4.@]
3452 unsigned char * WINAPI
NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3453 unsigned char **ppMemory
,
3454 PFORMAT_STRING pFormat
,
3455 unsigned char fMustAlloc
)
3457 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3458 PFORMAT_STRING pCArrayFormat
;
3459 ULONG esize
, bufsize
;
3461 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3463 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3464 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3466 ERR("invalid format type %x\n", pCStructFormat
->type
);
3467 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3470 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3471 pCStructFormat
->offset_to_array_description
;
3472 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3474 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3475 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3478 esize
= *(const WORD
*)(pCArrayFormat
+2);
3480 pCArrayFormat
= ReadConformance(pStubMsg
, pCArrayFormat
+ 4);
3482 ALIGN_POINTER(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
3484 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3486 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3487 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
3489 ERR("integer overflow of memory_size %u with bufsize %u\n",
3490 pCStructFormat
->memory_size
, bufsize
);
3491 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3493 /* work out how much memory to allocate if we need to do so */
3494 if (!*ppMemory
|| fMustAlloc
)
3496 SIZE_T size
= pCStructFormat
->memory_size
+ bufsize
;
3497 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3500 /* now copy the data */
3501 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3502 safe_copy_from_buffer(pStubMsg
, *ppMemory
, pCStructFormat
->memory_size
+ bufsize
);
3504 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3505 EmbeddedPointerUnmarshall(pStubMsg
, *ppMemory
, *ppMemory
, pFormat
, TRUE
/* FIXME */);
3510 /***********************************************************************
3511 * NdrConformantStructBufferSize [RPCRT4.@]
3513 void WINAPI
NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3514 unsigned char *pMemory
,
3515 PFORMAT_STRING pFormat
)
3517 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3518 PFORMAT_STRING pCArrayFormat
;
3521 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3523 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3524 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3526 ERR("invalid format type %x\n", pCStructFormat
->type
);
3527 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3530 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3531 pCStructFormat
->offset_to_array_description
;
3532 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3534 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3535 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3538 esize
= *(const WORD
*)(pCArrayFormat
+2);
3540 pCArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
, pCArrayFormat
+4, 0);
3541 SizeConformance(pStubMsg
);
3543 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCStructFormat
->alignment
+ 1);
3545 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3547 safe_buffer_length_increment(pStubMsg
, pCStructFormat
->memory_size
);
3548 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
3550 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3551 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3554 /***********************************************************************
3555 * NdrConformantStructMemorySize [RPCRT4.@]
3557 ULONG WINAPI
NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3558 PFORMAT_STRING pFormat
)
3564 /***********************************************************************
3565 * NdrConformantStructFree [RPCRT4.@]
3567 void WINAPI
NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3568 unsigned char *pMemory
,
3569 PFORMAT_STRING pFormat
)
3571 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3572 PFORMAT_STRING pCArrayFormat
;
3575 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3577 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3578 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3580 ERR("invalid format type %x\n", pCStructFormat
->type
);
3581 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3585 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3586 pCStructFormat
->offset_to_array_description
;
3587 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3589 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3590 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3593 esize
= *(const WORD
*)(pCArrayFormat
+2);
3595 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
3596 pCArrayFormat
+ 4, 0);
3598 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3600 /* copy constant sized part of struct */
3601 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3603 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3604 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
3607 /***********************************************************************
3608 * NdrConformantVaryingStructMarshall [RPCRT4.@]
3610 unsigned char * WINAPI
NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3611 unsigned char *pMemory
,
3612 PFORMAT_STRING pFormat
)
3614 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3615 PFORMAT_STRING pCVArrayFormat
;
3616 ULONG esize
, bufsize
;
3618 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3620 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3621 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3623 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3624 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3628 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3629 pCVStructFormat
->offset_to_array_description
;
3630 switch (*pCVArrayFormat
)
3632 case RPC_FC_CVARRAY
:
3633 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3635 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3636 pCVArrayFormat
+ 4, 0);
3637 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3640 case RPC_FC_C_CSTRING
:
3641 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
3642 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
3643 esize
= sizeof(char);
3644 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3645 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3646 pCVArrayFormat
+ 2, 0);
3648 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3650 case RPC_FC_C_WSTRING
:
3651 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
3652 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
3653 esize
= sizeof(WCHAR
);
3654 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3655 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3656 pCVArrayFormat
+ 2, 0);
3658 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3661 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3662 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3666 WriteConformance(pStubMsg
);
3668 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
3670 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3672 /* write constant sized part */
3673 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3674 safe_copy_to_buffer(pStubMsg
, pMemory
, pCVStructFormat
->memory_size
);
3676 WriteVariance(pStubMsg
);
3678 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3680 /* write array part */
3681 safe_copy_to_buffer(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
, bufsize
);
3683 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3688 /***********************************************************************
3689 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3691 unsigned char * WINAPI
NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3692 unsigned char **ppMemory
,
3693 PFORMAT_STRING pFormat
,
3694 unsigned char fMustAlloc
)
3696 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3697 PFORMAT_STRING pCVArrayFormat
;
3698 ULONG esize
, bufsize
;
3699 unsigned char cvarray_type
;
3701 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3703 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3704 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3706 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3707 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3711 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3712 pCVStructFormat
->offset_to_array_description
;
3713 cvarray_type
= *pCVArrayFormat
;
3714 switch (cvarray_type
)
3716 case RPC_FC_CVARRAY
:
3717 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3718 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 4);
3720 case RPC_FC_C_CSTRING
:
3721 esize
= sizeof(char);
3722 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3723 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3725 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3727 case RPC_FC_C_WSTRING
:
3728 esize
= sizeof(WCHAR
);
3729 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3730 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3732 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3735 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3736 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3740 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
3742 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3744 /* work out how much memory to allocate if we need to do so */
3745 if (!*ppMemory
|| fMustAlloc
)
3747 SIZE_T size
= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->MaxCount
);
3748 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3751 /* copy the constant data */
3752 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3753 safe_copy_from_buffer(pStubMsg
, *ppMemory
, pCVStructFormat
->memory_size
);
3755 pCVArrayFormat
= ReadVariance(pStubMsg
, pCVArrayFormat
, pStubMsg
->MaxCount
);
3757 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3759 if ((cvarray_type
== RPC_FC_C_CSTRING
) ||
3760 (cvarray_type
== RPC_FC_C_WSTRING
))
3763 /* strings must always have null terminating bytes */
3764 if (bufsize
< esize
)
3766 ERR("invalid string length of %d\n", pStubMsg
->ActualCount
);
3767 RpcRaiseException(RPC_S_INVALID_BOUND
);
3770 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
3771 if (pStubMsg
->Buffer
[i
] != 0)
3773 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
3774 i
, pStubMsg
->Buffer
[i
]);
3775 RpcRaiseException(RPC_S_INVALID_BOUND
);
3780 /* copy the array data */
3781 safe_copy_from_buffer(pStubMsg
, *ppMemory
+ pCVStructFormat
->memory_size
, bufsize
);
3783 if (cvarray_type
== RPC_FC_C_CSTRING
)
3784 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory
+ pCVStructFormat
->memory_size
)));
3785 else if (cvarray_type
== RPC_FC_C_WSTRING
)
3786 TRACE("string=%s\n", debugstr_w((WCHAR
*)(*ppMemory
+ pCVStructFormat
->memory_size
)));
3788 EmbeddedPointerUnmarshall(pStubMsg
, *ppMemory
, *ppMemory
, pFormat
, TRUE
/* FIXME */);
3793 /***********************************************************************
3794 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3796 void WINAPI
NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3797 unsigned char *pMemory
,
3798 PFORMAT_STRING pFormat
)
3800 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3801 PFORMAT_STRING pCVArrayFormat
;
3804 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3806 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3807 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3809 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3810 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3814 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3815 pCVStructFormat
->offset_to_array_description
;
3816 switch (*pCVArrayFormat
)
3818 case RPC_FC_CVARRAY
:
3819 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3821 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3822 pCVArrayFormat
+ 4, 0);
3823 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3826 case RPC_FC_C_CSTRING
:
3827 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
3828 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
3829 esize
= sizeof(char);
3830 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3831 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3832 pCVArrayFormat
+ 2, 0);
3834 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3836 case RPC_FC_C_WSTRING
:
3837 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
3838 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
3839 esize
= sizeof(WCHAR
);
3840 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3841 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3842 pCVArrayFormat
+ 2, 0);
3844 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3847 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3848 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3852 SizeConformance(pStubMsg
);
3854 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCVStructFormat
->alignment
+ 1);
3856 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3858 safe_buffer_length_increment(pStubMsg
, pCVStructFormat
->memory_size
);
3859 SizeVariance(pStubMsg
);
3860 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
3862 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3865 /***********************************************************************
3866 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
3868 ULONG WINAPI
NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3869 PFORMAT_STRING pFormat
)
3871 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3872 PFORMAT_STRING pCVArrayFormat
;
3874 unsigned char cvarray_type
;
3876 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
3878 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3879 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3881 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3882 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3886 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3887 pCVStructFormat
->offset_to_array_description
;
3888 cvarray_type
= *pCVArrayFormat
;
3889 switch (cvarray_type
)
3891 case RPC_FC_CVARRAY
:
3892 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3893 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 4);
3895 case RPC_FC_C_CSTRING
:
3896 esize
= sizeof(char);
3897 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3898 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3900 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3902 case RPC_FC_C_WSTRING
:
3903 esize
= sizeof(WCHAR
);
3904 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3905 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3907 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3910 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3911 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3915 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
3917 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3919 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
3920 pCVArrayFormat
= ReadVariance(pStubMsg
, pCVArrayFormat
, pStubMsg
->MaxCount
);
3921 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
3923 pStubMsg
->MemorySize
+= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->MaxCount
);
3925 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
3927 return pCVStructFormat
->memory_size
+ pStubMsg
->MaxCount
* esize
;
3930 /***********************************************************************
3931 * NdrConformantVaryingStructFree [RPCRT4.@]
3933 void WINAPI
NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3934 unsigned char *pMemory
,
3935 PFORMAT_STRING pFormat
)
3937 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3938 PFORMAT_STRING pCVArrayFormat
;
3941 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3943 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3944 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3946 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3947 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3951 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3952 pCVStructFormat
->offset_to_array_description
;
3953 switch (*pCVArrayFormat
)
3955 case RPC_FC_CVARRAY
:
3956 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3958 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3959 pCVArrayFormat
+ 4, 0);
3960 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3963 case RPC_FC_C_CSTRING
:
3964 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
3965 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
3966 esize
= sizeof(char);
3967 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3968 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3969 pCVArrayFormat
+ 2, 0);
3971 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3973 case RPC_FC_C_WSTRING
:
3974 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
3975 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
3976 esize
= sizeof(WCHAR
);
3977 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3978 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3979 pCVArrayFormat
+ 2, 0);
3981 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3984 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3985 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3989 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3991 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
3994 #include "pshpack1.h"
3998 unsigned char alignment
;
3999 unsigned short total_size
;
4000 } NDR_SMFARRAY_FORMAT
;
4005 unsigned char alignment
;
4006 unsigned long total_size
;
4007 } NDR_LGFARRAY_FORMAT
;
4008 #include "poppack.h"
4010 /***********************************************************************
4011 * NdrFixedArrayMarshall [RPCRT4.@]
4013 unsigned char * WINAPI
NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4014 unsigned char *pMemory
,
4015 PFORMAT_STRING pFormat
)
4017 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4018 unsigned long total_size
;
4020 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4022 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4023 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4025 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4026 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4030 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4032 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4034 total_size
= pSmFArrayFormat
->total_size
;
4035 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4039 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4040 total_size
= pLgFArrayFormat
->total_size
;
4041 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4044 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4045 safe_copy_to_buffer(pStubMsg
, pMemory
, total_size
);
4047 pFormat
= EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4052 /***********************************************************************
4053 * NdrFixedArrayUnmarshall [RPCRT4.@]
4055 unsigned char * WINAPI
NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4056 unsigned char **ppMemory
,
4057 PFORMAT_STRING pFormat
,
4058 unsigned char fMustAlloc
)
4060 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4061 unsigned long total_size
;
4062 unsigned char *saved_buffer
;
4064 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4066 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4067 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4069 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4070 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4074 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4076 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4078 total_size
= pSmFArrayFormat
->total_size
;
4079 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4083 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4084 total_size
= pLgFArrayFormat
->total_size
;
4085 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4089 *ppMemory
= NdrAllocate(pStubMsg
, total_size
);
4092 if (!pStubMsg
->IsClient
&& !*ppMemory
)
4093 /* for servers, we just point straight into the RPC buffer */
4094 *ppMemory
= pStubMsg
->Buffer
;
4097 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4098 safe_buffer_increment(pStubMsg
, total_size
);
4099 pFormat
= EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4101 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
4102 if (*ppMemory
!= saved_buffer
)
4103 memcpy(*ppMemory
, saved_buffer
, total_size
);
4108 /***********************************************************************
4109 * NdrFixedArrayBufferSize [RPCRT4.@]
4111 void WINAPI
NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4112 unsigned char *pMemory
,
4113 PFORMAT_STRING pFormat
)
4115 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4116 unsigned long total_size
;
4118 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4120 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4121 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4123 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4124 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4128 ALIGN_LENGTH(pStubMsg
->BufferLength
, pSmFArrayFormat
->alignment
+ 1);
4130 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4132 total_size
= pSmFArrayFormat
->total_size
;
4133 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4137 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4138 total_size
= pLgFArrayFormat
->total_size
;
4139 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4141 safe_buffer_length_increment(pStubMsg
, total_size
);
4143 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4146 /***********************************************************************
4147 * NdrFixedArrayMemorySize [RPCRT4.@]
4149 ULONG WINAPI
NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4150 PFORMAT_STRING pFormat
)
4152 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4155 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4157 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4158 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4160 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4161 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4165 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4167 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4169 total_size
= pSmFArrayFormat
->total_size
;
4170 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4174 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4175 total_size
= pLgFArrayFormat
->total_size
;
4176 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4178 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4179 safe_buffer_increment(pStubMsg
, total_size
);
4180 pStubMsg
->MemorySize
+= total_size
;
4182 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4187 /***********************************************************************
4188 * NdrFixedArrayFree [RPCRT4.@]
4190 void WINAPI
NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4191 unsigned char *pMemory
,
4192 PFORMAT_STRING pFormat
)
4194 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4196 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4198 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4199 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4201 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4202 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4206 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4207 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4210 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4211 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4214 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4217 /***********************************************************************
4218 * NdrVaryingArrayMarshall [RPCRT4.@]
4220 unsigned char * WINAPI
NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4221 unsigned char *pMemory
,
4222 PFORMAT_STRING pFormat
)
4224 unsigned char alignment
;
4225 DWORD elements
, esize
;
4228 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4230 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4231 (pFormat
[0] != RPC_FC_LGVARRAY
))
4233 ERR("invalid format type %x\n", pFormat
[0]);
4234 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4238 alignment
= pFormat
[1] + 1;
4240 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4243 pFormat
+= sizeof(WORD
);
4244 elements
= *(const WORD
*)pFormat
;
4245 pFormat
+= sizeof(WORD
);
4250 pFormat
+= sizeof(DWORD
);
4251 elements
= *(const DWORD
*)pFormat
;
4252 pFormat
+= sizeof(DWORD
);
4255 esize
= *(const WORD
*)pFormat
;
4256 pFormat
+= sizeof(WORD
);
4258 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4259 if ((pStubMsg
->ActualCount
> elements
) ||
4260 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4262 RpcRaiseException(RPC_S_INVALID_BOUND
);
4266 WriteVariance(pStubMsg
);
4268 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4270 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4271 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4272 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
4274 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4279 /***********************************************************************
4280 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4282 unsigned char * WINAPI
NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4283 unsigned char **ppMemory
,
4284 PFORMAT_STRING pFormat
,
4285 unsigned char fMustAlloc
)
4287 unsigned char alignment
;
4288 DWORD size
, elements
, esize
;
4291 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4293 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4294 (pFormat
[0] != RPC_FC_LGVARRAY
))
4296 ERR("invalid format type %x\n", pFormat
[0]);
4297 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4301 alignment
= pFormat
[1] + 1;
4303 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4306 size
= *(const WORD
*)pFormat
;
4307 pFormat
+= sizeof(WORD
);
4308 elements
= *(const WORD
*)pFormat
;
4309 pFormat
+= sizeof(WORD
);
4314 size
= *(const DWORD
*)pFormat
;
4315 pFormat
+= sizeof(DWORD
);
4316 elements
= *(const DWORD
*)pFormat
;
4317 pFormat
+= sizeof(DWORD
);
4320 esize
= *(const WORD
*)pFormat
;
4321 pFormat
+= sizeof(WORD
);
4323 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
4325 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4327 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4329 if (!*ppMemory
|| fMustAlloc
)
4330 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4331 safe_copy_from_buffer(pStubMsg
, *ppMemory
+ pStubMsg
->Offset
, bufsize
);
4333 EmbeddedPointerUnmarshall(pStubMsg
, *ppMemory
, *ppMemory
, pFormat
, TRUE
/* FIXME */);
4338 /***********************************************************************
4339 * NdrVaryingArrayBufferSize [RPCRT4.@]
4341 void WINAPI
NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4342 unsigned char *pMemory
,
4343 PFORMAT_STRING pFormat
)
4345 unsigned char alignment
;
4346 DWORD elements
, esize
;
4348 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4350 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4351 (pFormat
[0] != RPC_FC_LGVARRAY
))
4353 ERR("invalid format type %x\n", pFormat
[0]);
4354 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4358 alignment
= pFormat
[1] + 1;
4360 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4363 pFormat
+= sizeof(WORD
);
4364 elements
= *(const WORD
*)pFormat
;
4365 pFormat
+= sizeof(WORD
);
4370 pFormat
+= sizeof(DWORD
);
4371 elements
= *(const DWORD
*)pFormat
;
4372 pFormat
+= sizeof(DWORD
);
4375 esize
= *(const WORD
*)pFormat
;
4376 pFormat
+= sizeof(WORD
);
4378 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4379 if ((pStubMsg
->ActualCount
> elements
) ||
4380 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4382 RpcRaiseException(RPC_S_INVALID_BOUND
);
4386 SizeVariance(pStubMsg
);
4388 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
4390 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
4392 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4395 /***********************************************************************
4396 * NdrVaryingArrayMemorySize [RPCRT4.@]
4398 ULONG WINAPI
NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4399 PFORMAT_STRING pFormat
)
4401 unsigned char alignment
;
4402 DWORD size
, elements
, esize
;
4404 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4406 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4407 (pFormat
[0] != RPC_FC_LGVARRAY
))
4409 ERR("invalid format type %x\n", pFormat
[0]);
4410 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4414 alignment
= pFormat
[1] + 1;
4416 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4419 size
= *(const WORD
*)pFormat
;
4420 pFormat
+= sizeof(WORD
);
4421 elements
= *(const WORD
*)pFormat
;
4422 pFormat
+= sizeof(WORD
);
4427 size
= *(const DWORD
*)pFormat
;
4428 pFormat
+= sizeof(DWORD
);
4429 elements
= *(const DWORD
*)pFormat
;
4430 pFormat
+= sizeof(DWORD
);
4433 esize
= *(const WORD
*)pFormat
;
4434 pFormat
+= sizeof(WORD
);
4436 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
4438 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4440 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
4441 pStubMsg
->MemorySize
+= size
;
4443 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4445 return pStubMsg
->MemorySize
;
4448 /***********************************************************************
4449 * NdrVaryingArrayFree [RPCRT4.@]
4451 void WINAPI
NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4452 unsigned char *pMemory
,
4453 PFORMAT_STRING pFormat
)
4455 unsigned char alignment
;
4458 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4460 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4461 (pFormat
[0] != RPC_FC_LGVARRAY
))
4463 ERR("invalid format type %x\n", pFormat
[0]);
4464 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4468 alignment
= pFormat
[1] + 1;
4470 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4473 pFormat
+= sizeof(WORD
);
4474 elements
= *(const WORD
*)pFormat
;
4475 pFormat
+= sizeof(WORD
);
4480 pFormat
+= sizeof(DWORD
);
4481 elements
= *(const DWORD
*)pFormat
;
4482 pFormat
+= sizeof(DWORD
);
4485 pFormat
+= sizeof(WORD
);
4487 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4488 if ((pStubMsg
->ActualCount
> elements
) ||
4489 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4491 RpcRaiseException(RPC_S_INVALID_BOUND
);
4495 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4498 static ULONG
get_discriminant(unsigned char fc
, const unsigned char *pMemory
)
4506 return *(const UCHAR
*)pMemory
;
4511 return *(const USHORT
*)pMemory
;
4515 return *(const ULONG
*)pMemory
;
4517 FIXME("Unhandled base type: 0x%02x\n", fc
);
4522 static PFORMAT_STRING
get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg
,
4523 unsigned long discriminant
,
4524 PFORMAT_STRING pFormat
)
4526 unsigned short num_arms
, arm
, type
;
4528 num_arms
= *(const SHORT
*)pFormat
& 0x0fff;
4530 for(arm
= 0; arm
< num_arms
; arm
++)
4532 if(discriminant
== *(const ULONG
*)pFormat
)
4540 type
= *(const unsigned short*)pFormat
;
4541 TRACE("type %04x\n", type
);
4542 if(arm
== num_arms
) /* default arm extras */
4546 ERR("no arm for 0x%lx and no default case\n", discriminant
);
4547 RpcRaiseException(RPC_S_INVALID_TAG
);
4552 TRACE("falling back to empty default case for 0x%lx\n", discriminant
);
4559 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
, ULONG discriminant
, PFORMAT_STRING pFormat
)
4561 unsigned short type
;
4565 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4569 type
= *(const unsigned short*)pFormat
;
4570 if((type
& 0xff00) == 0x8000)
4572 unsigned char basetype
= LOBYTE(type
);
4573 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &basetype
);
4577 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4578 NDR_MARSHALL m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
4581 unsigned char *saved_buffer
= NULL
;
4582 int pointer_buffer_mark_set
= 0;
4589 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4590 saved_buffer
= pStubMsg
->Buffer
;
4591 if (pStubMsg
->PointerBufferMark
)
4593 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4594 pStubMsg
->PointerBufferMark
= NULL
;
4595 pointer_buffer_mark_set
= 1;
4598 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
4600 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char **)pMemory
, desc
);
4601 if (pointer_buffer_mark_set
)
4603 STD_OVERFLOW_CHECK(pStubMsg
);
4604 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4605 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
4607 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
4608 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
4609 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4611 pStubMsg
->Buffer
= saved_buffer
+ 4;
4615 m(pStubMsg
, pMemory
, desc
);
4618 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4623 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4624 unsigned char **ppMemory
,
4626 PFORMAT_STRING pFormat
,
4627 unsigned char fMustAlloc
)
4629 unsigned short type
;
4633 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4637 type
= *(const unsigned short*)pFormat
;
4638 if((type
& 0xff00) == 0x8000)
4640 unsigned char basetype
= LOBYTE(type
);
4641 return NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &basetype
, FALSE
);
4645 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4646 NDR_UNMARSHALL m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
4649 unsigned char *saved_buffer
= NULL
;
4650 int pointer_buffer_mark_set
= 0;
4657 **(void***)ppMemory
= NULL
;
4658 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4659 saved_buffer
= pStubMsg
->Buffer
;
4660 if (pStubMsg
->PointerBufferMark
)
4662 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4663 pStubMsg
->PointerBufferMark
= NULL
;
4664 pointer_buffer_mark_set
= 1;
4667 pStubMsg
->Buffer
+= 4; /* for pointer ID */
4669 if (saved_buffer
+ 4 > pStubMsg
->BufferEnd
)
4671 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
4672 saved_buffer
, pStubMsg
->BufferEnd
);
4673 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4676 PointerUnmarshall(pStubMsg
, saved_buffer
, *(unsigned char ***)ppMemory
, **(unsigned char ***)ppMemory
, desc
, fMustAlloc
);
4677 if (pointer_buffer_mark_set
)
4679 STD_OVERFLOW_CHECK(pStubMsg
);
4680 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4681 pStubMsg
->Buffer
= saved_buffer
+ 4;
4685 m(pStubMsg
, ppMemory
, desc
, fMustAlloc
);
4688 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4693 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg
,
4694 unsigned char *pMemory
,
4696 PFORMAT_STRING pFormat
)
4698 unsigned short type
;
4702 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4706 type
= *(const unsigned short*)pFormat
;
4707 if((type
& 0xff00) == 0x8000)
4709 unsigned char basetype
= LOBYTE(type
);
4710 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &basetype
);
4714 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4715 NDR_BUFFERSIZE m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
4724 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
4725 safe_buffer_length_increment(pStubMsg
, 4); /* for pointer ID */
4726 if (!pStubMsg
->IgnoreEmbeddedPointers
)
4728 int saved_buffer_length
= pStubMsg
->BufferLength
;
4729 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4730 pStubMsg
->PointerLength
= 0;
4731 if(!pStubMsg
->BufferLength
)
4732 ERR("BufferLength == 0??\n");
4733 PointerBufferSize(pStubMsg
, *(unsigned char **)pMemory
, desc
);
4734 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4735 pStubMsg
->BufferLength
= saved_buffer_length
;
4739 m(pStubMsg
, pMemory
, desc
);
4742 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
4746 static ULONG
union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg
,
4748 PFORMAT_STRING pFormat
)
4750 unsigned short type
, size
;
4752 size
= *(const unsigned short*)pFormat
;
4753 pStubMsg
->Memory
+= size
;
4756 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4760 type
= *(const unsigned short*)pFormat
;
4761 if((type
& 0xff00) == 0x8000)
4763 return NdrBaseTypeMemorySize(pStubMsg
, pFormat
);
4767 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4768 NDR_MEMORYSIZE m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
4769 unsigned char *saved_buffer
;
4778 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4779 saved_buffer
= pStubMsg
->Buffer
;
4780 safe_buffer_increment(pStubMsg
, 4);
4781 ALIGN_LENGTH(pStubMsg
->MemorySize
, 4);
4782 pStubMsg
->MemorySize
+= 4;
4783 if (!pStubMsg
->IgnoreEmbeddedPointers
)
4784 PointerMemorySize(pStubMsg
, saved_buffer
, pFormat
);
4787 return m(pStubMsg
, desc
);
4790 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4793 TRACE("size %d\n", size
);
4797 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg
,
4798 unsigned char *pMemory
,
4800 PFORMAT_STRING pFormat
)
4802 unsigned short type
;
4806 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4810 type
= *(const unsigned short*)pFormat
;
4811 if((type
& 0xff00) != 0x8000)
4813 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4814 NDR_FREE m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
4823 PointerFree(pStubMsg
, *(unsigned char **)pMemory
, desc
);
4826 m(pStubMsg
, pMemory
, desc
);
4829 else FIXME("no freer for embedded type %02x\n", *desc
);
4833 /***********************************************************************
4834 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
4836 unsigned char * WINAPI
NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4837 unsigned char *pMemory
,
4838 PFORMAT_STRING pFormat
)
4840 unsigned char switch_type
;
4841 unsigned char increment
;
4844 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4847 switch_type
= *pFormat
& 0xf;
4848 increment
= (*pFormat
& 0xf0) >> 4;
4851 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
4853 switch_value
= get_discriminant(switch_type
, pMemory
);
4854 TRACE("got switch value 0x%x\n", switch_value
);
4856 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &switch_type
);
4857 pMemory
+= increment
;
4859 return union_arm_marshall(pStubMsg
, pMemory
, switch_value
, pFormat
);
4862 /***********************************************************************
4863 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
4865 unsigned char * WINAPI
NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4866 unsigned char **ppMemory
,
4867 PFORMAT_STRING pFormat
,
4868 unsigned char fMustAlloc
)
4870 unsigned char switch_type
;
4871 unsigned char increment
;
4873 unsigned short size
;
4874 unsigned char *pMemoryArm
;
4876 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4879 switch_type
= *pFormat
& 0xf;
4880 increment
= (*pFormat
& 0xf0) >> 4;
4883 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
4884 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
4885 TRACE("got switch value 0x%x\n", switch_value
);
4887 size
= *(const unsigned short*)pFormat
+ increment
;
4888 if(!*ppMemory
|| fMustAlloc
)
4889 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4891 NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &switch_type
, FALSE
);
4892 pMemoryArm
= *ppMemory
+ increment
;
4894 return union_arm_unmarshall(pStubMsg
, &pMemoryArm
, switch_value
, pFormat
, fMustAlloc
);
4897 /***********************************************************************
4898 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
4900 void WINAPI
NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4901 unsigned char *pMemory
,
4902 PFORMAT_STRING pFormat
)
4904 unsigned char switch_type
;
4905 unsigned char increment
;
4908 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4911 switch_type
= *pFormat
& 0xf;
4912 increment
= (*pFormat
& 0xf0) >> 4;
4915 ALIGN_LENGTH(pStubMsg
->BufferLength
, increment
);
4916 switch_value
= get_discriminant(switch_type
, pMemory
);
4917 TRACE("got switch value 0x%x\n", switch_value
);
4919 /* Add discriminant size */
4920 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&switch_value
, &switch_type
);
4921 pMemory
+= increment
;
4923 union_arm_buffer_size(pStubMsg
, pMemory
, switch_value
, pFormat
);
4926 /***********************************************************************
4927 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
4929 ULONG WINAPI
NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4930 PFORMAT_STRING pFormat
)
4932 unsigned char switch_type
;
4933 unsigned char increment
;
4936 switch_type
= *pFormat
& 0xf;
4937 increment
= (*pFormat
& 0xf0) >> 4;
4940 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
4941 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
4942 TRACE("got switch value 0x%x\n", switch_value
);
4944 pStubMsg
->Memory
+= increment
;
4946 return increment
+ union_arm_memory_size(pStubMsg
, switch_value
, pFormat
+ *(const SHORT
*)pFormat
);
4949 /***********************************************************************
4950 * NdrEncapsulatedUnionFree [RPCRT4.@]
4952 void WINAPI
NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
4953 unsigned char *pMemory
,
4954 PFORMAT_STRING pFormat
)
4956 unsigned char switch_type
;
4957 unsigned char increment
;
4960 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4963 switch_type
= *pFormat
& 0xf;
4964 increment
= (*pFormat
& 0xf0) >> 4;
4967 switch_value
= get_discriminant(switch_type
, pMemory
);
4968 TRACE("got switch value 0x%x\n", switch_value
);
4970 pMemory
+= increment
;
4972 return union_arm_free(pStubMsg
, pMemory
, switch_value
, pFormat
);
4975 /***********************************************************************
4976 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
4978 unsigned char * WINAPI
NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4979 unsigned char *pMemory
,
4980 PFORMAT_STRING pFormat
)
4982 unsigned char switch_type
;
4984 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4987 switch_type
= *pFormat
;
4990 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
4991 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
4992 /* Marshall discriminant */
4993 NdrBaseTypeMarshall(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
4995 return union_arm_marshall(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
4998 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg
,
4999 PFORMAT_STRING
*ppFormat
)
5001 long discriminant
= 0;
5011 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5020 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5021 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5029 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
5030 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5035 FIXME("Unhandled base type: 0x%02x\n", **ppFormat
);
5039 if (pStubMsg
->fHasNewCorrDesc
)
5043 return discriminant
;
5046 /**********************************************************************
5047 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5049 unsigned char * WINAPI
NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5050 unsigned char **ppMemory
,
5051 PFORMAT_STRING pFormat
,
5052 unsigned char fMustAlloc
)
5055 unsigned short size
;
5057 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5060 /* Unmarshall discriminant */
5061 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
5062 TRACE("unmarshalled discriminant %lx\n", discriminant
);
5064 pFormat
+= *(const SHORT
*)pFormat
;
5066 size
= *(const unsigned short*)pFormat
;
5068 if(!*ppMemory
|| fMustAlloc
)
5069 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5071 return union_arm_unmarshall(pStubMsg
, ppMemory
, discriminant
, pFormat
, fMustAlloc
);
5074 /***********************************************************************
5075 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5077 void WINAPI
NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5078 unsigned char *pMemory
,
5079 PFORMAT_STRING pFormat
)
5081 unsigned char switch_type
;
5083 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5086 switch_type
= *pFormat
;
5089 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5090 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5091 /* Add discriminant size */
5092 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
5094 union_arm_buffer_size(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5097 /***********************************************************************
5098 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5100 ULONG WINAPI
NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5101 PFORMAT_STRING pFormat
)
5106 /* Unmarshall discriminant */
5107 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
5108 TRACE("unmarshalled discriminant 0x%x\n", discriminant
);
5110 return union_arm_memory_size(pStubMsg
, discriminant
, pFormat
+ *(const SHORT
*)pFormat
);
5113 /***********************************************************************
5114 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5116 void WINAPI
NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
5117 unsigned char *pMemory
,
5118 PFORMAT_STRING pFormat
)
5120 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5124 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5125 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5127 return union_arm_free(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5130 /***********************************************************************
5131 * NdrByteCountPointerMarshall [RPCRT4.@]
5133 unsigned char * WINAPI
NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5134 unsigned char *pMemory
,
5135 PFORMAT_STRING pFormat
)
5141 /***********************************************************************
5142 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5144 unsigned char * WINAPI
NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5145 unsigned char **ppMemory
,
5146 PFORMAT_STRING pFormat
,
5147 unsigned char fMustAlloc
)
5153 /***********************************************************************
5154 * NdrByteCountPointerBufferSize [RPCRT4.@]
5156 void WINAPI
NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5157 unsigned char *pMemory
,
5158 PFORMAT_STRING pFormat
)
5163 /***********************************************************************
5164 * NdrByteCountPointerMemorySize [RPCRT4.@]
5166 ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5167 PFORMAT_STRING pFormat
)
5173 /***********************************************************************
5174 * NdrByteCountPointerFree [RPCRT4.@]
5176 void WINAPI
NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
5177 unsigned char *pMemory
,
5178 PFORMAT_STRING pFormat
)
5183 /***********************************************************************
5184 * NdrXmitOrRepAsMarshall [RPCRT4.@]
5186 unsigned char * WINAPI
NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5187 unsigned char *pMemory
,
5188 PFORMAT_STRING pFormat
)
5194 /***********************************************************************
5195 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
5197 unsigned char * WINAPI
NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5198 unsigned char **ppMemory
,
5199 PFORMAT_STRING pFormat
,
5200 unsigned char fMustAlloc
)
5206 /***********************************************************************
5207 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
5209 void WINAPI
NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5210 unsigned char *pMemory
,
5211 PFORMAT_STRING pFormat
)
5216 /***********************************************************************
5217 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
5219 ULONG WINAPI
NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5220 PFORMAT_STRING pFormat
)
5226 /***********************************************************************
5227 * NdrXmitOrRepAsFree [RPCRT4.@]
5229 void WINAPI
NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg
,
5230 unsigned char *pMemory
,
5231 PFORMAT_STRING pFormat
)
5236 #include "pshpack1.h"
5240 unsigned char flags_type
; /* flags in upper nibble, type in lower nibble */
5244 #include "poppack.h"
5246 /***********************************************************************
5247 * NdrRangeMarshall [internal]
5249 unsigned char *WINAPI
NdrRangeMarshall(
5250 PMIDL_STUB_MESSAGE pStubMsg
,
5251 unsigned char *pMemory
,
5252 PFORMAT_STRING pFormat
)
5254 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5255 unsigned char base_type
;
5257 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5259 if (pRange
->type
!= RPC_FC_RANGE
)
5261 ERR("invalid format type %x\n", pRange
->type
);
5262 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5266 base_type
= pRange
->flags_type
& 0xf;
5268 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &base_type
);
5271 /***********************************************************************
5272 * NdrRangeUnmarshall
5274 unsigned char *WINAPI
NdrRangeUnmarshall(
5275 PMIDL_STUB_MESSAGE pStubMsg
,
5276 unsigned char **ppMemory
,
5277 PFORMAT_STRING pFormat
,
5278 unsigned char fMustAlloc
)
5280 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5281 unsigned char base_type
;
5283 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
5285 if (pRange
->type
!= RPC_FC_RANGE
)
5287 ERR("invalid format type %x\n", pRange
->type
);
5288 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5291 base_type
= pRange
->flags_type
& 0xf;
5293 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5294 base_type
, pRange
->low_value
, pRange
->high_value
);
5296 #define RANGE_UNMARSHALL(type, format_spec) \
5299 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5300 if (fMustAlloc || !*ppMemory) \
5301 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5302 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
5304 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
5305 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
5306 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
5308 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5309 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5311 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5312 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5313 (type)pRange->high_value); \
5314 RpcRaiseException(RPC_S_INVALID_BOUND); \
5317 TRACE("*ppMemory: %p\n", *ppMemory); \
5318 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5319 pStubMsg->Buffer += sizeof(type); \
5326 RANGE_UNMARSHALL(UCHAR
, "%d");
5327 TRACE("value: 0x%02x\n", **(UCHAR
**)ppMemory
);
5331 RANGE_UNMARSHALL(CHAR
, "%u");
5332 TRACE("value: 0x%02x\n", **(UCHAR
**)ppMemory
);
5334 case RPC_FC_WCHAR
: /* FIXME: valid? */
5336 RANGE_UNMARSHALL(USHORT
, "%u");
5337 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5340 RANGE_UNMARSHALL(SHORT
, "%d");
5341 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5344 RANGE_UNMARSHALL(LONG
, "%d");
5345 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5348 RANGE_UNMARSHALL(ULONG
, "%u");
5349 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5353 FIXME("Unhandled enum type\n");
5355 case RPC_FC_ERROR_STATUS_T
: /* FIXME: valid? */
5360 ERR("invalid range base type: 0x%02x\n", base_type
);
5361 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5367 /***********************************************************************
5368 * NdrRangeBufferSize [internal]
5370 void WINAPI
NdrRangeBufferSize(
5371 PMIDL_STUB_MESSAGE pStubMsg
,
5372 unsigned char *pMemory
,
5373 PFORMAT_STRING pFormat
)
5375 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5376 unsigned char base_type
;
5378 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5380 if (pRange
->type
!= RPC_FC_RANGE
)
5382 ERR("invalid format type %x\n", pRange
->type
);
5383 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5385 base_type
= pRange
->flags_type
& 0xf;
5387 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &base_type
);
5390 /***********************************************************************
5391 * NdrRangeMemorySize [internal]
5393 ULONG WINAPI
NdrRangeMemorySize(
5394 PMIDL_STUB_MESSAGE pStubMsg
,
5395 PFORMAT_STRING pFormat
)
5397 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5398 unsigned char base_type
;
5400 if (pRange
->type
!= RPC_FC_RANGE
)
5402 ERR("invalid format type %x\n", pRange
->type
);
5403 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5406 base_type
= pRange
->flags_type
& 0xf;
5408 return NdrBaseTypeMemorySize(pStubMsg
, &base_type
);
5411 /***********************************************************************
5412 * NdrRangeFree [internal]
5414 void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg
,
5415 unsigned char *pMemory
,
5416 PFORMAT_STRING pFormat
)
5418 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5423 /***********************************************************************
5424 * NdrBaseTypeMarshall [internal]
5426 static unsigned char *WINAPI
NdrBaseTypeMarshall(
5427 PMIDL_STUB_MESSAGE pStubMsg
,
5428 unsigned char *pMemory
,
5429 PFORMAT_STRING pFormat
)
5431 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5439 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(UCHAR
));
5440 TRACE("value: 0x%02x\n", *(UCHAR
*)pMemory
);
5445 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5446 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(USHORT
));
5447 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
5451 case RPC_FC_ERROR_STATUS_T
:
5453 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
5454 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONG
));
5455 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
5458 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(float));
5459 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
5462 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(double));
5463 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
5466 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONGLONG
));
5467 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONGLONG
));
5468 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
5471 /* only 16-bits on the wire, so do a sanity check */
5472 if (*(UINT
*)pMemory
> SHRT_MAX
)
5473 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
5474 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5475 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5476 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5477 *(USHORT
*)pStubMsg
->Buffer
= *(UINT
*)pMemory
;
5478 pStubMsg
->Buffer
+= sizeof(USHORT
);
5479 TRACE("value: 0x%04x\n", *(UINT
*)pMemory
);
5484 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5487 /* FIXME: what is the correct return value? */
5491 /***********************************************************************
5492 * NdrBaseTypeUnmarshall [internal]
5494 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(
5495 PMIDL_STUB_MESSAGE pStubMsg
,
5496 unsigned char **ppMemory
,
5497 PFORMAT_STRING pFormat
,
5498 unsigned char fMustAlloc
)
5500 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
5502 #define BASE_TYPE_UNMARSHALL(type) \
5503 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5504 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
5506 *ppMemory = pStubMsg->Buffer; \
5507 TRACE("*ppMemory: %p\n", *ppMemory); \
5512 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5513 TRACE("*ppMemory: %p\n", *ppMemory); \
5514 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5516 pStubMsg->Buffer += sizeof(type);
5524 BASE_TYPE_UNMARSHALL(UCHAR
);
5525 TRACE("value: 0x%02x\n", **(UCHAR
**)ppMemory
);
5530 BASE_TYPE_UNMARSHALL(USHORT
);
5531 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5535 case RPC_FC_ERROR_STATUS_T
:
5537 BASE_TYPE_UNMARSHALL(ULONG
);
5538 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5541 BASE_TYPE_UNMARSHALL(float);
5542 TRACE("value: %f\n", **(float **)ppMemory
);
5545 BASE_TYPE_UNMARSHALL(double);
5546 TRACE("value: %f\n", **(double **)ppMemory
);
5549 BASE_TYPE_UNMARSHALL(ULONGLONG
);
5550 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG
**)ppMemory
));
5553 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5554 if (fMustAlloc
|| !*ppMemory
)
5555 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT
));
5556 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > pStubMsg
->BufferEnd
)
5557 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5558 TRACE("*ppMemory: %p\n", *ppMemory
);
5559 /* 16-bits on the wire, but int in memory */
5560 **(UINT
**)ppMemory
= *(USHORT
*)pStubMsg
->Buffer
;
5561 pStubMsg
->Buffer
+= sizeof(USHORT
);
5562 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
5567 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5569 #undef BASE_TYPE_UNMARSHALL
5571 /* FIXME: what is the correct return value? */
5576 /***********************************************************************
5577 * NdrBaseTypeBufferSize [internal]
5579 static void WINAPI
NdrBaseTypeBufferSize(
5580 PMIDL_STUB_MESSAGE pStubMsg
,
5581 unsigned char *pMemory
,
5582 PFORMAT_STRING pFormat
)
5584 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5592 safe_buffer_length_increment(pStubMsg
, sizeof(UCHAR
));
5598 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(USHORT
));
5599 safe_buffer_length_increment(pStubMsg
, sizeof(USHORT
));
5604 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONG
));
5605 safe_buffer_length_increment(pStubMsg
, sizeof(ULONG
));
5608 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(float));
5609 safe_buffer_length_increment(pStubMsg
, sizeof(float));
5612 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(double));
5613 safe_buffer_length_increment(pStubMsg
, sizeof(double));
5616 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONGLONG
));
5617 safe_buffer_length_increment(pStubMsg
, sizeof(ULONGLONG
));
5619 case RPC_FC_ERROR_STATUS_T
:
5620 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(error_status_t
));
5621 safe_buffer_length_increment(pStubMsg
, sizeof(error_status_t
));
5626 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5630 /***********************************************************************
5631 * NdrBaseTypeMemorySize [internal]
5633 static ULONG WINAPI
NdrBaseTypeMemorySize(
5634 PMIDL_STUB_MESSAGE pStubMsg
,
5635 PFORMAT_STRING pFormat
)
5643 safe_buffer_increment(pStubMsg
, sizeof(UCHAR
));
5644 pStubMsg
->MemorySize
+= sizeof(UCHAR
);
5645 return sizeof(UCHAR
);
5649 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
5650 pStubMsg
->MemorySize
+= sizeof(USHORT
);
5651 return sizeof(USHORT
);
5655 safe_buffer_increment(pStubMsg
, sizeof(ULONG
));
5656 pStubMsg
->MemorySize
+= sizeof(ULONG
);
5657 return sizeof(ULONG
);
5659 safe_buffer_increment(pStubMsg
, sizeof(float));
5660 pStubMsg
->MemorySize
+= sizeof(float);
5661 return sizeof(float);
5663 safe_buffer_increment(pStubMsg
, sizeof(double));
5664 pStubMsg
->MemorySize
+= sizeof(double);
5665 return sizeof(double);
5667 safe_buffer_increment(pStubMsg
, sizeof(ULONGLONG
));
5668 pStubMsg
->MemorySize
+= sizeof(ULONGLONG
);
5669 return sizeof(ULONGLONG
);
5670 case RPC_FC_ERROR_STATUS_T
:
5671 safe_buffer_increment(pStubMsg
, sizeof(error_status_t
));
5672 pStubMsg
->MemorySize
+= sizeof(error_status_t
);
5673 return sizeof(error_status_t
);
5675 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
5676 pStubMsg
->MemorySize
+= sizeof(UINT
);
5677 return sizeof(UINT
);
5679 pStubMsg
->MemorySize
+= sizeof(void *);
5680 return sizeof(void *);
5682 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5687 /***********************************************************************
5688 * NdrBaseTypeFree [internal]
5690 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg
,
5691 unsigned char *pMemory
,
5692 PFORMAT_STRING pFormat
)
5694 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5699 /***********************************************************************
5700 * NdrContextHandleBufferSize [internal]
5702 static void WINAPI
NdrContextHandleBufferSize(
5703 PMIDL_STUB_MESSAGE pStubMsg
,
5704 unsigned char *pMemory
,
5705 PFORMAT_STRING pFormat
)
5707 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5709 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
5711 ERR("invalid format type %x\n", *pFormat
);
5712 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5714 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
5715 safe_buffer_length_increment(pStubMsg
, cbNDRContext
);
5718 /***********************************************************************
5719 * NdrContextHandleMarshall [internal]
5721 static unsigned char *WINAPI
NdrContextHandleMarshall(
5722 PMIDL_STUB_MESSAGE pStubMsg
,
5723 unsigned char *pMemory
,
5724 PFORMAT_STRING pFormat
)
5726 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5728 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
5730 ERR("invalid format type %x\n", *pFormat
);
5731 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5734 if (pFormat
[1] & 0x80)
5735 NdrClientContextMarshall(pStubMsg
, *(NDR_CCONTEXT
**)pMemory
, FALSE
);
5737 NdrClientContextMarshall(pStubMsg
, (NDR_CCONTEXT
*)pMemory
, FALSE
);
5742 /***********************************************************************
5743 * NdrContextHandleUnmarshall [internal]
5745 static unsigned char *WINAPI
NdrContextHandleUnmarshall(
5746 PMIDL_STUB_MESSAGE pStubMsg
,
5747 unsigned char **ppMemory
,
5748 PFORMAT_STRING pFormat
,
5749 unsigned char fMustAlloc
)
5751 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
5753 ERR("invalid format type %x\n", *pFormat
);
5754 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5757 **(NDR_CCONTEXT
**)ppMemory
= NULL
;
5758 NdrClientContextUnmarshall(pStubMsg
, *(NDR_CCONTEXT
**)ppMemory
, pStubMsg
->RpcMsg
->Handle
);
5763 /***********************************************************************
5764 * NdrClientContextMarshall [RPCRT4.@]
5766 void WINAPI
NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5767 NDR_CCONTEXT ContextHandle
,
5770 TRACE("(%p, %p, %d)\n", pStubMsg
, ContextHandle
, fCheck
);
5772 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5774 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5776 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
5777 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
5778 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5781 /* FIXME: what does fCheck do? */
5782 NDRCContextMarshall(ContextHandle
,
5785 pStubMsg
->Buffer
+= cbNDRContext
;
5788 /***********************************************************************
5789 * NdrClientContextUnmarshall [RPCRT4.@]
5791 void WINAPI
NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5792 NDR_CCONTEXT
* pContextHandle
,
5793 RPC_BINDING_HANDLE BindHandle
)
5795 TRACE("(%p, %p, %p)\n", pStubMsg
, pContextHandle
, BindHandle
);
5797 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5799 if (pStubMsg
->Buffer
+ cbNDRContext
> pStubMsg
->BufferEnd
)
5800 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5802 NDRCContextUnmarshall(pContextHandle
,
5805 pStubMsg
->RpcMsg
->DataRepresentation
);
5807 pStubMsg
->Buffer
+= cbNDRContext
;
5810 void WINAPI
NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5811 NDR_SCONTEXT ContextHandle
,
5812 NDR_RUNDOWN RundownRoutine
)
5814 FIXME("(%p, %p, %p): stub\n", pStubMsg
, ContextHandle
, RundownRoutine
);
5817 NDR_SCONTEXT WINAPI
NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
)
5819 FIXME("(%p): stub\n", pStubMsg
);
5823 void WINAPI
NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg
,
5824 unsigned char* pMemory
,
5825 PFORMAT_STRING pFormat
)
5827 FIXME("(%p, %p, %p): stub\n", pStubMsg
, pMemory
, pFormat
);
5830 NDR_SCONTEXT WINAPI
NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg
,
5831 PFORMAT_STRING pFormat
)
5833 FIXME("(%p, %p): stub\n", pStubMsg
, pFormat
);
5837 void WINAPI
NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5838 NDR_SCONTEXT ContextHandle
,
5839 NDR_RUNDOWN RundownRoutine
,
5840 PFORMAT_STRING pFormat
)
5842 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg
, ContextHandle
, RundownRoutine
, pFormat
);
5845 NDR_SCONTEXT WINAPI
NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5846 PFORMAT_STRING pFormat
)
5848 FIXME("(%p, %p): stub\n", pStubMsg
, pFormat
);
5852 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
5854 typedef struct ndr_context_handle
5858 } ndr_context_handle
;
5860 struct context_handle_entry
5864 RPC_BINDING_HANDLE handle
;
5865 ndr_context_handle wire_data
;
5868 static struct list context_handle_list
= LIST_INIT(context_handle_list
);
5870 static CRITICAL_SECTION ndr_context_cs
;
5871 static CRITICAL_SECTION_DEBUG ndr_context_debug
=
5873 0, 0, &ndr_context_cs
,
5874 { &ndr_context_debug
.ProcessLocksList
, &ndr_context_debug
.ProcessLocksList
},
5875 0, 0, { (DWORD_PTR
)(__FILE__
": ndr_context") }
5877 static CRITICAL_SECTION ndr_context_cs
= { &ndr_context_debug
, -1, 0, 0, 0, 0 };
5879 static struct context_handle_entry
*get_context_entry(NDR_CCONTEXT CContext
)
5881 struct context_handle_entry
*che
= (struct context_handle_entry
*) CContext
;
5883 if (che
->magic
!= NDR_CONTEXT_HANDLE_MAGIC
)
5888 static struct context_handle_entry
*context_entry_from_guid(LPCGUID uuid
)
5890 struct context_handle_entry
*che
;
5891 LIST_FOR_EACH_ENTRY(che
, &context_handle_list
, struct context_handle_entry
, entry
)
5892 if (IsEqualGUID(&che
->wire_data
.uuid
, uuid
))
5897 RPC_BINDING_HANDLE WINAPI
NDRCContextBinding(NDR_CCONTEXT CContext
)
5899 struct context_handle_entry
*che
;
5900 RPC_BINDING_HANDLE handle
= NULL
;
5902 TRACE("%p\n", CContext
);
5904 EnterCriticalSection(&ndr_context_cs
);
5905 che
= get_context_entry(CContext
);
5907 handle
= che
->handle
;
5908 LeaveCriticalSection(&ndr_context_cs
);
5911 RpcRaiseException(ERROR_INVALID_HANDLE
);
5915 void WINAPI
NDRCContextMarshall(NDR_CCONTEXT CContext
, void *pBuff
)
5917 struct context_handle_entry
*che
;
5919 TRACE("%p %p\n", CContext
, pBuff
);
5923 EnterCriticalSection(&ndr_context_cs
);
5924 che
= get_context_entry(CContext
);
5925 memcpy(pBuff
, &che
->wire_data
, sizeof (ndr_context_handle
));
5926 LeaveCriticalSection(&ndr_context_cs
);
5930 ndr_context_handle
*wire_data
= (ndr_context_handle
*)pBuff
;
5931 wire_data
->attributes
= 0;
5932 wire_data
->uuid
= GUID_NULL
;
5936 /***********************************************************************
5937 * RpcSmDestroyClientContext [RPCRT4.@]
5939 RPC_STATUS WINAPI
RpcSmDestroyClientContext(void **ContextHandle
)
5941 RPC_STATUS status
= RPC_X_SS_CONTEXT_MISMATCH
;
5942 struct context_handle_entry
*che
= NULL
;
5944 TRACE("(%p)\n", ContextHandle
);
5946 EnterCriticalSection(&ndr_context_cs
);
5947 che
= get_context_entry(*ContextHandle
);
5948 *ContextHandle
= NULL
;
5952 list_remove(&che
->entry
);
5955 LeaveCriticalSection(&ndr_context_cs
);
5959 RpcBindingFree(&che
->handle
);
5960 HeapFree(GetProcessHeap(), 0, che
);
5966 /***********************************************************************
5967 * RpcSsDestroyClientContext [RPCRT4.@]
5969 void WINAPI
RpcSsDestroyClientContext(void **ContextHandle
)
5971 RPC_STATUS status
= RpcSmDestroyClientContext(ContextHandle
);
5972 if (status
!= RPC_S_OK
)
5973 RpcRaiseException(status
);
5976 static UINT
ndr_update_context_handle(NDR_CCONTEXT
*CContext
,
5977 RPC_BINDING_HANDLE hBinding
,
5978 const ndr_context_handle
*chi
)
5980 struct context_handle_entry
*che
= NULL
;
5982 /* a null UUID means we should free the context handle */
5983 if (IsEqualGUID(&chi
->uuid
, &GUID_NULL
))
5987 che
= get_context_entry(*CContext
);
5989 return ERROR_INVALID_HANDLE
;
5990 list_remove(&che
->entry
);
5991 RpcBindingFree(&che
->handle
);
5992 HeapFree(GetProcessHeap(), 0, che
);
5996 /* if there's no existing entry matching the GUID, allocate one */
5997 else if (!(che
= context_entry_from_guid(&chi
->uuid
)))
5999 che
= HeapAlloc(GetProcessHeap(), 0, sizeof *che
);
6001 return ERROR_NOT_ENOUGH_MEMORY
;
6002 che
->magic
= NDR_CONTEXT_HANDLE_MAGIC
;
6003 RpcBindingCopy(hBinding
, &che
->handle
);
6004 list_add_tail(&context_handle_list
, &che
->entry
);
6005 memcpy(&che
->wire_data
, chi
, sizeof *chi
);
6010 return ERROR_SUCCESS
;
6013 /***********************************************************************
6014 * NDRCContextUnmarshall [RPCRT4.@]
6016 void WINAPI
NDRCContextUnmarshall(NDR_CCONTEXT
*CContext
,
6017 RPC_BINDING_HANDLE hBinding
,
6018 void *pBuff
, ULONG DataRepresentation
)
6022 TRACE("*%p=(%p) %p %p %08x\n",
6023 CContext
, *CContext
, hBinding
, pBuff
, DataRepresentation
);
6025 EnterCriticalSection(&ndr_context_cs
);
6026 r
= ndr_update_context_handle(CContext
, hBinding
, pBuff
);
6027 LeaveCriticalSection(&ndr_context_cs
);
6029 RpcRaiseException(r
);
6032 /***********************************************************************
6033 * NDRSContextMarshall [RPCRT4.@]
6035 void WINAPI
NDRSContextMarshall(NDR_SCONTEXT CContext
,
6037 NDR_RUNDOWN userRunDownIn
)
6039 FIXME("(%p %p %p): stub\n", CContext
, pBuff
, userRunDownIn
);
6042 /***********************************************************************
6043 * NDRSContextMarshallEx [RPCRT4.@]
6045 void WINAPI
NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding
,
6046 NDR_SCONTEXT CContext
,
6048 NDR_RUNDOWN userRunDownIn
)
6050 FIXME("(%p %p %p %p): stub\n", hBinding
, CContext
, pBuff
, userRunDownIn
);
6053 /***********************************************************************
6054 * NDRSContextMarshall2 [RPCRT4.@]
6056 void WINAPI
NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding
,
6057 NDR_SCONTEXT CContext
,
6059 NDR_RUNDOWN userRunDownIn
,
6060 void *CtxGuard
, ULONG Flags
)
6062 FIXME("(%p %p %p %p %p %u): stub\n",
6063 hBinding
, CContext
, pBuff
, userRunDownIn
, CtxGuard
, Flags
);
6066 /***********************************************************************
6067 * NDRSContextUnmarshall [RPCRT4.@]
6069 NDR_SCONTEXT WINAPI
NDRSContextUnmarshall(void *pBuff
,
6070 ULONG DataRepresentation
)
6072 FIXME("(%p %08x): stub\n", pBuff
, DataRepresentation
);
6076 /***********************************************************************
6077 * NDRSContextUnmarshallEx [RPCRT4.@]
6079 NDR_SCONTEXT WINAPI
NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding
,
6081 ULONG DataRepresentation
)
6083 FIXME("(%p %p %08x): stub\n", hBinding
, pBuff
, DataRepresentation
);
6087 /***********************************************************************
6088 * NDRSContextUnmarshall2 [RPCRT4.@]
6090 NDR_SCONTEXT WINAPI
NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding
,
6092 ULONG DataRepresentation
,
6093 void *CtxGuard
, ULONG Flags
)
6095 FIXME("(%p %p %08x %p %u): stub\n",
6096 hBinding
, pBuff
, DataRepresentation
, CtxGuard
, Flags
);