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
;
1129 DWORD pointer_id
= 0;
1130 int pointer_needs_sizing
;
1132 TRACE("(%p,%p,%p)\n", pStubMsg
, Buffer
, pFormat
);
1133 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1135 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1136 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1139 case RPC_FC_RP
: /* ref pointer (always non-null) */
1140 pointer_needs_sizing
= 1;
1142 case RPC_FC_UP
: /* unique pointer */
1143 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
1144 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1145 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1147 pointer_needs_sizing
= 1;
1149 pointer_needs_sizing
= 0;
1154 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1155 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1156 pointer_needs_sizing
= !NdrFullPointerQueryRefId(
1157 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, &pointer
);
1161 FIXME("unhandled ptr type=%02x\n", type
);
1162 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1166 if (attr
& RPC_FC_P_DEREF
) {
1170 if (pointer_needs_sizing
) {
1171 m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
1172 if (m
) m(pStubMsg
, desc
);
1173 else FIXME("no memorysizer for data type=%02x\n", *desc
);
1176 return pStubMsg
->MemorySize
;
1179 /***********************************************************************
1180 * PointerFree [internal]
1182 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1183 unsigned char *Pointer
,
1184 PFORMAT_STRING pFormat
)
1186 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1187 PFORMAT_STRING desc
;
1190 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1191 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1192 if (attr
& RPC_FC_P_DONTFREE
) return;
1194 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1195 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1197 if (!Pointer
) return;
1199 if (type
== RPC_FC_FP
) {
1200 int pointer_needs_freeing
= NdrFullPointerFree(
1201 pStubMsg
->FullPtrXlatTables
, Pointer
);
1202 if (!pointer_needs_freeing
)
1206 if (attr
& RPC_FC_P_DEREF
) {
1207 Pointer
= *(unsigned char**)Pointer
;
1208 TRACE("deref => %p\n", Pointer
);
1211 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
1212 if (m
) m(pStubMsg
, Pointer
, desc
);
1214 /* we should check if the memory comes from NdrAllocate,
1215 * and deallocate only if so - checking if the pointer is between
1216 * BufferStart and BufferEnd will not always work since the buffer
1217 * may be reallocated when the server wants to marshal the reply */
1218 if (Pointer
>= (unsigned char *)pStubMsg
->RpcMsg
->Buffer
||
1219 Pointer
<= (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
1222 if (attr
& RPC_FC_P_ONSTACK
) {
1223 TRACE("not freeing stack ptr %p\n", Pointer
);
1226 TRACE("freeing %p\n", Pointer
);
1227 NdrFree(pStubMsg
, Pointer
);
1230 TRACE("not freeing %p\n", Pointer
);
1233 /***********************************************************************
1234 * EmbeddedPointerMarshall
1236 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1237 unsigned char *pMemory
,
1238 PFORMAT_STRING pFormat
)
1240 unsigned char *Mark
= pStubMsg
->BufferMark
;
1241 unsigned rep
, count
, stride
;
1243 unsigned char *saved_buffer
= NULL
;
1245 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1247 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1250 if (pStubMsg
->PointerBufferMark
)
1252 saved_buffer
= pStubMsg
->Buffer
;
1253 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1254 pStubMsg
->PointerBufferMark
= NULL
;
1257 while (pFormat
[0] != RPC_FC_END
) {
1258 switch (pFormat
[0]) {
1260 FIXME("unknown repeat type %d\n", pFormat
[0]);
1261 case RPC_FC_NO_REPEAT
:
1267 case RPC_FC_FIXED_REPEAT
:
1268 rep
= *(const WORD
*)&pFormat
[2];
1269 stride
= *(const WORD
*)&pFormat
[4];
1270 count
= *(const WORD
*)&pFormat
[8];
1273 case RPC_FC_VARIABLE_REPEAT
:
1274 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1275 stride
= *(const WORD
*)&pFormat
[2];
1276 count
= *(const WORD
*)&pFormat
[6];
1280 for (i
= 0; i
< rep
; i
++) {
1281 PFORMAT_STRING info
= pFormat
;
1282 unsigned char *membase
= pMemory
+ (i
* stride
);
1283 unsigned char *bufbase
= Mark
+ (i
* stride
);
1286 for (u
=0; u
<count
; u
++,info
+=8) {
1287 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1288 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1289 unsigned char *saved_memory
= pStubMsg
->Memory
;
1291 pStubMsg
->Memory
= pMemory
;
1292 PointerMarshall(pStubMsg
, bufptr
, *(unsigned char**)memptr
, info
+4);
1293 pStubMsg
->Memory
= saved_memory
;
1296 pFormat
+= 8 * count
;
1301 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1302 pStubMsg
->Buffer
= saved_buffer
;
1305 STD_OVERFLOW_CHECK(pStubMsg
);
1310 /***********************************************************************
1311 * EmbeddedPointerUnmarshall
1313 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1314 unsigned char *pDstMemoryPtrs
,
1315 unsigned char *pSrcMemoryPtrs
,
1316 PFORMAT_STRING pFormat
,
1317 unsigned char fMustAlloc
)
1319 unsigned char *Mark
= pStubMsg
->BufferMark
;
1320 unsigned rep
, count
, stride
;
1322 unsigned char *saved_buffer
= NULL
;
1324 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg
, pDstMemoryPtrs
, pSrcMemoryPtrs
, pFormat
, fMustAlloc
);
1326 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1329 if (pStubMsg
->PointerBufferMark
)
1331 saved_buffer
= pStubMsg
->Buffer
;
1332 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1333 pStubMsg
->PointerBufferMark
= NULL
;
1336 while (pFormat
[0] != RPC_FC_END
) {
1337 TRACE("pFormat[0] = 0x%x\n", pFormat
[0]);
1338 switch (pFormat
[0]) {
1340 FIXME("unknown repeat type %d\n", pFormat
[0]);
1341 case RPC_FC_NO_REPEAT
:
1347 case RPC_FC_FIXED_REPEAT
:
1348 rep
= *(const WORD
*)&pFormat
[2];
1349 stride
= *(const WORD
*)&pFormat
[4];
1350 count
= *(const WORD
*)&pFormat
[8];
1353 case RPC_FC_VARIABLE_REPEAT
:
1354 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1355 stride
= *(const WORD
*)&pFormat
[2];
1356 count
= *(const WORD
*)&pFormat
[6];
1360 for (i
= 0; i
< rep
; i
++) {
1361 PFORMAT_STRING info
= pFormat
;
1362 unsigned char *memdstbase
= pDstMemoryPtrs
+ (i
* stride
);
1363 unsigned char *memsrcbase
= pSrcMemoryPtrs
+ (i
* stride
);
1364 unsigned char *bufbase
= Mark
+ (i
* stride
);
1367 for (u
=0; u
<count
; u
++,info
+=8) {
1368 unsigned char **memdstptr
= (unsigned char **)(memdstbase
+ *(const SHORT
*)&info
[0]);
1369 unsigned char **memsrcptr
= (unsigned char **)(memsrcbase
+ *(const SHORT
*)&info
[0]);
1370 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1371 PointerUnmarshall(pStubMsg
, bufptr
, memdstptr
, *memsrcptr
, info
+4, fMustAlloc
);
1374 pFormat
+= 8 * count
;
1379 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1380 pStubMsg
->Buffer
= saved_buffer
;
1386 /***********************************************************************
1387 * EmbeddedPointerBufferSize
1389 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1390 unsigned char *pMemory
,
1391 PFORMAT_STRING pFormat
)
1393 unsigned rep
, count
, stride
;
1395 ULONG saved_buffer_length
= 0;
1397 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1399 if (pStubMsg
->IgnoreEmbeddedPointers
) return;
1401 if (*pFormat
!= RPC_FC_PP
) return;
1404 if (pStubMsg
->PointerLength
)
1406 saved_buffer_length
= pStubMsg
->BufferLength
;
1407 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
1408 pStubMsg
->PointerLength
= 0;
1411 while (pFormat
[0] != RPC_FC_END
) {
1412 switch (pFormat
[0]) {
1414 FIXME("unknown repeat type %d\n", pFormat
[0]);
1415 case RPC_FC_NO_REPEAT
:
1421 case RPC_FC_FIXED_REPEAT
:
1422 rep
= *(const WORD
*)&pFormat
[2];
1423 stride
= *(const WORD
*)&pFormat
[4];
1424 count
= *(const WORD
*)&pFormat
[8];
1427 case RPC_FC_VARIABLE_REPEAT
:
1428 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1429 stride
= *(const WORD
*)&pFormat
[2];
1430 count
= *(const WORD
*)&pFormat
[6];
1434 for (i
= 0; i
< rep
; i
++) {
1435 PFORMAT_STRING info
= pFormat
;
1436 unsigned char *membase
= pMemory
+ (i
* stride
);
1439 for (u
=0; u
<count
; u
++,info
+=8) {
1440 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1441 unsigned char *saved_memory
= pStubMsg
->Memory
;
1443 pStubMsg
->Memory
= pMemory
;
1444 PointerBufferSize(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1445 pStubMsg
->Memory
= saved_memory
;
1448 pFormat
+= 8 * count
;
1451 if (saved_buffer_length
)
1453 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
1454 pStubMsg
->BufferLength
= saved_buffer_length
;
1458 /***********************************************************************
1459 * EmbeddedPointerMemorySize [internal]
1461 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1462 PFORMAT_STRING pFormat
)
1464 unsigned char *Mark
= pStubMsg
->BufferMark
;
1465 unsigned rep
, count
, stride
;
1468 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1470 if (pStubMsg
->IgnoreEmbeddedPointers
) return 0;
1472 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1474 if (*pFormat
!= RPC_FC_PP
) return 0;
1477 while (pFormat
[0] != RPC_FC_END
) {
1478 switch (pFormat
[0]) {
1480 FIXME("unknown repeat type %d\n", pFormat
[0]);
1481 case RPC_FC_NO_REPEAT
:
1487 case RPC_FC_FIXED_REPEAT
:
1488 rep
= *(const WORD
*)&pFormat
[2];
1489 stride
= *(const WORD
*)&pFormat
[4];
1490 count
= *(const WORD
*)&pFormat
[8];
1493 case RPC_FC_VARIABLE_REPEAT
:
1494 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1495 stride
= *(const WORD
*)&pFormat
[2];
1496 count
= *(const WORD
*)&pFormat
[6];
1500 for (i
= 0; i
< rep
; i
++) {
1501 PFORMAT_STRING info
= pFormat
;
1502 unsigned char *bufbase
= Mark
+ (i
* stride
);
1504 for (u
=0; u
<count
; u
++,info
+=8) {
1505 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1506 PointerMemorySize(pStubMsg
, bufptr
, info
+4);
1509 pFormat
+= 8 * count
;
1515 /***********************************************************************
1516 * EmbeddedPointerFree [internal]
1518 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1519 unsigned char *pMemory
,
1520 PFORMAT_STRING pFormat
)
1522 unsigned rep
, count
, stride
;
1525 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1526 if (*pFormat
!= RPC_FC_PP
) return;
1529 while (pFormat
[0] != RPC_FC_END
) {
1530 switch (pFormat
[0]) {
1532 FIXME("unknown repeat type %d\n", pFormat
[0]);
1533 case RPC_FC_NO_REPEAT
:
1539 case RPC_FC_FIXED_REPEAT
:
1540 rep
= *(const WORD
*)&pFormat
[2];
1541 stride
= *(const WORD
*)&pFormat
[4];
1542 count
= *(const WORD
*)&pFormat
[8];
1545 case RPC_FC_VARIABLE_REPEAT
:
1546 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1547 stride
= *(const WORD
*)&pFormat
[2];
1548 count
= *(const WORD
*)&pFormat
[6];
1552 for (i
= 0; i
< rep
; i
++) {
1553 PFORMAT_STRING info
= pFormat
;
1554 unsigned char *membase
= pMemory
+ (i
* stride
);
1557 for (u
=0; u
<count
; u
++,info
+=8) {
1558 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1559 unsigned char *saved_memory
= pStubMsg
->Memory
;
1561 pStubMsg
->Memory
= pMemory
;
1562 PointerFree(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1563 pStubMsg
->Memory
= saved_memory
;
1566 pFormat
+= 8 * count
;
1570 /***********************************************************************
1571 * NdrPointerMarshall [RPCRT4.@]
1573 unsigned char * WINAPI
NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1574 unsigned char *pMemory
,
1575 PFORMAT_STRING pFormat
)
1577 unsigned char *Buffer
;
1579 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1581 /* incremement the buffer here instead of in PointerMarshall,
1582 * as that is used by embedded pointers which already handle the incrementing
1583 * the buffer, and shouldn't write any additional pointer data to the wire */
1584 if (*pFormat
!= RPC_FC_RP
)
1586 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1587 Buffer
= pStubMsg
->Buffer
;
1588 safe_buffer_increment(pStubMsg
, 4);
1591 Buffer
= pStubMsg
->Buffer
;
1593 PointerMarshall(pStubMsg
, Buffer
, pMemory
, pFormat
);
1598 /***********************************************************************
1599 * NdrPointerUnmarshall [RPCRT4.@]
1601 unsigned char * WINAPI
NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1602 unsigned char **ppMemory
,
1603 PFORMAT_STRING pFormat
,
1604 unsigned char fMustAlloc
)
1606 unsigned char *Buffer
;
1608 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1610 /* incremement the buffer here instead of in PointerUnmarshall,
1611 * as that is used by embedded pointers which already handle the incrementing
1612 * the buffer, and shouldn't read any additional pointer data from the
1614 if (*pFormat
!= RPC_FC_RP
)
1616 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1617 Buffer
= pStubMsg
->Buffer
;
1618 safe_buffer_increment(pStubMsg
, 4);
1621 Buffer
= pStubMsg
->Buffer
;
1623 PointerUnmarshall(pStubMsg
, Buffer
, ppMemory
, *ppMemory
, pFormat
, fMustAlloc
);
1628 /***********************************************************************
1629 * NdrPointerBufferSize [RPCRT4.@]
1631 void WINAPI
NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1632 unsigned char *pMemory
,
1633 PFORMAT_STRING pFormat
)
1635 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1637 /* incremement the buffer length here instead of in PointerBufferSize,
1638 * as that is used by embedded pointers which already handle the buffer
1639 * length, and shouldn't write anything more to the wire */
1640 if (*pFormat
!= RPC_FC_RP
)
1642 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
1643 safe_buffer_length_increment(pStubMsg
, 4);
1646 PointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1649 /***********************************************************************
1650 * NdrPointerMemorySize [RPCRT4.@]
1652 ULONG WINAPI
NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1653 PFORMAT_STRING pFormat
)
1655 /* unsigned size = *(LPWORD)(pFormat+2); */
1656 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1657 PointerMemorySize(pStubMsg
, pStubMsg
->Buffer
, pFormat
);
1661 /***********************************************************************
1662 * NdrPointerFree [RPCRT4.@]
1664 void WINAPI
NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1665 unsigned char *pMemory
,
1666 PFORMAT_STRING pFormat
)
1668 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1669 PointerFree(pStubMsg
, pMemory
, pFormat
);
1672 /***********************************************************************
1673 * NdrSimpleTypeMarshall [RPCRT4.@]
1675 void WINAPI
NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1676 unsigned char FormatChar
)
1678 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &FormatChar
);
1681 /***********************************************************************
1682 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1684 void WINAPI
NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1685 unsigned char FormatChar
)
1687 NdrBaseTypeUnmarshall(pStubMsg
, &pMemory
, &FormatChar
, 0);
1690 /***********************************************************************
1691 * NdrSimpleStructMarshall [RPCRT4.@]
1693 unsigned char * WINAPI
NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1694 unsigned char *pMemory
,
1695 PFORMAT_STRING pFormat
)
1697 unsigned size
= *(const WORD
*)(pFormat
+2);
1698 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1700 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1702 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1703 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
1705 if (pFormat
[0] != RPC_FC_STRUCT
)
1706 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
+4);
1711 /***********************************************************************
1712 * NdrSimpleStructUnmarshall [RPCRT4.@]
1714 unsigned char * WINAPI
NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1715 unsigned char **ppMemory
,
1716 PFORMAT_STRING pFormat
,
1717 unsigned char fMustAlloc
)
1719 unsigned size
= *(const WORD
*)(pFormat
+2);
1720 unsigned char *saved_buffer
;
1721 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1723 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1726 *ppMemory
= NdrAllocate(pStubMsg
, size
);
1729 if (!pStubMsg
->IsClient
&& !*ppMemory
)
1730 /* for servers, we just point straight into the RPC buffer */
1731 *ppMemory
= pStubMsg
->Buffer
;
1734 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1735 safe_buffer_increment(pStubMsg
, size
);
1736 if (pFormat
[0] == RPC_FC_PSTRUCT
)
1737 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
+4, fMustAlloc
);
1739 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
1740 if (*ppMemory
!= saved_buffer
)
1741 memcpy(*ppMemory
, saved_buffer
, size
);
1746 /***********************************************************************
1747 * NdrSimpleStructBufferSize [RPCRT4.@]
1749 void WINAPI
NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1750 unsigned char *pMemory
,
1751 PFORMAT_STRING pFormat
)
1753 unsigned size
= *(const WORD
*)(pFormat
+2);
1754 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1756 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
1758 safe_buffer_length_increment(pStubMsg
, size
);
1759 if (pFormat
[0] != RPC_FC_STRUCT
)
1760 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
+4);
1763 /***********************************************************************
1764 * NdrSimpleStructMemorySize [RPCRT4.@]
1766 ULONG WINAPI
NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1767 PFORMAT_STRING pFormat
)
1769 unsigned short size
= *(const WORD
*)(pFormat
+2);
1771 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1773 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1774 pStubMsg
->MemorySize
+= size
;
1775 safe_buffer_increment(pStubMsg
, size
);
1777 if (pFormat
[0] != RPC_FC_STRUCT
)
1778 EmbeddedPointerMemorySize(pStubMsg
, pFormat
+4);
1782 /***********************************************************************
1783 * NdrSimpleStructFree [RPCRT4.@]
1785 void WINAPI
NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
1786 unsigned char *pMemory
,
1787 PFORMAT_STRING pFormat
)
1789 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1790 if (pFormat
[0] != RPC_FC_STRUCT
)
1791 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
+4);
1795 static unsigned long EmbeddedComplexSize(const MIDL_STUB_MESSAGE
*pStubMsg
,
1796 PFORMAT_STRING pFormat
)
1800 case RPC_FC_PSTRUCT
:
1801 case RPC_FC_CSTRUCT
:
1802 case RPC_FC_BOGUS_STRUCT
:
1803 case RPC_FC_SMFARRAY
:
1804 case RPC_FC_SMVARRAY
:
1805 return *(const WORD
*)&pFormat
[2];
1806 case RPC_FC_USER_MARSHAL
:
1807 return *(const WORD
*)&pFormat
[4];
1808 case RPC_FC_NON_ENCAPSULATED_UNION
:
1810 if (pStubMsg
->fHasNewCorrDesc
)
1815 pFormat
+= *(const SHORT
*)pFormat
;
1816 return *(const SHORT
*)pFormat
;
1818 return sizeof(void *);
1820 FIXME("unhandled embedded type %02x\n", *pFormat
);
1826 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1827 PFORMAT_STRING pFormat
)
1829 NDR_MEMORYSIZE m
= NdrMemorySizer
[*pFormat
& NDR_TABLE_MASK
];
1833 FIXME("no memorysizer for data type=%02x\n", *pFormat
);
1837 return m(pStubMsg
, pFormat
);
1841 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1842 unsigned char *pMemory
,
1843 PFORMAT_STRING pFormat
,
1844 PFORMAT_STRING pPointer
)
1846 PFORMAT_STRING desc
;
1850 while (*pFormat
!= RPC_FC_END
) {
1856 TRACE("byte=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
1857 safe_copy_to_buffer(pStubMsg
, pMemory
, 1);
1863 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
1864 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
1870 TRACE("long=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
1871 safe_copy_to_buffer(pStubMsg
, pMemory
, 4);
1875 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
1876 safe_copy_to_buffer(pStubMsg
, pMemory
, 8);
1879 case RPC_FC_POINTER
:
1881 unsigned char *saved_buffer
;
1882 int pointer_buffer_mark_set
= 0;
1883 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
1884 saved_buffer
= pStubMsg
->Buffer
;
1885 if (pStubMsg
->PointerBufferMark
)
1887 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1888 pStubMsg
->PointerBufferMark
= NULL
;
1889 pointer_buffer_mark_set
= 1;
1892 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
1893 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char**)pMemory
, pPointer
);
1894 if (pointer_buffer_mark_set
)
1896 STD_OVERFLOW_CHECK(pStubMsg
);
1897 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1898 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
1900 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
1901 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
1902 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1904 pStubMsg
->Buffer
= saved_buffer
+ 4;
1910 case RPC_FC_ALIGNM4
:
1911 ALIGN_POINTER(pMemory
, 4);
1913 case RPC_FC_ALIGNM8
:
1914 ALIGN_POINTER(pMemory
, 8);
1916 case RPC_FC_STRUCTPAD1
:
1917 case RPC_FC_STRUCTPAD2
:
1918 case RPC_FC_STRUCTPAD3
:
1919 case RPC_FC_STRUCTPAD4
:
1920 case RPC_FC_STRUCTPAD5
:
1921 case RPC_FC_STRUCTPAD6
:
1922 case RPC_FC_STRUCTPAD7
:
1923 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
1925 case RPC_FC_EMBEDDED_COMPLEX
:
1926 pMemory
+= pFormat
[1];
1928 desc
= pFormat
+ *(const SHORT
*)pFormat
;
1929 size
= EmbeddedComplexSize(pStubMsg
, desc
);
1930 TRACE("embedded complex (size=%ld) <= %p\n", size
, pMemory
);
1931 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
1934 /* for some reason interface pointers aren't generated as
1935 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
1936 * they still need the derefencing treatment that pointers are
1938 if (*desc
== RPC_FC_IP
)
1939 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
1941 m(pStubMsg
, pMemory
, desc
);
1943 else FIXME("no marshaller for embedded type %02x\n", *desc
);
1950 FIXME("unhandled format 0x%02x\n", *pFormat
);
1958 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1959 unsigned char *pMemory
,
1960 PFORMAT_STRING pFormat
,
1961 PFORMAT_STRING pPointer
)
1963 PFORMAT_STRING desc
;
1967 while (*pFormat
!= RPC_FC_END
) {
1973 safe_copy_from_buffer(pStubMsg
, pMemory
, 1);
1974 TRACE("byte=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
1980 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
1981 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
1987 safe_copy_from_buffer(pStubMsg
, pMemory
, 4);
1988 TRACE("long=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
1992 safe_copy_from_buffer(pStubMsg
, pMemory
, 8);
1993 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
1996 case RPC_FC_POINTER
:
1998 unsigned char *saved_buffer
;
1999 int pointer_buffer_mark_set
= 0;
2000 TRACE("pointer => %p\n", pMemory
);
2001 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2002 saved_buffer
= pStubMsg
->Buffer
;
2003 if (pStubMsg
->PointerBufferMark
)
2005 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2006 pStubMsg
->PointerBufferMark
= NULL
;
2007 pointer_buffer_mark_set
= 1;
2010 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2012 PointerUnmarshall(pStubMsg
, saved_buffer
, (unsigned char**)pMemory
, *(unsigned char**)pMemory
, pPointer
, TRUE
);
2013 if (pointer_buffer_mark_set
)
2015 STD_OVERFLOW_CHECK(pStubMsg
);
2016 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2017 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
2019 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2020 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
2021 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2023 pStubMsg
->Buffer
= saved_buffer
+ 4;
2029 case RPC_FC_ALIGNM4
:
2030 ALIGN_POINTER(pMemory
, 4);
2032 case RPC_FC_ALIGNM8
:
2033 ALIGN_POINTER(pMemory
, 8);
2035 case RPC_FC_STRUCTPAD1
:
2036 case RPC_FC_STRUCTPAD2
:
2037 case RPC_FC_STRUCTPAD3
:
2038 case RPC_FC_STRUCTPAD4
:
2039 case RPC_FC_STRUCTPAD5
:
2040 case RPC_FC_STRUCTPAD6
:
2041 case RPC_FC_STRUCTPAD7
:
2042 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2044 case RPC_FC_EMBEDDED_COMPLEX
:
2045 pMemory
+= pFormat
[1];
2047 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2048 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2049 TRACE("embedded complex (size=%ld) => %p\n", size
, pMemory
);
2050 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
2051 memset(pMemory
, 0, size
); /* just in case */
2054 /* for some reason interface pointers aren't generated as
2055 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2056 * they still need the derefencing treatment that pointers are
2058 if (*desc
== RPC_FC_IP
)
2059 m(pStubMsg
, (unsigned char **)pMemory
, desc
, FALSE
);
2061 m(pStubMsg
, &pMemory
, desc
, FALSE
);
2063 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
2070 FIXME("unhandled format %d\n", *pFormat
);
2078 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2079 unsigned char *pMemory
,
2080 PFORMAT_STRING pFormat
,
2081 PFORMAT_STRING pPointer
)
2083 PFORMAT_STRING desc
;
2087 while (*pFormat
!= RPC_FC_END
) {
2093 safe_buffer_length_increment(pStubMsg
, 1);
2099 safe_buffer_length_increment(pStubMsg
, 2);
2105 safe_buffer_length_increment(pStubMsg
, 4);
2109 safe_buffer_length_increment(pStubMsg
, 8);
2112 case RPC_FC_POINTER
:
2113 if (!pStubMsg
->IgnoreEmbeddedPointers
)
2115 int saved_buffer_length
= pStubMsg
->BufferLength
;
2116 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2117 pStubMsg
->PointerLength
= 0;
2118 if(!pStubMsg
->BufferLength
)
2119 ERR("BufferLength == 0??\n");
2120 PointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
2121 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2122 pStubMsg
->BufferLength
= saved_buffer_length
;
2124 safe_buffer_length_increment(pStubMsg
, 4);
2128 case RPC_FC_ALIGNM4
:
2129 ALIGN_POINTER(pMemory
, 4);
2131 case RPC_FC_ALIGNM8
:
2132 ALIGN_POINTER(pMemory
, 8);
2134 case RPC_FC_STRUCTPAD1
:
2135 case RPC_FC_STRUCTPAD2
:
2136 case RPC_FC_STRUCTPAD3
:
2137 case RPC_FC_STRUCTPAD4
:
2138 case RPC_FC_STRUCTPAD5
:
2139 case RPC_FC_STRUCTPAD6
:
2140 case RPC_FC_STRUCTPAD7
:
2141 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2143 case RPC_FC_EMBEDDED_COMPLEX
:
2144 pMemory
+= pFormat
[1];
2146 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2147 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2148 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
2151 /* for some reason interface pointers aren't generated as
2152 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2153 * they still need the derefencing treatment that pointers are
2155 if (*desc
== RPC_FC_IP
)
2156 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2158 m(pStubMsg
, pMemory
, desc
);
2160 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
2167 FIXME("unhandled format 0x%02x\n", *pFormat
);
2175 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
2176 unsigned char *pMemory
,
2177 PFORMAT_STRING pFormat
,
2178 PFORMAT_STRING pPointer
)
2180 PFORMAT_STRING desc
;
2184 while (*pFormat
!= RPC_FC_END
) {
2205 case RPC_FC_POINTER
:
2206 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
2210 case RPC_FC_ALIGNM4
:
2211 ALIGN_POINTER(pMemory
, 4);
2213 case RPC_FC_ALIGNM8
:
2214 ALIGN_POINTER(pMemory
, 8);
2216 case RPC_FC_STRUCTPAD1
:
2217 case RPC_FC_STRUCTPAD2
:
2218 case RPC_FC_STRUCTPAD3
:
2219 case RPC_FC_STRUCTPAD4
:
2220 case RPC_FC_STRUCTPAD5
:
2221 case RPC_FC_STRUCTPAD6
:
2222 case RPC_FC_STRUCTPAD7
:
2223 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2225 case RPC_FC_EMBEDDED_COMPLEX
:
2226 pMemory
+= pFormat
[1];
2228 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2229 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2230 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
2233 /* for some reason interface pointers aren't generated as
2234 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2235 * they still need the derefencing treatment that pointers are
2237 if (*desc
== RPC_FC_IP
)
2238 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2240 m(pStubMsg
, pMemory
, desc
);
2242 else FIXME("no freer for embedded type %02x\n", *desc
);
2249 FIXME("unhandled format 0x%02x\n", *pFormat
);
2257 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2258 PFORMAT_STRING pFormat
)
2260 PFORMAT_STRING desc
;
2261 unsigned long size
= 0;
2263 while (*pFormat
!= RPC_FC_END
) {
2270 safe_buffer_increment(pStubMsg
, 1);
2276 safe_buffer_increment(pStubMsg
, 2);
2282 safe_buffer_increment(pStubMsg
, 4);
2286 safe_buffer_increment(pStubMsg
, 8);
2288 case RPC_FC_POINTER
:
2290 safe_buffer_increment(pStubMsg
, 4);
2291 if (!pStubMsg
->IgnoreEmbeddedPointers
)
2292 FIXME("embedded pointers\n");
2294 case RPC_FC_ALIGNM4
:
2295 ALIGN_LENGTH(size
, 4);
2296 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2298 case RPC_FC_ALIGNM8
:
2299 ALIGN_LENGTH(size
, 8);
2300 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
2302 case RPC_FC_STRUCTPAD1
:
2303 case RPC_FC_STRUCTPAD2
:
2304 case RPC_FC_STRUCTPAD3
:
2305 case RPC_FC_STRUCTPAD4
:
2306 case RPC_FC_STRUCTPAD5
:
2307 case RPC_FC_STRUCTPAD6
:
2308 case RPC_FC_STRUCTPAD7
:
2309 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2311 case RPC_FC_EMBEDDED_COMPLEX
:
2314 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2315 size
+= EmbeddedComplexMemorySize(pStubMsg
, desc
);
2321 FIXME("unhandled format 0x%02x\n", *pFormat
);
2329 /***********************************************************************
2330 * NdrComplexStructMarshall [RPCRT4.@]
2332 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2333 unsigned char *pMemory
,
2334 PFORMAT_STRING pFormat
)
2336 PFORMAT_STRING conf_array
= NULL
;
2337 PFORMAT_STRING pointer_desc
= NULL
;
2338 unsigned char *OldMemory
= pStubMsg
->Memory
;
2339 int pointer_buffer_mark_set
= 0;
2341 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2343 if (!pStubMsg
->PointerBufferMark
)
2345 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2346 /* save buffer length */
2347 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2349 /* get the buffer pointer after complex array data, but before
2351 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- pStubMsg
->BufferStart
;
2352 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2353 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
2354 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2356 /* save it for use by embedded pointer code later */
2357 pStubMsg
->PointerBufferMark
= pStubMsg
->BufferStart
+ pStubMsg
->BufferLength
;
2358 TRACE("difference = 0x%x\n", pStubMsg
->PointerBufferMark
- pStubMsg
->Buffer
);
2359 pointer_buffer_mark_set
= 1;
2361 /* restore the original buffer length */
2362 pStubMsg
->BufferLength
= saved_buffer_length
;
2365 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2368 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2370 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2373 pStubMsg
->Memory
= pMemory
;
2375 ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2378 NdrConformantArrayMarshall(pStubMsg
, pMemory
, conf_array
);
2380 pStubMsg
->Memory
= OldMemory
;
2382 if (pointer_buffer_mark_set
)
2384 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2385 pStubMsg
->PointerBufferMark
= NULL
;
2388 STD_OVERFLOW_CHECK(pStubMsg
);
2393 /***********************************************************************
2394 * NdrComplexStructUnmarshall [RPCRT4.@]
2396 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2397 unsigned char **ppMemory
,
2398 PFORMAT_STRING pFormat
,
2399 unsigned char fMustAlloc
)
2401 unsigned size
= *(const WORD
*)(pFormat
+2);
2402 PFORMAT_STRING conf_array
= NULL
;
2403 PFORMAT_STRING pointer_desc
= NULL
;
2404 unsigned char *pMemory
;
2405 int pointer_buffer_mark_set
= 0;
2407 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2409 if (!pStubMsg
->PointerBufferMark
)
2411 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2412 /* save buffer pointer */
2413 unsigned char *saved_buffer
= pStubMsg
->Buffer
;
2415 /* get the buffer pointer after complex array data, but before
2417 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2418 NdrComplexStructMemorySize(pStubMsg
, pFormat
);
2419 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2421 /* save it for use by embedded pointer code later */
2422 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2423 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->PointerBufferMark
- saved_buffer
));
2424 pointer_buffer_mark_set
= 1;
2426 /* restore the original buffer */
2427 pStubMsg
->Buffer
= saved_buffer
;
2430 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2432 if (fMustAlloc
|| !*ppMemory
)
2434 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2435 memset(*ppMemory
, 0, size
);
2439 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2441 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2444 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
);
2447 NdrConformantArrayUnmarshall(pStubMsg
, &pMemory
, conf_array
, fMustAlloc
);
2449 if (pointer_buffer_mark_set
)
2451 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2452 pStubMsg
->PointerBufferMark
= NULL
;
2458 /***********************************************************************
2459 * NdrComplexStructBufferSize [RPCRT4.@]
2461 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2462 unsigned char *pMemory
,
2463 PFORMAT_STRING pFormat
)
2465 PFORMAT_STRING conf_array
= NULL
;
2466 PFORMAT_STRING pointer_desc
= NULL
;
2467 unsigned char *OldMemory
= pStubMsg
->Memory
;
2468 int pointer_length_set
= 0;
2470 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2472 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
2474 if(!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
2476 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2477 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2479 /* get the buffer length after complex struct data, but before
2481 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2482 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
2483 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2485 /* save it for use by embedded pointer code later */
2486 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2487 pointer_length_set
= 1;
2488 TRACE("difference = 0x%lx\n", pStubMsg
->PointerLength
- saved_buffer_length
);
2490 /* restore the original buffer length */
2491 pStubMsg
->BufferLength
= saved_buffer_length
;
2495 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2497 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2500 pStubMsg
->Memory
= pMemory
;
2502 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2505 NdrConformantArrayBufferSize(pStubMsg
, pMemory
, conf_array
);
2507 pStubMsg
->Memory
= OldMemory
;
2509 if(pointer_length_set
)
2511 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2512 pStubMsg
->PointerLength
= 0;
2517 /***********************************************************************
2518 * NdrComplexStructMemorySize [RPCRT4.@]
2520 ULONG WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2521 PFORMAT_STRING pFormat
)
2523 unsigned size
= *(const WORD
*)(pFormat
+2);
2524 PFORMAT_STRING conf_array
= NULL
;
2525 PFORMAT_STRING pointer_desc
= NULL
;
2527 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2529 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2532 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2534 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2537 ComplexStructMemorySize(pStubMsg
, pFormat
);
2540 NdrConformantArrayMemorySize(pStubMsg
, conf_array
);
2545 /***********************************************************************
2546 * NdrComplexStructFree [RPCRT4.@]
2548 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
2549 unsigned char *pMemory
,
2550 PFORMAT_STRING pFormat
)
2552 PFORMAT_STRING conf_array
= NULL
;
2553 PFORMAT_STRING pointer_desc
= NULL
;
2554 unsigned char *OldMemory
= pStubMsg
->Memory
;
2556 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2559 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2561 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2564 pStubMsg
->Memory
= pMemory
;
2566 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2569 NdrConformantArrayFree(pStubMsg
, pMemory
, conf_array
);
2571 pStubMsg
->Memory
= OldMemory
;
2574 /***********************************************************************
2575 * NdrConformantArrayMarshall [RPCRT4.@]
2577 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2578 unsigned char *pMemory
,
2579 PFORMAT_STRING pFormat
)
2581 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
2582 unsigned char alignment
= pFormat
[1] + 1;
2584 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2585 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2587 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2589 WriteConformance(pStubMsg
);
2591 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2593 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2594 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2595 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
2597 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2602 /***********************************************************************
2603 * NdrConformantArrayUnmarshall [RPCRT4.@]
2605 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2606 unsigned char **ppMemory
,
2607 PFORMAT_STRING pFormat
,
2608 unsigned char fMustAlloc
)
2610 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
2611 unsigned char alignment
= pFormat
[1] + 1;
2612 unsigned char *saved_buffer
;
2614 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2615 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2617 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2619 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2620 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2623 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2626 if (!pStubMsg
->IsClient
&& !*ppMemory
)
2627 /* for servers, we just point straight into the RPC buffer */
2628 *ppMemory
= pStubMsg
->Buffer
;
2631 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2632 safe_buffer_increment(pStubMsg
, size
);
2633 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
2635 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
2636 if (*ppMemory
!= saved_buffer
)
2637 memcpy(*ppMemory
, saved_buffer
, size
);
2642 /***********************************************************************
2643 * NdrConformantArrayBufferSize [RPCRT4.@]
2645 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2646 unsigned char *pMemory
,
2647 PFORMAT_STRING pFormat
)
2649 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
2650 unsigned char alignment
= pFormat
[1] + 1;
2652 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2653 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2655 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2657 SizeConformance(pStubMsg
);
2659 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
2661 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2662 /* conformance value plus array */
2663 safe_buffer_length_increment(pStubMsg
, size
);
2665 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
2668 /***********************************************************************
2669 * NdrConformantArrayMemorySize [RPCRT4.@]
2671 ULONG WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2672 PFORMAT_STRING pFormat
)
2674 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
2675 unsigned char alignment
= pFormat
[1] + 1;
2677 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2678 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2680 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2681 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2682 pStubMsg
->MemorySize
+= size
;
2684 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2685 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2686 safe_buffer_increment(pStubMsg
, size
);
2688 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2690 return pStubMsg
->MemorySize
;
2693 /***********************************************************************
2694 * NdrConformantArrayFree [RPCRT4.@]
2696 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
2697 unsigned char *pMemory
,
2698 PFORMAT_STRING pFormat
)
2700 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2701 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2703 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2705 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2709 /***********************************************************************
2710 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2712 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2713 unsigned char* pMemory
,
2714 PFORMAT_STRING pFormat
)
2717 unsigned char alignment
= pFormat
[1] + 1;
2718 DWORD esize
= *(const WORD
*)(pFormat
+2);
2720 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
2722 if (pFormat
[0] != RPC_FC_CVARRAY
)
2724 ERR("invalid format type %x\n", pFormat
[0]);
2725 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2729 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2730 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2732 WriteConformance(pStubMsg
);
2733 WriteVariance(pStubMsg
);
2735 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2737 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2739 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2740 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
2742 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2748 /***********************************************************************
2749 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2751 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2752 unsigned char** ppMemory
,
2753 PFORMAT_STRING pFormat
,
2754 unsigned char fMustAlloc
)
2756 ULONG bufsize
, memsize
;
2757 unsigned char alignment
= pFormat
[1] + 1;
2758 DWORD esize
= *(const WORD
*)(pFormat
+2);
2760 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2762 if (pFormat
[0] != RPC_FC_CVARRAY
)
2764 ERR("invalid format type %x\n", pFormat
[0]);
2765 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2769 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2770 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2772 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2774 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2775 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2777 if (!*ppMemory
|| fMustAlloc
)
2778 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2779 safe_copy_from_buffer(pStubMsg
, *ppMemory
+ pStubMsg
->Offset
, bufsize
);
2781 EmbeddedPointerUnmarshall(pStubMsg
, *ppMemory
, *ppMemory
, pFormat
, TRUE
/* FIXME */);
2787 /***********************************************************************
2788 * NdrConformantVaryingArrayFree [RPCRT4.@]
2790 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
2791 unsigned char* pMemory
,
2792 PFORMAT_STRING pFormat
)
2794 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2796 if (pFormat
[0] != RPC_FC_CVARRAY
)
2798 ERR("invalid format type %x\n", pFormat
[0]);
2799 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2803 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2804 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2806 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2810 /***********************************************************************
2811 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2813 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
2814 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
2816 unsigned char alignment
= pFormat
[1] + 1;
2817 DWORD esize
= *(const WORD
*)(pFormat
+2);
2819 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
2821 if (pFormat
[0] != RPC_FC_CVARRAY
)
2823 ERR("invalid format type %x\n", pFormat
[0]);
2824 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2829 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2830 /* compute length */
2831 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2833 SizeConformance(pStubMsg
);
2834 SizeVariance(pStubMsg
);
2836 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
2838 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
2840 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
2844 /***********************************************************************
2845 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2847 ULONG WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
2848 PFORMAT_STRING pFormat
)
2855 /***********************************************************************
2856 * NdrComplexArrayMarshall [RPCRT4.@]
2858 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2859 unsigned char *pMemory
,
2860 PFORMAT_STRING pFormat
)
2862 ULONG i
, count
, def
;
2863 BOOL variance_present
;
2864 unsigned char alignment
;
2865 int pointer_buffer_mark_set
= 0;
2867 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2869 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
2871 ERR("invalid format type %x\n", pFormat
[0]);
2872 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2876 alignment
= pFormat
[1] + 1;
2878 if (!pStubMsg
->PointerBufferMark
)
2880 /* save buffer fields that may be changed by buffer sizer functions
2881 * and that may be needed later on */
2882 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2883 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2884 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
2885 unsigned long saved_offset
= pStubMsg
->Offset
;
2886 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
2888 /* get the buffer pointer after complex array data, but before
2890 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- pStubMsg
->BufferStart
;
2891 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2892 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
2893 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2895 /* save it for use by embedded pointer code later */
2896 pStubMsg
->PointerBufferMark
= pStubMsg
->BufferStart
+ pStubMsg
->BufferLength
;
2897 TRACE("difference = 0x%x\n", pStubMsg
->Buffer
- pStubMsg
->BufferStart
);
2898 pointer_buffer_mark_set
= 1;
2900 /* restore fields */
2901 pStubMsg
->ActualCount
= saved_actual_count
;
2902 pStubMsg
->Offset
= saved_offset
;
2903 pStubMsg
->MaxCount
= saved_max_count
;
2904 pStubMsg
->BufferLength
= saved_buffer_length
;
2907 def
= *(const WORD
*)&pFormat
[2];
2910 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
2911 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
2913 variance_present
= IsConformanceOrVariancePresent(pFormat
);
2914 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
2915 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
2917 WriteConformance(pStubMsg
);
2918 if (variance_present
)
2919 WriteVariance(pStubMsg
);
2921 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2923 count
= pStubMsg
->ActualCount
;
2924 for (i
= 0; i
< count
; i
++)
2925 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
2927 STD_OVERFLOW_CHECK(pStubMsg
);
2929 if (pointer_buffer_mark_set
)
2931 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2932 pStubMsg
->PointerBufferMark
= NULL
;
2938 /***********************************************************************
2939 * NdrComplexArrayUnmarshall [RPCRT4.@]
2941 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2942 unsigned char **ppMemory
,
2943 PFORMAT_STRING pFormat
,
2944 unsigned char fMustAlloc
)
2946 ULONG i
, count
, size
;
2947 unsigned char alignment
;
2948 unsigned char *pMemory
;
2949 unsigned char *saved_buffer
;
2950 int pointer_buffer_mark_set
= 0;
2951 int saved_ignore_embedded
;
2953 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2955 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
2957 ERR("invalid format type %x\n", pFormat
[0]);
2958 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2962 alignment
= pFormat
[1] + 1;
2964 saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2965 /* save buffer pointer */
2966 saved_buffer
= pStubMsg
->Buffer
;
2967 /* get the buffer pointer after complex array data, but before
2969 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2970 pStubMsg
->MemorySize
= 0;
2971 NdrComplexArrayMemorySize(pStubMsg
, pFormat
);
2972 size
= pStubMsg
->MemorySize
;
2973 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2975 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->Buffer
- saved_buffer
));
2976 if (!pStubMsg
->PointerBufferMark
)
2978 /* save it for use by embedded pointer code later */
2979 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2980 pointer_buffer_mark_set
= 1;
2982 /* restore the original buffer */
2983 pStubMsg
->Buffer
= saved_buffer
;
2987 pFormat
= ReadConformance(pStubMsg
, pFormat
);
2988 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2990 if (fMustAlloc
|| !*ppMemory
)
2992 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2993 memset(*ppMemory
, 0, size
);
2996 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2998 pMemory
= *ppMemory
;
2999 count
= pStubMsg
->ActualCount
;
3000 for (i
= 0; i
< count
; i
++)
3001 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
3003 if (pointer_buffer_mark_set
)
3005 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3006 pStubMsg
->PointerBufferMark
= NULL
;
3012 /***********************************************************************
3013 * NdrComplexArrayBufferSize [RPCRT4.@]
3015 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3016 unsigned char *pMemory
,
3017 PFORMAT_STRING pFormat
)
3019 ULONG i
, count
, def
;
3020 unsigned char alignment
;
3021 BOOL variance_present
;
3022 int pointer_length_set
= 0;
3024 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3026 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3028 ERR("invalid format type %x\n", pFormat
[0]);
3029 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3033 alignment
= pFormat
[1] + 1;
3035 if (!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
3037 /* save buffer fields that may be changed by buffer sizer functions
3038 * and that may be needed later on */
3039 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3040 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
3041 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
3042 unsigned long saved_offset
= pStubMsg
->Offset
;
3043 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
3045 /* get the buffer pointer after complex array data, but before
3047 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3048 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
3049 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3051 /* save it for use by embedded pointer code later */
3052 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3053 pointer_length_set
= 1;
3055 /* restore fields */
3056 pStubMsg
->ActualCount
= saved_actual_count
;
3057 pStubMsg
->Offset
= saved_offset
;
3058 pStubMsg
->MaxCount
= saved_max_count
;
3059 pStubMsg
->BufferLength
= saved_buffer_length
;
3061 def
= *(const WORD
*)&pFormat
[2];
3064 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3065 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3066 SizeConformance(pStubMsg
);
3068 variance_present
= IsConformanceOrVariancePresent(pFormat
);
3069 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3070 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3072 if (variance_present
)
3073 SizeVariance(pStubMsg
);
3075 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
3077 count
= pStubMsg
->ActualCount
;
3078 for (i
= 0; i
< count
; i
++)
3079 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
3081 if(pointer_length_set
)
3083 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3084 pStubMsg
->PointerLength
= 0;
3088 /***********************************************************************
3089 * NdrComplexArrayMemorySize [RPCRT4.@]
3091 ULONG WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3092 PFORMAT_STRING pFormat
)
3094 ULONG i
, count
, esize
, SavedMemorySize
, MemorySize
;
3095 unsigned char alignment
;
3096 unsigned char *Buffer
;
3098 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3100 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3102 ERR("invalid format type %x\n", pFormat
[0]);
3103 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3107 alignment
= pFormat
[1] + 1;
3111 pFormat
= ReadConformance(pStubMsg
, pFormat
);
3112 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3114 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3116 SavedMemorySize
= pStubMsg
->MemorySize
;
3118 Buffer
= pStubMsg
->Buffer
;
3119 pStubMsg
->MemorySize
= 0;
3120 esize
= ComplexStructMemorySize(pStubMsg
, pFormat
);
3121 pStubMsg
->Buffer
= Buffer
;
3123 MemorySize
= safe_multiply(pStubMsg
->MaxCount
, esize
);
3125 count
= pStubMsg
->ActualCount
;
3126 for (i
= 0; i
< count
; i
++)
3127 ComplexStructMemorySize(pStubMsg
, pFormat
);
3129 pStubMsg
->MemorySize
= SavedMemorySize
;
3131 pStubMsg
->MemorySize
+= MemorySize
;
3135 /***********************************************************************
3136 * NdrComplexArrayFree [RPCRT4.@]
3138 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3139 unsigned char *pMemory
,
3140 PFORMAT_STRING pFormat
)
3142 ULONG i
, count
, def
;
3144 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3146 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3148 ERR("invalid format type %x\n", pFormat
[0]);
3149 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3153 def
= *(const WORD
*)&pFormat
[2];
3156 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3157 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3159 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3160 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3162 count
= pStubMsg
->ActualCount
;
3163 for (i
= 0; i
< count
; i
++)
3164 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
3167 static ULONG
UserMarshalFlags(const MIDL_STUB_MESSAGE
*pStubMsg
)
3169 return MAKELONG(pStubMsg
->dwDestContext
,
3170 pStubMsg
->RpcMsg
->DataRepresentation
);
3173 #define USER_MARSHAL_PTR_PREFIX \
3174 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3175 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3177 /***********************************************************************
3178 * NdrUserMarshalMarshall [RPCRT4.@]
3180 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3181 unsigned char *pMemory
,
3182 PFORMAT_STRING pFormat
)
3184 unsigned flags
= pFormat
[1];
3185 unsigned index
= *(const WORD
*)&pFormat
[2];
3186 unsigned char *saved_buffer
= NULL
;
3187 ULONG uflag
= UserMarshalFlags(pStubMsg
);
3188 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3189 TRACE("index=%d\n", index
);
3191 if (flags
& USER_MARSHAL_POINTER
)
3193 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3194 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, USER_MARSHAL_PTR_PREFIX
);
3195 pStubMsg
->Buffer
+= 4;
3196 if (pStubMsg
->PointerBufferMark
)
3198 saved_buffer
= pStubMsg
->Buffer
;
3199 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3200 pStubMsg
->PointerBufferMark
= NULL
;
3202 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3205 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3208 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
3209 &uflag
, pStubMsg
->Buffer
, pMemory
);
3213 STD_OVERFLOW_CHECK(pStubMsg
);
3214 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3215 pStubMsg
->Buffer
= saved_buffer
;
3218 STD_OVERFLOW_CHECK(pStubMsg
);
3223 /***********************************************************************
3224 * NdrUserMarshalUnmarshall [RPCRT4.@]
3226 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3227 unsigned char **ppMemory
,
3228 PFORMAT_STRING pFormat
,
3229 unsigned char fMustAlloc
)
3231 unsigned flags
= pFormat
[1];
3232 unsigned index
= *(const WORD
*)&pFormat
[2];
3233 DWORD memsize
= *(const WORD
*)&pFormat
[4];
3234 unsigned char *saved_buffer
= NULL
;
3235 ULONG uflag
= UserMarshalFlags(pStubMsg
);
3236 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3237 TRACE("index=%d\n", index
);
3239 if (flags
& USER_MARSHAL_POINTER
)
3241 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3242 /* skip pointer prefix */
3243 pStubMsg
->Buffer
+= 4;
3244 if (pStubMsg
->PointerBufferMark
)
3246 saved_buffer
= pStubMsg
->Buffer
;
3247 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3248 pStubMsg
->PointerBufferMark
= NULL
;
3250 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3253 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3255 if (fMustAlloc
|| !*ppMemory
)
3256 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
3259 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
3260 &uflag
, pStubMsg
->Buffer
, *ppMemory
);
3264 STD_OVERFLOW_CHECK(pStubMsg
);
3265 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3266 pStubMsg
->Buffer
= saved_buffer
;
3272 /***********************************************************************
3273 * NdrUserMarshalBufferSize [RPCRT4.@]
3275 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3276 unsigned char *pMemory
,
3277 PFORMAT_STRING pFormat
)
3279 unsigned flags
= pFormat
[1];
3280 unsigned index
= *(const WORD
*)&pFormat
[2];
3281 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
3282 ULONG uflag
= UserMarshalFlags(pStubMsg
);
3283 unsigned long saved_buffer_length
= 0;
3284 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3285 TRACE("index=%d\n", index
);
3287 if (flags
& USER_MARSHAL_POINTER
)
3289 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
3290 /* skip pointer prefix */
3291 safe_buffer_length_increment(pStubMsg
, 4);
3292 if (pStubMsg
->IgnoreEmbeddedPointers
)
3294 if (pStubMsg
->PointerLength
)
3296 saved_buffer_length
= pStubMsg
->BufferLength
;
3297 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3298 pStubMsg
->PointerLength
= 0;
3300 ALIGN_LENGTH(pStubMsg
->BufferLength
, 8);
3303 ALIGN_LENGTH(pStubMsg
->BufferLength
, (flags
& 0xf) + 1);
3306 TRACE("size=%d\n", bufsize
);
3307 safe_buffer_length_increment(pStubMsg
, bufsize
);
3310 pStubMsg
->BufferLength
=
3311 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
3312 &uflag
, pStubMsg
->BufferLength
, pMemory
);
3314 if (saved_buffer_length
)
3316 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3317 pStubMsg
->BufferLength
= saved_buffer_length
;
3322 /***********************************************************************
3323 * NdrUserMarshalMemorySize [RPCRT4.@]
3325 ULONG WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3326 PFORMAT_STRING pFormat
)
3328 unsigned flags
= pFormat
[1];
3329 unsigned index
= *(const WORD
*)&pFormat
[2];
3330 DWORD memsize
= *(const WORD
*)&pFormat
[4];
3331 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
3333 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3334 TRACE("index=%d\n", index
);
3336 pStubMsg
->MemorySize
+= memsize
;
3338 if (flags
& USER_MARSHAL_POINTER
)
3340 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3341 /* skip pointer prefix */
3342 pStubMsg
->Buffer
+= 4;
3343 if (pStubMsg
->IgnoreEmbeddedPointers
)
3344 return pStubMsg
->MemorySize
;
3345 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3348 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3351 FIXME("not implemented for varying buffer size\n");
3353 pStubMsg
->Buffer
+= bufsize
;
3355 return pStubMsg
->MemorySize
;
3358 /***********************************************************************
3359 * NdrUserMarshalFree [RPCRT4.@]
3361 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
3362 unsigned char *pMemory
,
3363 PFORMAT_STRING pFormat
)
3365 /* unsigned flags = pFormat[1]; */
3366 unsigned index
= *(const WORD
*)&pFormat
[2];
3367 ULONG uflag
= UserMarshalFlags(pStubMsg
);
3368 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3369 TRACE("index=%d\n", index
);
3371 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
3375 /***********************************************************************
3376 * NdrClearOutParameters [RPCRT4.@]
3378 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
3379 PFORMAT_STRING pFormat
,
3382 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
3385 /***********************************************************************
3386 * NdrConvert [RPCRT4.@]
3388 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
3390 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
3391 /* FIXME: since this stub doesn't do any converting, the proper behavior
3392 is to raise an exception */
3395 /***********************************************************************
3396 * NdrConvert2 [RPCRT4.@]
3398 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, LONG NumberParams
)
3400 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3401 pStubMsg
, pFormat
, NumberParams
);
3402 /* FIXME: since this stub doesn't do any converting, the proper behavior
3403 is to raise an exception */
3406 #include "pshpack1.h"
3407 typedef struct _NDR_CSTRUCT_FORMAT
3410 unsigned char alignment
;
3411 unsigned short memory_size
;
3412 short offset_to_array_description
;
3413 } NDR_CSTRUCT_FORMAT
, NDR_CVSTRUCT_FORMAT
;
3414 #include "poppack.h"
3416 /***********************************************************************
3417 * NdrConformantStructMarshall [RPCRT4.@]
3419 unsigned char * WINAPI
NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3420 unsigned char *pMemory
,
3421 PFORMAT_STRING pFormat
)
3423 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3424 PFORMAT_STRING pCArrayFormat
;
3425 ULONG esize
, bufsize
;
3427 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3429 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3430 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3432 ERR("invalid format type %x\n", pCStructFormat
->type
);
3433 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3437 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3438 pCStructFormat
->offset_to_array_description
;
3439 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3441 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3442 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3445 esize
= *(const WORD
*)(pCArrayFormat
+2);
3447 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
3448 pCArrayFormat
+ 4, 0);
3450 WriteConformance(pStubMsg
);
3452 ALIGN_POINTER(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
3454 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3456 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3457 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
3459 ERR("integer overflow of memory_size %u with bufsize %u\n",
3460 pCStructFormat
->memory_size
, bufsize
);
3461 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3463 /* copy constant sized part of struct */
3464 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3465 safe_copy_to_buffer(pStubMsg
, pMemory
, pCStructFormat
->memory_size
+ bufsize
);
3467 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3468 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3473 /***********************************************************************
3474 * NdrConformantStructUnmarshall [RPCRT4.@]
3476 unsigned char * WINAPI
NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3477 unsigned char **ppMemory
,
3478 PFORMAT_STRING pFormat
,
3479 unsigned char fMustAlloc
)
3481 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3482 PFORMAT_STRING pCArrayFormat
;
3483 ULONG esize
, bufsize
;
3484 unsigned char *saved_buffer
;
3486 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3488 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3489 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3491 ERR("invalid format type %x\n", pCStructFormat
->type
);
3492 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3495 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3496 pCStructFormat
->offset_to_array_description
;
3497 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3499 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3500 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3503 esize
= *(const WORD
*)(pCArrayFormat
+2);
3505 pCArrayFormat
= ReadConformance(pStubMsg
, pCArrayFormat
+ 4);
3507 ALIGN_POINTER(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
3509 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3511 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3512 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
3514 ERR("integer overflow of memory_size %u with bufsize %u\n",
3515 pCStructFormat
->memory_size
, bufsize
);
3516 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3521 SIZE_T size
= pCStructFormat
->memory_size
+ bufsize
;
3522 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3526 if (!pStubMsg
->IsClient
&& !*ppMemory
)
3527 /* for servers, we just point straight into the RPC buffer */
3528 *ppMemory
= pStubMsg
->Buffer
;
3531 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3532 safe_buffer_increment(pStubMsg
, pCStructFormat
->memory_size
+ bufsize
);
3533 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3534 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
3536 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
3537 if (*ppMemory
!= saved_buffer
)
3538 memcpy(*ppMemory
, saved_buffer
, pCStructFormat
->memory_size
+ bufsize
);
3543 /***********************************************************************
3544 * NdrConformantStructBufferSize [RPCRT4.@]
3546 void WINAPI
NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3547 unsigned char *pMemory
,
3548 PFORMAT_STRING pFormat
)
3550 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3551 PFORMAT_STRING pCArrayFormat
;
3554 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3556 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3557 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3559 ERR("invalid format type %x\n", pCStructFormat
->type
);
3560 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3563 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3564 pCStructFormat
->offset_to_array_description
;
3565 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3567 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3568 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3571 esize
= *(const WORD
*)(pCArrayFormat
+2);
3573 pCArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
, pCArrayFormat
+4, 0);
3574 SizeConformance(pStubMsg
);
3576 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCStructFormat
->alignment
+ 1);
3578 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3580 safe_buffer_length_increment(pStubMsg
, pCStructFormat
->memory_size
);
3581 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
3583 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3584 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3587 /***********************************************************************
3588 * NdrConformantStructMemorySize [RPCRT4.@]
3590 ULONG WINAPI
NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3591 PFORMAT_STRING pFormat
)
3597 /***********************************************************************
3598 * NdrConformantStructFree [RPCRT4.@]
3600 void WINAPI
NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3601 unsigned char *pMemory
,
3602 PFORMAT_STRING pFormat
)
3604 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3605 PFORMAT_STRING pCArrayFormat
;
3608 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3610 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3611 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3613 ERR("invalid format type %x\n", pCStructFormat
->type
);
3614 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3618 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3619 pCStructFormat
->offset_to_array_description
;
3620 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3622 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3623 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3626 esize
= *(const WORD
*)(pCArrayFormat
+2);
3628 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
3629 pCArrayFormat
+ 4, 0);
3631 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3633 /* copy constant sized part of struct */
3634 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3636 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3637 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
3640 /***********************************************************************
3641 * NdrConformantVaryingStructMarshall [RPCRT4.@]
3643 unsigned char * WINAPI
NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3644 unsigned char *pMemory
,
3645 PFORMAT_STRING pFormat
)
3647 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3648 PFORMAT_STRING pCVArrayFormat
;
3649 ULONG esize
, bufsize
;
3651 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3653 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3654 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3656 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3657 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3661 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3662 pCVStructFormat
->offset_to_array_description
;
3663 switch (*pCVArrayFormat
)
3665 case RPC_FC_CVARRAY
:
3666 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3668 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3669 pCVArrayFormat
+ 4, 0);
3670 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3673 case RPC_FC_C_CSTRING
:
3674 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
3675 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
3676 esize
= sizeof(char);
3677 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3678 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3679 pCVArrayFormat
+ 2, 0);
3681 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3683 case RPC_FC_C_WSTRING
:
3684 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
3685 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
3686 esize
= sizeof(WCHAR
);
3687 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3688 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3689 pCVArrayFormat
+ 2, 0);
3691 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3694 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3695 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3699 WriteConformance(pStubMsg
);
3701 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
3703 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3705 /* write constant sized part */
3706 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3707 safe_copy_to_buffer(pStubMsg
, pMemory
, pCVStructFormat
->memory_size
);
3709 WriteVariance(pStubMsg
);
3711 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3713 /* write array part */
3714 safe_copy_to_buffer(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
, bufsize
);
3716 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3721 /***********************************************************************
3722 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3724 unsigned char * WINAPI
NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3725 unsigned char **ppMemory
,
3726 PFORMAT_STRING pFormat
,
3727 unsigned char fMustAlloc
)
3729 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3730 PFORMAT_STRING pCVArrayFormat
;
3731 ULONG esize
, bufsize
;
3732 unsigned char cvarray_type
;
3734 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3736 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3737 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3739 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3740 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3744 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3745 pCVStructFormat
->offset_to_array_description
;
3746 cvarray_type
= *pCVArrayFormat
;
3747 switch (cvarray_type
)
3749 case RPC_FC_CVARRAY
:
3750 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3751 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 4);
3753 case RPC_FC_C_CSTRING
:
3754 esize
= sizeof(char);
3755 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3756 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3758 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3760 case RPC_FC_C_WSTRING
:
3761 esize
= sizeof(WCHAR
);
3762 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3763 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3765 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3768 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3769 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3773 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
3775 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3777 /* work out how much memory to allocate if we need to do so */
3778 if (!*ppMemory
|| fMustAlloc
)
3780 SIZE_T size
= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->MaxCount
);
3781 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3784 /* copy the constant data */
3785 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3786 safe_copy_from_buffer(pStubMsg
, *ppMemory
, pCVStructFormat
->memory_size
);
3788 pCVArrayFormat
= ReadVariance(pStubMsg
, pCVArrayFormat
, pStubMsg
->MaxCount
);
3790 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3792 if ((cvarray_type
== RPC_FC_C_CSTRING
) ||
3793 (cvarray_type
== RPC_FC_C_WSTRING
))
3796 /* strings must always have null terminating bytes */
3797 if (bufsize
< esize
)
3799 ERR("invalid string length of %d\n", pStubMsg
->ActualCount
);
3800 RpcRaiseException(RPC_S_INVALID_BOUND
);
3803 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
3804 if (pStubMsg
->Buffer
[i
] != 0)
3806 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
3807 i
, pStubMsg
->Buffer
[i
]);
3808 RpcRaiseException(RPC_S_INVALID_BOUND
);
3813 /* copy the array data */
3814 safe_copy_from_buffer(pStubMsg
, *ppMemory
+ pCVStructFormat
->memory_size
, bufsize
);
3816 if (cvarray_type
== RPC_FC_C_CSTRING
)
3817 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory
+ pCVStructFormat
->memory_size
)));
3818 else if (cvarray_type
== RPC_FC_C_WSTRING
)
3819 TRACE("string=%s\n", debugstr_w((WCHAR
*)(*ppMemory
+ pCVStructFormat
->memory_size
)));
3821 EmbeddedPointerUnmarshall(pStubMsg
, *ppMemory
, *ppMemory
, pFormat
, TRUE
/* FIXME */);
3826 /***********************************************************************
3827 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3829 void WINAPI
NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3830 unsigned char *pMemory
,
3831 PFORMAT_STRING pFormat
)
3833 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3834 PFORMAT_STRING pCVArrayFormat
;
3837 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3839 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3840 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3842 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3843 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3847 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3848 pCVStructFormat
->offset_to_array_description
;
3849 switch (*pCVArrayFormat
)
3851 case RPC_FC_CVARRAY
:
3852 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3854 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3855 pCVArrayFormat
+ 4, 0);
3856 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3859 case RPC_FC_C_CSTRING
:
3860 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
3861 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
3862 esize
= sizeof(char);
3863 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3864 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3865 pCVArrayFormat
+ 2, 0);
3867 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3869 case RPC_FC_C_WSTRING
:
3870 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
3871 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
3872 esize
= sizeof(WCHAR
);
3873 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3874 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3875 pCVArrayFormat
+ 2, 0);
3877 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3880 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3881 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3885 SizeConformance(pStubMsg
);
3887 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCVStructFormat
->alignment
+ 1);
3889 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3891 safe_buffer_length_increment(pStubMsg
, pCVStructFormat
->memory_size
);
3892 SizeVariance(pStubMsg
);
3893 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
3895 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3898 /***********************************************************************
3899 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
3901 ULONG WINAPI
NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3902 PFORMAT_STRING pFormat
)
3904 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3905 PFORMAT_STRING pCVArrayFormat
;
3907 unsigned char cvarray_type
;
3909 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
3911 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3912 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3914 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3915 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3919 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3920 pCVStructFormat
->offset_to_array_description
;
3921 cvarray_type
= *pCVArrayFormat
;
3922 switch (cvarray_type
)
3924 case RPC_FC_CVARRAY
:
3925 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3926 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 4);
3928 case RPC_FC_C_CSTRING
:
3929 esize
= sizeof(char);
3930 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3931 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3933 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3935 case RPC_FC_C_WSTRING
:
3936 esize
= sizeof(WCHAR
);
3937 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3938 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3940 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3943 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3944 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3948 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
3950 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3952 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
3953 pCVArrayFormat
= ReadVariance(pStubMsg
, pCVArrayFormat
, pStubMsg
->MaxCount
);
3954 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
3956 pStubMsg
->MemorySize
+= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->MaxCount
);
3958 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
3960 return pCVStructFormat
->memory_size
+ pStubMsg
->MaxCount
* esize
;
3963 /***********************************************************************
3964 * NdrConformantVaryingStructFree [RPCRT4.@]
3966 void WINAPI
NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3967 unsigned char *pMemory
,
3968 PFORMAT_STRING pFormat
)
3970 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3971 PFORMAT_STRING pCVArrayFormat
;
3974 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3976 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3977 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3979 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3980 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3984 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3985 pCVStructFormat
->offset_to_array_description
;
3986 switch (*pCVArrayFormat
)
3988 case RPC_FC_CVARRAY
:
3989 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3991 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3992 pCVArrayFormat
+ 4, 0);
3993 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3996 case RPC_FC_C_CSTRING
:
3997 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
3998 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
3999 esize
= sizeof(char);
4000 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4001 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4002 pCVArrayFormat
+ 2, 0);
4004 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4006 case RPC_FC_C_WSTRING
:
4007 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
4008 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
4009 esize
= sizeof(WCHAR
);
4010 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4011 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4012 pCVArrayFormat
+ 2, 0);
4014 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4017 ERR("invalid array format type %x\n", *pCVArrayFormat
);
4018 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4022 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4024 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4027 #include "pshpack1.h"
4031 unsigned char alignment
;
4032 unsigned short total_size
;
4033 } NDR_SMFARRAY_FORMAT
;
4038 unsigned char alignment
;
4039 unsigned long total_size
;
4040 } NDR_LGFARRAY_FORMAT
;
4041 #include "poppack.h"
4043 /***********************************************************************
4044 * NdrFixedArrayMarshall [RPCRT4.@]
4046 unsigned char * WINAPI
NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4047 unsigned char *pMemory
,
4048 PFORMAT_STRING pFormat
)
4050 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4051 unsigned long total_size
;
4053 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4055 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4056 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4058 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4059 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4063 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4065 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4067 total_size
= pSmFArrayFormat
->total_size
;
4068 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4072 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4073 total_size
= pLgFArrayFormat
->total_size
;
4074 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4077 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4078 safe_copy_to_buffer(pStubMsg
, pMemory
, total_size
);
4080 pFormat
= EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4085 /***********************************************************************
4086 * NdrFixedArrayUnmarshall [RPCRT4.@]
4088 unsigned char * WINAPI
NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4089 unsigned char **ppMemory
,
4090 PFORMAT_STRING pFormat
,
4091 unsigned char fMustAlloc
)
4093 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4094 unsigned long total_size
;
4095 unsigned char *saved_buffer
;
4097 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4099 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4100 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4102 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4103 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4107 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4109 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4111 total_size
= pSmFArrayFormat
->total_size
;
4112 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4116 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4117 total_size
= pLgFArrayFormat
->total_size
;
4118 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4122 *ppMemory
= NdrAllocate(pStubMsg
, total_size
);
4125 if (!pStubMsg
->IsClient
&& !*ppMemory
)
4126 /* for servers, we just point straight into the RPC buffer */
4127 *ppMemory
= pStubMsg
->Buffer
;
4130 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4131 safe_buffer_increment(pStubMsg
, total_size
);
4132 pFormat
= EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4134 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
4135 if (*ppMemory
!= saved_buffer
)
4136 memcpy(*ppMemory
, saved_buffer
, total_size
);
4141 /***********************************************************************
4142 * NdrFixedArrayBufferSize [RPCRT4.@]
4144 void WINAPI
NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4145 unsigned char *pMemory
,
4146 PFORMAT_STRING pFormat
)
4148 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4149 unsigned long total_size
;
4151 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4153 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4154 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4156 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4157 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4161 ALIGN_LENGTH(pStubMsg
->BufferLength
, pSmFArrayFormat
->alignment
+ 1);
4163 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4165 total_size
= pSmFArrayFormat
->total_size
;
4166 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4170 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4171 total_size
= pLgFArrayFormat
->total_size
;
4172 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4174 safe_buffer_length_increment(pStubMsg
, total_size
);
4176 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4179 /***********************************************************************
4180 * NdrFixedArrayMemorySize [RPCRT4.@]
4182 ULONG WINAPI
NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4183 PFORMAT_STRING pFormat
)
4185 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4188 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4190 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4191 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4193 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4194 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4198 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4200 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4202 total_size
= pSmFArrayFormat
->total_size
;
4203 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4207 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4208 total_size
= pLgFArrayFormat
->total_size
;
4209 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4211 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4212 safe_buffer_increment(pStubMsg
, total_size
);
4213 pStubMsg
->MemorySize
+= total_size
;
4215 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4220 /***********************************************************************
4221 * NdrFixedArrayFree [RPCRT4.@]
4223 void WINAPI
NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4224 unsigned char *pMemory
,
4225 PFORMAT_STRING pFormat
)
4227 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4229 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4231 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4232 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4234 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4235 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4239 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4240 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4243 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4244 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4247 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4250 /***********************************************************************
4251 * NdrVaryingArrayMarshall [RPCRT4.@]
4253 unsigned char * WINAPI
NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4254 unsigned char *pMemory
,
4255 PFORMAT_STRING pFormat
)
4257 unsigned char alignment
;
4258 DWORD elements
, esize
;
4261 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4263 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4264 (pFormat
[0] != RPC_FC_LGVARRAY
))
4266 ERR("invalid format type %x\n", pFormat
[0]);
4267 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4271 alignment
= pFormat
[1] + 1;
4273 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4276 pFormat
+= sizeof(WORD
);
4277 elements
= *(const WORD
*)pFormat
;
4278 pFormat
+= sizeof(WORD
);
4283 pFormat
+= sizeof(DWORD
);
4284 elements
= *(const DWORD
*)pFormat
;
4285 pFormat
+= sizeof(DWORD
);
4288 esize
= *(const WORD
*)pFormat
;
4289 pFormat
+= sizeof(WORD
);
4291 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4292 if ((pStubMsg
->ActualCount
> elements
) ||
4293 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4295 RpcRaiseException(RPC_S_INVALID_BOUND
);
4299 WriteVariance(pStubMsg
);
4301 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4303 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4304 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4305 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
4307 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4312 /***********************************************************************
4313 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4315 unsigned char * WINAPI
NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4316 unsigned char **ppMemory
,
4317 PFORMAT_STRING pFormat
,
4318 unsigned char fMustAlloc
)
4320 unsigned char alignment
;
4321 DWORD size
, elements
, esize
;
4324 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4326 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4327 (pFormat
[0] != RPC_FC_LGVARRAY
))
4329 ERR("invalid format type %x\n", pFormat
[0]);
4330 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4334 alignment
= pFormat
[1] + 1;
4336 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4339 size
= *(const WORD
*)pFormat
;
4340 pFormat
+= sizeof(WORD
);
4341 elements
= *(const WORD
*)pFormat
;
4342 pFormat
+= sizeof(WORD
);
4347 size
= *(const DWORD
*)pFormat
;
4348 pFormat
+= sizeof(DWORD
);
4349 elements
= *(const DWORD
*)pFormat
;
4350 pFormat
+= sizeof(DWORD
);
4353 esize
= *(const WORD
*)pFormat
;
4354 pFormat
+= sizeof(WORD
);
4356 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
4358 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4360 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4362 if (!*ppMemory
|| fMustAlloc
)
4363 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4364 safe_copy_from_buffer(pStubMsg
, *ppMemory
+ pStubMsg
->Offset
, bufsize
);
4366 EmbeddedPointerUnmarshall(pStubMsg
, *ppMemory
, *ppMemory
, pFormat
, TRUE
/* FIXME */);
4371 /***********************************************************************
4372 * NdrVaryingArrayBufferSize [RPCRT4.@]
4374 void WINAPI
NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4375 unsigned char *pMemory
,
4376 PFORMAT_STRING pFormat
)
4378 unsigned char alignment
;
4379 DWORD elements
, esize
;
4381 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4383 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4384 (pFormat
[0] != RPC_FC_LGVARRAY
))
4386 ERR("invalid format type %x\n", pFormat
[0]);
4387 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4391 alignment
= pFormat
[1] + 1;
4393 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4396 pFormat
+= sizeof(WORD
);
4397 elements
= *(const WORD
*)pFormat
;
4398 pFormat
+= sizeof(WORD
);
4403 pFormat
+= sizeof(DWORD
);
4404 elements
= *(const DWORD
*)pFormat
;
4405 pFormat
+= sizeof(DWORD
);
4408 esize
= *(const WORD
*)pFormat
;
4409 pFormat
+= sizeof(WORD
);
4411 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4412 if ((pStubMsg
->ActualCount
> elements
) ||
4413 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4415 RpcRaiseException(RPC_S_INVALID_BOUND
);
4419 SizeVariance(pStubMsg
);
4421 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
4423 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
4425 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4428 /***********************************************************************
4429 * NdrVaryingArrayMemorySize [RPCRT4.@]
4431 ULONG WINAPI
NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4432 PFORMAT_STRING pFormat
)
4434 unsigned char alignment
;
4435 DWORD size
, elements
, esize
;
4437 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4439 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4440 (pFormat
[0] != RPC_FC_LGVARRAY
))
4442 ERR("invalid format type %x\n", pFormat
[0]);
4443 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4447 alignment
= pFormat
[1] + 1;
4449 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4452 size
= *(const WORD
*)pFormat
;
4453 pFormat
+= sizeof(WORD
);
4454 elements
= *(const WORD
*)pFormat
;
4455 pFormat
+= sizeof(WORD
);
4460 size
= *(const DWORD
*)pFormat
;
4461 pFormat
+= sizeof(DWORD
);
4462 elements
= *(const DWORD
*)pFormat
;
4463 pFormat
+= sizeof(DWORD
);
4466 esize
= *(const WORD
*)pFormat
;
4467 pFormat
+= sizeof(WORD
);
4469 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
4471 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4473 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
4474 pStubMsg
->MemorySize
+= size
;
4476 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4478 return pStubMsg
->MemorySize
;
4481 /***********************************************************************
4482 * NdrVaryingArrayFree [RPCRT4.@]
4484 void WINAPI
NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4485 unsigned char *pMemory
,
4486 PFORMAT_STRING pFormat
)
4488 unsigned char alignment
;
4491 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4493 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4494 (pFormat
[0] != RPC_FC_LGVARRAY
))
4496 ERR("invalid format type %x\n", pFormat
[0]);
4497 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4501 alignment
= pFormat
[1] + 1;
4503 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4506 pFormat
+= sizeof(WORD
);
4507 elements
= *(const WORD
*)pFormat
;
4508 pFormat
+= sizeof(WORD
);
4513 pFormat
+= sizeof(DWORD
);
4514 elements
= *(const DWORD
*)pFormat
;
4515 pFormat
+= sizeof(DWORD
);
4518 pFormat
+= sizeof(WORD
);
4520 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4521 if ((pStubMsg
->ActualCount
> elements
) ||
4522 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4524 RpcRaiseException(RPC_S_INVALID_BOUND
);
4528 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4531 static ULONG
get_discriminant(unsigned char fc
, const unsigned char *pMemory
)
4539 return *(const UCHAR
*)pMemory
;
4544 return *(const USHORT
*)pMemory
;
4548 return *(const ULONG
*)pMemory
;
4550 FIXME("Unhandled base type: 0x%02x\n", fc
);
4555 static PFORMAT_STRING
get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg
,
4556 unsigned long discriminant
,
4557 PFORMAT_STRING pFormat
)
4559 unsigned short num_arms
, arm
, type
;
4561 num_arms
= *(const SHORT
*)pFormat
& 0x0fff;
4563 for(arm
= 0; arm
< num_arms
; arm
++)
4565 if(discriminant
== *(const ULONG
*)pFormat
)
4573 type
= *(const unsigned short*)pFormat
;
4574 TRACE("type %04x\n", type
);
4575 if(arm
== num_arms
) /* default arm extras */
4579 ERR("no arm for 0x%lx and no default case\n", discriminant
);
4580 RpcRaiseException(RPC_S_INVALID_TAG
);
4585 TRACE("falling back to empty default case for 0x%lx\n", discriminant
);
4592 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
, ULONG discriminant
, PFORMAT_STRING pFormat
)
4594 unsigned short type
;
4598 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4602 type
= *(const unsigned short*)pFormat
;
4603 if((type
& 0xff00) == 0x8000)
4605 unsigned char basetype
= LOBYTE(type
);
4606 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &basetype
);
4610 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4611 NDR_MARSHALL m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
4614 unsigned char *saved_buffer
= NULL
;
4615 int pointer_buffer_mark_set
= 0;
4622 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4623 saved_buffer
= pStubMsg
->Buffer
;
4624 if (pStubMsg
->PointerBufferMark
)
4626 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4627 pStubMsg
->PointerBufferMark
= NULL
;
4628 pointer_buffer_mark_set
= 1;
4631 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
4633 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char **)pMemory
, desc
);
4634 if (pointer_buffer_mark_set
)
4636 STD_OVERFLOW_CHECK(pStubMsg
);
4637 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4638 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
4640 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
4641 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
4642 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4644 pStubMsg
->Buffer
= saved_buffer
+ 4;
4648 m(pStubMsg
, pMemory
, desc
);
4651 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4656 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4657 unsigned char **ppMemory
,
4659 PFORMAT_STRING pFormat
,
4660 unsigned char fMustAlloc
)
4662 unsigned short type
;
4666 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4670 type
= *(const unsigned short*)pFormat
;
4671 if((type
& 0xff00) == 0x8000)
4673 unsigned char basetype
= LOBYTE(type
);
4674 return NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &basetype
, FALSE
);
4678 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4679 NDR_UNMARSHALL m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
4682 unsigned char *saved_buffer
= NULL
;
4683 int pointer_buffer_mark_set
= 0;
4690 **(void***)ppMemory
= NULL
;
4691 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4692 saved_buffer
= pStubMsg
->Buffer
;
4693 if (pStubMsg
->PointerBufferMark
)
4695 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4696 pStubMsg
->PointerBufferMark
= NULL
;
4697 pointer_buffer_mark_set
= 1;
4700 pStubMsg
->Buffer
+= 4; /* for pointer ID */
4702 if (saved_buffer
+ 4 > pStubMsg
->BufferEnd
)
4704 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
4705 saved_buffer
, pStubMsg
->BufferEnd
);
4706 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4709 PointerUnmarshall(pStubMsg
, saved_buffer
, *(unsigned char ***)ppMemory
, **(unsigned char ***)ppMemory
, desc
, fMustAlloc
);
4710 if (pointer_buffer_mark_set
)
4712 STD_OVERFLOW_CHECK(pStubMsg
);
4713 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4714 pStubMsg
->Buffer
= saved_buffer
+ 4;
4718 m(pStubMsg
, ppMemory
, desc
, fMustAlloc
);
4721 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4726 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg
,
4727 unsigned char *pMemory
,
4729 PFORMAT_STRING pFormat
)
4731 unsigned short type
;
4735 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4739 type
= *(const unsigned short*)pFormat
;
4740 if((type
& 0xff00) == 0x8000)
4742 unsigned char basetype
= LOBYTE(type
);
4743 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &basetype
);
4747 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4748 NDR_BUFFERSIZE m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
4757 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
4758 safe_buffer_length_increment(pStubMsg
, 4); /* for pointer ID */
4759 if (!pStubMsg
->IgnoreEmbeddedPointers
)
4761 int saved_buffer_length
= pStubMsg
->BufferLength
;
4762 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4763 pStubMsg
->PointerLength
= 0;
4764 if(!pStubMsg
->BufferLength
)
4765 ERR("BufferLength == 0??\n");
4766 PointerBufferSize(pStubMsg
, *(unsigned char **)pMemory
, desc
);
4767 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4768 pStubMsg
->BufferLength
= saved_buffer_length
;
4772 m(pStubMsg
, pMemory
, desc
);
4775 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
4779 static ULONG
union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg
,
4781 PFORMAT_STRING pFormat
)
4783 unsigned short type
, size
;
4785 size
= *(const unsigned short*)pFormat
;
4786 pStubMsg
->Memory
+= size
;
4789 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4793 type
= *(const unsigned short*)pFormat
;
4794 if((type
& 0xff00) == 0x8000)
4796 return NdrBaseTypeMemorySize(pStubMsg
, pFormat
);
4800 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4801 NDR_MEMORYSIZE m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
4802 unsigned char *saved_buffer
;
4811 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4812 saved_buffer
= pStubMsg
->Buffer
;
4813 safe_buffer_increment(pStubMsg
, 4);
4814 ALIGN_LENGTH(pStubMsg
->MemorySize
, 4);
4815 pStubMsg
->MemorySize
+= 4;
4816 if (!pStubMsg
->IgnoreEmbeddedPointers
)
4817 PointerMemorySize(pStubMsg
, saved_buffer
, pFormat
);
4820 return m(pStubMsg
, desc
);
4823 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4826 TRACE("size %d\n", size
);
4830 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg
,
4831 unsigned char *pMemory
,
4833 PFORMAT_STRING pFormat
)
4835 unsigned short type
;
4839 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4843 type
= *(const unsigned short*)pFormat
;
4844 if((type
& 0xff00) != 0x8000)
4846 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4847 NDR_FREE m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
4856 PointerFree(pStubMsg
, *(unsigned char **)pMemory
, desc
);
4859 m(pStubMsg
, pMemory
, desc
);
4862 else FIXME("no freer for embedded type %02x\n", *desc
);
4866 /***********************************************************************
4867 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
4869 unsigned char * WINAPI
NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4870 unsigned char *pMemory
,
4871 PFORMAT_STRING pFormat
)
4873 unsigned char switch_type
;
4874 unsigned char increment
;
4877 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4880 switch_type
= *pFormat
& 0xf;
4881 increment
= (*pFormat
& 0xf0) >> 4;
4884 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
4886 switch_value
= get_discriminant(switch_type
, pMemory
);
4887 TRACE("got switch value 0x%x\n", switch_value
);
4889 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &switch_type
);
4890 pMemory
+= increment
;
4892 return union_arm_marshall(pStubMsg
, pMemory
, switch_value
, pFormat
);
4895 /***********************************************************************
4896 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
4898 unsigned char * WINAPI
NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4899 unsigned char **ppMemory
,
4900 PFORMAT_STRING pFormat
,
4901 unsigned char fMustAlloc
)
4903 unsigned char switch_type
;
4904 unsigned char increment
;
4906 unsigned short size
;
4907 unsigned char *pMemoryArm
;
4909 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4912 switch_type
= *pFormat
& 0xf;
4913 increment
= (*pFormat
& 0xf0) >> 4;
4916 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
4917 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
4918 TRACE("got switch value 0x%x\n", switch_value
);
4920 size
= *(const unsigned short*)pFormat
+ increment
;
4921 if(!*ppMemory
|| fMustAlloc
)
4922 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4924 NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &switch_type
, FALSE
);
4925 pMemoryArm
= *ppMemory
+ increment
;
4927 return union_arm_unmarshall(pStubMsg
, &pMemoryArm
, switch_value
, pFormat
, fMustAlloc
);
4930 /***********************************************************************
4931 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
4933 void WINAPI
NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4934 unsigned char *pMemory
,
4935 PFORMAT_STRING pFormat
)
4937 unsigned char switch_type
;
4938 unsigned char increment
;
4941 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4944 switch_type
= *pFormat
& 0xf;
4945 increment
= (*pFormat
& 0xf0) >> 4;
4948 ALIGN_LENGTH(pStubMsg
->BufferLength
, increment
);
4949 switch_value
= get_discriminant(switch_type
, pMemory
);
4950 TRACE("got switch value 0x%x\n", switch_value
);
4952 /* Add discriminant size */
4953 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&switch_value
, &switch_type
);
4954 pMemory
+= increment
;
4956 union_arm_buffer_size(pStubMsg
, pMemory
, switch_value
, pFormat
);
4959 /***********************************************************************
4960 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
4962 ULONG WINAPI
NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4963 PFORMAT_STRING pFormat
)
4965 unsigned char switch_type
;
4966 unsigned char increment
;
4969 switch_type
= *pFormat
& 0xf;
4970 increment
= (*pFormat
& 0xf0) >> 4;
4973 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
4974 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
4975 TRACE("got switch value 0x%x\n", switch_value
);
4977 pStubMsg
->Memory
+= increment
;
4979 return increment
+ union_arm_memory_size(pStubMsg
, switch_value
, pFormat
+ *(const SHORT
*)pFormat
);
4982 /***********************************************************************
4983 * NdrEncapsulatedUnionFree [RPCRT4.@]
4985 void WINAPI
NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
4986 unsigned char *pMemory
,
4987 PFORMAT_STRING pFormat
)
4989 unsigned char switch_type
;
4990 unsigned char increment
;
4993 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4996 switch_type
= *pFormat
& 0xf;
4997 increment
= (*pFormat
& 0xf0) >> 4;
5000 switch_value
= get_discriminant(switch_type
, pMemory
);
5001 TRACE("got switch value 0x%x\n", switch_value
);
5003 pMemory
+= increment
;
5005 return union_arm_free(pStubMsg
, pMemory
, switch_value
, pFormat
);
5008 /***********************************************************************
5009 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5011 unsigned char * WINAPI
NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5012 unsigned char *pMemory
,
5013 PFORMAT_STRING pFormat
)
5015 unsigned char switch_type
;
5017 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5020 switch_type
= *pFormat
;
5023 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5024 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5025 /* Marshall discriminant */
5026 NdrBaseTypeMarshall(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
5028 return union_arm_marshall(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5031 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg
,
5032 PFORMAT_STRING
*ppFormat
)
5034 long discriminant
= 0;
5044 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5053 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5054 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5062 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
5063 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5068 FIXME("Unhandled base type: 0x%02x\n", **ppFormat
);
5072 if (pStubMsg
->fHasNewCorrDesc
)
5076 return discriminant
;
5079 /**********************************************************************
5080 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5082 unsigned char * WINAPI
NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5083 unsigned char **ppMemory
,
5084 PFORMAT_STRING pFormat
,
5085 unsigned char fMustAlloc
)
5088 unsigned short size
;
5090 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5093 /* Unmarshall discriminant */
5094 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
5095 TRACE("unmarshalled discriminant %lx\n", discriminant
);
5097 pFormat
+= *(const SHORT
*)pFormat
;
5099 size
= *(const unsigned short*)pFormat
;
5101 if(!*ppMemory
|| fMustAlloc
)
5102 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5104 return union_arm_unmarshall(pStubMsg
, ppMemory
, discriminant
, pFormat
, fMustAlloc
);
5107 /***********************************************************************
5108 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5110 void WINAPI
NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5111 unsigned char *pMemory
,
5112 PFORMAT_STRING pFormat
)
5114 unsigned char switch_type
;
5116 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5119 switch_type
= *pFormat
;
5122 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5123 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5124 /* Add discriminant size */
5125 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
5127 union_arm_buffer_size(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5130 /***********************************************************************
5131 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5133 ULONG WINAPI
NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5134 PFORMAT_STRING pFormat
)
5139 /* Unmarshall discriminant */
5140 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
5141 TRACE("unmarshalled discriminant 0x%x\n", discriminant
);
5143 return union_arm_memory_size(pStubMsg
, discriminant
, pFormat
+ *(const SHORT
*)pFormat
);
5146 /***********************************************************************
5147 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5149 void WINAPI
NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
5150 unsigned char *pMemory
,
5151 PFORMAT_STRING pFormat
)
5153 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5157 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5158 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5160 return union_arm_free(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5163 /***********************************************************************
5164 * NdrByteCountPointerMarshall [RPCRT4.@]
5166 unsigned char * WINAPI
NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5167 unsigned char *pMemory
,
5168 PFORMAT_STRING pFormat
)
5174 /***********************************************************************
5175 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5177 unsigned char * WINAPI
NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5178 unsigned char **ppMemory
,
5179 PFORMAT_STRING pFormat
,
5180 unsigned char fMustAlloc
)
5186 /***********************************************************************
5187 * NdrByteCountPointerBufferSize [RPCRT4.@]
5189 void WINAPI
NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5190 unsigned char *pMemory
,
5191 PFORMAT_STRING pFormat
)
5196 /***********************************************************************
5197 * NdrByteCountPointerMemorySize [RPCRT4.@]
5199 ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5200 PFORMAT_STRING pFormat
)
5206 /***********************************************************************
5207 * NdrByteCountPointerFree [RPCRT4.@]
5209 void WINAPI
NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
5210 unsigned char *pMemory
,
5211 PFORMAT_STRING pFormat
)
5216 /***********************************************************************
5217 * NdrXmitOrRepAsMarshall [RPCRT4.@]
5219 unsigned char * WINAPI
NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5220 unsigned char *pMemory
,
5221 PFORMAT_STRING pFormat
)
5227 /***********************************************************************
5228 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
5230 unsigned char * WINAPI
NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5231 unsigned char **ppMemory
,
5232 PFORMAT_STRING pFormat
,
5233 unsigned char fMustAlloc
)
5239 /***********************************************************************
5240 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
5242 void WINAPI
NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5243 unsigned char *pMemory
,
5244 PFORMAT_STRING pFormat
)
5249 /***********************************************************************
5250 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
5252 ULONG WINAPI
NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5253 PFORMAT_STRING pFormat
)
5259 /***********************************************************************
5260 * NdrXmitOrRepAsFree [RPCRT4.@]
5262 void WINAPI
NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg
,
5263 unsigned char *pMemory
,
5264 PFORMAT_STRING pFormat
)
5269 #include "pshpack1.h"
5273 unsigned char flags_type
; /* flags in upper nibble, type in lower nibble */
5277 #include "poppack.h"
5279 /***********************************************************************
5280 * NdrRangeMarshall [internal]
5282 unsigned char *WINAPI
NdrRangeMarshall(
5283 PMIDL_STUB_MESSAGE pStubMsg
,
5284 unsigned char *pMemory
,
5285 PFORMAT_STRING pFormat
)
5287 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5288 unsigned char base_type
;
5290 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5292 if (pRange
->type
!= RPC_FC_RANGE
)
5294 ERR("invalid format type %x\n", pRange
->type
);
5295 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5299 base_type
= pRange
->flags_type
& 0xf;
5301 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &base_type
);
5304 /***********************************************************************
5305 * NdrRangeUnmarshall
5307 unsigned char *WINAPI
NdrRangeUnmarshall(
5308 PMIDL_STUB_MESSAGE pStubMsg
,
5309 unsigned char **ppMemory
,
5310 PFORMAT_STRING pFormat
,
5311 unsigned char fMustAlloc
)
5313 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5314 unsigned char base_type
;
5316 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
5318 if (pRange
->type
!= RPC_FC_RANGE
)
5320 ERR("invalid format type %x\n", pRange
->type
);
5321 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5324 base_type
= pRange
->flags_type
& 0xf;
5326 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5327 base_type
, pRange
->low_value
, pRange
->high_value
);
5329 #define RANGE_UNMARSHALL(type, format_spec) \
5332 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5333 if (fMustAlloc || !*ppMemory) \
5334 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5335 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
5337 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
5338 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
5339 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
5341 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5342 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5344 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5345 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5346 (type)pRange->high_value); \
5347 RpcRaiseException(RPC_S_INVALID_BOUND); \
5350 TRACE("*ppMemory: %p\n", *ppMemory); \
5351 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5352 pStubMsg->Buffer += sizeof(type); \
5359 RANGE_UNMARSHALL(UCHAR
, "%d");
5360 TRACE("value: 0x%02x\n", **(UCHAR
**)ppMemory
);
5364 RANGE_UNMARSHALL(CHAR
, "%u");
5365 TRACE("value: 0x%02x\n", **(UCHAR
**)ppMemory
);
5367 case RPC_FC_WCHAR
: /* FIXME: valid? */
5369 RANGE_UNMARSHALL(USHORT
, "%u");
5370 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5373 RANGE_UNMARSHALL(SHORT
, "%d");
5374 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5377 RANGE_UNMARSHALL(LONG
, "%d");
5378 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5381 RANGE_UNMARSHALL(ULONG
, "%u");
5382 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5386 FIXME("Unhandled enum type\n");
5388 case RPC_FC_ERROR_STATUS_T
: /* FIXME: valid? */
5393 ERR("invalid range base type: 0x%02x\n", base_type
);
5394 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5400 /***********************************************************************
5401 * NdrRangeBufferSize [internal]
5403 void WINAPI
NdrRangeBufferSize(
5404 PMIDL_STUB_MESSAGE pStubMsg
,
5405 unsigned char *pMemory
,
5406 PFORMAT_STRING pFormat
)
5408 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5409 unsigned char base_type
;
5411 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5413 if (pRange
->type
!= RPC_FC_RANGE
)
5415 ERR("invalid format type %x\n", pRange
->type
);
5416 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5418 base_type
= pRange
->flags_type
& 0xf;
5420 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &base_type
);
5423 /***********************************************************************
5424 * NdrRangeMemorySize [internal]
5426 ULONG WINAPI
NdrRangeMemorySize(
5427 PMIDL_STUB_MESSAGE pStubMsg
,
5428 PFORMAT_STRING pFormat
)
5430 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5431 unsigned char base_type
;
5433 if (pRange
->type
!= RPC_FC_RANGE
)
5435 ERR("invalid format type %x\n", pRange
->type
);
5436 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5439 base_type
= pRange
->flags_type
& 0xf;
5441 return NdrBaseTypeMemorySize(pStubMsg
, &base_type
);
5444 /***********************************************************************
5445 * NdrRangeFree [internal]
5447 void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg
,
5448 unsigned char *pMemory
,
5449 PFORMAT_STRING pFormat
)
5451 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5456 /***********************************************************************
5457 * NdrBaseTypeMarshall [internal]
5459 static unsigned char *WINAPI
NdrBaseTypeMarshall(
5460 PMIDL_STUB_MESSAGE pStubMsg
,
5461 unsigned char *pMemory
,
5462 PFORMAT_STRING pFormat
)
5464 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5472 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(UCHAR
));
5473 TRACE("value: 0x%02x\n", *(UCHAR
*)pMemory
);
5478 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5479 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(USHORT
));
5480 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
5484 case RPC_FC_ERROR_STATUS_T
:
5486 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
5487 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONG
));
5488 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
5491 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(float));
5492 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
5495 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(double));
5496 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
5499 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONGLONG
));
5500 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONGLONG
));
5501 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
5504 /* only 16-bits on the wire, so do a sanity check */
5505 if (*(UINT
*)pMemory
> SHRT_MAX
)
5506 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
5507 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5508 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5509 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5510 *(USHORT
*)pStubMsg
->Buffer
= *(UINT
*)pMemory
;
5511 pStubMsg
->Buffer
+= sizeof(USHORT
);
5512 TRACE("value: 0x%04x\n", *(UINT
*)pMemory
);
5517 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5520 /* FIXME: what is the correct return value? */
5524 /***********************************************************************
5525 * NdrBaseTypeUnmarshall [internal]
5527 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(
5528 PMIDL_STUB_MESSAGE pStubMsg
,
5529 unsigned char **ppMemory
,
5530 PFORMAT_STRING pFormat
,
5531 unsigned char fMustAlloc
)
5533 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
5535 #define BASE_TYPE_UNMARSHALL(type) \
5536 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5537 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
5539 *ppMemory = pStubMsg->Buffer; \
5540 TRACE("*ppMemory: %p\n", *ppMemory); \
5545 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5546 TRACE("*ppMemory: %p\n", *ppMemory); \
5547 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5549 pStubMsg->Buffer += sizeof(type);
5557 BASE_TYPE_UNMARSHALL(UCHAR
);
5558 TRACE("value: 0x%02x\n", **(UCHAR
**)ppMemory
);
5563 BASE_TYPE_UNMARSHALL(USHORT
);
5564 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5568 case RPC_FC_ERROR_STATUS_T
:
5570 BASE_TYPE_UNMARSHALL(ULONG
);
5571 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5574 BASE_TYPE_UNMARSHALL(float);
5575 TRACE("value: %f\n", **(float **)ppMemory
);
5578 BASE_TYPE_UNMARSHALL(double);
5579 TRACE("value: %f\n", **(double **)ppMemory
);
5582 BASE_TYPE_UNMARSHALL(ULONGLONG
);
5583 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG
**)ppMemory
));
5586 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5587 if (fMustAlloc
|| !*ppMemory
)
5588 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT
));
5589 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > pStubMsg
->BufferEnd
)
5590 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5591 TRACE("*ppMemory: %p\n", *ppMemory
);
5592 /* 16-bits on the wire, but int in memory */
5593 **(UINT
**)ppMemory
= *(USHORT
*)pStubMsg
->Buffer
;
5594 pStubMsg
->Buffer
+= sizeof(USHORT
);
5595 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
5600 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5602 #undef BASE_TYPE_UNMARSHALL
5604 /* FIXME: what is the correct return value? */
5609 /***********************************************************************
5610 * NdrBaseTypeBufferSize [internal]
5612 static void WINAPI
NdrBaseTypeBufferSize(
5613 PMIDL_STUB_MESSAGE pStubMsg
,
5614 unsigned char *pMemory
,
5615 PFORMAT_STRING pFormat
)
5617 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5625 safe_buffer_length_increment(pStubMsg
, sizeof(UCHAR
));
5631 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(USHORT
));
5632 safe_buffer_length_increment(pStubMsg
, sizeof(USHORT
));
5637 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONG
));
5638 safe_buffer_length_increment(pStubMsg
, sizeof(ULONG
));
5641 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(float));
5642 safe_buffer_length_increment(pStubMsg
, sizeof(float));
5645 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(double));
5646 safe_buffer_length_increment(pStubMsg
, sizeof(double));
5649 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONGLONG
));
5650 safe_buffer_length_increment(pStubMsg
, sizeof(ULONGLONG
));
5652 case RPC_FC_ERROR_STATUS_T
:
5653 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(error_status_t
));
5654 safe_buffer_length_increment(pStubMsg
, sizeof(error_status_t
));
5659 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5663 /***********************************************************************
5664 * NdrBaseTypeMemorySize [internal]
5666 static ULONG WINAPI
NdrBaseTypeMemorySize(
5667 PMIDL_STUB_MESSAGE pStubMsg
,
5668 PFORMAT_STRING pFormat
)
5670 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg
, *pFormat
);
5678 safe_buffer_increment(pStubMsg
, sizeof(UCHAR
));
5679 pStubMsg
->MemorySize
+= sizeof(UCHAR
);
5680 return sizeof(UCHAR
);
5684 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
5685 pStubMsg
->MemorySize
+= sizeof(USHORT
);
5686 return sizeof(USHORT
);
5690 safe_buffer_increment(pStubMsg
, sizeof(ULONG
));
5691 pStubMsg
->MemorySize
+= sizeof(ULONG
);
5692 return sizeof(ULONG
);
5694 safe_buffer_increment(pStubMsg
, sizeof(float));
5695 pStubMsg
->MemorySize
+= sizeof(float);
5696 return sizeof(float);
5698 safe_buffer_increment(pStubMsg
, sizeof(double));
5699 pStubMsg
->MemorySize
+= sizeof(double);
5700 return sizeof(double);
5702 safe_buffer_increment(pStubMsg
, sizeof(ULONGLONG
));
5703 pStubMsg
->MemorySize
+= sizeof(ULONGLONG
);
5704 return sizeof(ULONGLONG
);
5705 case RPC_FC_ERROR_STATUS_T
:
5706 safe_buffer_increment(pStubMsg
, sizeof(error_status_t
));
5707 pStubMsg
->MemorySize
+= sizeof(error_status_t
);
5708 return sizeof(error_status_t
);
5710 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
5711 pStubMsg
->MemorySize
+= sizeof(UINT
);
5712 return sizeof(UINT
);
5714 pStubMsg
->MemorySize
+= sizeof(void *);
5715 return sizeof(void *);
5717 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5722 /***********************************************************************
5723 * NdrBaseTypeFree [internal]
5725 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg
,
5726 unsigned char *pMemory
,
5727 PFORMAT_STRING pFormat
)
5729 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5734 /***********************************************************************
5735 * NdrContextHandleBufferSize [internal]
5737 static void WINAPI
NdrContextHandleBufferSize(
5738 PMIDL_STUB_MESSAGE pStubMsg
,
5739 unsigned char *pMemory
,
5740 PFORMAT_STRING pFormat
)
5742 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5744 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
5746 ERR("invalid format type %x\n", *pFormat
);
5747 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5749 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
5750 safe_buffer_length_increment(pStubMsg
, cbNDRContext
);
5753 /***********************************************************************
5754 * NdrContextHandleMarshall [internal]
5756 static unsigned char *WINAPI
NdrContextHandleMarshall(
5757 PMIDL_STUB_MESSAGE pStubMsg
,
5758 unsigned char *pMemory
,
5759 PFORMAT_STRING pFormat
)
5761 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5763 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
5765 ERR("invalid format type %x\n", *pFormat
);
5766 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5769 if (pFormat
[1] & 0x80)
5770 NdrClientContextMarshall(pStubMsg
, *(NDR_CCONTEXT
**)pMemory
, FALSE
);
5772 NdrClientContextMarshall(pStubMsg
, (NDR_CCONTEXT
*)pMemory
, FALSE
);
5777 /***********************************************************************
5778 * NdrContextHandleUnmarshall [internal]
5780 static unsigned char *WINAPI
NdrContextHandleUnmarshall(
5781 PMIDL_STUB_MESSAGE pStubMsg
,
5782 unsigned char **ppMemory
,
5783 PFORMAT_STRING pFormat
,
5784 unsigned char fMustAlloc
)
5786 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
5788 ERR("invalid format type %x\n", *pFormat
);
5789 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5792 **(NDR_CCONTEXT
**)ppMemory
= NULL
;
5793 NdrClientContextUnmarshall(pStubMsg
, *(NDR_CCONTEXT
**)ppMemory
, pStubMsg
->RpcMsg
->Handle
);
5798 /***********************************************************************
5799 * NdrClientContextMarshall [RPCRT4.@]
5801 void WINAPI
NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5802 NDR_CCONTEXT ContextHandle
,
5805 TRACE("(%p, %p, %d)\n", pStubMsg
, ContextHandle
, fCheck
);
5807 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5809 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5811 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
5812 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
5813 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5816 /* FIXME: what does fCheck do? */
5817 NDRCContextMarshall(ContextHandle
,
5820 pStubMsg
->Buffer
+= cbNDRContext
;
5823 /***********************************************************************
5824 * NdrClientContextUnmarshall [RPCRT4.@]
5826 void WINAPI
NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5827 NDR_CCONTEXT
* pContextHandle
,
5828 RPC_BINDING_HANDLE BindHandle
)
5830 TRACE("(%p, %p, %p)\n", pStubMsg
, pContextHandle
, BindHandle
);
5832 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5834 if (pStubMsg
->Buffer
+ cbNDRContext
> pStubMsg
->BufferEnd
)
5835 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5837 NDRCContextUnmarshall(pContextHandle
,
5840 pStubMsg
->RpcMsg
->DataRepresentation
);
5842 pStubMsg
->Buffer
+= cbNDRContext
;
5845 void WINAPI
NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5846 NDR_SCONTEXT ContextHandle
,
5847 NDR_RUNDOWN RundownRoutine
)
5849 FIXME("(%p, %p, %p): stub\n", pStubMsg
, ContextHandle
, RundownRoutine
);
5852 NDR_SCONTEXT WINAPI
NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
)
5854 FIXME("(%p): stub\n", pStubMsg
);
5858 void WINAPI
NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg
,
5859 unsigned char* pMemory
,
5860 PFORMAT_STRING pFormat
)
5862 FIXME("(%p, %p, %p): stub\n", pStubMsg
, pMemory
, pFormat
);
5865 NDR_SCONTEXT WINAPI
NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg
,
5866 PFORMAT_STRING pFormat
)
5868 FIXME("(%p, %p): stub\n", pStubMsg
, pFormat
);
5872 void WINAPI
NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5873 NDR_SCONTEXT ContextHandle
,
5874 NDR_RUNDOWN RundownRoutine
,
5875 PFORMAT_STRING pFormat
)
5877 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg
, ContextHandle
, RundownRoutine
, pFormat
);
5880 NDR_SCONTEXT WINAPI
NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5881 PFORMAT_STRING pFormat
)
5883 FIXME("(%p, %p): stub\n", pStubMsg
, pFormat
);
5887 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
5889 typedef struct ndr_context_handle
5893 } ndr_context_handle
;
5895 struct context_handle_entry
5899 RPC_BINDING_HANDLE handle
;
5900 ndr_context_handle wire_data
;
5903 static struct list context_handle_list
= LIST_INIT(context_handle_list
);
5905 static CRITICAL_SECTION ndr_context_cs
;
5906 static CRITICAL_SECTION_DEBUG ndr_context_debug
=
5908 0, 0, &ndr_context_cs
,
5909 { &ndr_context_debug
.ProcessLocksList
, &ndr_context_debug
.ProcessLocksList
},
5910 0, 0, { (DWORD_PTR
)(__FILE__
": ndr_context") }
5912 static CRITICAL_SECTION ndr_context_cs
= { &ndr_context_debug
, -1, 0, 0, 0, 0 };
5914 static struct context_handle_entry
*get_context_entry(NDR_CCONTEXT CContext
)
5916 struct context_handle_entry
*che
= (struct context_handle_entry
*) CContext
;
5918 if (che
->magic
!= NDR_CONTEXT_HANDLE_MAGIC
)
5923 static struct context_handle_entry
*context_entry_from_guid(LPCGUID uuid
)
5925 struct context_handle_entry
*che
;
5926 LIST_FOR_EACH_ENTRY(che
, &context_handle_list
, struct context_handle_entry
, entry
)
5927 if (IsEqualGUID(&che
->wire_data
.uuid
, uuid
))
5932 RPC_BINDING_HANDLE WINAPI
NDRCContextBinding(NDR_CCONTEXT CContext
)
5934 struct context_handle_entry
*che
;
5935 RPC_BINDING_HANDLE handle
= NULL
;
5937 TRACE("%p\n", CContext
);
5939 EnterCriticalSection(&ndr_context_cs
);
5940 che
= get_context_entry(CContext
);
5942 handle
= che
->handle
;
5943 LeaveCriticalSection(&ndr_context_cs
);
5946 RpcRaiseException(ERROR_INVALID_HANDLE
);
5950 void WINAPI
NDRCContextMarshall(NDR_CCONTEXT CContext
, void *pBuff
)
5952 struct context_handle_entry
*che
;
5954 TRACE("%p %p\n", CContext
, pBuff
);
5958 EnterCriticalSection(&ndr_context_cs
);
5959 che
= get_context_entry(CContext
);
5960 memcpy(pBuff
, &che
->wire_data
, sizeof (ndr_context_handle
));
5961 LeaveCriticalSection(&ndr_context_cs
);
5965 ndr_context_handle
*wire_data
= (ndr_context_handle
*)pBuff
;
5966 wire_data
->attributes
= 0;
5967 wire_data
->uuid
= GUID_NULL
;
5971 /***********************************************************************
5972 * RpcSmDestroyClientContext [RPCRT4.@]
5974 RPC_STATUS WINAPI
RpcSmDestroyClientContext(void **ContextHandle
)
5976 RPC_STATUS status
= RPC_X_SS_CONTEXT_MISMATCH
;
5977 struct context_handle_entry
*che
= NULL
;
5979 TRACE("(%p)\n", ContextHandle
);
5981 EnterCriticalSection(&ndr_context_cs
);
5982 che
= get_context_entry(*ContextHandle
);
5983 *ContextHandle
= NULL
;
5987 list_remove(&che
->entry
);
5990 LeaveCriticalSection(&ndr_context_cs
);
5994 RpcBindingFree(&che
->handle
);
5995 HeapFree(GetProcessHeap(), 0, che
);
6001 /***********************************************************************
6002 * RpcSsDestroyClientContext [RPCRT4.@]
6004 void WINAPI
RpcSsDestroyClientContext(void **ContextHandle
)
6006 RPC_STATUS status
= RpcSmDestroyClientContext(ContextHandle
);
6007 if (status
!= RPC_S_OK
)
6008 RpcRaiseException(status
);
6011 static UINT
ndr_update_context_handle(NDR_CCONTEXT
*CContext
,
6012 RPC_BINDING_HANDLE hBinding
,
6013 const ndr_context_handle
*chi
)
6015 struct context_handle_entry
*che
= NULL
;
6017 /* a null UUID means we should free the context handle */
6018 if (IsEqualGUID(&chi
->uuid
, &GUID_NULL
))
6022 che
= get_context_entry(*CContext
);
6024 return ERROR_INVALID_HANDLE
;
6025 list_remove(&che
->entry
);
6026 RpcBindingFree(&che
->handle
);
6027 HeapFree(GetProcessHeap(), 0, che
);
6031 /* if there's no existing entry matching the GUID, allocate one */
6032 else if (!(che
= context_entry_from_guid(&chi
->uuid
)))
6034 che
= HeapAlloc(GetProcessHeap(), 0, sizeof *che
);
6036 return ERROR_NOT_ENOUGH_MEMORY
;
6037 che
->magic
= NDR_CONTEXT_HANDLE_MAGIC
;
6038 RpcBindingCopy(hBinding
, &che
->handle
);
6039 list_add_tail(&context_handle_list
, &che
->entry
);
6040 memcpy(&che
->wire_data
, chi
, sizeof *chi
);
6045 return ERROR_SUCCESS
;
6048 /***********************************************************************
6049 * NDRCContextUnmarshall [RPCRT4.@]
6051 void WINAPI
NDRCContextUnmarshall(NDR_CCONTEXT
*CContext
,
6052 RPC_BINDING_HANDLE hBinding
,
6053 void *pBuff
, ULONG DataRepresentation
)
6057 TRACE("*%p=(%p) %p %p %08x\n",
6058 CContext
, *CContext
, hBinding
, pBuff
, DataRepresentation
);
6060 EnterCriticalSection(&ndr_context_cs
);
6061 r
= ndr_update_context_handle(CContext
, hBinding
, pBuff
);
6062 LeaveCriticalSection(&ndr_context_cs
);
6064 RpcRaiseException(r
);
6067 /***********************************************************************
6068 * NDRSContextMarshall [RPCRT4.@]
6070 void WINAPI
NDRSContextMarshall(NDR_SCONTEXT CContext
,
6072 NDR_RUNDOWN userRunDownIn
)
6074 FIXME("(%p %p %p): stub\n", CContext
, pBuff
, userRunDownIn
);
6077 /***********************************************************************
6078 * NDRSContextMarshallEx [RPCRT4.@]
6080 void WINAPI
NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding
,
6081 NDR_SCONTEXT CContext
,
6083 NDR_RUNDOWN userRunDownIn
)
6085 FIXME("(%p %p %p %p): stub\n", hBinding
, CContext
, pBuff
, userRunDownIn
);
6088 /***********************************************************************
6089 * NDRSContextMarshall2 [RPCRT4.@]
6091 void WINAPI
NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding
,
6092 NDR_SCONTEXT CContext
,
6094 NDR_RUNDOWN userRunDownIn
,
6095 void *CtxGuard
, ULONG Flags
)
6097 FIXME("(%p %p %p %p %p %u): stub\n",
6098 hBinding
, CContext
, pBuff
, userRunDownIn
, CtxGuard
, Flags
);
6101 /***********************************************************************
6102 * NDRSContextUnmarshall [RPCRT4.@]
6104 NDR_SCONTEXT WINAPI
NDRSContextUnmarshall(void *pBuff
,
6105 ULONG DataRepresentation
)
6107 FIXME("(%p %08x): stub\n", pBuff
, DataRepresentation
);
6111 /***********************************************************************
6112 * NDRSContextUnmarshallEx [RPCRT4.@]
6114 NDR_SCONTEXT WINAPI
NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding
,
6116 ULONG DataRepresentation
)
6118 FIXME("(%p %p %08x): stub\n", hBinding
, pBuff
, DataRepresentation
);
6122 /***********************************************************************
6123 * NDRSContextUnmarshall2 [RPCRT4.@]
6125 NDR_SCONTEXT WINAPI
NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding
,
6127 ULONG DataRepresentation
,
6128 void *CtxGuard
, ULONG Flags
)
6130 FIXME("(%p %p %08x %p %u): stub\n",
6131 hBinding
, pBuff
, DataRepresentation
, CtxGuard
, Flags
);