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
;
1467 unsigned char *saved_buffer
= NULL
;
1469 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1471 if (pStubMsg
->IgnoreEmbeddedPointers
) return 0;
1473 if (pStubMsg
->PointerBufferMark
)
1475 saved_buffer
= pStubMsg
->Buffer
;
1476 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1477 pStubMsg
->PointerBufferMark
= NULL
;
1480 if (*pFormat
!= RPC_FC_PP
) return 0;
1483 while (pFormat
[0] != RPC_FC_END
) {
1484 switch (pFormat
[0]) {
1486 FIXME("unknown repeat type %d\n", pFormat
[0]);
1487 case RPC_FC_NO_REPEAT
:
1493 case RPC_FC_FIXED_REPEAT
:
1494 rep
= *(const WORD
*)&pFormat
[2];
1495 stride
= *(const WORD
*)&pFormat
[4];
1496 count
= *(const WORD
*)&pFormat
[8];
1499 case RPC_FC_VARIABLE_REPEAT
:
1500 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1501 stride
= *(const WORD
*)&pFormat
[2];
1502 count
= *(const WORD
*)&pFormat
[6];
1506 for (i
= 0; i
< rep
; i
++) {
1507 PFORMAT_STRING info
= pFormat
;
1508 unsigned char *bufbase
= Mark
+ (i
* stride
);
1510 for (u
=0; u
<count
; u
++,info
+=8) {
1511 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1512 PointerMemorySize(pStubMsg
, bufptr
, info
+4);
1515 pFormat
+= 8 * count
;
1520 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1521 pStubMsg
->Buffer
= saved_buffer
;
1527 /***********************************************************************
1528 * EmbeddedPointerFree [internal]
1530 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1531 unsigned char *pMemory
,
1532 PFORMAT_STRING pFormat
)
1534 unsigned rep
, count
, stride
;
1537 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1538 if (*pFormat
!= RPC_FC_PP
) return;
1541 while (pFormat
[0] != RPC_FC_END
) {
1542 switch (pFormat
[0]) {
1544 FIXME("unknown repeat type %d\n", pFormat
[0]);
1545 case RPC_FC_NO_REPEAT
:
1551 case RPC_FC_FIXED_REPEAT
:
1552 rep
= *(const WORD
*)&pFormat
[2];
1553 stride
= *(const WORD
*)&pFormat
[4];
1554 count
= *(const WORD
*)&pFormat
[8];
1557 case RPC_FC_VARIABLE_REPEAT
:
1558 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1559 stride
= *(const WORD
*)&pFormat
[2];
1560 count
= *(const WORD
*)&pFormat
[6];
1564 for (i
= 0; i
< rep
; i
++) {
1565 PFORMAT_STRING info
= pFormat
;
1566 unsigned char *membase
= pMemory
+ (i
* stride
);
1569 for (u
=0; u
<count
; u
++,info
+=8) {
1570 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1571 unsigned char *saved_memory
= pStubMsg
->Memory
;
1573 pStubMsg
->Memory
= pMemory
;
1574 PointerFree(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1575 pStubMsg
->Memory
= saved_memory
;
1578 pFormat
+= 8 * count
;
1582 /***********************************************************************
1583 * NdrPointerMarshall [RPCRT4.@]
1585 unsigned char * WINAPI
NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1586 unsigned char *pMemory
,
1587 PFORMAT_STRING pFormat
)
1589 unsigned char *Buffer
;
1591 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1593 /* incremement the buffer here instead of in PointerMarshall,
1594 * as that is used by embedded pointers which already handle the incrementing
1595 * the buffer, and shouldn't write any additional pointer data to the wire */
1596 if (*pFormat
!= RPC_FC_RP
)
1598 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1599 Buffer
= pStubMsg
->Buffer
;
1600 safe_buffer_increment(pStubMsg
, 4);
1603 Buffer
= pStubMsg
->Buffer
;
1605 PointerMarshall(pStubMsg
, Buffer
, pMemory
, pFormat
);
1610 /***********************************************************************
1611 * NdrPointerUnmarshall [RPCRT4.@]
1613 unsigned char * WINAPI
NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1614 unsigned char **ppMemory
,
1615 PFORMAT_STRING pFormat
,
1616 unsigned char fMustAlloc
)
1618 unsigned char *Buffer
;
1620 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1622 /* incremement the buffer here instead of in PointerUnmarshall,
1623 * as that is used by embedded pointers which already handle the incrementing
1624 * the buffer, and shouldn't read any additional pointer data from the
1626 if (*pFormat
!= RPC_FC_RP
)
1628 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1629 Buffer
= pStubMsg
->Buffer
;
1630 safe_buffer_increment(pStubMsg
, 4);
1633 Buffer
= pStubMsg
->Buffer
;
1635 PointerUnmarshall(pStubMsg
, Buffer
, ppMemory
, *ppMemory
, pFormat
, fMustAlloc
);
1640 /***********************************************************************
1641 * NdrPointerBufferSize [RPCRT4.@]
1643 void WINAPI
NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1644 unsigned char *pMemory
,
1645 PFORMAT_STRING pFormat
)
1647 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1649 /* incremement the buffer length here instead of in PointerBufferSize,
1650 * as that is used by embedded pointers which already handle the buffer
1651 * length, and shouldn't write anything more to the wire */
1652 if (*pFormat
!= RPC_FC_RP
)
1654 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
1655 safe_buffer_length_increment(pStubMsg
, 4);
1658 PointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1661 /***********************************************************************
1662 * NdrPointerMemorySize [RPCRT4.@]
1664 ULONG WINAPI
NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1665 PFORMAT_STRING pFormat
)
1667 /* unsigned size = *(LPWORD)(pFormat+2); */
1668 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1669 PointerMemorySize(pStubMsg
, pStubMsg
->Buffer
, pFormat
);
1673 /***********************************************************************
1674 * NdrPointerFree [RPCRT4.@]
1676 void WINAPI
NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1677 unsigned char *pMemory
,
1678 PFORMAT_STRING pFormat
)
1680 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1681 PointerFree(pStubMsg
, pMemory
, pFormat
);
1684 /***********************************************************************
1685 * NdrSimpleTypeMarshall [RPCRT4.@]
1687 void WINAPI
NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1688 unsigned char FormatChar
)
1690 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &FormatChar
);
1693 /***********************************************************************
1694 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1696 void WINAPI
NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1697 unsigned char FormatChar
)
1699 NdrBaseTypeUnmarshall(pStubMsg
, &pMemory
, &FormatChar
, 0);
1702 /***********************************************************************
1703 * NdrSimpleStructMarshall [RPCRT4.@]
1705 unsigned char * WINAPI
NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1706 unsigned char *pMemory
,
1707 PFORMAT_STRING pFormat
)
1709 unsigned size
= *(const WORD
*)(pFormat
+2);
1710 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1712 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1714 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1715 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
1717 if (pFormat
[0] != RPC_FC_STRUCT
)
1718 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
+4);
1723 /***********************************************************************
1724 * NdrSimpleStructUnmarshall [RPCRT4.@]
1726 unsigned char * WINAPI
NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1727 unsigned char **ppMemory
,
1728 PFORMAT_STRING pFormat
,
1729 unsigned char fMustAlloc
)
1731 unsigned size
= *(const WORD
*)(pFormat
+2);
1732 unsigned char *saved_buffer
;
1733 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1735 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1738 *ppMemory
= NdrAllocate(pStubMsg
, size
);
1741 if (!pStubMsg
->IsClient
&& !*ppMemory
)
1742 /* for servers, we just point straight into the RPC buffer */
1743 *ppMemory
= pStubMsg
->Buffer
;
1746 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1747 safe_buffer_increment(pStubMsg
, size
);
1748 if (pFormat
[0] == RPC_FC_PSTRUCT
)
1749 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
+4, fMustAlloc
);
1751 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
1752 if (*ppMemory
!= saved_buffer
)
1753 memcpy(*ppMemory
, saved_buffer
, size
);
1758 /***********************************************************************
1759 * NdrSimpleStructBufferSize [RPCRT4.@]
1761 void WINAPI
NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1762 unsigned char *pMemory
,
1763 PFORMAT_STRING pFormat
)
1765 unsigned size
= *(const WORD
*)(pFormat
+2);
1766 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1768 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
1770 safe_buffer_length_increment(pStubMsg
, size
);
1771 if (pFormat
[0] != RPC_FC_STRUCT
)
1772 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
+4);
1775 /***********************************************************************
1776 * NdrSimpleStructMemorySize [RPCRT4.@]
1778 ULONG WINAPI
NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1779 PFORMAT_STRING pFormat
)
1781 unsigned short size
= *(const WORD
*)(pFormat
+2);
1783 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1785 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1786 pStubMsg
->MemorySize
+= size
;
1787 safe_buffer_increment(pStubMsg
, size
);
1789 if (pFormat
[0] != RPC_FC_STRUCT
)
1790 EmbeddedPointerMemorySize(pStubMsg
, pFormat
+4);
1791 return pStubMsg
->MemorySize
;
1794 /***********************************************************************
1795 * NdrSimpleStructFree [RPCRT4.@]
1797 void WINAPI
NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
1798 unsigned char *pMemory
,
1799 PFORMAT_STRING pFormat
)
1801 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1802 if (pFormat
[0] != RPC_FC_STRUCT
)
1803 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
+4);
1807 static unsigned long EmbeddedComplexSize(const MIDL_STUB_MESSAGE
*pStubMsg
,
1808 PFORMAT_STRING pFormat
)
1812 case RPC_FC_PSTRUCT
:
1813 case RPC_FC_CSTRUCT
:
1814 case RPC_FC_BOGUS_STRUCT
:
1815 case RPC_FC_SMFARRAY
:
1816 case RPC_FC_SMVARRAY
:
1817 return *(const WORD
*)&pFormat
[2];
1818 case RPC_FC_USER_MARSHAL
:
1819 return *(const WORD
*)&pFormat
[4];
1820 case RPC_FC_NON_ENCAPSULATED_UNION
:
1822 if (pStubMsg
->fHasNewCorrDesc
)
1827 pFormat
+= *(const SHORT
*)pFormat
;
1828 return *(const SHORT
*)pFormat
;
1830 return sizeof(void *);
1832 FIXME("unhandled embedded type %02x\n", *pFormat
);
1838 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1839 PFORMAT_STRING pFormat
)
1841 NDR_MEMORYSIZE m
= NdrMemorySizer
[*pFormat
& NDR_TABLE_MASK
];
1845 FIXME("no memorysizer for data type=%02x\n", *pFormat
);
1849 return m(pStubMsg
, pFormat
);
1853 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1854 unsigned char *pMemory
,
1855 PFORMAT_STRING pFormat
,
1856 PFORMAT_STRING pPointer
)
1858 PFORMAT_STRING desc
;
1862 while (*pFormat
!= RPC_FC_END
) {
1868 TRACE("byte=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
1869 safe_copy_to_buffer(pStubMsg
, pMemory
, 1);
1875 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
1876 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
1882 TRACE("long=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
1883 safe_copy_to_buffer(pStubMsg
, pMemory
, 4);
1887 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
1888 safe_copy_to_buffer(pStubMsg
, pMemory
, 8);
1891 case RPC_FC_POINTER
:
1893 unsigned char *saved_buffer
;
1894 int pointer_buffer_mark_set
= 0;
1895 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
1896 saved_buffer
= pStubMsg
->Buffer
;
1897 if (pStubMsg
->PointerBufferMark
)
1899 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1900 pStubMsg
->PointerBufferMark
= NULL
;
1901 pointer_buffer_mark_set
= 1;
1904 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
1905 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char**)pMemory
, pPointer
);
1906 if (pointer_buffer_mark_set
)
1908 STD_OVERFLOW_CHECK(pStubMsg
);
1909 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1910 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
1912 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
1913 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
1914 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1916 pStubMsg
->Buffer
= saved_buffer
+ 4;
1922 case RPC_FC_ALIGNM4
:
1923 ALIGN_POINTER(pMemory
, 4);
1925 case RPC_FC_ALIGNM8
:
1926 ALIGN_POINTER(pMemory
, 8);
1928 case RPC_FC_STRUCTPAD1
:
1929 case RPC_FC_STRUCTPAD2
:
1930 case RPC_FC_STRUCTPAD3
:
1931 case RPC_FC_STRUCTPAD4
:
1932 case RPC_FC_STRUCTPAD5
:
1933 case RPC_FC_STRUCTPAD6
:
1934 case RPC_FC_STRUCTPAD7
:
1935 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
1937 case RPC_FC_EMBEDDED_COMPLEX
:
1938 pMemory
+= pFormat
[1];
1940 desc
= pFormat
+ *(const SHORT
*)pFormat
;
1941 size
= EmbeddedComplexSize(pStubMsg
, desc
);
1942 TRACE("embedded complex (size=%ld) <= %p\n", size
, pMemory
);
1943 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
1946 /* for some reason interface pointers aren't generated as
1947 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
1948 * they still need the derefencing treatment that pointers are
1950 if (*desc
== RPC_FC_IP
)
1951 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
1953 m(pStubMsg
, pMemory
, desc
);
1955 else FIXME("no marshaller for embedded type %02x\n", *desc
);
1962 FIXME("unhandled format 0x%02x\n", *pFormat
);
1970 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1971 unsigned char *pMemory
,
1972 PFORMAT_STRING pFormat
,
1973 PFORMAT_STRING pPointer
)
1975 PFORMAT_STRING desc
;
1979 while (*pFormat
!= RPC_FC_END
) {
1985 safe_copy_from_buffer(pStubMsg
, pMemory
, 1);
1986 TRACE("byte=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
1992 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
1993 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
1999 safe_copy_from_buffer(pStubMsg
, pMemory
, 4);
2000 TRACE("long=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
2004 safe_copy_from_buffer(pStubMsg
, pMemory
, 8);
2005 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2008 case RPC_FC_POINTER
:
2010 unsigned char *saved_buffer
;
2011 int pointer_buffer_mark_set
= 0;
2012 TRACE("pointer => %p\n", pMemory
);
2013 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2014 saved_buffer
= pStubMsg
->Buffer
;
2015 if (pStubMsg
->PointerBufferMark
)
2017 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2018 pStubMsg
->PointerBufferMark
= NULL
;
2019 pointer_buffer_mark_set
= 1;
2022 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2024 PointerUnmarshall(pStubMsg
, saved_buffer
, (unsigned char**)pMemory
, *(unsigned char**)pMemory
, pPointer
, TRUE
);
2025 if (pointer_buffer_mark_set
)
2027 STD_OVERFLOW_CHECK(pStubMsg
);
2028 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2029 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
2031 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2032 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
2033 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2035 pStubMsg
->Buffer
= saved_buffer
+ 4;
2041 case RPC_FC_ALIGNM4
:
2042 ALIGN_POINTER(pMemory
, 4);
2044 case RPC_FC_ALIGNM8
:
2045 ALIGN_POINTER(pMemory
, 8);
2047 case RPC_FC_STRUCTPAD1
:
2048 case RPC_FC_STRUCTPAD2
:
2049 case RPC_FC_STRUCTPAD3
:
2050 case RPC_FC_STRUCTPAD4
:
2051 case RPC_FC_STRUCTPAD5
:
2052 case RPC_FC_STRUCTPAD6
:
2053 case RPC_FC_STRUCTPAD7
:
2054 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2056 case RPC_FC_EMBEDDED_COMPLEX
:
2057 pMemory
+= pFormat
[1];
2059 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2060 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2061 TRACE("embedded complex (size=%ld) => %p\n", size
, pMemory
);
2062 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
2063 memset(pMemory
, 0, size
); /* just in case */
2066 /* for some reason interface pointers aren't generated as
2067 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2068 * they still need the derefencing treatment that pointers are
2070 if (*desc
== RPC_FC_IP
)
2071 m(pStubMsg
, (unsigned char **)pMemory
, desc
, FALSE
);
2073 m(pStubMsg
, &pMemory
, desc
, FALSE
);
2075 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
2082 FIXME("unhandled format %d\n", *pFormat
);
2090 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2091 unsigned char *pMemory
,
2092 PFORMAT_STRING pFormat
,
2093 PFORMAT_STRING pPointer
)
2095 PFORMAT_STRING desc
;
2099 while (*pFormat
!= RPC_FC_END
) {
2105 safe_buffer_length_increment(pStubMsg
, 1);
2111 safe_buffer_length_increment(pStubMsg
, 2);
2117 safe_buffer_length_increment(pStubMsg
, 4);
2121 safe_buffer_length_increment(pStubMsg
, 8);
2124 case RPC_FC_POINTER
:
2125 if (!pStubMsg
->IgnoreEmbeddedPointers
)
2127 int saved_buffer_length
= pStubMsg
->BufferLength
;
2128 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2129 pStubMsg
->PointerLength
= 0;
2130 if(!pStubMsg
->BufferLength
)
2131 ERR("BufferLength == 0??\n");
2132 PointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
2133 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2134 pStubMsg
->BufferLength
= saved_buffer_length
;
2136 safe_buffer_length_increment(pStubMsg
, 4);
2140 case RPC_FC_ALIGNM4
:
2141 ALIGN_POINTER(pMemory
, 4);
2143 case RPC_FC_ALIGNM8
:
2144 ALIGN_POINTER(pMemory
, 8);
2146 case RPC_FC_STRUCTPAD1
:
2147 case RPC_FC_STRUCTPAD2
:
2148 case RPC_FC_STRUCTPAD3
:
2149 case RPC_FC_STRUCTPAD4
:
2150 case RPC_FC_STRUCTPAD5
:
2151 case RPC_FC_STRUCTPAD6
:
2152 case RPC_FC_STRUCTPAD7
:
2153 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2155 case RPC_FC_EMBEDDED_COMPLEX
:
2156 pMemory
+= pFormat
[1];
2158 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2159 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2160 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
2163 /* for some reason interface pointers aren't generated as
2164 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2165 * they still need the derefencing treatment that pointers are
2167 if (*desc
== RPC_FC_IP
)
2168 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2170 m(pStubMsg
, pMemory
, desc
);
2172 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
2179 FIXME("unhandled format 0x%02x\n", *pFormat
);
2187 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
2188 unsigned char *pMemory
,
2189 PFORMAT_STRING pFormat
,
2190 PFORMAT_STRING pPointer
)
2192 PFORMAT_STRING desc
;
2196 while (*pFormat
!= RPC_FC_END
) {
2217 case RPC_FC_POINTER
:
2218 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
2222 case RPC_FC_ALIGNM4
:
2223 ALIGN_POINTER(pMemory
, 4);
2225 case RPC_FC_ALIGNM8
:
2226 ALIGN_POINTER(pMemory
, 8);
2228 case RPC_FC_STRUCTPAD1
:
2229 case RPC_FC_STRUCTPAD2
:
2230 case RPC_FC_STRUCTPAD3
:
2231 case RPC_FC_STRUCTPAD4
:
2232 case RPC_FC_STRUCTPAD5
:
2233 case RPC_FC_STRUCTPAD6
:
2234 case RPC_FC_STRUCTPAD7
:
2235 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2237 case RPC_FC_EMBEDDED_COMPLEX
:
2238 pMemory
+= pFormat
[1];
2240 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2241 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2242 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
2245 /* for some reason interface pointers aren't generated as
2246 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2247 * they still need the derefencing treatment that pointers are
2249 if (*desc
== RPC_FC_IP
)
2250 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2252 m(pStubMsg
, pMemory
, desc
);
2254 else FIXME("no freer for embedded type %02x\n", *desc
);
2261 FIXME("unhandled format 0x%02x\n", *pFormat
);
2269 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2270 PFORMAT_STRING pFormat
)
2272 PFORMAT_STRING desc
;
2273 unsigned long size
= 0;
2275 while (*pFormat
!= RPC_FC_END
) {
2282 safe_buffer_increment(pStubMsg
, 1);
2288 safe_buffer_increment(pStubMsg
, 2);
2294 safe_buffer_increment(pStubMsg
, 4);
2298 safe_buffer_increment(pStubMsg
, 8);
2300 case RPC_FC_POINTER
:
2302 safe_buffer_increment(pStubMsg
, 4);
2303 if (!pStubMsg
->IgnoreEmbeddedPointers
)
2304 FIXME("embedded pointers\n");
2306 case RPC_FC_ALIGNM4
:
2307 ALIGN_LENGTH(size
, 4);
2308 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2310 case RPC_FC_ALIGNM8
:
2311 ALIGN_LENGTH(size
, 8);
2312 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
2314 case RPC_FC_STRUCTPAD1
:
2315 case RPC_FC_STRUCTPAD2
:
2316 case RPC_FC_STRUCTPAD3
:
2317 case RPC_FC_STRUCTPAD4
:
2318 case RPC_FC_STRUCTPAD5
:
2319 case RPC_FC_STRUCTPAD6
:
2320 case RPC_FC_STRUCTPAD7
:
2321 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2323 case RPC_FC_EMBEDDED_COMPLEX
:
2326 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2327 size
+= EmbeddedComplexMemorySize(pStubMsg
, desc
);
2333 FIXME("unhandled format 0x%02x\n", *pFormat
);
2341 /***********************************************************************
2342 * NdrComplexStructMarshall [RPCRT4.@]
2344 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2345 unsigned char *pMemory
,
2346 PFORMAT_STRING pFormat
)
2348 PFORMAT_STRING conf_array
= NULL
;
2349 PFORMAT_STRING pointer_desc
= NULL
;
2350 unsigned char *OldMemory
= pStubMsg
->Memory
;
2351 int pointer_buffer_mark_set
= 0;
2353 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2355 if (!pStubMsg
->PointerBufferMark
)
2357 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2358 /* save buffer length */
2359 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2361 /* get the buffer pointer after complex array data, but before
2363 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- pStubMsg
->BufferStart
;
2364 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2365 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
2366 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2368 /* save it for use by embedded pointer code later */
2369 pStubMsg
->PointerBufferMark
= pStubMsg
->BufferStart
+ pStubMsg
->BufferLength
;
2370 TRACE("difference = 0x%x\n", pStubMsg
->PointerBufferMark
- pStubMsg
->Buffer
);
2371 pointer_buffer_mark_set
= 1;
2373 /* restore the original buffer length */
2374 pStubMsg
->BufferLength
= saved_buffer_length
;
2377 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2380 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2382 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2385 pStubMsg
->Memory
= pMemory
;
2387 ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2390 NdrConformantArrayMarshall(pStubMsg
, pMemory
, conf_array
);
2392 pStubMsg
->Memory
= OldMemory
;
2394 if (pointer_buffer_mark_set
)
2396 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2397 pStubMsg
->PointerBufferMark
= NULL
;
2400 STD_OVERFLOW_CHECK(pStubMsg
);
2405 /***********************************************************************
2406 * NdrComplexStructUnmarshall [RPCRT4.@]
2408 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2409 unsigned char **ppMemory
,
2410 PFORMAT_STRING pFormat
,
2411 unsigned char fMustAlloc
)
2413 unsigned size
= *(const WORD
*)(pFormat
+2);
2414 PFORMAT_STRING conf_array
= NULL
;
2415 PFORMAT_STRING pointer_desc
= NULL
;
2416 unsigned char *pMemory
;
2417 int pointer_buffer_mark_set
= 0;
2419 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2421 if (!pStubMsg
->PointerBufferMark
)
2423 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2424 /* save buffer pointer */
2425 unsigned char *saved_buffer
= pStubMsg
->Buffer
;
2427 /* get the buffer pointer after complex array data, but before
2429 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2430 NdrComplexStructMemorySize(pStubMsg
, pFormat
);
2431 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2433 /* save it for use by embedded pointer code later */
2434 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2435 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->PointerBufferMark
- saved_buffer
));
2436 pointer_buffer_mark_set
= 1;
2438 /* restore the original buffer */
2439 pStubMsg
->Buffer
= saved_buffer
;
2442 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2444 if (fMustAlloc
|| !*ppMemory
)
2446 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2447 memset(*ppMemory
, 0, size
);
2451 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2453 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2456 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
);
2459 NdrConformantArrayUnmarshall(pStubMsg
, &pMemory
, conf_array
, fMustAlloc
);
2461 if (pointer_buffer_mark_set
)
2463 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2464 pStubMsg
->PointerBufferMark
= NULL
;
2470 /***********************************************************************
2471 * NdrComplexStructBufferSize [RPCRT4.@]
2473 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2474 unsigned char *pMemory
,
2475 PFORMAT_STRING pFormat
)
2477 PFORMAT_STRING conf_array
= NULL
;
2478 PFORMAT_STRING pointer_desc
= NULL
;
2479 unsigned char *OldMemory
= pStubMsg
->Memory
;
2480 int pointer_length_set
= 0;
2482 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2484 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
2486 if(!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
2488 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2489 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2491 /* get the buffer length after complex struct data, but before
2493 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2494 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
2495 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2497 /* save it for use by embedded pointer code later */
2498 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2499 pointer_length_set
= 1;
2500 TRACE("difference = 0x%lx\n", pStubMsg
->PointerLength
- saved_buffer_length
);
2502 /* restore the original buffer length */
2503 pStubMsg
->BufferLength
= saved_buffer_length
;
2507 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2509 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2512 pStubMsg
->Memory
= pMemory
;
2514 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2517 NdrConformantArrayBufferSize(pStubMsg
, pMemory
, conf_array
);
2519 pStubMsg
->Memory
= OldMemory
;
2521 if(pointer_length_set
)
2523 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2524 pStubMsg
->PointerLength
= 0;
2529 /***********************************************************************
2530 * NdrComplexStructMemorySize [RPCRT4.@]
2532 ULONG WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2533 PFORMAT_STRING pFormat
)
2535 unsigned size
= *(const WORD
*)(pFormat
+2);
2536 PFORMAT_STRING conf_array
= NULL
;
2537 PFORMAT_STRING pointer_desc
= NULL
;
2539 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2541 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2544 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2546 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2549 ComplexStructMemorySize(pStubMsg
, pFormat
);
2552 NdrConformantArrayMemorySize(pStubMsg
, conf_array
);
2557 /***********************************************************************
2558 * NdrComplexStructFree [RPCRT4.@]
2560 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
2561 unsigned char *pMemory
,
2562 PFORMAT_STRING pFormat
)
2564 PFORMAT_STRING conf_array
= NULL
;
2565 PFORMAT_STRING pointer_desc
= NULL
;
2566 unsigned char *OldMemory
= pStubMsg
->Memory
;
2568 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2571 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2573 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2576 pStubMsg
->Memory
= pMemory
;
2578 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2581 NdrConformantArrayFree(pStubMsg
, pMemory
, conf_array
);
2583 pStubMsg
->Memory
= OldMemory
;
2586 /***********************************************************************
2587 * NdrConformantArrayMarshall [RPCRT4.@]
2589 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2590 unsigned char *pMemory
,
2591 PFORMAT_STRING pFormat
)
2593 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
2594 unsigned char alignment
= pFormat
[1] + 1;
2596 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2597 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2599 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2601 WriteConformance(pStubMsg
);
2603 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2605 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2606 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2607 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
2609 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2614 /***********************************************************************
2615 * NdrConformantArrayUnmarshall [RPCRT4.@]
2617 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2618 unsigned char **ppMemory
,
2619 PFORMAT_STRING pFormat
,
2620 unsigned char fMustAlloc
)
2622 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
2623 unsigned char alignment
= pFormat
[1] + 1;
2624 unsigned char *saved_buffer
;
2626 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2627 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2629 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2631 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2632 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2635 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2638 if (!pStubMsg
->IsClient
&& !*ppMemory
)
2639 /* for servers, we just point straight into the RPC buffer */
2640 *ppMemory
= pStubMsg
->Buffer
;
2643 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2644 safe_buffer_increment(pStubMsg
, size
);
2645 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
2647 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
2648 if (*ppMemory
!= saved_buffer
)
2649 memcpy(*ppMemory
, saved_buffer
, size
);
2654 /***********************************************************************
2655 * NdrConformantArrayBufferSize [RPCRT4.@]
2657 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2658 unsigned char *pMemory
,
2659 PFORMAT_STRING pFormat
)
2661 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
2662 unsigned char alignment
= pFormat
[1] + 1;
2664 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2665 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2667 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2669 SizeConformance(pStubMsg
);
2671 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
2673 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2674 /* conformance value plus array */
2675 safe_buffer_length_increment(pStubMsg
, size
);
2677 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
2680 /***********************************************************************
2681 * NdrConformantArrayMemorySize [RPCRT4.@]
2683 ULONG WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2684 PFORMAT_STRING pFormat
)
2686 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
2687 unsigned char alignment
= pFormat
[1] + 1;
2689 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2690 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2692 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2693 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2694 pStubMsg
->MemorySize
+= size
;
2696 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2697 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2698 safe_buffer_increment(pStubMsg
, size
);
2700 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2702 return pStubMsg
->MemorySize
;
2705 /***********************************************************************
2706 * NdrConformantArrayFree [RPCRT4.@]
2708 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
2709 unsigned char *pMemory
,
2710 PFORMAT_STRING pFormat
)
2712 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2713 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2715 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2717 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2721 /***********************************************************************
2722 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2724 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2725 unsigned char* pMemory
,
2726 PFORMAT_STRING pFormat
)
2729 unsigned char alignment
= pFormat
[1] + 1;
2730 DWORD esize
= *(const WORD
*)(pFormat
+2);
2732 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
2734 if (pFormat
[0] != RPC_FC_CVARRAY
)
2736 ERR("invalid format type %x\n", pFormat
[0]);
2737 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2741 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2742 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2744 WriteConformance(pStubMsg
);
2745 WriteVariance(pStubMsg
);
2747 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2749 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2751 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2752 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
2754 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2760 /***********************************************************************
2761 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2763 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2764 unsigned char** ppMemory
,
2765 PFORMAT_STRING pFormat
,
2766 unsigned char fMustAlloc
)
2768 ULONG bufsize
, memsize
;
2769 unsigned char alignment
= pFormat
[1] + 1;
2770 DWORD esize
= *(const WORD
*)(pFormat
+2);
2772 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2774 if (pFormat
[0] != RPC_FC_CVARRAY
)
2776 ERR("invalid format type %x\n", pFormat
[0]);
2777 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2781 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2782 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2784 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2786 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2787 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2789 if (!*ppMemory
|| fMustAlloc
)
2790 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2791 safe_copy_from_buffer(pStubMsg
, *ppMemory
+ pStubMsg
->Offset
, bufsize
);
2793 EmbeddedPointerUnmarshall(pStubMsg
, *ppMemory
, *ppMemory
, pFormat
, TRUE
/* FIXME */);
2799 /***********************************************************************
2800 * NdrConformantVaryingArrayFree [RPCRT4.@]
2802 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
2803 unsigned char* pMemory
,
2804 PFORMAT_STRING pFormat
)
2806 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2808 if (pFormat
[0] != RPC_FC_CVARRAY
)
2810 ERR("invalid format type %x\n", pFormat
[0]);
2811 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2815 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2816 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2818 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2822 /***********************************************************************
2823 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2825 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
2826 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
2828 unsigned char alignment
= pFormat
[1] + 1;
2829 DWORD esize
= *(const WORD
*)(pFormat
+2);
2831 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
2833 if (pFormat
[0] != RPC_FC_CVARRAY
)
2835 ERR("invalid format type %x\n", pFormat
[0]);
2836 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2841 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2842 /* compute length */
2843 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2845 SizeConformance(pStubMsg
);
2846 SizeVariance(pStubMsg
);
2848 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
2850 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
2852 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
2856 /***********************************************************************
2857 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2859 ULONG WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
2860 PFORMAT_STRING pFormat
)
2867 /***********************************************************************
2868 * NdrComplexArrayMarshall [RPCRT4.@]
2870 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2871 unsigned char *pMemory
,
2872 PFORMAT_STRING pFormat
)
2874 ULONG i
, count
, def
;
2875 BOOL variance_present
;
2876 unsigned char alignment
;
2877 int pointer_buffer_mark_set
= 0;
2879 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2881 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
2883 ERR("invalid format type %x\n", pFormat
[0]);
2884 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2888 alignment
= pFormat
[1] + 1;
2890 if (!pStubMsg
->PointerBufferMark
)
2892 /* save buffer fields that may be changed by buffer sizer functions
2893 * and that may be needed later on */
2894 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2895 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2896 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
2897 unsigned long saved_offset
= pStubMsg
->Offset
;
2898 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
2900 /* get the buffer pointer after complex array data, but before
2902 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- pStubMsg
->BufferStart
;
2903 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2904 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
2905 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2907 /* save it for use by embedded pointer code later */
2908 pStubMsg
->PointerBufferMark
= pStubMsg
->BufferStart
+ pStubMsg
->BufferLength
;
2909 TRACE("difference = 0x%x\n", pStubMsg
->Buffer
- pStubMsg
->BufferStart
);
2910 pointer_buffer_mark_set
= 1;
2912 /* restore fields */
2913 pStubMsg
->ActualCount
= saved_actual_count
;
2914 pStubMsg
->Offset
= saved_offset
;
2915 pStubMsg
->MaxCount
= saved_max_count
;
2916 pStubMsg
->BufferLength
= saved_buffer_length
;
2919 def
= *(const WORD
*)&pFormat
[2];
2922 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
2923 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
2925 variance_present
= IsConformanceOrVariancePresent(pFormat
);
2926 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
2927 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
2929 WriteConformance(pStubMsg
);
2930 if (variance_present
)
2931 WriteVariance(pStubMsg
);
2933 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2935 count
= pStubMsg
->ActualCount
;
2936 for (i
= 0; i
< count
; i
++)
2937 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
2939 STD_OVERFLOW_CHECK(pStubMsg
);
2941 if (pointer_buffer_mark_set
)
2943 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2944 pStubMsg
->PointerBufferMark
= NULL
;
2950 /***********************************************************************
2951 * NdrComplexArrayUnmarshall [RPCRT4.@]
2953 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2954 unsigned char **ppMemory
,
2955 PFORMAT_STRING pFormat
,
2956 unsigned char fMustAlloc
)
2958 ULONG i
, count
, size
;
2959 unsigned char alignment
;
2960 unsigned char *pMemory
;
2961 unsigned char *saved_buffer
;
2962 int pointer_buffer_mark_set
= 0;
2963 int saved_ignore_embedded
;
2965 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2967 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
2969 ERR("invalid format type %x\n", pFormat
[0]);
2970 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2974 alignment
= pFormat
[1] + 1;
2976 saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2977 /* save buffer pointer */
2978 saved_buffer
= pStubMsg
->Buffer
;
2979 /* get the buffer pointer after complex array data, but before
2981 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2982 pStubMsg
->MemorySize
= 0;
2983 NdrComplexArrayMemorySize(pStubMsg
, pFormat
);
2984 size
= pStubMsg
->MemorySize
;
2985 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2987 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->Buffer
- saved_buffer
));
2988 if (!pStubMsg
->PointerBufferMark
)
2990 /* save it for use by embedded pointer code later */
2991 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2992 pointer_buffer_mark_set
= 1;
2994 /* restore the original buffer */
2995 pStubMsg
->Buffer
= saved_buffer
;
2999 pFormat
= ReadConformance(pStubMsg
, pFormat
);
3000 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3002 if (fMustAlloc
|| !*ppMemory
)
3004 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3005 memset(*ppMemory
, 0, size
);
3008 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3010 pMemory
= *ppMemory
;
3011 count
= pStubMsg
->ActualCount
;
3012 for (i
= 0; i
< count
; i
++)
3013 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
3015 if (pointer_buffer_mark_set
)
3017 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3018 pStubMsg
->PointerBufferMark
= NULL
;
3024 /***********************************************************************
3025 * NdrComplexArrayBufferSize [RPCRT4.@]
3027 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3028 unsigned char *pMemory
,
3029 PFORMAT_STRING pFormat
)
3031 ULONG i
, count
, def
;
3032 unsigned char alignment
;
3033 BOOL variance_present
;
3034 int pointer_length_set
= 0;
3036 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3038 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3040 ERR("invalid format type %x\n", pFormat
[0]);
3041 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3045 alignment
= pFormat
[1] + 1;
3047 if (!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
3049 /* save buffer fields that may be changed by buffer sizer functions
3050 * and that may be needed later on */
3051 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3052 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
3053 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
3054 unsigned long saved_offset
= pStubMsg
->Offset
;
3055 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
3057 /* get the buffer pointer after complex array data, but before
3059 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3060 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
3061 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3063 /* save it for use by embedded pointer code later */
3064 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3065 pointer_length_set
= 1;
3067 /* restore fields */
3068 pStubMsg
->ActualCount
= saved_actual_count
;
3069 pStubMsg
->Offset
= saved_offset
;
3070 pStubMsg
->MaxCount
= saved_max_count
;
3071 pStubMsg
->BufferLength
= saved_buffer_length
;
3073 def
= *(const WORD
*)&pFormat
[2];
3076 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3077 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3078 SizeConformance(pStubMsg
);
3080 variance_present
= IsConformanceOrVariancePresent(pFormat
);
3081 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3082 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3084 if (variance_present
)
3085 SizeVariance(pStubMsg
);
3087 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
3089 count
= pStubMsg
->ActualCount
;
3090 for (i
= 0; i
< count
; i
++)
3091 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
3093 if(pointer_length_set
)
3095 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3096 pStubMsg
->PointerLength
= 0;
3100 /***********************************************************************
3101 * NdrComplexArrayMemorySize [RPCRT4.@]
3103 ULONG WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3104 PFORMAT_STRING pFormat
)
3106 ULONG i
, count
, esize
, SavedMemorySize
, MemorySize
;
3107 unsigned char alignment
;
3108 unsigned char *Buffer
;
3110 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3112 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3114 ERR("invalid format type %x\n", pFormat
[0]);
3115 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3119 alignment
= pFormat
[1] + 1;
3123 pFormat
= ReadConformance(pStubMsg
, pFormat
);
3124 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3126 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3128 SavedMemorySize
= pStubMsg
->MemorySize
;
3130 Buffer
= pStubMsg
->Buffer
;
3131 pStubMsg
->MemorySize
= 0;
3132 esize
= ComplexStructMemorySize(pStubMsg
, pFormat
);
3133 pStubMsg
->Buffer
= Buffer
;
3135 MemorySize
= safe_multiply(pStubMsg
->MaxCount
, esize
);
3137 count
= pStubMsg
->ActualCount
;
3138 for (i
= 0; i
< count
; i
++)
3139 ComplexStructMemorySize(pStubMsg
, pFormat
);
3141 pStubMsg
->MemorySize
= SavedMemorySize
;
3143 pStubMsg
->MemorySize
+= MemorySize
;
3147 /***********************************************************************
3148 * NdrComplexArrayFree [RPCRT4.@]
3150 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3151 unsigned char *pMemory
,
3152 PFORMAT_STRING pFormat
)
3154 ULONG i
, count
, def
;
3156 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3158 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3160 ERR("invalid format type %x\n", pFormat
[0]);
3161 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3165 def
= *(const WORD
*)&pFormat
[2];
3168 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3169 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3171 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3172 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3174 count
= pStubMsg
->ActualCount
;
3175 for (i
= 0; i
< count
; i
++)
3176 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
3179 static ULONG
UserMarshalFlags(const MIDL_STUB_MESSAGE
*pStubMsg
)
3181 return MAKELONG(pStubMsg
->dwDestContext
,
3182 pStubMsg
->RpcMsg
->DataRepresentation
);
3185 #define USER_MARSHAL_PTR_PREFIX \
3186 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3187 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3189 /***********************************************************************
3190 * NdrUserMarshalMarshall [RPCRT4.@]
3192 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3193 unsigned char *pMemory
,
3194 PFORMAT_STRING pFormat
)
3196 unsigned flags
= pFormat
[1];
3197 unsigned index
= *(const WORD
*)&pFormat
[2];
3198 unsigned char *saved_buffer
= NULL
;
3199 ULONG uflag
= UserMarshalFlags(pStubMsg
);
3200 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3201 TRACE("index=%d\n", index
);
3203 if (flags
& USER_MARSHAL_POINTER
)
3205 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3206 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, USER_MARSHAL_PTR_PREFIX
);
3207 pStubMsg
->Buffer
+= 4;
3208 if (pStubMsg
->PointerBufferMark
)
3210 saved_buffer
= pStubMsg
->Buffer
;
3211 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3212 pStubMsg
->PointerBufferMark
= NULL
;
3214 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3217 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3220 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
3221 &uflag
, pStubMsg
->Buffer
, pMemory
);
3225 STD_OVERFLOW_CHECK(pStubMsg
);
3226 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3227 pStubMsg
->Buffer
= saved_buffer
;
3230 STD_OVERFLOW_CHECK(pStubMsg
);
3235 /***********************************************************************
3236 * NdrUserMarshalUnmarshall [RPCRT4.@]
3238 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3239 unsigned char **ppMemory
,
3240 PFORMAT_STRING pFormat
,
3241 unsigned char fMustAlloc
)
3243 unsigned flags
= pFormat
[1];
3244 unsigned index
= *(const WORD
*)&pFormat
[2];
3245 DWORD memsize
= *(const WORD
*)&pFormat
[4];
3246 unsigned char *saved_buffer
= NULL
;
3247 ULONG uflag
= UserMarshalFlags(pStubMsg
);
3248 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3249 TRACE("index=%d\n", index
);
3251 if (flags
& USER_MARSHAL_POINTER
)
3253 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3254 /* skip pointer prefix */
3255 pStubMsg
->Buffer
+= 4;
3256 if (pStubMsg
->PointerBufferMark
)
3258 saved_buffer
= pStubMsg
->Buffer
;
3259 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3260 pStubMsg
->PointerBufferMark
= NULL
;
3262 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3265 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3267 if (fMustAlloc
|| !*ppMemory
)
3268 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
3271 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
3272 &uflag
, pStubMsg
->Buffer
, *ppMemory
);
3276 STD_OVERFLOW_CHECK(pStubMsg
);
3277 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3278 pStubMsg
->Buffer
= saved_buffer
;
3284 /***********************************************************************
3285 * NdrUserMarshalBufferSize [RPCRT4.@]
3287 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3288 unsigned char *pMemory
,
3289 PFORMAT_STRING pFormat
)
3291 unsigned flags
= pFormat
[1];
3292 unsigned index
= *(const WORD
*)&pFormat
[2];
3293 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
3294 ULONG uflag
= UserMarshalFlags(pStubMsg
);
3295 unsigned long saved_buffer_length
= 0;
3296 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3297 TRACE("index=%d\n", index
);
3299 if (flags
& USER_MARSHAL_POINTER
)
3301 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
3302 /* skip pointer prefix */
3303 safe_buffer_length_increment(pStubMsg
, 4);
3304 if (pStubMsg
->IgnoreEmbeddedPointers
)
3306 if (pStubMsg
->PointerLength
)
3308 saved_buffer_length
= pStubMsg
->BufferLength
;
3309 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3310 pStubMsg
->PointerLength
= 0;
3312 ALIGN_LENGTH(pStubMsg
->BufferLength
, 8);
3315 ALIGN_LENGTH(pStubMsg
->BufferLength
, (flags
& 0xf) + 1);
3318 TRACE("size=%d\n", bufsize
);
3319 safe_buffer_length_increment(pStubMsg
, bufsize
);
3322 pStubMsg
->BufferLength
=
3323 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
3324 &uflag
, pStubMsg
->BufferLength
, pMemory
);
3326 if (saved_buffer_length
)
3328 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3329 pStubMsg
->BufferLength
= saved_buffer_length
;
3334 /***********************************************************************
3335 * NdrUserMarshalMemorySize [RPCRT4.@]
3337 ULONG WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3338 PFORMAT_STRING pFormat
)
3340 unsigned flags
= pFormat
[1];
3341 unsigned index
= *(const WORD
*)&pFormat
[2];
3342 DWORD memsize
= *(const WORD
*)&pFormat
[4];
3343 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
3345 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3346 TRACE("index=%d\n", index
);
3348 pStubMsg
->MemorySize
+= memsize
;
3350 if (flags
& USER_MARSHAL_POINTER
)
3352 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3353 /* skip pointer prefix */
3354 pStubMsg
->Buffer
+= 4;
3355 if (pStubMsg
->IgnoreEmbeddedPointers
)
3356 return pStubMsg
->MemorySize
;
3357 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3360 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3363 FIXME("not implemented for varying buffer size\n");
3365 pStubMsg
->Buffer
+= bufsize
;
3367 return pStubMsg
->MemorySize
;
3370 /***********************************************************************
3371 * NdrUserMarshalFree [RPCRT4.@]
3373 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
3374 unsigned char *pMemory
,
3375 PFORMAT_STRING pFormat
)
3377 /* unsigned flags = pFormat[1]; */
3378 unsigned index
= *(const WORD
*)&pFormat
[2];
3379 ULONG uflag
= UserMarshalFlags(pStubMsg
);
3380 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3381 TRACE("index=%d\n", index
);
3383 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
3387 /***********************************************************************
3388 * NdrClearOutParameters [RPCRT4.@]
3390 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
3391 PFORMAT_STRING pFormat
,
3394 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
3397 /***********************************************************************
3398 * NdrConvert [RPCRT4.@]
3400 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
3402 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
3403 /* FIXME: since this stub doesn't do any converting, the proper behavior
3404 is to raise an exception */
3407 /***********************************************************************
3408 * NdrConvert2 [RPCRT4.@]
3410 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, LONG NumberParams
)
3412 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3413 pStubMsg
, pFormat
, NumberParams
);
3414 /* FIXME: since this stub doesn't do any converting, the proper behavior
3415 is to raise an exception */
3418 #include "pshpack1.h"
3419 typedef struct _NDR_CSTRUCT_FORMAT
3422 unsigned char alignment
;
3423 unsigned short memory_size
;
3424 short offset_to_array_description
;
3425 } NDR_CSTRUCT_FORMAT
, NDR_CVSTRUCT_FORMAT
;
3426 #include "poppack.h"
3428 /***********************************************************************
3429 * NdrConformantStructMarshall [RPCRT4.@]
3431 unsigned char * WINAPI
NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3432 unsigned char *pMemory
,
3433 PFORMAT_STRING pFormat
)
3435 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3436 PFORMAT_STRING pCArrayFormat
;
3437 ULONG esize
, bufsize
;
3439 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3441 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3442 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3444 ERR("invalid format type %x\n", pCStructFormat
->type
);
3445 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3449 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3450 pCStructFormat
->offset_to_array_description
;
3451 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3453 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3454 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3457 esize
= *(const WORD
*)(pCArrayFormat
+2);
3459 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
3460 pCArrayFormat
+ 4, 0);
3462 WriteConformance(pStubMsg
);
3464 ALIGN_POINTER(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
3466 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3468 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3469 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
3471 ERR("integer overflow of memory_size %u with bufsize %u\n",
3472 pCStructFormat
->memory_size
, bufsize
);
3473 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3475 /* copy constant sized part of struct */
3476 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3477 safe_copy_to_buffer(pStubMsg
, pMemory
, pCStructFormat
->memory_size
+ bufsize
);
3479 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3480 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3485 /***********************************************************************
3486 * NdrConformantStructUnmarshall [RPCRT4.@]
3488 unsigned char * WINAPI
NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3489 unsigned char **ppMemory
,
3490 PFORMAT_STRING pFormat
,
3491 unsigned char fMustAlloc
)
3493 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3494 PFORMAT_STRING pCArrayFormat
;
3495 ULONG esize
, bufsize
;
3496 unsigned char *saved_buffer
;
3498 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3500 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3501 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3503 ERR("invalid format type %x\n", pCStructFormat
->type
);
3504 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3507 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3508 pCStructFormat
->offset_to_array_description
;
3509 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3511 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3512 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3515 esize
= *(const WORD
*)(pCArrayFormat
+2);
3517 pCArrayFormat
= ReadConformance(pStubMsg
, pCArrayFormat
+ 4);
3519 ALIGN_POINTER(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
3521 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3523 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3524 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
3526 ERR("integer overflow of memory_size %u with bufsize %u\n",
3527 pCStructFormat
->memory_size
, bufsize
);
3528 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3533 SIZE_T size
= pCStructFormat
->memory_size
+ bufsize
;
3534 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3538 if (!pStubMsg
->IsClient
&& !*ppMemory
)
3539 /* for servers, we just point straight into the RPC buffer */
3540 *ppMemory
= pStubMsg
->Buffer
;
3543 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3544 safe_buffer_increment(pStubMsg
, pCStructFormat
->memory_size
+ bufsize
);
3545 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3546 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
3548 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
3549 if (*ppMemory
!= saved_buffer
)
3550 memcpy(*ppMemory
, saved_buffer
, pCStructFormat
->memory_size
+ bufsize
);
3555 /***********************************************************************
3556 * NdrConformantStructBufferSize [RPCRT4.@]
3558 void WINAPI
NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3559 unsigned char *pMemory
,
3560 PFORMAT_STRING pFormat
)
3562 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3563 PFORMAT_STRING pCArrayFormat
;
3566 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3568 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3569 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3571 ERR("invalid format type %x\n", pCStructFormat
->type
);
3572 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3575 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3576 pCStructFormat
->offset_to_array_description
;
3577 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3579 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3580 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3583 esize
= *(const WORD
*)(pCArrayFormat
+2);
3585 pCArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
, pCArrayFormat
+4, 0);
3586 SizeConformance(pStubMsg
);
3588 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCStructFormat
->alignment
+ 1);
3590 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3592 safe_buffer_length_increment(pStubMsg
, pCStructFormat
->memory_size
);
3593 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
3595 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3596 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3599 /***********************************************************************
3600 * NdrConformantStructMemorySize [RPCRT4.@]
3602 ULONG WINAPI
NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3603 PFORMAT_STRING pFormat
)
3609 /***********************************************************************
3610 * NdrConformantStructFree [RPCRT4.@]
3612 void WINAPI
NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3613 unsigned char *pMemory
,
3614 PFORMAT_STRING pFormat
)
3616 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3617 PFORMAT_STRING pCArrayFormat
;
3620 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3622 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3623 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3625 ERR("invalid format type %x\n", pCStructFormat
->type
);
3626 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3630 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3631 pCStructFormat
->offset_to_array_description
;
3632 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3634 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3635 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3638 esize
= *(const WORD
*)(pCArrayFormat
+2);
3640 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
3641 pCArrayFormat
+ 4, 0);
3643 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3645 /* copy constant sized part of struct */
3646 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3648 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3649 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
3652 /***********************************************************************
3653 * NdrConformantVaryingStructMarshall [RPCRT4.@]
3655 unsigned char * WINAPI
NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3656 unsigned char *pMemory
,
3657 PFORMAT_STRING pFormat
)
3659 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3660 PFORMAT_STRING pCVArrayFormat
;
3661 ULONG esize
, bufsize
;
3663 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3665 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3666 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3668 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3669 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3673 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3674 pCVStructFormat
->offset_to_array_description
;
3675 switch (*pCVArrayFormat
)
3677 case RPC_FC_CVARRAY
:
3678 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3680 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3681 pCVArrayFormat
+ 4, 0);
3682 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3685 case RPC_FC_C_CSTRING
:
3686 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
3687 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
3688 esize
= sizeof(char);
3689 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3690 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3691 pCVArrayFormat
+ 2, 0);
3693 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3695 case RPC_FC_C_WSTRING
:
3696 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
3697 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
3698 esize
= sizeof(WCHAR
);
3699 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3700 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3701 pCVArrayFormat
+ 2, 0);
3703 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3706 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3707 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3711 WriteConformance(pStubMsg
);
3713 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
3715 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3717 /* write constant sized part */
3718 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3719 safe_copy_to_buffer(pStubMsg
, pMemory
, pCVStructFormat
->memory_size
);
3721 WriteVariance(pStubMsg
);
3723 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3725 /* write array part */
3726 safe_copy_to_buffer(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
, bufsize
);
3728 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3733 /***********************************************************************
3734 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3736 unsigned char * WINAPI
NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3737 unsigned char **ppMemory
,
3738 PFORMAT_STRING pFormat
,
3739 unsigned char fMustAlloc
)
3741 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3742 PFORMAT_STRING pCVArrayFormat
;
3743 ULONG esize
, bufsize
;
3744 unsigned char cvarray_type
;
3746 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3748 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3749 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3751 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3752 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3756 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3757 pCVStructFormat
->offset_to_array_description
;
3758 cvarray_type
= *pCVArrayFormat
;
3759 switch (cvarray_type
)
3761 case RPC_FC_CVARRAY
:
3762 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3763 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 4);
3765 case RPC_FC_C_CSTRING
:
3766 esize
= sizeof(char);
3767 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3768 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3770 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3772 case RPC_FC_C_WSTRING
:
3773 esize
= sizeof(WCHAR
);
3774 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3775 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3777 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3780 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3781 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3785 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
3787 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3789 /* work out how much memory to allocate if we need to do so */
3790 if (!*ppMemory
|| fMustAlloc
)
3792 SIZE_T size
= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->MaxCount
);
3793 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3796 /* copy the constant data */
3797 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3798 safe_copy_from_buffer(pStubMsg
, *ppMemory
, pCVStructFormat
->memory_size
);
3800 pCVArrayFormat
= ReadVariance(pStubMsg
, pCVArrayFormat
, pStubMsg
->MaxCount
);
3802 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3804 if ((cvarray_type
== RPC_FC_C_CSTRING
) ||
3805 (cvarray_type
== RPC_FC_C_WSTRING
))
3808 /* strings must always have null terminating bytes */
3809 if (bufsize
< esize
)
3811 ERR("invalid string length of %d\n", pStubMsg
->ActualCount
);
3812 RpcRaiseException(RPC_S_INVALID_BOUND
);
3815 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
3816 if (pStubMsg
->Buffer
[i
] != 0)
3818 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
3819 i
, pStubMsg
->Buffer
[i
]);
3820 RpcRaiseException(RPC_S_INVALID_BOUND
);
3825 /* copy the array data */
3826 safe_copy_from_buffer(pStubMsg
, *ppMemory
+ pCVStructFormat
->memory_size
, bufsize
);
3828 if (cvarray_type
== RPC_FC_C_CSTRING
)
3829 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory
+ pCVStructFormat
->memory_size
)));
3830 else if (cvarray_type
== RPC_FC_C_WSTRING
)
3831 TRACE("string=%s\n", debugstr_w((WCHAR
*)(*ppMemory
+ pCVStructFormat
->memory_size
)));
3833 EmbeddedPointerUnmarshall(pStubMsg
, *ppMemory
, *ppMemory
, pFormat
, TRUE
/* FIXME */);
3838 /***********************************************************************
3839 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3841 void WINAPI
NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3842 unsigned char *pMemory
,
3843 PFORMAT_STRING pFormat
)
3845 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3846 PFORMAT_STRING pCVArrayFormat
;
3849 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3851 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3852 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3854 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3855 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3859 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3860 pCVStructFormat
->offset_to_array_description
;
3861 switch (*pCVArrayFormat
)
3863 case RPC_FC_CVARRAY
:
3864 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3866 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3867 pCVArrayFormat
+ 4, 0);
3868 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3871 case RPC_FC_C_CSTRING
:
3872 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
3873 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
3874 esize
= sizeof(char);
3875 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3876 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3877 pCVArrayFormat
+ 2, 0);
3879 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3881 case RPC_FC_C_WSTRING
:
3882 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
3883 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
3884 esize
= sizeof(WCHAR
);
3885 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3886 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3887 pCVArrayFormat
+ 2, 0);
3889 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3892 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3893 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3897 SizeConformance(pStubMsg
);
3899 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCVStructFormat
->alignment
+ 1);
3901 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3903 safe_buffer_length_increment(pStubMsg
, pCVStructFormat
->memory_size
);
3904 SizeVariance(pStubMsg
);
3905 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
3907 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3910 /***********************************************************************
3911 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
3913 ULONG WINAPI
NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3914 PFORMAT_STRING pFormat
)
3916 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3917 PFORMAT_STRING pCVArrayFormat
;
3919 unsigned char cvarray_type
;
3921 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
3923 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3924 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3926 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3927 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3931 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3932 pCVStructFormat
->offset_to_array_description
;
3933 cvarray_type
= *pCVArrayFormat
;
3934 switch (cvarray_type
)
3936 case RPC_FC_CVARRAY
:
3937 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3938 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 4);
3940 case RPC_FC_C_CSTRING
:
3941 esize
= sizeof(char);
3942 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3943 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3945 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3947 case RPC_FC_C_WSTRING
:
3948 esize
= sizeof(WCHAR
);
3949 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3950 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3952 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3955 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3956 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3960 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
3962 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3964 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
3965 pCVArrayFormat
= ReadVariance(pStubMsg
, pCVArrayFormat
, pStubMsg
->MaxCount
);
3966 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
3968 pStubMsg
->MemorySize
+= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->MaxCount
);
3970 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
3972 return pCVStructFormat
->memory_size
+ pStubMsg
->MaxCount
* esize
;
3975 /***********************************************************************
3976 * NdrConformantVaryingStructFree [RPCRT4.@]
3978 void WINAPI
NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3979 unsigned char *pMemory
,
3980 PFORMAT_STRING pFormat
)
3982 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3983 PFORMAT_STRING pCVArrayFormat
;
3986 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3988 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3989 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3991 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3992 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3996 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3997 pCVStructFormat
->offset_to_array_description
;
3998 switch (*pCVArrayFormat
)
4000 case RPC_FC_CVARRAY
:
4001 esize
= *(const WORD
*)(pCVArrayFormat
+2);
4003 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4004 pCVArrayFormat
+ 4, 0);
4005 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4008 case RPC_FC_C_CSTRING
:
4009 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
4010 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
4011 esize
= sizeof(char);
4012 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4013 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4014 pCVArrayFormat
+ 2, 0);
4016 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4018 case RPC_FC_C_WSTRING
:
4019 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
4020 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
4021 esize
= sizeof(WCHAR
);
4022 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4023 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4024 pCVArrayFormat
+ 2, 0);
4026 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4029 ERR("invalid array format type %x\n", *pCVArrayFormat
);
4030 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4034 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4036 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4039 #include "pshpack1.h"
4043 unsigned char alignment
;
4044 unsigned short total_size
;
4045 } NDR_SMFARRAY_FORMAT
;
4050 unsigned char alignment
;
4051 unsigned long total_size
;
4052 } NDR_LGFARRAY_FORMAT
;
4053 #include "poppack.h"
4055 /***********************************************************************
4056 * NdrFixedArrayMarshall [RPCRT4.@]
4058 unsigned char * WINAPI
NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4059 unsigned char *pMemory
,
4060 PFORMAT_STRING pFormat
)
4062 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4063 unsigned long total_size
;
4065 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4067 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4068 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4070 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4071 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4075 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4077 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4079 total_size
= pSmFArrayFormat
->total_size
;
4080 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4084 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4085 total_size
= pLgFArrayFormat
->total_size
;
4086 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4089 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4090 safe_copy_to_buffer(pStubMsg
, pMemory
, total_size
);
4092 pFormat
= EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4097 /***********************************************************************
4098 * NdrFixedArrayUnmarshall [RPCRT4.@]
4100 unsigned char * WINAPI
NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4101 unsigned char **ppMemory
,
4102 PFORMAT_STRING pFormat
,
4103 unsigned char fMustAlloc
)
4105 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4106 unsigned long total_size
;
4107 unsigned char *saved_buffer
;
4109 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4111 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4112 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4114 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4115 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4119 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4121 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4123 total_size
= pSmFArrayFormat
->total_size
;
4124 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4128 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4129 total_size
= pLgFArrayFormat
->total_size
;
4130 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4134 *ppMemory
= NdrAllocate(pStubMsg
, total_size
);
4137 if (!pStubMsg
->IsClient
&& !*ppMemory
)
4138 /* for servers, we just point straight into the RPC buffer */
4139 *ppMemory
= pStubMsg
->Buffer
;
4142 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4143 safe_buffer_increment(pStubMsg
, total_size
);
4144 pFormat
= EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4146 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
4147 if (*ppMemory
!= saved_buffer
)
4148 memcpy(*ppMemory
, saved_buffer
, total_size
);
4153 /***********************************************************************
4154 * NdrFixedArrayBufferSize [RPCRT4.@]
4156 void WINAPI
NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4157 unsigned char *pMemory
,
4158 PFORMAT_STRING pFormat
)
4160 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4161 unsigned long total_size
;
4163 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4165 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4166 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4168 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4169 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4173 ALIGN_LENGTH(pStubMsg
->BufferLength
, pSmFArrayFormat
->alignment
+ 1);
4175 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4177 total_size
= pSmFArrayFormat
->total_size
;
4178 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4182 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4183 total_size
= pLgFArrayFormat
->total_size
;
4184 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4186 safe_buffer_length_increment(pStubMsg
, total_size
);
4188 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4191 /***********************************************************************
4192 * NdrFixedArrayMemorySize [RPCRT4.@]
4194 ULONG WINAPI
NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4195 PFORMAT_STRING pFormat
)
4197 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4200 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4202 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4203 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4205 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4206 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4210 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4212 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4214 total_size
= pSmFArrayFormat
->total_size
;
4215 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4219 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4220 total_size
= pLgFArrayFormat
->total_size
;
4221 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4223 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4224 safe_buffer_increment(pStubMsg
, total_size
);
4225 pStubMsg
->MemorySize
+= total_size
;
4227 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4232 /***********************************************************************
4233 * NdrFixedArrayFree [RPCRT4.@]
4235 void WINAPI
NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4236 unsigned char *pMemory
,
4237 PFORMAT_STRING pFormat
)
4239 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4241 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4243 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4244 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4246 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4247 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4251 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4252 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4255 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4256 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4259 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4262 /***********************************************************************
4263 * NdrVaryingArrayMarshall [RPCRT4.@]
4265 unsigned char * WINAPI
NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4266 unsigned char *pMemory
,
4267 PFORMAT_STRING pFormat
)
4269 unsigned char alignment
;
4270 DWORD elements
, esize
;
4273 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4275 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4276 (pFormat
[0] != RPC_FC_LGVARRAY
))
4278 ERR("invalid format type %x\n", pFormat
[0]);
4279 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4283 alignment
= pFormat
[1] + 1;
4285 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4288 pFormat
+= sizeof(WORD
);
4289 elements
= *(const WORD
*)pFormat
;
4290 pFormat
+= sizeof(WORD
);
4295 pFormat
+= sizeof(DWORD
);
4296 elements
= *(const DWORD
*)pFormat
;
4297 pFormat
+= sizeof(DWORD
);
4300 esize
= *(const WORD
*)pFormat
;
4301 pFormat
+= sizeof(WORD
);
4303 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4304 if ((pStubMsg
->ActualCount
> elements
) ||
4305 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4307 RpcRaiseException(RPC_S_INVALID_BOUND
);
4311 WriteVariance(pStubMsg
);
4313 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4315 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4316 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4317 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
4319 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4324 /***********************************************************************
4325 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4327 unsigned char * WINAPI
NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4328 unsigned char **ppMemory
,
4329 PFORMAT_STRING pFormat
,
4330 unsigned char fMustAlloc
)
4332 unsigned char alignment
;
4333 DWORD size
, elements
, esize
;
4336 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4338 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4339 (pFormat
[0] != RPC_FC_LGVARRAY
))
4341 ERR("invalid format type %x\n", pFormat
[0]);
4342 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4346 alignment
= pFormat
[1] + 1;
4348 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4351 size
= *(const WORD
*)pFormat
;
4352 pFormat
+= sizeof(WORD
);
4353 elements
= *(const WORD
*)pFormat
;
4354 pFormat
+= sizeof(WORD
);
4359 size
= *(const DWORD
*)pFormat
;
4360 pFormat
+= sizeof(DWORD
);
4361 elements
= *(const DWORD
*)pFormat
;
4362 pFormat
+= sizeof(DWORD
);
4365 esize
= *(const WORD
*)pFormat
;
4366 pFormat
+= sizeof(WORD
);
4368 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
4370 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4372 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4374 if (!*ppMemory
|| fMustAlloc
)
4375 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4376 safe_copy_from_buffer(pStubMsg
, *ppMemory
+ pStubMsg
->Offset
, bufsize
);
4378 EmbeddedPointerUnmarshall(pStubMsg
, *ppMemory
, *ppMemory
, pFormat
, TRUE
/* FIXME */);
4383 /***********************************************************************
4384 * NdrVaryingArrayBufferSize [RPCRT4.@]
4386 void WINAPI
NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4387 unsigned char *pMemory
,
4388 PFORMAT_STRING pFormat
)
4390 unsigned char alignment
;
4391 DWORD elements
, esize
;
4393 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4395 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4396 (pFormat
[0] != RPC_FC_LGVARRAY
))
4398 ERR("invalid format type %x\n", pFormat
[0]);
4399 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4403 alignment
= pFormat
[1] + 1;
4405 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4408 pFormat
+= sizeof(WORD
);
4409 elements
= *(const WORD
*)pFormat
;
4410 pFormat
+= sizeof(WORD
);
4415 pFormat
+= sizeof(DWORD
);
4416 elements
= *(const DWORD
*)pFormat
;
4417 pFormat
+= sizeof(DWORD
);
4420 esize
= *(const WORD
*)pFormat
;
4421 pFormat
+= sizeof(WORD
);
4423 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4424 if ((pStubMsg
->ActualCount
> elements
) ||
4425 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4427 RpcRaiseException(RPC_S_INVALID_BOUND
);
4431 SizeVariance(pStubMsg
);
4433 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
4435 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
4437 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4440 /***********************************************************************
4441 * NdrVaryingArrayMemorySize [RPCRT4.@]
4443 ULONG WINAPI
NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4444 PFORMAT_STRING pFormat
)
4446 unsigned char alignment
;
4447 DWORD size
, elements
, esize
;
4449 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4451 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4452 (pFormat
[0] != RPC_FC_LGVARRAY
))
4454 ERR("invalid format type %x\n", pFormat
[0]);
4455 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4459 alignment
= pFormat
[1] + 1;
4461 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4464 size
= *(const WORD
*)pFormat
;
4465 pFormat
+= sizeof(WORD
);
4466 elements
= *(const WORD
*)pFormat
;
4467 pFormat
+= sizeof(WORD
);
4472 size
= *(const DWORD
*)pFormat
;
4473 pFormat
+= sizeof(DWORD
);
4474 elements
= *(const DWORD
*)pFormat
;
4475 pFormat
+= sizeof(DWORD
);
4478 esize
= *(const WORD
*)pFormat
;
4479 pFormat
+= sizeof(WORD
);
4481 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
4483 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4485 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
4486 pStubMsg
->MemorySize
+= size
;
4488 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4490 return pStubMsg
->MemorySize
;
4493 /***********************************************************************
4494 * NdrVaryingArrayFree [RPCRT4.@]
4496 void WINAPI
NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4497 unsigned char *pMemory
,
4498 PFORMAT_STRING pFormat
)
4500 unsigned char alignment
;
4503 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4505 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4506 (pFormat
[0] != RPC_FC_LGVARRAY
))
4508 ERR("invalid format type %x\n", pFormat
[0]);
4509 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4513 alignment
= pFormat
[1] + 1;
4515 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4518 pFormat
+= sizeof(WORD
);
4519 elements
= *(const WORD
*)pFormat
;
4520 pFormat
+= sizeof(WORD
);
4525 pFormat
+= sizeof(DWORD
);
4526 elements
= *(const DWORD
*)pFormat
;
4527 pFormat
+= sizeof(DWORD
);
4530 pFormat
+= sizeof(WORD
);
4532 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4533 if ((pStubMsg
->ActualCount
> elements
) ||
4534 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4536 RpcRaiseException(RPC_S_INVALID_BOUND
);
4540 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4543 static ULONG
get_discriminant(unsigned char fc
, const unsigned char *pMemory
)
4551 return *(const UCHAR
*)pMemory
;
4556 return *(const USHORT
*)pMemory
;
4560 return *(const ULONG
*)pMemory
;
4562 FIXME("Unhandled base type: 0x%02x\n", fc
);
4567 static PFORMAT_STRING
get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg
,
4568 unsigned long discriminant
,
4569 PFORMAT_STRING pFormat
)
4571 unsigned short num_arms
, arm
, type
;
4573 num_arms
= *(const SHORT
*)pFormat
& 0x0fff;
4575 for(arm
= 0; arm
< num_arms
; arm
++)
4577 if(discriminant
== *(const ULONG
*)pFormat
)
4585 type
= *(const unsigned short*)pFormat
;
4586 TRACE("type %04x\n", type
);
4587 if(arm
== num_arms
) /* default arm extras */
4591 ERR("no arm for 0x%lx and no default case\n", discriminant
);
4592 RpcRaiseException(RPC_S_INVALID_TAG
);
4597 TRACE("falling back to empty default case for 0x%lx\n", discriminant
);
4604 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
, ULONG discriminant
, PFORMAT_STRING pFormat
)
4606 unsigned short type
;
4610 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4614 type
= *(const unsigned short*)pFormat
;
4615 if((type
& 0xff00) == 0x8000)
4617 unsigned char basetype
= LOBYTE(type
);
4618 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &basetype
);
4622 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4623 NDR_MARSHALL m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
4626 unsigned char *saved_buffer
= NULL
;
4627 int pointer_buffer_mark_set
= 0;
4634 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4635 saved_buffer
= pStubMsg
->Buffer
;
4636 if (pStubMsg
->PointerBufferMark
)
4638 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4639 pStubMsg
->PointerBufferMark
= NULL
;
4640 pointer_buffer_mark_set
= 1;
4643 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
4645 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char **)pMemory
, desc
);
4646 if (pointer_buffer_mark_set
)
4648 STD_OVERFLOW_CHECK(pStubMsg
);
4649 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4650 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
4652 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
4653 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
4654 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4656 pStubMsg
->Buffer
= saved_buffer
+ 4;
4660 m(pStubMsg
, pMemory
, desc
);
4663 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4668 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4669 unsigned char **ppMemory
,
4671 PFORMAT_STRING pFormat
,
4672 unsigned char fMustAlloc
)
4674 unsigned short type
;
4678 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4682 type
= *(const unsigned short*)pFormat
;
4683 if((type
& 0xff00) == 0x8000)
4685 unsigned char basetype
= LOBYTE(type
);
4686 return NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &basetype
, FALSE
);
4690 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4691 NDR_UNMARSHALL m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
4694 unsigned char *saved_buffer
= NULL
;
4695 int pointer_buffer_mark_set
= 0;
4702 **(void***)ppMemory
= NULL
;
4703 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4704 saved_buffer
= pStubMsg
->Buffer
;
4705 if (pStubMsg
->PointerBufferMark
)
4707 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4708 pStubMsg
->PointerBufferMark
= NULL
;
4709 pointer_buffer_mark_set
= 1;
4712 pStubMsg
->Buffer
+= 4; /* for pointer ID */
4714 if (saved_buffer
+ 4 > pStubMsg
->BufferEnd
)
4716 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
4717 saved_buffer
, pStubMsg
->BufferEnd
);
4718 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4721 PointerUnmarshall(pStubMsg
, saved_buffer
, *(unsigned char ***)ppMemory
, **(unsigned char ***)ppMemory
, desc
, fMustAlloc
);
4722 if (pointer_buffer_mark_set
)
4724 STD_OVERFLOW_CHECK(pStubMsg
);
4725 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4726 pStubMsg
->Buffer
= saved_buffer
+ 4;
4730 m(pStubMsg
, ppMemory
, desc
, fMustAlloc
);
4733 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4738 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg
,
4739 unsigned char *pMemory
,
4741 PFORMAT_STRING pFormat
)
4743 unsigned short type
;
4747 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4751 type
= *(const unsigned short*)pFormat
;
4752 if((type
& 0xff00) == 0x8000)
4754 unsigned char basetype
= LOBYTE(type
);
4755 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &basetype
);
4759 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4760 NDR_BUFFERSIZE m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
4769 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
4770 safe_buffer_length_increment(pStubMsg
, 4); /* for pointer ID */
4771 if (!pStubMsg
->IgnoreEmbeddedPointers
)
4773 int saved_buffer_length
= pStubMsg
->BufferLength
;
4774 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4775 pStubMsg
->PointerLength
= 0;
4776 if(!pStubMsg
->BufferLength
)
4777 ERR("BufferLength == 0??\n");
4778 PointerBufferSize(pStubMsg
, *(unsigned char **)pMemory
, desc
);
4779 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4780 pStubMsg
->BufferLength
= saved_buffer_length
;
4784 m(pStubMsg
, pMemory
, desc
);
4787 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
4791 static ULONG
union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg
,
4793 PFORMAT_STRING pFormat
)
4795 unsigned short type
, size
;
4797 size
= *(const unsigned short*)pFormat
;
4798 pStubMsg
->Memory
+= size
;
4801 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4805 type
= *(const unsigned short*)pFormat
;
4806 if((type
& 0xff00) == 0x8000)
4808 return NdrBaseTypeMemorySize(pStubMsg
, pFormat
);
4812 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4813 NDR_MEMORYSIZE m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
4814 unsigned char *saved_buffer
;
4823 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4824 saved_buffer
= pStubMsg
->Buffer
;
4825 safe_buffer_increment(pStubMsg
, 4);
4826 ALIGN_LENGTH(pStubMsg
->MemorySize
, 4);
4827 pStubMsg
->MemorySize
+= 4;
4828 if (!pStubMsg
->IgnoreEmbeddedPointers
)
4829 PointerMemorySize(pStubMsg
, saved_buffer
, pFormat
);
4832 return m(pStubMsg
, desc
);
4835 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4838 TRACE("size %d\n", size
);
4842 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg
,
4843 unsigned char *pMemory
,
4845 PFORMAT_STRING pFormat
)
4847 unsigned short type
;
4851 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4855 type
= *(const unsigned short*)pFormat
;
4856 if((type
& 0xff00) != 0x8000)
4858 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4859 NDR_FREE m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
4868 PointerFree(pStubMsg
, *(unsigned char **)pMemory
, desc
);
4871 m(pStubMsg
, pMemory
, desc
);
4874 else FIXME("no freer for embedded type %02x\n", *desc
);
4878 /***********************************************************************
4879 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
4881 unsigned char * WINAPI
NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4882 unsigned char *pMemory
,
4883 PFORMAT_STRING pFormat
)
4885 unsigned char switch_type
;
4886 unsigned char increment
;
4889 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4892 switch_type
= *pFormat
& 0xf;
4893 increment
= (*pFormat
& 0xf0) >> 4;
4896 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
4898 switch_value
= get_discriminant(switch_type
, pMemory
);
4899 TRACE("got switch value 0x%x\n", switch_value
);
4901 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &switch_type
);
4902 pMemory
+= increment
;
4904 return union_arm_marshall(pStubMsg
, pMemory
, switch_value
, pFormat
);
4907 /***********************************************************************
4908 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
4910 unsigned char * WINAPI
NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4911 unsigned char **ppMemory
,
4912 PFORMAT_STRING pFormat
,
4913 unsigned char fMustAlloc
)
4915 unsigned char switch_type
;
4916 unsigned char increment
;
4918 unsigned short size
;
4919 unsigned char *pMemoryArm
;
4921 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4924 switch_type
= *pFormat
& 0xf;
4925 increment
= (*pFormat
& 0xf0) >> 4;
4928 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
4929 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
4930 TRACE("got switch value 0x%x\n", switch_value
);
4932 size
= *(const unsigned short*)pFormat
+ increment
;
4933 if(!*ppMemory
|| fMustAlloc
)
4934 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4936 NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &switch_type
, FALSE
);
4937 pMemoryArm
= *ppMemory
+ increment
;
4939 return union_arm_unmarshall(pStubMsg
, &pMemoryArm
, switch_value
, pFormat
, fMustAlloc
);
4942 /***********************************************************************
4943 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
4945 void WINAPI
NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4946 unsigned char *pMemory
,
4947 PFORMAT_STRING pFormat
)
4949 unsigned char switch_type
;
4950 unsigned char increment
;
4953 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4956 switch_type
= *pFormat
& 0xf;
4957 increment
= (*pFormat
& 0xf0) >> 4;
4960 ALIGN_LENGTH(pStubMsg
->BufferLength
, increment
);
4961 switch_value
= get_discriminant(switch_type
, pMemory
);
4962 TRACE("got switch value 0x%x\n", switch_value
);
4964 /* Add discriminant size */
4965 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&switch_value
, &switch_type
);
4966 pMemory
+= increment
;
4968 union_arm_buffer_size(pStubMsg
, pMemory
, switch_value
, pFormat
);
4971 /***********************************************************************
4972 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
4974 ULONG WINAPI
NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4975 PFORMAT_STRING pFormat
)
4977 unsigned char switch_type
;
4978 unsigned char increment
;
4981 switch_type
= *pFormat
& 0xf;
4982 increment
= (*pFormat
& 0xf0) >> 4;
4985 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
4986 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
4987 TRACE("got switch value 0x%x\n", switch_value
);
4989 pStubMsg
->Memory
+= increment
;
4991 return increment
+ union_arm_memory_size(pStubMsg
, switch_value
, pFormat
+ *(const SHORT
*)pFormat
);
4994 /***********************************************************************
4995 * NdrEncapsulatedUnionFree [RPCRT4.@]
4997 void WINAPI
NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
4998 unsigned char *pMemory
,
4999 PFORMAT_STRING pFormat
)
5001 unsigned char switch_type
;
5002 unsigned char increment
;
5005 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5008 switch_type
= *pFormat
& 0xf;
5009 increment
= (*pFormat
& 0xf0) >> 4;
5012 switch_value
= get_discriminant(switch_type
, pMemory
);
5013 TRACE("got switch value 0x%x\n", switch_value
);
5015 pMemory
+= increment
;
5017 return union_arm_free(pStubMsg
, pMemory
, switch_value
, pFormat
);
5020 /***********************************************************************
5021 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5023 unsigned char * WINAPI
NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5024 unsigned char *pMemory
,
5025 PFORMAT_STRING pFormat
)
5027 unsigned char switch_type
;
5029 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5032 switch_type
= *pFormat
;
5035 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5036 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5037 /* Marshall discriminant */
5038 NdrBaseTypeMarshall(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
5040 return union_arm_marshall(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5043 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg
,
5044 PFORMAT_STRING
*ppFormat
)
5046 long discriminant
= 0;
5056 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5065 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5066 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5074 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
5075 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5080 FIXME("Unhandled base type: 0x%02x\n", **ppFormat
);
5084 if (pStubMsg
->fHasNewCorrDesc
)
5088 return discriminant
;
5091 /**********************************************************************
5092 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5094 unsigned char * WINAPI
NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5095 unsigned char **ppMemory
,
5096 PFORMAT_STRING pFormat
,
5097 unsigned char fMustAlloc
)
5100 unsigned short size
;
5102 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5105 /* Unmarshall discriminant */
5106 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
5107 TRACE("unmarshalled discriminant %lx\n", discriminant
);
5109 pFormat
+= *(const SHORT
*)pFormat
;
5111 size
= *(const unsigned short*)pFormat
;
5113 if(!*ppMemory
|| fMustAlloc
)
5114 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5116 return union_arm_unmarshall(pStubMsg
, ppMemory
, discriminant
, pFormat
, fMustAlloc
);
5119 /***********************************************************************
5120 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5122 void WINAPI
NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5123 unsigned char *pMemory
,
5124 PFORMAT_STRING pFormat
)
5126 unsigned char switch_type
;
5128 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5131 switch_type
= *pFormat
;
5134 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5135 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5136 /* Add discriminant size */
5137 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
5139 union_arm_buffer_size(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5142 /***********************************************************************
5143 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5145 ULONG WINAPI
NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5146 PFORMAT_STRING pFormat
)
5151 /* Unmarshall discriminant */
5152 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
5153 TRACE("unmarshalled discriminant 0x%x\n", discriminant
);
5155 return union_arm_memory_size(pStubMsg
, discriminant
, pFormat
+ *(const SHORT
*)pFormat
);
5158 /***********************************************************************
5159 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5161 void WINAPI
NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
5162 unsigned char *pMemory
,
5163 PFORMAT_STRING pFormat
)
5165 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5169 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5170 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5172 return union_arm_free(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5175 /***********************************************************************
5176 * NdrByteCountPointerMarshall [RPCRT4.@]
5178 unsigned char * WINAPI
NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5179 unsigned char *pMemory
,
5180 PFORMAT_STRING pFormat
)
5186 /***********************************************************************
5187 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5189 unsigned char * WINAPI
NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5190 unsigned char **ppMemory
,
5191 PFORMAT_STRING pFormat
,
5192 unsigned char fMustAlloc
)
5198 /***********************************************************************
5199 * NdrByteCountPointerBufferSize [RPCRT4.@]
5201 void WINAPI
NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5202 unsigned char *pMemory
,
5203 PFORMAT_STRING pFormat
)
5208 /***********************************************************************
5209 * NdrByteCountPointerMemorySize [RPCRT4.@]
5211 ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5212 PFORMAT_STRING pFormat
)
5218 /***********************************************************************
5219 * NdrByteCountPointerFree [RPCRT4.@]
5221 void WINAPI
NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
5222 unsigned char *pMemory
,
5223 PFORMAT_STRING pFormat
)
5228 /***********************************************************************
5229 * NdrXmitOrRepAsMarshall [RPCRT4.@]
5231 unsigned char * WINAPI
NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5232 unsigned char *pMemory
,
5233 PFORMAT_STRING pFormat
)
5239 /***********************************************************************
5240 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
5242 unsigned char * WINAPI
NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5243 unsigned char **ppMemory
,
5244 PFORMAT_STRING pFormat
,
5245 unsigned char fMustAlloc
)
5251 /***********************************************************************
5252 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
5254 void WINAPI
NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5255 unsigned char *pMemory
,
5256 PFORMAT_STRING pFormat
)
5261 /***********************************************************************
5262 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
5264 ULONG WINAPI
NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5265 PFORMAT_STRING pFormat
)
5271 /***********************************************************************
5272 * NdrXmitOrRepAsFree [RPCRT4.@]
5274 void WINAPI
NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg
,
5275 unsigned char *pMemory
,
5276 PFORMAT_STRING pFormat
)
5281 #include "pshpack1.h"
5285 unsigned char flags_type
; /* flags in upper nibble, type in lower nibble */
5289 #include "poppack.h"
5291 /***********************************************************************
5292 * NdrRangeMarshall [internal]
5294 unsigned char *WINAPI
NdrRangeMarshall(
5295 PMIDL_STUB_MESSAGE pStubMsg
,
5296 unsigned char *pMemory
,
5297 PFORMAT_STRING pFormat
)
5299 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5300 unsigned char base_type
;
5302 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5304 if (pRange
->type
!= RPC_FC_RANGE
)
5306 ERR("invalid format type %x\n", pRange
->type
);
5307 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5311 base_type
= pRange
->flags_type
& 0xf;
5313 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &base_type
);
5316 /***********************************************************************
5317 * NdrRangeUnmarshall
5319 unsigned char *WINAPI
NdrRangeUnmarshall(
5320 PMIDL_STUB_MESSAGE pStubMsg
,
5321 unsigned char **ppMemory
,
5322 PFORMAT_STRING pFormat
,
5323 unsigned char fMustAlloc
)
5325 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5326 unsigned char base_type
;
5328 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
5330 if (pRange
->type
!= RPC_FC_RANGE
)
5332 ERR("invalid format type %x\n", pRange
->type
);
5333 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5336 base_type
= pRange
->flags_type
& 0xf;
5338 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5339 base_type
, pRange
->low_value
, pRange
->high_value
);
5341 #define RANGE_UNMARSHALL(type, format_spec) \
5344 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5345 if (fMustAlloc || !*ppMemory) \
5346 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5347 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
5349 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
5350 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
5351 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
5353 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5354 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5356 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5357 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5358 (type)pRange->high_value); \
5359 RpcRaiseException(RPC_S_INVALID_BOUND); \
5362 TRACE("*ppMemory: %p\n", *ppMemory); \
5363 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5364 pStubMsg->Buffer += sizeof(type); \
5371 RANGE_UNMARSHALL(UCHAR
, "%d");
5372 TRACE("value: 0x%02x\n", **(UCHAR
**)ppMemory
);
5376 RANGE_UNMARSHALL(CHAR
, "%u");
5377 TRACE("value: 0x%02x\n", **(UCHAR
**)ppMemory
);
5379 case RPC_FC_WCHAR
: /* FIXME: valid? */
5381 RANGE_UNMARSHALL(USHORT
, "%u");
5382 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5385 RANGE_UNMARSHALL(SHORT
, "%d");
5386 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5389 RANGE_UNMARSHALL(LONG
, "%d");
5390 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5393 RANGE_UNMARSHALL(ULONG
, "%u");
5394 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5398 FIXME("Unhandled enum type\n");
5400 case RPC_FC_ERROR_STATUS_T
: /* FIXME: valid? */
5405 ERR("invalid range base type: 0x%02x\n", base_type
);
5406 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5412 /***********************************************************************
5413 * NdrRangeBufferSize [internal]
5415 void WINAPI
NdrRangeBufferSize(
5416 PMIDL_STUB_MESSAGE pStubMsg
,
5417 unsigned char *pMemory
,
5418 PFORMAT_STRING pFormat
)
5420 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5421 unsigned char base_type
;
5423 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5425 if (pRange
->type
!= RPC_FC_RANGE
)
5427 ERR("invalid format type %x\n", pRange
->type
);
5428 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5430 base_type
= pRange
->flags_type
& 0xf;
5432 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &base_type
);
5435 /***********************************************************************
5436 * NdrRangeMemorySize [internal]
5438 ULONG WINAPI
NdrRangeMemorySize(
5439 PMIDL_STUB_MESSAGE pStubMsg
,
5440 PFORMAT_STRING pFormat
)
5442 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5443 unsigned char base_type
;
5445 if (pRange
->type
!= RPC_FC_RANGE
)
5447 ERR("invalid format type %x\n", pRange
->type
);
5448 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5451 base_type
= pRange
->flags_type
& 0xf;
5453 return NdrBaseTypeMemorySize(pStubMsg
, &base_type
);
5456 /***********************************************************************
5457 * NdrRangeFree [internal]
5459 void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg
,
5460 unsigned char *pMemory
,
5461 PFORMAT_STRING pFormat
)
5463 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5468 /***********************************************************************
5469 * NdrBaseTypeMarshall [internal]
5471 static unsigned char *WINAPI
NdrBaseTypeMarshall(
5472 PMIDL_STUB_MESSAGE pStubMsg
,
5473 unsigned char *pMemory
,
5474 PFORMAT_STRING pFormat
)
5476 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5484 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(UCHAR
));
5485 TRACE("value: 0x%02x\n", *(UCHAR
*)pMemory
);
5490 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5491 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(USHORT
));
5492 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
5496 case RPC_FC_ERROR_STATUS_T
:
5498 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
5499 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONG
));
5500 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
5503 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(float));
5504 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
5507 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(double));
5508 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
5511 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONGLONG
));
5512 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONGLONG
));
5513 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
5516 /* only 16-bits on the wire, so do a sanity check */
5517 if (*(UINT
*)pMemory
> SHRT_MAX
)
5518 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
5519 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5520 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5521 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5522 *(USHORT
*)pStubMsg
->Buffer
= *(UINT
*)pMemory
;
5523 pStubMsg
->Buffer
+= sizeof(USHORT
);
5524 TRACE("value: 0x%04x\n", *(UINT
*)pMemory
);
5529 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5532 /* FIXME: what is the correct return value? */
5536 /***********************************************************************
5537 * NdrBaseTypeUnmarshall [internal]
5539 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(
5540 PMIDL_STUB_MESSAGE pStubMsg
,
5541 unsigned char **ppMemory
,
5542 PFORMAT_STRING pFormat
,
5543 unsigned char fMustAlloc
)
5545 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
5547 #define BASE_TYPE_UNMARSHALL(type) \
5548 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5549 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
5551 *ppMemory = pStubMsg->Buffer; \
5552 TRACE("*ppMemory: %p\n", *ppMemory); \
5557 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5558 TRACE("*ppMemory: %p\n", *ppMemory); \
5559 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5561 pStubMsg->Buffer += sizeof(type);
5569 BASE_TYPE_UNMARSHALL(UCHAR
);
5570 TRACE("value: 0x%02x\n", **(UCHAR
**)ppMemory
);
5575 BASE_TYPE_UNMARSHALL(USHORT
);
5576 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5580 case RPC_FC_ERROR_STATUS_T
:
5582 BASE_TYPE_UNMARSHALL(ULONG
);
5583 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5586 BASE_TYPE_UNMARSHALL(float);
5587 TRACE("value: %f\n", **(float **)ppMemory
);
5590 BASE_TYPE_UNMARSHALL(double);
5591 TRACE("value: %f\n", **(double **)ppMemory
);
5594 BASE_TYPE_UNMARSHALL(ULONGLONG
);
5595 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG
**)ppMemory
));
5598 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5599 if (fMustAlloc
|| !*ppMemory
)
5600 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT
));
5601 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > pStubMsg
->BufferEnd
)
5602 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5603 TRACE("*ppMemory: %p\n", *ppMemory
);
5604 /* 16-bits on the wire, but int in memory */
5605 **(UINT
**)ppMemory
= *(USHORT
*)pStubMsg
->Buffer
;
5606 pStubMsg
->Buffer
+= sizeof(USHORT
);
5607 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
5612 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5614 #undef BASE_TYPE_UNMARSHALL
5616 /* FIXME: what is the correct return value? */
5621 /***********************************************************************
5622 * NdrBaseTypeBufferSize [internal]
5624 static void WINAPI
NdrBaseTypeBufferSize(
5625 PMIDL_STUB_MESSAGE pStubMsg
,
5626 unsigned char *pMemory
,
5627 PFORMAT_STRING pFormat
)
5629 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5637 safe_buffer_length_increment(pStubMsg
, sizeof(UCHAR
));
5643 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(USHORT
));
5644 safe_buffer_length_increment(pStubMsg
, sizeof(USHORT
));
5649 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONG
));
5650 safe_buffer_length_increment(pStubMsg
, sizeof(ULONG
));
5653 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(float));
5654 safe_buffer_length_increment(pStubMsg
, sizeof(float));
5657 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(double));
5658 safe_buffer_length_increment(pStubMsg
, sizeof(double));
5661 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONGLONG
));
5662 safe_buffer_length_increment(pStubMsg
, sizeof(ULONGLONG
));
5664 case RPC_FC_ERROR_STATUS_T
:
5665 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(error_status_t
));
5666 safe_buffer_length_increment(pStubMsg
, sizeof(error_status_t
));
5671 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5675 /***********************************************************************
5676 * NdrBaseTypeMemorySize [internal]
5678 static ULONG WINAPI
NdrBaseTypeMemorySize(
5679 PMIDL_STUB_MESSAGE pStubMsg
,
5680 PFORMAT_STRING pFormat
)
5682 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg
, *pFormat
);
5690 safe_buffer_increment(pStubMsg
, sizeof(UCHAR
));
5691 pStubMsg
->MemorySize
+= sizeof(UCHAR
);
5692 return sizeof(UCHAR
);
5696 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
5697 pStubMsg
->MemorySize
+= sizeof(USHORT
);
5698 return sizeof(USHORT
);
5702 safe_buffer_increment(pStubMsg
, sizeof(ULONG
));
5703 pStubMsg
->MemorySize
+= sizeof(ULONG
);
5704 return sizeof(ULONG
);
5706 safe_buffer_increment(pStubMsg
, sizeof(float));
5707 pStubMsg
->MemorySize
+= sizeof(float);
5708 return sizeof(float);
5710 safe_buffer_increment(pStubMsg
, sizeof(double));
5711 pStubMsg
->MemorySize
+= sizeof(double);
5712 return sizeof(double);
5714 safe_buffer_increment(pStubMsg
, sizeof(ULONGLONG
));
5715 pStubMsg
->MemorySize
+= sizeof(ULONGLONG
);
5716 return sizeof(ULONGLONG
);
5717 case RPC_FC_ERROR_STATUS_T
:
5718 safe_buffer_increment(pStubMsg
, sizeof(error_status_t
));
5719 pStubMsg
->MemorySize
+= sizeof(error_status_t
);
5720 return sizeof(error_status_t
);
5722 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
5723 pStubMsg
->MemorySize
+= sizeof(UINT
);
5724 return sizeof(UINT
);
5726 pStubMsg
->MemorySize
+= sizeof(void *);
5727 return sizeof(void *);
5729 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5734 /***********************************************************************
5735 * NdrBaseTypeFree [internal]
5737 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg
,
5738 unsigned char *pMemory
,
5739 PFORMAT_STRING pFormat
)
5741 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5746 /***********************************************************************
5747 * NdrContextHandleBufferSize [internal]
5749 static void WINAPI
NdrContextHandleBufferSize(
5750 PMIDL_STUB_MESSAGE pStubMsg
,
5751 unsigned char *pMemory
,
5752 PFORMAT_STRING pFormat
)
5754 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5756 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
5758 ERR("invalid format type %x\n", *pFormat
);
5759 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5761 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
5762 safe_buffer_length_increment(pStubMsg
, cbNDRContext
);
5765 /***********************************************************************
5766 * NdrContextHandleMarshall [internal]
5768 static unsigned char *WINAPI
NdrContextHandleMarshall(
5769 PMIDL_STUB_MESSAGE pStubMsg
,
5770 unsigned char *pMemory
,
5771 PFORMAT_STRING pFormat
)
5773 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5775 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
5777 ERR("invalid format type %x\n", *pFormat
);
5778 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5781 if (pFormat
[1] & 0x80)
5782 NdrClientContextMarshall(pStubMsg
, *(NDR_CCONTEXT
**)pMemory
, FALSE
);
5784 NdrClientContextMarshall(pStubMsg
, (NDR_CCONTEXT
*)pMemory
, FALSE
);
5789 /***********************************************************************
5790 * NdrContextHandleUnmarshall [internal]
5792 static unsigned char *WINAPI
NdrContextHandleUnmarshall(
5793 PMIDL_STUB_MESSAGE pStubMsg
,
5794 unsigned char **ppMemory
,
5795 PFORMAT_STRING pFormat
,
5796 unsigned char fMustAlloc
)
5798 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
5800 ERR("invalid format type %x\n", *pFormat
);
5801 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5804 **(NDR_CCONTEXT
**)ppMemory
= NULL
;
5805 NdrClientContextUnmarshall(pStubMsg
, *(NDR_CCONTEXT
**)ppMemory
, pStubMsg
->RpcMsg
->Handle
);
5810 /***********************************************************************
5811 * NdrClientContextMarshall [RPCRT4.@]
5813 void WINAPI
NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5814 NDR_CCONTEXT ContextHandle
,
5817 TRACE("(%p, %p, %d)\n", pStubMsg
, ContextHandle
, fCheck
);
5819 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5821 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5823 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
5824 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
5825 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5828 /* FIXME: what does fCheck do? */
5829 NDRCContextMarshall(ContextHandle
,
5832 pStubMsg
->Buffer
+= cbNDRContext
;
5835 /***********************************************************************
5836 * NdrClientContextUnmarshall [RPCRT4.@]
5838 void WINAPI
NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5839 NDR_CCONTEXT
* pContextHandle
,
5840 RPC_BINDING_HANDLE BindHandle
)
5842 TRACE("(%p, %p, %p)\n", pStubMsg
, pContextHandle
, BindHandle
);
5844 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5846 if (pStubMsg
->Buffer
+ cbNDRContext
> pStubMsg
->BufferEnd
)
5847 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5849 NDRCContextUnmarshall(pContextHandle
,
5852 pStubMsg
->RpcMsg
->DataRepresentation
);
5854 pStubMsg
->Buffer
+= cbNDRContext
;
5857 void WINAPI
NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5858 NDR_SCONTEXT ContextHandle
,
5859 NDR_RUNDOWN RundownRoutine
)
5861 FIXME("(%p, %p, %p): stub\n", pStubMsg
, ContextHandle
, RundownRoutine
);
5864 NDR_SCONTEXT WINAPI
NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
)
5866 FIXME("(%p): stub\n", pStubMsg
);
5870 void WINAPI
NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg
,
5871 unsigned char* pMemory
,
5872 PFORMAT_STRING pFormat
)
5874 FIXME("(%p, %p, %p): stub\n", pStubMsg
, pMemory
, pFormat
);
5877 NDR_SCONTEXT WINAPI
NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg
,
5878 PFORMAT_STRING pFormat
)
5880 FIXME("(%p, %p): stub\n", pStubMsg
, pFormat
);
5884 void WINAPI
NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5885 NDR_SCONTEXT ContextHandle
,
5886 NDR_RUNDOWN RundownRoutine
,
5887 PFORMAT_STRING pFormat
)
5889 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg
, ContextHandle
, RundownRoutine
, pFormat
);
5892 NDR_SCONTEXT WINAPI
NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5893 PFORMAT_STRING pFormat
)
5895 FIXME("(%p, %p): stub\n", pStubMsg
, pFormat
);
5899 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
5901 typedef struct ndr_context_handle
5905 } ndr_context_handle
;
5907 struct context_handle_entry
5911 RPC_BINDING_HANDLE handle
;
5912 ndr_context_handle wire_data
;
5915 static struct list context_handle_list
= LIST_INIT(context_handle_list
);
5917 static CRITICAL_SECTION ndr_context_cs
;
5918 static CRITICAL_SECTION_DEBUG ndr_context_debug
=
5920 0, 0, &ndr_context_cs
,
5921 { &ndr_context_debug
.ProcessLocksList
, &ndr_context_debug
.ProcessLocksList
},
5922 0, 0, { (DWORD_PTR
)(__FILE__
": ndr_context") }
5924 static CRITICAL_SECTION ndr_context_cs
= { &ndr_context_debug
, -1, 0, 0, 0, 0 };
5926 static struct context_handle_entry
*get_context_entry(NDR_CCONTEXT CContext
)
5928 struct context_handle_entry
*che
= (struct context_handle_entry
*) CContext
;
5930 if (che
->magic
!= NDR_CONTEXT_HANDLE_MAGIC
)
5935 static struct context_handle_entry
*context_entry_from_guid(LPCGUID uuid
)
5937 struct context_handle_entry
*che
;
5938 LIST_FOR_EACH_ENTRY(che
, &context_handle_list
, struct context_handle_entry
, entry
)
5939 if (IsEqualGUID(&che
->wire_data
.uuid
, uuid
))
5944 RPC_BINDING_HANDLE WINAPI
NDRCContextBinding(NDR_CCONTEXT CContext
)
5946 struct context_handle_entry
*che
;
5947 RPC_BINDING_HANDLE handle
= NULL
;
5949 TRACE("%p\n", CContext
);
5951 EnterCriticalSection(&ndr_context_cs
);
5952 che
= get_context_entry(CContext
);
5954 handle
= che
->handle
;
5955 LeaveCriticalSection(&ndr_context_cs
);
5958 RpcRaiseException(ERROR_INVALID_HANDLE
);
5962 void WINAPI
NDRCContextMarshall(NDR_CCONTEXT CContext
, void *pBuff
)
5964 struct context_handle_entry
*che
;
5966 TRACE("%p %p\n", CContext
, pBuff
);
5970 EnterCriticalSection(&ndr_context_cs
);
5971 che
= get_context_entry(CContext
);
5972 memcpy(pBuff
, &che
->wire_data
, sizeof (ndr_context_handle
));
5973 LeaveCriticalSection(&ndr_context_cs
);
5977 ndr_context_handle
*wire_data
= (ndr_context_handle
*)pBuff
;
5978 wire_data
->attributes
= 0;
5979 wire_data
->uuid
= GUID_NULL
;
5983 /***********************************************************************
5984 * RpcSmDestroyClientContext [RPCRT4.@]
5986 RPC_STATUS WINAPI
RpcSmDestroyClientContext(void **ContextHandle
)
5988 RPC_STATUS status
= RPC_X_SS_CONTEXT_MISMATCH
;
5989 struct context_handle_entry
*che
= NULL
;
5991 TRACE("(%p)\n", ContextHandle
);
5993 EnterCriticalSection(&ndr_context_cs
);
5994 che
= get_context_entry(*ContextHandle
);
5995 *ContextHandle
= NULL
;
5999 list_remove(&che
->entry
);
6002 LeaveCriticalSection(&ndr_context_cs
);
6006 RpcBindingFree(&che
->handle
);
6007 HeapFree(GetProcessHeap(), 0, che
);
6013 /***********************************************************************
6014 * RpcSsDestroyClientContext [RPCRT4.@]
6016 void WINAPI
RpcSsDestroyClientContext(void **ContextHandle
)
6018 RPC_STATUS status
= RpcSmDestroyClientContext(ContextHandle
);
6019 if (status
!= RPC_S_OK
)
6020 RpcRaiseException(status
);
6023 static UINT
ndr_update_context_handle(NDR_CCONTEXT
*CContext
,
6024 RPC_BINDING_HANDLE hBinding
,
6025 const ndr_context_handle
*chi
)
6027 struct context_handle_entry
*che
= NULL
;
6029 /* a null UUID means we should free the context handle */
6030 if (IsEqualGUID(&chi
->uuid
, &GUID_NULL
))
6034 che
= get_context_entry(*CContext
);
6036 return ERROR_INVALID_HANDLE
;
6037 list_remove(&che
->entry
);
6038 RpcBindingFree(&che
->handle
);
6039 HeapFree(GetProcessHeap(), 0, che
);
6043 /* if there's no existing entry matching the GUID, allocate one */
6044 else if (!(che
= context_entry_from_guid(&chi
->uuid
)))
6046 che
= HeapAlloc(GetProcessHeap(), 0, sizeof *che
);
6048 return ERROR_NOT_ENOUGH_MEMORY
;
6049 che
->magic
= NDR_CONTEXT_HANDLE_MAGIC
;
6050 RpcBindingCopy(hBinding
, &che
->handle
);
6051 list_add_tail(&context_handle_list
, &che
->entry
);
6052 memcpy(&che
->wire_data
, chi
, sizeof *chi
);
6057 return ERROR_SUCCESS
;
6060 /***********************************************************************
6061 * NDRCContextUnmarshall [RPCRT4.@]
6063 void WINAPI
NDRCContextUnmarshall(NDR_CCONTEXT
*CContext
,
6064 RPC_BINDING_HANDLE hBinding
,
6065 void *pBuff
, ULONG DataRepresentation
)
6069 TRACE("*%p=(%p) %p %p %08x\n",
6070 CContext
, *CContext
, hBinding
, pBuff
, DataRepresentation
);
6072 EnterCriticalSection(&ndr_context_cs
);
6073 r
= ndr_update_context_handle(CContext
, hBinding
, pBuff
);
6074 LeaveCriticalSection(&ndr_context_cs
);
6076 RpcRaiseException(r
);
6079 /***********************************************************************
6080 * NDRSContextMarshall [RPCRT4.@]
6082 void WINAPI
NDRSContextMarshall(NDR_SCONTEXT CContext
,
6084 NDR_RUNDOWN userRunDownIn
)
6086 FIXME("(%p %p %p): stub\n", CContext
, pBuff
, userRunDownIn
);
6089 /***********************************************************************
6090 * NDRSContextMarshallEx [RPCRT4.@]
6092 void WINAPI
NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding
,
6093 NDR_SCONTEXT CContext
,
6095 NDR_RUNDOWN userRunDownIn
)
6097 FIXME("(%p %p %p %p): stub\n", hBinding
, CContext
, pBuff
, userRunDownIn
);
6100 /***********************************************************************
6101 * NDRSContextMarshall2 [RPCRT4.@]
6103 void WINAPI
NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding
,
6104 NDR_SCONTEXT CContext
,
6106 NDR_RUNDOWN userRunDownIn
,
6107 void *CtxGuard
, ULONG Flags
)
6109 FIXME("(%p %p %p %p %p %u): stub\n",
6110 hBinding
, CContext
, pBuff
, userRunDownIn
, CtxGuard
, Flags
);
6113 /***********************************************************************
6114 * NDRSContextUnmarshall [RPCRT4.@]
6116 NDR_SCONTEXT WINAPI
NDRSContextUnmarshall(void *pBuff
,
6117 ULONG DataRepresentation
)
6119 FIXME("(%p %08x): stub\n", pBuff
, DataRepresentation
);
6123 /***********************************************************************
6124 * NDRSContextUnmarshallEx [RPCRT4.@]
6126 NDR_SCONTEXT WINAPI
NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding
,
6128 ULONG DataRepresentation
)
6130 FIXME("(%p %p %08x): stub\n", hBinding
, pBuff
, DataRepresentation
);
6134 /***********************************************************************
6135 * NDRSContextUnmarshall2 [RPCRT4.@]
6137 NDR_SCONTEXT WINAPI
NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding
,
6139 ULONG DataRepresentation
,
6140 void *CtxGuard
, ULONG Flags
)
6142 FIXME("(%p %p %08x %p %u): stub\n",
6143 hBinding
, pBuff
, DataRepresentation
, CtxGuard
, Flags
);