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
23 * - Byte count pointers
24 * - transmit_as/represent as
25 * - Multi-dimensional arrays
26 * - Conversion functions (NdrConvert)
27 * - Checks for integer addition overflow in user marshall functions
42 #include "wine/unicode.h"
43 #include "wine/rpcfc.h"
45 #include "wine/debug.h"
47 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
50 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
51 (*((UINT32 *)(pchar)) = (uint32))
53 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
54 (*((UINT32 *)(pchar)))
56 /* these would work for i386 too, but less efficient */
57 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
58 (*(pchar) = LOBYTE(LOWORD(uint32)), \
59 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
60 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
61 *((pchar)+3) = HIBYTE(HIWORD(uint32)))
63 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
65 MAKEWORD(*(pchar), *((pchar)+1)), \
66 MAKEWORD(*((pchar)+2), *((pchar)+3))))
69 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
70 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
71 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
72 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
73 *(pchar) = HIBYTE(HIWORD(uint32)))
75 #define BIG_ENDIAN_UINT32_READ(pchar) \
77 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
78 MAKEWORD(*((pchar)+1), *(pchar))))
80 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
81 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
82 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
83 # define NDR_LOCAL_UINT32_READ(pchar) \
84 BIG_ENDIAN_UINT32_READ(pchar)
86 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
87 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
88 # define NDR_LOCAL_UINT32_READ(pchar) \
89 LITTLE_ENDIAN_UINT32_READ(pchar)
92 /* _Align must be the desired alignment,
93 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
94 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
95 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
96 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
97 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
98 #define ALIGN_POINTER_CLEAR(_Ptr, _Align) \
100 memset((_Ptr), 0, ((_Align) - (ULONG_PTR)(_Ptr)) & ((_Align) - 1)); \
101 ALIGN_POINTER(_Ptr, _Align); \
104 #define STD_OVERFLOW_CHECK(_Msg) do { \
105 TRACE("buffer=%d/%d\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
106 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
107 ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
110 #define NDR_POINTER_ID_BASE 0x20000
111 #define NDR_POINTER_ID(pStubMsg) (NDR_POINTER_ID_BASE + ((pStubMsg)->UniquePtrCount++) * 4)
112 #define NDR_TABLE_SIZE 128
113 #define NDR_TABLE_MASK 127
115 static unsigned char *WINAPI
NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
116 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
117 static void WINAPI
NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
118 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
119 static ULONG WINAPI
NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
121 static unsigned char *WINAPI
NdrContextHandleMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
122 static void WINAPI
NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
123 static unsigned char *WINAPI
NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
125 static unsigned char *WINAPI
NdrRangeMarshall(PMIDL_STUB_MESSAGE
,unsigned char *, PFORMAT_STRING
);
126 static void WINAPI
NdrRangeBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
127 static ULONG WINAPI
NdrRangeMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
128 static void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
130 static ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
132 const NDR_MARSHALL NdrMarshaller
[NDR_TABLE_SIZE
] = {
134 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
135 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
136 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
137 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
141 NdrPointerMarshall
, NdrPointerMarshall
,
142 NdrPointerMarshall
, NdrPointerMarshall
,
144 NdrSimpleStructMarshall
, NdrSimpleStructMarshall
,
145 NdrConformantStructMarshall
, NdrConformantStructMarshall
,
146 NdrConformantVaryingStructMarshall
,
147 NdrComplexStructMarshall
,
149 NdrConformantArrayMarshall
,
150 NdrConformantVaryingArrayMarshall
,
151 NdrFixedArrayMarshall
, NdrFixedArrayMarshall
,
152 NdrVaryingArrayMarshall
, NdrVaryingArrayMarshall
,
153 NdrComplexArrayMarshall
,
155 NdrConformantStringMarshall
, 0, 0,
156 NdrConformantStringMarshall
,
157 NdrNonConformantStringMarshall
, 0, 0, 0,
159 NdrEncapsulatedUnionMarshall
,
160 NdrNonEncapsulatedUnionMarshall
,
161 NdrByteCountPointerMarshall
,
162 NdrXmitOrRepAsMarshall
, NdrXmitOrRepAsMarshall
,
164 NdrInterfacePointerMarshall
,
166 NdrContextHandleMarshall
,
169 NdrUserMarshalMarshall
,
174 const NDR_UNMARSHALL NdrUnmarshaller
[NDR_TABLE_SIZE
] = {
176 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
177 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
178 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
179 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
181 NdrBaseTypeUnmarshall
,
183 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
184 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
186 NdrSimpleStructUnmarshall
, NdrSimpleStructUnmarshall
,
187 NdrConformantStructUnmarshall
, NdrConformantStructUnmarshall
,
188 NdrConformantVaryingStructUnmarshall
,
189 NdrComplexStructUnmarshall
,
191 NdrConformantArrayUnmarshall
,
192 NdrConformantVaryingArrayUnmarshall
,
193 NdrFixedArrayUnmarshall
, NdrFixedArrayUnmarshall
,
194 NdrVaryingArrayUnmarshall
, NdrVaryingArrayUnmarshall
,
195 NdrComplexArrayUnmarshall
,
197 NdrConformantStringUnmarshall
, 0, 0,
198 NdrConformantStringUnmarshall
,
199 NdrNonConformantStringUnmarshall
, 0, 0, 0,
201 NdrEncapsulatedUnionUnmarshall
,
202 NdrNonEncapsulatedUnionUnmarshall
,
203 NdrByteCountPointerUnmarshall
,
204 NdrXmitOrRepAsUnmarshall
, NdrXmitOrRepAsUnmarshall
,
206 NdrInterfacePointerUnmarshall
,
208 NdrContextHandleUnmarshall
,
211 NdrUserMarshalUnmarshall
,
216 const NDR_BUFFERSIZE NdrBufferSizer
[NDR_TABLE_SIZE
] = {
218 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
219 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
220 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
221 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
223 NdrBaseTypeBufferSize
,
225 NdrPointerBufferSize
, NdrPointerBufferSize
,
226 NdrPointerBufferSize
, NdrPointerBufferSize
,
228 NdrSimpleStructBufferSize
, NdrSimpleStructBufferSize
,
229 NdrConformantStructBufferSize
, NdrConformantStructBufferSize
,
230 NdrConformantVaryingStructBufferSize
,
231 NdrComplexStructBufferSize
,
233 NdrConformantArrayBufferSize
,
234 NdrConformantVaryingArrayBufferSize
,
235 NdrFixedArrayBufferSize
, NdrFixedArrayBufferSize
,
236 NdrVaryingArrayBufferSize
, NdrVaryingArrayBufferSize
,
237 NdrComplexArrayBufferSize
,
239 NdrConformantStringBufferSize
, 0, 0,
240 NdrConformantStringBufferSize
,
241 NdrNonConformantStringBufferSize
, 0, 0, 0,
243 NdrEncapsulatedUnionBufferSize
,
244 NdrNonEncapsulatedUnionBufferSize
,
245 NdrByteCountPointerBufferSize
,
246 NdrXmitOrRepAsBufferSize
, NdrXmitOrRepAsBufferSize
,
248 NdrInterfacePointerBufferSize
,
250 NdrContextHandleBufferSize
,
253 NdrUserMarshalBufferSize
,
258 const NDR_MEMORYSIZE NdrMemorySizer
[NDR_TABLE_SIZE
] = {
260 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
261 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
262 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
263 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
265 NdrBaseTypeMemorySize
,
267 NdrPointerMemorySize
, NdrPointerMemorySize
,
268 NdrPointerMemorySize
, NdrPointerMemorySize
,
270 NdrSimpleStructMemorySize
, NdrSimpleStructMemorySize
,
271 NdrConformantStructMemorySize
, NdrConformantStructMemorySize
,
272 NdrConformantVaryingStructMemorySize
,
273 NdrComplexStructMemorySize
,
275 NdrConformantArrayMemorySize
,
276 NdrConformantVaryingArrayMemorySize
,
277 NdrFixedArrayMemorySize
, NdrFixedArrayMemorySize
,
278 NdrVaryingArrayMemorySize
, NdrVaryingArrayMemorySize
,
279 NdrComplexArrayMemorySize
,
281 NdrConformantStringMemorySize
, 0, 0,
282 NdrConformantStringMemorySize
,
283 NdrNonConformantStringMemorySize
, 0, 0, 0,
285 NdrEncapsulatedUnionMemorySize
,
286 NdrNonEncapsulatedUnionMemorySize
,
287 NdrByteCountPointerMemorySize
,
288 NdrXmitOrRepAsMemorySize
, NdrXmitOrRepAsMemorySize
,
290 NdrInterfacePointerMemorySize
,
295 NdrUserMarshalMemorySize
,
300 const NDR_FREE NdrFreer
[NDR_TABLE_SIZE
] = {
302 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
303 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
304 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
305 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
309 NdrPointerFree
, NdrPointerFree
,
310 NdrPointerFree
, NdrPointerFree
,
312 NdrSimpleStructFree
, NdrSimpleStructFree
,
313 NdrConformantStructFree
, NdrConformantStructFree
,
314 NdrConformantVaryingStructFree
,
315 NdrComplexStructFree
,
317 NdrConformantArrayFree
,
318 NdrConformantVaryingArrayFree
,
319 NdrFixedArrayFree
, NdrFixedArrayFree
,
320 NdrVaryingArrayFree
, NdrVaryingArrayFree
,
326 NdrEncapsulatedUnionFree
,
327 NdrNonEncapsulatedUnionFree
,
329 NdrXmitOrRepAsFree
, NdrXmitOrRepAsFree
,
331 NdrInterfacePointerFree
,
342 typedef struct _NDR_MEMORY_LIST
347 struct _NDR_MEMORY_LIST
*next
;
350 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
352 /***********************************************************************
353 * NdrAllocate [RPCRT4.@]
355 * Allocates a block of memory using pStubMsg->pfnAllocate.
358 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
359 * len [I] Size of memory block to allocate.
362 * The memory block of size len that was allocated.
365 * The memory block is always 8-byte aligned.
366 * If the function is unable to allocate memory an ERROR_OUTOFMEMORY
367 * exception is raised.
369 void * WINAPI
NdrAllocate(MIDL_STUB_MESSAGE
*pStubMsg
, SIZE_T len
)
374 NDR_MEMORY_LIST
*mem_list
;
376 aligned_len
= ALIGNED_LENGTH(len
, 8);
377 adjusted_len
= aligned_len
+ sizeof(NDR_MEMORY_LIST
);
378 /* check for overflow */
379 if (adjusted_len
< len
)
381 ERR("overflow of adjusted_len %ld, len %ld\n", adjusted_len
, len
);
382 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
385 p
= pStubMsg
->pfnAllocate(adjusted_len
);
386 if (!p
) RpcRaiseException(ERROR_OUTOFMEMORY
);
388 mem_list
= (NDR_MEMORY_LIST
*)((char *)p
+ aligned_len
);
389 mem_list
->magic
= MEML_MAGIC
;
390 mem_list
->size
= aligned_len
;
391 mem_list
->reserved
= 0;
392 mem_list
->next
= pStubMsg
->pMemoryList
;
393 pStubMsg
->pMemoryList
= mem_list
;
399 static void NdrFree(MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *Pointer
)
401 TRACE("(%p, %p)\n", pStubMsg
, Pointer
);
403 pStubMsg
->pfnFree(Pointer
);
406 static inline BOOL
IsConformanceOrVariancePresent(PFORMAT_STRING pFormat
)
408 return (*(const ULONG
*)pFormat
!= -1);
411 static PFORMAT_STRING
ReadConformance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
)
413 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
414 if (pStubMsg
->Buffer
+ 4 > pStubMsg
->BufferEnd
)
415 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
416 pStubMsg
->MaxCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
417 pStubMsg
->Buffer
+= 4;
418 TRACE("unmarshalled conformance is %ld\n", pStubMsg
->MaxCount
);
419 if (pStubMsg
->fHasNewCorrDesc
)
425 static inline PFORMAT_STRING
ReadVariance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
, ULONG MaxValue
)
427 if (pFormat
&& !IsConformanceOrVariancePresent(pFormat
))
429 pStubMsg
->Offset
= 0;
430 pStubMsg
->ActualCount
= pStubMsg
->MaxCount
;
434 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
435 if (pStubMsg
->Buffer
+ 8 > pStubMsg
->BufferEnd
)
436 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
437 pStubMsg
->Offset
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
438 pStubMsg
->Buffer
+= 4;
439 TRACE("offset is %d\n", pStubMsg
->Offset
);
440 pStubMsg
->ActualCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
441 pStubMsg
->Buffer
+= 4;
442 TRACE("variance is %d\n", pStubMsg
->ActualCount
);
444 if ((pStubMsg
->ActualCount
> MaxValue
) ||
445 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> MaxValue
))
447 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
448 pStubMsg
->ActualCount
, pStubMsg
->Offset
, MaxValue
);
449 RpcRaiseException(RPC_S_INVALID_BOUND
);
454 if (pStubMsg
->fHasNewCorrDesc
)
460 /* writes the conformance value to the buffer */
461 static inline void WriteConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
463 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
464 if (pStubMsg
->Buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
465 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
466 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->MaxCount
);
467 pStubMsg
->Buffer
+= 4;
470 /* writes the variance values to the buffer */
471 static inline void WriteVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
473 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
474 if (pStubMsg
->Buffer
+ 8 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
475 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
476 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->Offset
);
477 pStubMsg
->Buffer
+= 4;
478 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->ActualCount
);
479 pStubMsg
->Buffer
+= 4;
482 /* requests buffer space for the conformance value */
483 static inline void SizeConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
485 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
486 if (pStubMsg
->BufferLength
+ 4 < pStubMsg
->BufferLength
)
487 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
488 pStubMsg
->BufferLength
+= 4;
491 /* requests buffer space for the variance values */
492 static inline void SizeVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
494 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
495 if (pStubMsg
->BufferLength
+ 8 < pStubMsg
->BufferLength
)
496 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
497 pStubMsg
->BufferLength
+= 8;
500 PFORMAT_STRING
ComputeConformanceOrVariance(
501 MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *pMemory
,
502 PFORMAT_STRING pFormat
, ULONG_PTR def
, ULONG_PTR
*pCount
)
504 BYTE dtype
= pFormat
[0] & 0xf;
505 short ofs
= *(const short *)&pFormat
[2];
509 if (!IsConformanceOrVariancePresent(pFormat
)) {
510 /* null descriptor */
515 switch (pFormat
[0] & 0xf0) {
516 case RPC_FC_NORMAL_CONFORMANCE
:
517 TRACE("normal conformance, ofs=%d\n", ofs
);
520 case RPC_FC_POINTER_CONFORMANCE
:
521 TRACE("pointer conformance, ofs=%d\n", ofs
);
522 ptr
= pStubMsg
->Memory
;
524 case RPC_FC_TOP_LEVEL_CONFORMANCE
:
525 TRACE("toplevel conformance, ofs=%d\n", ofs
);
526 if (pStubMsg
->StackTop
) {
527 ptr
= pStubMsg
->StackTop
;
530 /* -Os mode, *pCount is already set */
534 case RPC_FC_CONSTANT_CONFORMANCE
:
535 data
= ofs
| ((DWORD
)pFormat
[1] << 16);
536 TRACE("constant conformance, val=%d\n", data
);
539 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE
:
540 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs
);
541 if (pStubMsg
->StackTop
) {
542 ptr
= pStubMsg
->StackTop
;
550 FIXME("unknown conformance type %x\n", pFormat
[0] & 0xf0);
553 switch (pFormat
[1]) {
554 case RPC_FC_DEREFERENCE
:
555 ptr
= *(LPVOID
*)((char *)ptr
+ ofs
);
557 case RPC_FC_CALLBACK
:
559 unsigned char *old_stack_top
= pStubMsg
->StackTop
;
560 pStubMsg
->StackTop
= ptr
;
562 /* ofs is index into StubDesc->apfnExprEval */
563 TRACE("callback conformance into apfnExprEval[%d]\n", ofs
);
564 pStubMsg
->StubDesc
->apfnExprEval
[ofs
](pStubMsg
);
566 pStubMsg
->StackTop
= old_stack_top
;
568 /* the callback function always stores the computed value in MaxCount */
569 *pCount
= pStubMsg
->MaxCount
;
573 ptr
= (char *)ptr
+ ofs
;
586 data
= *(USHORT
*)ptr
;
597 FIXME("unknown conformance data type %x\n", dtype
);
600 TRACE("dereferenced data type %x at %p, got %d\n", dtype
, ptr
, data
);
603 switch (pFormat
[1]) {
604 case RPC_FC_DEREFERENCE
: /* already handled */
621 FIXME("unknown conformance op %d\n", pFormat
[1]);
626 TRACE("resulting conformance is %ld\n", *pCount
);
627 if (pStubMsg
->fHasNewCorrDesc
)
633 static inline PFORMAT_STRING
SkipConformance(PMIDL_STUB_MESSAGE pStubMsg
,
634 PFORMAT_STRING pFormat
)
636 if (IsConformanceOrVariancePresent(pFormat
))
638 if (pStubMsg
->fHasNewCorrDesc
)
646 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
647 * the result overflows 32-bits */
648 static inline ULONG
safe_multiply(ULONG a
, ULONG b
)
650 ULONGLONG ret
= (ULONGLONG
)a
* b
;
651 if (ret
> 0xffffffff)
653 RpcRaiseException(RPC_S_INVALID_BOUND
);
659 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
661 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
662 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
663 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
664 pStubMsg
->Buffer
+= size
;
667 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
669 if (pStubMsg
->BufferLength
+ size
< pStubMsg
->BufferLength
) /* integer overflow of pStubMsg->BufferSize */
671 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
672 pStubMsg
->BufferLength
, size
);
673 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
675 pStubMsg
->BufferLength
+= size
;
678 /* copies data from the buffer, checking that there is enough data in the buffer
680 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, void *p
, ULONG size
)
682 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
683 (pStubMsg
->Buffer
+ size
> pStubMsg
->BufferEnd
))
685 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
686 pStubMsg
->Buffer
, pStubMsg
->BufferEnd
, size
);
687 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
689 if (p
== pStubMsg
->Buffer
)
690 ERR("pointer is the same as the buffer\n");
691 memcpy(p
, pStubMsg
->Buffer
, size
);
692 pStubMsg
->Buffer
+= size
;
695 /* copies data to the buffer, checking that there is enough space to do so */
696 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, const void *p
, ULONG size
)
698 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
699 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
701 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
702 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
,
704 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
706 memcpy(pStubMsg
->Buffer
, p
, size
);
707 pStubMsg
->Buffer
+= size
;
710 /* verify that string data sitting in the buffer is valid and safe to
712 static void validate_string_data(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG bufsize
, ULONG esize
)
716 /* verify the buffer is safe to access */
717 if ((pStubMsg
->Buffer
+ bufsize
< pStubMsg
->Buffer
) ||
718 (pStubMsg
->Buffer
+ bufsize
> pStubMsg
->BufferEnd
))
720 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize
,
721 pStubMsg
->BufferEnd
, pStubMsg
->Buffer
);
722 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
725 /* strings must always have null terminating bytes */
728 ERR("invalid string length of %d\n", bufsize
/ esize
);
729 RpcRaiseException(RPC_S_INVALID_BOUND
);
732 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
733 if (pStubMsg
->Buffer
[i
] != 0)
735 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
736 i
, pStubMsg
->Buffer
[i
]);
737 RpcRaiseException(RPC_S_INVALID_BOUND
);
741 static inline void dump_pointer_attr(unsigned char attr
)
743 if (attr
& RPC_FC_P_ALLOCALLNODES
)
744 TRACE(" RPC_FC_P_ALLOCALLNODES");
745 if (attr
& RPC_FC_P_DONTFREE
)
746 TRACE(" RPC_FC_P_DONTFREE");
747 if (attr
& RPC_FC_P_ONSTACK
)
748 TRACE(" RPC_FC_P_ONSTACK");
749 if (attr
& RPC_FC_P_SIMPLEPOINTER
)
750 TRACE(" RPC_FC_P_SIMPLEPOINTER");
751 if (attr
& RPC_FC_P_DEREF
)
752 TRACE(" RPC_FC_P_DEREF");
756 /***********************************************************************
757 * PointerMarshall [internal]
759 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
760 unsigned char *Buffer
,
761 unsigned char *Pointer
,
762 PFORMAT_STRING pFormat
)
764 unsigned type
= pFormat
[0], attr
= pFormat
[1];
768 int pointer_needs_marshaling
;
770 TRACE("(%p,%p,%p,%p)\n", pStubMsg
, Buffer
, Pointer
, pFormat
);
771 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
773 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
774 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
777 case RPC_FC_RP
: /* ref pointer (always non-null) */
780 ERR("NULL ref pointer is not allowed\n");
781 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
783 pointer_needs_marshaling
= 1;
785 case RPC_FC_UP
: /* unique pointer */
786 case RPC_FC_OP
: /* object pointer - same as unique here */
788 pointer_needs_marshaling
= 1;
790 pointer_needs_marshaling
= 0;
791 pointer_id
= Pointer
? NDR_POINTER_ID(pStubMsg
) : 0;
792 TRACE("writing 0x%08x to buffer\n", pointer_id
);
793 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
796 pointer_needs_marshaling
= !NdrFullPointerQueryPointer(
797 pStubMsg
->FullPtrXlatTables
, Pointer
, 1, &pointer_id
);
798 TRACE("writing 0x%08x to buffer\n", pointer_id
);
799 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
802 FIXME("unhandled ptr type=%02x\n", type
);
803 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
807 TRACE("calling marshaller for type 0x%x\n", (int)*desc
);
809 if (pointer_needs_marshaling
) {
810 if (attr
& RPC_FC_P_DEREF
) {
811 Pointer
= *(unsigned char**)Pointer
;
812 TRACE("deref => %p\n", Pointer
);
814 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
815 if (m
) m(pStubMsg
, Pointer
, desc
);
816 else FIXME("no marshaller for data type=%02x\n", *desc
);
819 STD_OVERFLOW_CHECK(pStubMsg
);
822 /***********************************************************************
823 * PointerUnmarshall [internal]
825 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
826 unsigned char *Buffer
,
827 unsigned char **pPointer
,
828 unsigned char *pSrcPointer
,
829 PFORMAT_STRING pFormat
,
830 unsigned char fMustAlloc
)
832 unsigned type
= pFormat
[0], attr
= pFormat
[1];
835 DWORD pointer_id
= 0;
836 int pointer_needs_unmarshaling
;
838 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg
, Buffer
, pPointer
, pSrcPointer
, pFormat
, fMustAlloc
);
839 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
841 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
842 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
845 case RPC_FC_RP
: /* ref pointer (always non-null) */
846 pointer_needs_unmarshaling
= 1;
848 case RPC_FC_UP
: /* unique pointer */
849 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
850 TRACE("pointer_id is 0x%08x\n", pointer_id
);
852 pointer_needs_unmarshaling
= 1;
855 pointer_needs_unmarshaling
= 0;
858 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
859 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
860 TRACE("pointer_id is 0x%08x\n", pointer_id
);
861 if (!fMustAlloc
&& pSrcPointer
)
863 FIXME("free object pointer %p\n", pSrcPointer
);
867 pointer_needs_unmarshaling
= 1;
871 pointer_needs_unmarshaling
= 0;
875 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
876 TRACE("pointer_id is 0x%08x\n", pointer_id
);
877 pointer_needs_unmarshaling
= !NdrFullPointerQueryRefId(
878 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, (void **)pPointer
);
881 FIXME("unhandled ptr type=%02x\n", type
);
882 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
886 if (pointer_needs_unmarshaling
) {
887 unsigned char *base_ptr_val
= *pPointer
;
888 unsigned char **current_ptr
= pPointer
;
889 if (pStubMsg
->IsClient
) {
891 /* if we aren't forcing allocation of memory then try to use the existing
892 * (source) pointer to unmarshall the data into so that [in,out]
893 * parameters behave correctly. it doesn't matter if the parameter is
894 * [out] only since in that case the pointer will be NULL. we force
895 * allocation when the source pointer is NULL here instead of in the type
896 * unmarshalling routine for the benefit of the deref code below */
899 TRACE("setting *pPointer to %p\n", pSrcPointer
);
900 *pPointer
= base_ptr_val
= pSrcPointer
;
906 /* the memory in a stub is never initialised, so we have to work out here
907 * whether we have to initialise it so we can use the optimisation of
908 * setting the pointer to the buffer, if possible, or set fMustAlloc to
910 if (attr
& RPC_FC_P_DEREF
) {
918 if (attr
& RPC_FC_P_ALLOCALLNODES
)
919 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
921 if (attr
& RPC_FC_P_DEREF
) {
923 base_ptr_val
= NdrAllocate(pStubMsg
, sizeof(void *));
924 *pPointer
= base_ptr_val
;
925 current_ptr
= (unsigned char **)base_ptr_val
;
927 current_ptr
= *(unsigned char***)current_ptr
;
928 TRACE("deref => %p\n", current_ptr
);
929 if (!fMustAlloc
&& !*current_ptr
) fMustAlloc
= TRUE
;
931 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
932 if (m
) m(pStubMsg
, current_ptr
, desc
, fMustAlloc
);
933 else FIXME("no unmarshaller for data type=%02x\n", *desc
);
935 if (type
== RPC_FC_FP
)
936 NdrFullPointerInsertRefId(pStubMsg
->FullPtrXlatTables
, pointer_id
,
940 TRACE("pointer=%p\n", *pPointer
);
943 /***********************************************************************
944 * PointerBufferSize [internal]
946 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
947 unsigned char *Pointer
,
948 PFORMAT_STRING pFormat
)
950 unsigned type
= pFormat
[0], attr
= pFormat
[1];
953 int pointer_needs_sizing
;
956 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
957 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
959 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
960 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
963 case RPC_FC_RP
: /* ref pointer (always non-null) */
966 ERR("NULL ref pointer is not allowed\n");
967 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
972 /* NULL pointer has no further representation */
977 pointer_needs_sizing
= !NdrFullPointerQueryPointer(
978 pStubMsg
->FullPtrXlatTables
, Pointer
, 0, &pointer_id
);
979 if (!pointer_needs_sizing
)
983 FIXME("unhandled ptr type=%02x\n", type
);
984 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
988 if (attr
& RPC_FC_P_DEREF
) {
989 Pointer
= *(unsigned char**)Pointer
;
990 TRACE("deref => %p\n", Pointer
);
993 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
994 if (m
) m(pStubMsg
, Pointer
, desc
);
995 else FIXME("no buffersizer for data type=%02x\n", *desc
);
998 /***********************************************************************
999 * PointerMemorySize [internal]
1001 static ULONG
PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1002 unsigned char *Buffer
, PFORMAT_STRING pFormat
)
1004 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1005 PFORMAT_STRING desc
;
1007 DWORD pointer_id
= 0;
1008 int pointer_needs_sizing
;
1010 TRACE("(%p,%p,%p)\n", pStubMsg
, Buffer
, pFormat
);
1011 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1013 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1014 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1017 case RPC_FC_RP
: /* ref pointer (always non-null) */
1018 pointer_needs_sizing
= 1;
1020 case RPC_FC_UP
: /* unique pointer */
1021 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
1022 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1023 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1025 pointer_needs_sizing
= 1;
1027 pointer_needs_sizing
= 0;
1032 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1033 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1034 pointer_needs_sizing
= !NdrFullPointerQueryRefId(
1035 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, &pointer
);
1039 FIXME("unhandled ptr type=%02x\n", type
);
1040 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1044 if (attr
& RPC_FC_P_DEREF
) {
1048 if (pointer_needs_sizing
) {
1049 m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
1050 if (m
) m(pStubMsg
, desc
);
1051 else FIXME("no memorysizer for data type=%02x\n", *desc
);
1054 return pStubMsg
->MemorySize
;
1057 /***********************************************************************
1058 * PointerFree [internal]
1060 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1061 unsigned char *Pointer
,
1062 PFORMAT_STRING pFormat
)
1064 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1065 PFORMAT_STRING desc
;
1067 unsigned char *current_pointer
= Pointer
;
1069 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1070 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1071 if (attr
& RPC_FC_P_DONTFREE
) return;
1073 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1074 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1076 if (!Pointer
) return;
1078 if (type
== RPC_FC_FP
) {
1079 int pointer_needs_freeing
= NdrFullPointerFree(
1080 pStubMsg
->FullPtrXlatTables
, Pointer
);
1081 if (!pointer_needs_freeing
)
1085 if (attr
& RPC_FC_P_DEREF
) {
1086 current_pointer
= *(unsigned char**)Pointer
;
1087 TRACE("deref => %p\n", current_pointer
);
1090 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
1091 if (m
) m(pStubMsg
, current_pointer
, desc
);
1093 /* this check stops us from trying to free buffer memory. we don't have to
1094 * worry about clients, since they won't call this function.
1095 * we don't have to check for the buffer being reallocated because
1096 * BufferStart and BufferEnd won't be reset when allocating memory for
1097 * sending the response. we don't have to check for the new buffer here as
1098 * it won't be used a type memory, only for buffer memory */
1099 if (Pointer
>= pStubMsg
->BufferStart
&& Pointer
< pStubMsg
->BufferEnd
)
1102 if (attr
& RPC_FC_P_ONSTACK
) {
1103 TRACE("not freeing stack ptr %p\n", Pointer
);
1106 TRACE("freeing %p\n", Pointer
);
1107 NdrFree(pStubMsg
, Pointer
);
1110 TRACE("not freeing %p\n", Pointer
);
1113 /***********************************************************************
1114 * EmbeddedPointerMarshall
1116 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1117 unsigned char *pMemory
,
1118 PFORMAT_STRING pFormat
)
1120 unsigned char *Mark
= pStubMsg
->BufferMark
;
1121 unsigned rep
, count
, stride
;
1123 unsigned char *saved_buffer
= NULL
;
1125 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1127 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1130 if (pStubMsg
->PointerBufferMark
)
1132 saved_buffer
= pStubMsg
->Buffer
;
1133 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1134 pStubMsg
->PointerBufferMark
= NULL
;
1137 while (pFormat
[0] != RPC_FC_END
) {
1138 switch (pFormat
[0]) {
1140 FIXME("unknown repeat type %d\n", pFormat
[0]);
1141 case RPC_FC_NO_REPEAT
:
1147 case RPC_FC_FIXED_REPEAT
:
1148 rep
= *(const WORD
*)&pFormat
[2];
1149 stride
= *(const WORD
*)&pFormat
[4];
1150 count
= *(const WORD
*)&pFormat
[8];
1153 case RPC_FC_VARIABLE_REPEAT
:
1154 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1155 stride
= *(const WORD
*)&pFormat
[2];
1156 count
= *(const WORD
*)&pFormat
[6];
1160 for (i
= 0; i
< rep
; i
++) {
1161 PFORMAT_STRING info
= pFormat
;
1162 unsigned char *membase
= pMemory
+ (i
* stride
);
1163 unsigned char *bufbase
= Mark
+ (i
* stride
);
1166 for (u
=0; u
<count
; u
++,info
+=8) {
1167 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1168 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1169 unsigned char *saved_memory
= pStubMsg
->Memory
;
1171 pStubMsg
->Memory
= pMemory
;
1172 PointerMarshall(pStubMsg
, bufptr
, *(unsigned char**)memptr
, info
+4);
1173 pStubMsg
->Memory
= saved_memory
;
1176 pFormat
+= 8 * count
;
1181 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1182 pStubMsg
->Buffer
= saved_buffer
;
1185 STD_OVERFLOW_CHECK(pStubMsg
);
1190 /***********************************************************************
1191 * EmbeddedPointerUnmarshall
1193 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1194 unsigned char *pDstBuffer
,
1195 unsigned char *pSrcMemoryPtrs
,
1196 PFORMAT_STRING pFormat
,
1197 unsigned char fMustAlloc
)
1199 unsigned char *Mark
= pStubMsg
->BufferMark
;
1200 unsigned rep
, count
, stride
;
1202 unsigned char *saved_buffer
= NULL
;
1204 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg
, pDstBuffer
, pSrcMemoryPtrs
, pFormat
, fMustAlloc
);
1206 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1209 if (pStubMsg
->PointerBufferMark
)
1211 saved_buffer
= pStubMsg
->Buffer
;
1212 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1213 pStubMsg
->PointerBufferMark
= NULL
;
1216 while (pFormat
[0] != RPC_FC_END
) {
1217 TRACE("pFormat[0] = 0x%x\n", pFormat
[0]);
1218 switch (pFormat
[0]) {
1220 FIXME("unknown repeat type %d\n", pFormat
[0]);
1221 case RPC_FC_NO_REPEAT
:
1227 case RPC_FC_FIXED_REPEAT
:
1228 rep
= *(const WORD
*)&pFormat
[2];
1229 stride
= *(const WORD
*)&pFormat
[4];
1230 count
= *(const WORD
*)&pFormat
[8];
1233 case RPC_FC_VARIABLE_REPEAT
:
1234 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1235 stride
= *(const WORD
*)&pFormat
[2];
1236 count
= *(const WORD
*)&pFormat
[6];
1240 for (i
= 0; i
< rep
; i
++) {
1241 PFORMAT_STRING info
= pFormat
;
1242 unsigned char *bufdstbase
= pDstBuffer
+ (i
* stride
);
1243 unsigned char *memsrcbase
= pSrcMemoryPtrs
+ (i
* stride
);
1244 unsigned char *bufbase
= Mark
+ (i
* stride
);
1247 for (u
=0; u
<count
; u
++,info
+=8) {
1248 unsigned char **bufdstptr
= (unsigned char **)(bufdstbase
+ *(const SHORT
*)&info
[2]);
1249 unsigned char **memsrcptr
= (unsigned char **)(memsrcbase
+ *(const SHORT
*)&info
[0]);
1250 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1251 PointerUnmarshall(pStubMsg
, bufptr
, bufdstptr
, *memsrcptr
, info
+4, fMustAlloc
);
1254 pFormat
+= 8 * count
;
1259 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1260 pStubMsg
->Buffer
= saved_buffer
;
1266 /***********************************************************************
1267 * EmbeddedPointerBufferSize
1269 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1270 unsigned char *pMemory
,
1271 PFORMAT_STRING pFormat
)
1273 unsigned rep
, count
, stride
;
1275 ULONG saved_buffer_length
= 0;
1277 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1279 if (pStubMsg
->IgnoreEmbeddedPointers
) return;
1281 if (*pFormat
!= RPC_FC_PP
) return;
1284 if (pStubMsg
->PointerLength
)
1286 saved_buffer_length
= pStubMsg
->BufferLength
;
1287 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
1288 pStubMsg
->PointerLength
= 0;
1291 while (pFormat
[0] != RPC_FC_END
) {
1292 switch (pFormat
[0]) {
1294 FIXME("unknown repeat type %d\n", pFormat
[0]);
1295 case RPC_FC_NO_REPEAT
:
1301 case RPC_FC_FIXED_REPEAT
:
1302 rep
= *(const WORD
*)&pFormat
[2];
1303 stride
= *(const WORD
*)&pFormat
[4];
1304 count
= *(const WORD
*)&pFormat
[8];
1307 case RPC_FC_VARIABLE_REPEAT
:
1308 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1309 stride
= *(const WORD
*)&pFormat
[2];
1310 count
= *(const WORD
*)&pFormat
[6];
1314 for (i
= 0; i
< rep
; i
++) {
1315 PFORMAT_STRING info
= pFormat
;
1316 unsigned char *membase
= pMemory
+ (i
* stride
);
1319 for (u
=0; u
<count
; u
++,info
+=8) {
1320 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1321 unsigned char *saved_memory
= pStubMsg
->Memory
;
1323 pStubMsg
->Memory
= pMemory
;
1324 PointerBufferSize(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1325 pStubMsg
->Memory
= saved_memory
;
1328 pFormat
+= 8 * count
;
1331 if (saved_buffer_length
)
1333 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
1334 pStubMsg
->BufferLength
= saved_buffer_length
;
1338 /***********************************************************************
1339 * EmbeddedPointerMemorySize [internal]
1341 static ULONG
EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1342 PFORMAT_STRING pFormat
)
1344 unsigned char *Mark
= pStubMsg
->BufferMark
;
1345 unsigned rep
, count
, stride
;
1347 unsigned char *saved_buffer
= NULL
;
1349 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1351 if (pStubMsg
->IgnoreEmbeddedPointers
) return 0;
1353 if (pStubMsg
->PointerBufferMark
)
1355 saved_buffer
= pStubMsg
->Buffer
;
1356 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1357 pStubMsg
->PointerBufferMark
= NULL
;
1360 if (*pFormat
!= RPC_FC_PP
) return 0;
1363 while (pFormat
[0] != RPC_FC_END
) {
1364 switch (pFormat
[0]) {
1366 FIXME("unknown repeat type %d\n", pFormat
[0]);
1367 case RPC_FC_NO_REPEAT
:
1373 case RPC_FC_FIXED_REPEAT
:
1374 rep
= *(const WORD
*)&pFormat
[2];
1375 stride
= *(const WORD
*)&pFormat
[4];
1376 count
= *(const WORD
*)&pFormat
[8];
1379 case RPC_FC_VARIABLE_REPEAT
:
1380 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1381 stride
= *(const WORD
*)&pFormat
[2];
1382 count
= *(const WORD
*)&pFormat
[6];
1386 for (i
= 0; i
< rep
; i
++) {
1387 PFORMAT_STRING info
= pFormat
;
1388 unsigned char *bufbase
= Mark
+ (i
* stride
);
1390 for (u
=0; u
<count
; u
++,info
+=8) {
1391 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1392 PointerMemorySize(pStubMsg
, bufptr
, info
+4);
1395 pFormat
+= 8 * count
;
1400 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1401 pStubMsg
->Buffer
= saved_buffer
;
1407 /***********************************************************************
1408 * EmbeddedPointerFree [internal]
1410 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1411 unsigned char *pMemory
,
1412 PFORMAT_STRING pFormat
)
1414 unsigned rep
, count
, stride
;
1417 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1418 if (*pFormat
!= RPC_FC_PP
) return;
1421 while (pFormat
[0] != RPC_FC_END
) {
1422 switch (pFormat
[0]) {
1424 FIXME("unknown repeat type %d\n", pFormat
[0]);
1425 case RPC_FC_NO_REPEAT
:
1431 case RPC_FC_FIXED_REPEAT
:
1432 rep
= *(const WORD
*)&pFormat
[2];
1433 stride
= *(const WORD
*)&pFormat
[4];
1434 count
= *(const WORD
*)&pFormat
[8];
1437 case RPC_FC_VARIABLE_REPEAT
:
1438 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1439 stride
= *(const WORD
*)&pFormat
[2];
1440 count
= *(const WORD
*)&pFormat
[6];
1444 for (i
= 0; i
< rep
; i
++) {
1445 PFORMAT_STRING info
= pFormat
;
1446 unsigned char *membase
= pMemory
+ (i
* stride
);
1449 for (u
=0; u
<count
; u
++,info
+=8) {
1450 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1451 unsigned char *saved_memory
= pStubMsg
->Memory
;
1453 pStubMsg
->Memory
= pMemory
;
1454 PointerFree(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1455 pStubMsg
->Memory
= saved_memory
;
1458 pFormat
+= 8 * count
;
1462 /***********************************************************************
1463 * NdrPointerMarshall [RPCRT4.@]
1465 unsigned char * WINAPI
NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1466 unsigned char *pMemory
,
1467 PFORMAT_STRING pFormat
)
1469 unsigned char *Buffer
;
1471 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1473 /* Increment the buffer here instead of in PointerMarshall,
1474 * as that is used by embedded pointers which already handle the incrementing
1475 * the buffer, and shouldn't write any additional pointer data to the wire */
1476 if (*pFormat
!= RPC_FC_RP
)
1478 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
1479 Buffer
= pStubMsg
->Buffer
;
1480 safe_buffer_increment(pStubMsg
, 4);
1483 Buffer
= pStubMsg
->Buffer
;
1485 PointerMarshall(pStubMsg
, Buffer
, pMemory
, pFormat
);
1490 /***********************************************************************
1491 * NdrPointerUnmarshall [RPCRT4.@]
1493 unsigned char * WINAPI
NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1494 unsigned char **ppMemory
,
1495 PFORMAT_STRING pFormat
,
1496 unsigned char fMustAlloc
)
1498 unsigned char *Buffer
;
1500 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1502 if (*pFormat
== RPC_FC_RP
)
1504 Buffer
= pStubMsg
->Buffer
;
1505 /* Do the NULL ref pointer check here because embedded pointers can be
1506 * NULL if the type the pointer is embedded in was allocated rather than
1507 * being passed in by the client */
1508 if (pStubMsg
->IsClient
&& !*ppMemory
)
1510 ERR("NULL ref pointer is not allowed\n");
1511 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
1516 /* Increment the buffer here instead of in PointerUnmarshall,
1517 * as that is used by embedded pointers which already handle the incrementing
1518 * the buffer, and shouldn't read any additional pointer data from the
1520 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1521 Buffer
= pStubMsg
->Buffer
;
1522 safe_buffer_increment(pStubMsg
, 4);
1525 PointerUnmarshall(pStubMsg
, Buffer
, ppMemory
, *ppMemory
, pFormat
, fMustAlloc
);
1530 /***********************************************************************
1531 * NdrPointerBufferSize [RPCRT4.@]
1533 void WINAPI
NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1534 unsigned char *pMemory
,
1535 PFORMAT_STRING pFormat
)
1537 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1539 /* Increment the buffer length here instead of in PointerBufferSize,
1540 * as that is used by embedded pointers which already handle the buffer
1541 * length, and shouldn't write anything more to the wire */
1542 if (*pFormat
!= RPC_FC_RP
)
1544 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
1545 safe_buffer_length_increment(pStubMsg
, 4);
1548 PointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1551 /***********************************************************************
1552 * NdrPointerMemorySize [RPCRT4.@]
1554 ULONG WINAPI
NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1555 PFORMAT_STRING pFormat
)
1557 /* unsigned size = *(LPWORD)(pFormat+2); */
1558 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1559 PointerMemorySize(pStubMsg
, pStubMsg
->Buffer
, pFormat
);
1563 /***********************************************************************
1564 * NdrPointerFree [RPCRT4.@]
1566 void WINAPI
NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1567 unsigned char *pMemory
,
1568 PFORMAT_STRING pFormat
)
1570 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1571 PointerFree(pStubMsg
, pMemory
, pFormat
);
1574 /***********************************************************************
1575 * NdrSimpleTypeMarshall [RPCRT4.@]
1577 void WINAPI
NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1578 unsigned char FormatChar
)
1580 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &FormatChar
);
1583 /***********************************************************************
1584 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1586 * Unmarshall a base type.
1589 * Doesn't check that the buffer is long enough before copying, so the caller
1592 void WINAPI
NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1593 unsigned char FormatChar
)
1595 #define BASE_TYPE_UNMARSHALL(type) \
1596 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
1597 TRACE("pMemory: %p\n", pMemory); \
1598 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1599 pStubMsg->Buffer += sizeof(type);
1607 BASE_TYPE_UNMARSHALL(UCHAR
);
1608 TRACE("value: 0x%02x\n", *pMemory
);
1613 BASE_TYPE_UNMARSHALL(USHORT
);
1614 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
1618 case RPC_FC_ERROR_STATUS_T
:
1620 BASE_TYPE_UNMARSHALL(ULONG
);
1621 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
1624 BASE_TYPE_UNMARSHALL(float);
1625 TRACE("value: %f\n", *(float *)pMemory
);
1628 BASE_TYPE_UNMARSHALL(double);
1629 TRACE("value: %f\n", *(double *)pMemory
);
1632 BASE_TYPE_UNMARSHALL(ULONGLONG
);
1633 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
1636 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
1637 TRACE("pMemory: %p\n", pMemory
);
1638 /* 16-bits on the wire, but int in memory */
1639 *(UINT
*)pMemory
= *(USHORT
*)pStubMsg
->Buffer
;
1640 pStubMsg
->Buffer
+= sizeof(USHORT
);
1641 TRACE("value: 0x%08x\n", *(UINT
*)pMemory
);
1646 FIXME("Unhandled base type: 0x%02x\n", FormatChar
);
1648 #undef BASE_TYPE_UNMARSHALL
1651 /***********************************************************************
1652 * NdrSimpleStructMarshall [RPCRT4.@]
1654 unsigned char * WINAPI
NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1655 unsigned char *pMemory
,
1656 PFORMAT_STRING pFormat
)
1658 unsigned size
= *(const WORD
*)(pFormat
+2);
1659 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1661 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pFormat
[1] + 1);
1663 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1664 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
1666 if (pFormat
[0] != RPC_FC_STRUCT
)
1667 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
+4);
1672 /***********************************************************************
1673 * NdrSimpleStructUnmarshall [RPCRT4.@]
1675 unsigned char * WINAPI
NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1676 unsigned char **ppMemory
,
1677 PFORMAT_STRING pFormat
,
1678 unsigned char fMustAlloc
)
1680 unsigned size
= *(const WORD
*)(pFormat
+2);
1681 unsigned char *saved_buffer
;
1682 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1684 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1687 *ppMemory
= NdrAllocate(pStubMsg
, size
);
1690 if (!pStubMsg
->IsClient
&& !*ppMemory
)
1691 /* for servers, we just point straight into the RPC buffer */
1692 *ppMemory
= pStubMsg
->Buffer
;
1695 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1696 safe_buffer_increment(pStubMsg
, size
);
1697 if (pFormat
[0] == RPC_FC_PSTRUCT
)
1698 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
+4, fMustAlloc
);
1700 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
1701 if (*ppMemory
!= saved_buffer
)
1702 memcpy(*ppMemory
, saved_buffer
, size
);
1707 /***********************************************************************
1708 * NdrSimpleStructBufferSize [RPCRT4.@]
1710 void WINAPI
NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1711 unsigned char *pMemory
,
1712 PFORMAT_STRING pFormat
)
1714 unsigned size
= *(const WORD
*)(pFormat
+2);
1715 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1717 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
1719 safe_buffer_length_increment(pStubMsg
, size
);
1720 if (pFormat
[0] != RPC_FC_STRUCT
)
1721 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
+4);
1724 /***********************************************************************
1725 * NdrSimpleStructMemorySize [RPCRT4.@]
1727 ULONG WINAPI
NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1728 PFORMAT_STRING pFormat
)
1730 unsigned short size
= *(const WORD
*)(pFormat
+2);
1732 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1734 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1735 pStubMsg
->MemorySize
+= size
;
1736 safe_buffer_increment(pStubMsg
, size
);
1738 if (pFormat
[0] != RPC_FC_STRUCT
)
1739 EmbeddedPointerMemorySize(pStubMsg
, pFormat
+4);
1740 return pStubMsg
->MemorySize
;
1743 /***********************************************************************
1744 * NdrSimpleStructFree [RPCRT4.@]
1746 void WINAPI
NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
1747 unsigned char *pMemory
,
1748 PFORMAT_STRING pFormat
)
1750 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1751 if (pFormat
[0] != RPC_FC_STRUCT
)
1752 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
+4);
1757 static inline void array_compute_and_size_conformance(
1758 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1759 PFORMAT_STRING pFormat
)
1764 ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1765 SizeConformance(pStubMsg
);
1767 case RPC_FC_CVARRAY
:
1768 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, 0);
1769 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
1770 SizeConformance(pStubMsg
);
1772 case RPC_FC_C_CSTRING
:
1773 case RPC_FC_C_WSTRING
:
1774 if (pFormat
[0] == RPC_FC_C_CSTRING
)
1776 TRACE("string=%s\n", debugstr_a((const char *)pMemory
));
1777 pStubMsg
->ActualCount
= strlen((const char *)pMemory
)+1;
1781 TRACE("string=%s\n", debugstr_w((LPCWSTR
)pMemory
));
1782 pStubMsg
->ActualCount
= strlenW((LPCWSTR
)pMemory
)+1;
1785 if (fc
== RPC_FC_STRING_SIZED
)
1786 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
1788 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
1790 SizeConformance(pStubMsg
);
1793 ERR("unknown array format 0x%x\n", fc
);
1794 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1798 static inline void array_buffer_size(
1799 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1800 PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
1804 unsigned char alignment
;
1809 esize
= *(const WORD
*)(pFormat
+2);
1810 alignment
= pFormat
[1] + 1;
1812 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1814 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
1816 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
1817 /* conformance value plus array */
1818 safe_buffer_length_increment(pStubMsg
, size
);
1821 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1823 case RPC_FC_CVARRAY
:
1824 esize
= *(const WORD
*)(pFormat
+2);
1825 alignment
= pFormat
[1] + 1;
1827 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1828 pFormat
= SkipConformance(pStubMsg
, pFormat
);
1830 SizeVariance(pStubMsg
);
1832 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
1834 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1835 safe_buffer_length_increment(pStubMsg
, size
);
1838 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1840 case RPC_FC_C_CSTRING
:
1841 case RPC_FC_C_WSTRING
:
1842 if (fc
== RPC_FC_C_CSTRING
)
1847 SizeVariance(pStubMsg
);
1849 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1850 safe_buffer_length_increment(pStubMsg
, size
);
1853 ERR("unknown array format 0x%x\n", fc
);
1854 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1858 static inline void array_compute_and_write_conformance(
1859 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1860 PFORMAT_STRING pFormat
)
1865 ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1866 WriteConformance(pStubMsg
);
1868 case RPC_FC_CVARRAY
:
1869 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, 0);
1870 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
1871 WriteConformance(pStubMsg
);
1873 case RPC_FC_C_CSTRING
:
1874 case RPC_FC_C_WSTRING
:
1875 if (fc
== RPC_FC_C_CSTRING
)
1877 TRACE("string=%s\n", debugstr_a((const char *)pMemory
));
1878 pStubMsg
->ActualCount
= strlen((const char *)pMemory
)+1;
1882 TRACE("string=%s\n", debugstr_w((LPCWSTR
)pMemory
));
1883 pStubMsg
->ActualCount
= strlenW((LPCWSTR
)pMemory
)+1;
1885 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
1886 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
1888 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
1889 pStubMsg
->Offset
= 0;
1890 WriteConformance(pStubMsg
);
1893 ERR("unknown array format 0x%x\n", fc
);
1894 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1898 static inline void array_write_variance_and_marshall(
1899 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1900 PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
1904 unsigned char alignment
;
1909 esize
= *(const WORD
*)(pFormat
+2);
1910 alignment
= pFormat
[1] + 1;
1912 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1914 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
1916 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
1918 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1919 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
1922 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
1924 case RPC_FC_CVARRAY
:
1925 esize
= *(const WORD
*)(pFormat
+2);
1926 alignment
= pFormat
[1] + 1;
1929 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1931 pFormat
= SkipConformance(pStubMsg
, pFormat
);
1933 WriteVariance(pStubMsg
);
1935 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
1937 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1940 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1941 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, size
);
1944 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
1946 case RPC_FC_C_CSTRING
:
1947 case RPC_FC_C_WSTRING
:
1948 if (fc
== RPC_FC_C_CSTRING
)
1953 WriteVariance(pStubMsg
);
1955 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1956 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
1959 ERR("unknown array format 0x%x\n", fc
);
1960 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1964 static inline ULONG
array_read_conformance(
1965 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
1972 esize
= *(const WORD
*)(pFormat
+2);
1973 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
1974 return safe_multiply(esize
, pStubMsg
->MaxCount
);
1975 case RPC_FC_CVARRAY
:
1976 esize
= *(const WORD
*)(pFormat
+2);
1977 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
1978 return safe_multiply(esize
, pStubMsg
->MaxCount
);
1979 case RPC_FC_C_CSTRING
:
1980 case RPC_FC_C_WSTRING
:
1981 if (fc
== RPC_FC_C_CSTRING
)
1986 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
1987 ReadConformance(pStubMsg
, pFormat
+ 2);
1989 ReadConformance(pStubMsg
, NULL
);
1990 return safe_multiply(esize
, pStubMsg
->MaxCount
);
1992 ERR("unknown array format 0x%x\n", fc
);
1993 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1997 static inline ULONG
array_read_variance_and_unmarshall(
1998 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char **ppMemory
,
1999 PFORMAT_STRING pFormat
, unsigned char fMustAlloc
,
2000 unsigned char fUseBufferMemoryServer
, unsigned char fUnmarshall
)
2002 ULONG bufsize
, memsize
;
2004 unsigned char alignment
;
2005 unsigned char *saved_buffer
;
2011 esize
= *(const WORD
*)(pFormat
+2);
2012 alignment
= pFormat
[1] + 1;
2014 bufsize
= memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2016 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2018 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2023 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2026 if (fUseBufferMemoryServer
&& !pStubMsg
->IsClient
&& !*ppMemory
)
2027 /* for servers, we just point straight into the RPC buffer */
2028 *ppMemory
= pStubMsg
->Buffer
;
2031 saved_buffer
= pStubMsg
->Buffer
;
2032 safe_buffer_increment(pStubMsg
, bufsize
);
2034 pStubMsg
->BufferMark
= saved_buffer
;
2035 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
2037 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
2038 if (*ppMemory
!= saved_buffer
)
2039 memcpy(*ppMemory
, saved_buffer
, bufsize
);
2042 case RPC_FC_CVARRAY
:
2043 esize
= *(const WORD
*)(pFormat
+2);
2044 alignment
= pFormat
[1] + 1;
2046 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2048 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2050 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2052 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2053 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2057 offset
= pStubMsg
->Offset
;
2059 if (!fMustAlloc
&& !*ppMemory
)
2062 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2063 saved_buffer
= pStubMsg
->Buffer
;
2064 safe_buffer_increment(pStubMsg
, bufsize
);
2066 pStubMsg
->BufferMark
= saved_buffer
;
2067 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
,
2070 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
2073 case RPC_FC_C_CSTRING
:
2074 case RPC_FC_C_WSTRING
:
2075 if (fc
== RPC_FC_C_CSTRING
)
2080 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
2082 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
2084 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2085 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
2086 RpcRaiseException(RPC_S_INVALID_BOUND
);
2088 if (pStubMsg
->Offset
)
2090 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2091 RpcRaiseException(RPC_S_INVALID_BOUND
);
2094 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2095 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2097 validate_string_data(pStubMsg
, bufsize
, esize
);
2102 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2105 if (fUseBufferMemoryServer
&& !pStubMsg
->IsClient
&&
2106 !*ppMemory
&& (pStubMsg
->MaxCount
== pStubMsg
->ActualCount
))
2107 /* if the data in the RPC buffer is big enough, we just point
2108 * straight into it */
2109 *ppMemory
= pStubMsg
->Buffer
;
2110 else if (!*ppMemory
)
2111 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2114 if (*ppMemory
== pStubMsg
->Buffer
)
2115 safe_buffer_increment(pStubMsg
, bufsize
);
2117 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
2119 if (*pFormat
== RPC_FC_C_CSTRING
)
2120 TRACE("string=%s\n", debugstr_a((char*)*ppMemory
));
2122 TRACE("string=%s\n", debugstr_w((LPWSTR
)*ppMemory
));
2126 ERR("unknown array format 0x%x\n", fc
);
2127 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2131 static inline void array_memory_size(
2132 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
,
2133 unsigned char fHasPointers
)
2135 ULONG bufsize
, memsize
;
2137 unsigned char alignment
;
2142 esize
= *(const WORD
*)(pFormat
+2);
2143 alignment
= pFormat
[1] + 1;
2145 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2147 bufsize
= memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2148 pStubMsg
->MemorySize
+= memsize
;
2150 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2152 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2153 safe_buffer_increment(pStubMsg
, bufsize
);
2156 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2158 case RPC_FC_CVARRAY
:
2159 esize
= *(const WORD
*)(pFormat
+2);
2160 alignment
= pFormat
[1] + 1;
2162 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2164 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2166 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2167 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2168 pStubMsg
->MemorySize
+= memsize
;
2170 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2172 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2173 safe_buffer_increment(pStubMsg
, bufsize
);
2176 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2178 case RPC_FC_C_CSTRING
:
2179 case RPC_FC_C_WSTRING
:
2180 if (fc
== RPC_FC_C_CSTRING
)
2185 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
2187 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
2189 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2190 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
2191 RpcRaiseException(RPC_S_INVALID_BOUND
);
2193 if (pStubMsg
->Offset
)
2195 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2196 RpcRaiseException(RPC_S_INVALID_BOUND
);
2199 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2200 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2202 validate_string_data(pStubMsg
, bufsize
, esize
);
2204 safe_buffer_increment(pStubMsg
, bufsize
);
2205 pStubMsg
->MemorySize
+= memsize
;
2208 ERR("unknown array format 0x%x\n", fc
);
2209 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2213 static inline void array_free(
2214 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
,
2215 unsigned char *pMemory
, PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
2220 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2222 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2224 case RPC_FC_CVARRAY
:
2225 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2226 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2228 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2230 case RPC_FC_C_CSTRING
:
2231 case RPC_FC_C_WSTRING
:
2232 /* No embedded pointers so nothing to do */
2235 ERR("unknown array format 0x%x\n", fc
);
2236 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2241 * NdrConformantString:
2243 * What MS calls a ConformantString is, in DCE terminology,
2244 * a Varying-Conformant String.
2246 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2247 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2248 * into unmarshalled string)
2249 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2251 * data: CHARTYPE[maxlen]
2253 * ], where CHARTYPE is the appropriate character type (specified externally)
2257 /***********************************************************************
2258 * NdrConformantStringMarshall [RPCRT4.@]
2260 unsigned char *WINAPI
NdrConformantStringMarshall(MIDL_STUB_MESSAGE
*pStubMsg
,
2261 unsigned char *pszMessage
, PFORMAT_STRING pFormat
)
2263 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg
, pszMessage
, pFormat
);
2265 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2266 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2267 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2270 /* allow compiler to optimise inline function by passing constant into
2271 * these functions */
2272 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2273 array_compute_and_write_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pszMessage
,
2275 array_write_variance_and_marshall(RPC_FC_C_CSTRING
, pStubMsg
, pszMessage
,
2276 pFormat
, TRUE
/* fHasPointers */);
2278 array_compute_and_write_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pszMessage
,
2280 array_write_variance_and_marshall(RPC_FC_C_WSTRING
, pStubMsg
, pszMessage
,
2281 pFormat
, TRUE
/* fHasPointers */);
2287 /***********************************************************************
2288 * NdrConformantStringBufferSize [RPCRT4.@]
2290 void WINAPI
NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2291 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
2293 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2295 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2296 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2297 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2300 /* allow compiler to optimise inline function by passing constant into
2301 * these functions */
2302 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2303 array_compute_and_size_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pMemory
,
2305 array_buffer_size(RPC_FC_C_CSTRING
, pStubMsg
, pMemory
, pFormat
,
2306 TRUE
/* fHasPointers */);
2308 array_compute_and_size_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pMemory
,
2310 array_buffer_size(RPC_FC_C_WSTRING
, pStubMsg
, pMemory
, pFormat
,
2311 TRUE
/* fHasPointers */);
2315 /************************************************************************
2316 * NdrConformantStringMemorySize [RPCRT4.@]
2318 ULONG WINAPI
NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
2319 PFORMAT_STRING pFormat
)
2321 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
2323 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2324 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2325 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2328 /* allow compiler to optimise inline function by passing constant into
2329 * these functions */
2330 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2331 array_read_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
);
2332 array_memory_size(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
,
2333 TRUE
/* fHasPointers */);
2335 array_read_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
);
2336 array_memory_size(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
,
2337 TRUE
/* fHasPointers */);
2340 return pStubMsg
->MemorySize
;
2343 /************************************************************************
2344 * NdrConformantStringUnmarshall [RPCRT4.@]
2346 unsigned char *WINAPI
NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2347 unsigned char** ppMemory
, PFORMAT_STRING pFormat
, unsigned char fMustAlloc
)
2349 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2350 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
2352 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2353 ERR("Unhandled string type: %#x\n", *pFormat
);
2354 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2357 /* allow compiler to optimise inline function by passing constant into
2358 * these functions */
2359 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2360 array_read_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
);
2361 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING
, pStubMsg
, ppMemory
,
2362 pFormat
, fMustAlloc
,
2363 TRUE
/* fUseBufferMemoryServer */,
2364 TRUE
/* fUnmarshall */);
2366 array_read_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
);
2367 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING
, pStubMsg
, ppMemory
,
2368 pFormat
, fMustAlloc
,
2369 TRUE
/* fUseBufferMemoryServer */,
2370 TRUE
/* fUnmarshall */);
2376 /***********************************************************************
2377 * NdrNonConformantStringMarshall [RPCRT4.@]
2379 unsigned char * WINAPI
NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2380 unsigned char *pMemory
,
2381 PFORMAT_STRING pFormat
)
2383 ULONG esize
, size
, maxsize
;
2385 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2387 maxsize
= *(USHORT
*)&pFormat
[2];
2389 if (*pFormat
== RPC_FC_CSTRING
)
2392 const char *str
= (const char *)pMemory
;
2393 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
2395 TRACE("string=%s\n", debugstr_an(str
, i
));
2396 pStubMsg
->ActualCount
= i
+ 1;
2399 else if (*pFormat
== RPC_FC_WSTRING
)
2402 const WCHAR
*str
= (const WCHAR
*)pMemory
;
2403 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
2405 TRACE("string=%s\n", debugstr_wn(str
, i
));
2406 pStubMsg
->ActualCount
= i
+ 1;
2411 ERR("Unhandled string type: %#x\n", *pFormat
);
2412 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2415 pStubMsg
->Offset
= 0;
2416 WriteVariance(pStubMsg
);
2418 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2419 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
2424 /***********************************************************************
2425 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2427 unsigned char * WINAPI
NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2428 unsigned char **ppMemory
,
2429 PFORMAT_STRING pFormat
,
2430 unsigned char fMustAlloc
)
2432 ULONG bufsize
, memsize
, esize
, maxsize
;
2434 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2435 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
2437 maxsize
= *(USHORT
*)&pFormat
[2];
2439 ReadVariance(pStubMsg
, NULL
, maxsize
);
2440 if (pStubMsg
->Offset
)
2442 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2443 RpcRaiseException(RPC_S_INVALID_BOUND
);
2446 if (*pFormat
== RPC_FC_CSTRING
) esize
= 1;
2447 else if (*pFormat
== RPC_FC_WSTRING
) esize
= 2;
2450 ERR("Unhandled string type: %#x\n", *pFormat
);
2451 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2454 memsize
= esize
* maxsize
;
2455 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2457 validate_string_data(pStubMsg
, bufsize
, esize
);
2459 if (!fMustAlloc
&& !*ppMemory
)
2462 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2464 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
2466 if (*pFormat
== RPC_FC_CSTRING
) {
2467 TRACE("string=%s\n", debugstr_an((char*)*ppMemory
, pStubMsg
->ActualCount
));
2469 else if (*pFormat
== RPC_FC_WSTRING
) {
2470 TRACE("string=%s\n", debugstr_wn((LPWSTR
)*ppMemory
, pStubMsg
->ActualCount
));
2476 /***********************************************************************
2477 * NdrNonConformantStringBufferSize [RPCRT4.@]
2479 void WINAPI
NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2480 unsigned char *pMemory
,
2481 PFORMAT_STRING pFormat
)
2483 ULONG esize
, maxsize
;
2485 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2487 maxsize
= *(USHORT
*)&pFormat
[2];
2489 SizeVariance(pStubMsg
);
2491 if (*pFormat
== RPC_FC_CSTRING
)
2494 const char *str
= (const char *)pMemory
;
2495 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
2497 TRACE("string=%s\n", debugstr_an(str
, i
));
2498 pStubMsg
->ActualCount
= i
+ 1;
2501 else if (*pFormat
== RPC_FC_WSTRING
)
2504 const WCHAR
*str
= (const WCHAR
*)pMemory
;
2505 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
2507 TRACE("string=%s\n", debugstr_wn(str
, i
));
2508 pStubMsg
->ActualCount
= i
+ 1;
2513 ERR("Unhandled string type: %#x\n", *pFormat
);
2514 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2517 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
2520 /***********************************************************************
2521 * NdrNonConformantStringMemorySize [RPCRT4.@]
2523 ULONG WINAPI
NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2524 PFORMAT_STRING pFormat
)
2526 ULONG bufsize
, memsize
, esize
, maxsize
;
2528 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
2530 maxsize
= *(USHORT
*)&pFormat
[2];
2532 ReadVariance(pStubMsg
, NULL
, maxsize
);
2534 if (pStubMsg
->Offset
)
2536 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2537 RpcRaiseException(RPC_S_INVALID_BOUND
);
2540 if (*pFormat
== RPC_FC_CSTRING
) esize
= 1;
2541 else if (*pFormat
== RPC_FC_WSTRING
) esize
= 2;
2544 ERR("Unhandled string type: %#x\n", *pFormat
);
2545 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2548 memsize
= esize
* maxsize
;
2549 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2551 validate_string_data(pStubMsg
, bufsize
, esize
);
2553 safe_buffer_increment(pStubMsg
, bufsize
);
2554 pStubMsg
->MemorySize
+= memsize
;
2556 return pStubMsg
->MemorySize
;
2561 #include "pshpack1.h"
2565 unsigned char flags_type
; /* flags in upper nibble, type in lower nibble */
2569 #include "poppack.h"
2571 static ULONG
EmbeddedComplexSize(MIDL_STUB_MESSAGE
*pStubMsg
,
2572 PFORMAT_STRING pFormat
)
2576 case RPC_FC_PSTRUCT
:
2577 case RPC_FC_CSTRUCT
:
2578 case RPC_FC_BOGUS_STRUCT
:
2579 case RPC_FC_SMFARRAY
:
2580 case RPC_FC_SMVARRAY
:
2581 case RPC_FC_CSTRING
:
2582 return *(const WORD
*)&pFormat
[2];
2583 case RPC_FC_USER_MARSHAL
:
2584 return *(const WORD
*)&pFormat
[4];
2585 case RPC_FC_RANGE
: {
2586 switch (((const NDR_RANGE
*)pFormat
)->flags_type
& 0xf) {
2591 return sizeof(UCHAR
);
2595 return sizeof(USHORT
);
2599 return sizeof(ULONG
);
2601 return sizeof(float);
2603 return sizeof(double);
2605 return sizeof(ULONGLONG
);
2607 return sizeof(UINT
);
2609 ERR("unknown type 0x%x\n", ((const NDR_RANGE
*)pFormat
)->flags_type
& 0xf);
2610 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2613 case RPC_FC_NON_ENCAPSULATED_UNION
:
2615 if (pStubMsg
->fHasNewCorrDesc
)
2620 pFormat
+= *(const SHORT
*)pFormat
;
2621 return *(const SHORT
*)pFormat
;
2623 return sizeof(void *);
2624 case RPC_FC_WSTRING
:
2625 return *(const WORD
*)&pFormat
[2] * 2;
2627 FIXME("unhandled embedded type %02x\n", *pFormat
);
2633 static ULONG
EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2634 PFORMAT_STRING pFormat
)
2636 NDR_MEMORYSIZE m
= NdrMemorySizer
[*pFormat
& NDR_TABLE_MASK
];
2640 FIXME("no memorysizer for data type=%02x\n", *pFormat
);
2644 return m(pStubMsg
, pFormat
);
2648 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2649 unsigned char *pMemory
,
2650 PFORMAT_STRING pFormat
,
2651 PFORMAT_STRING pPointer
)
2653 PFORMAT_STRING desc
;
2657 while (*pFormat
!= RPC_FC_END
) {
2663 TRACE("byte=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2664 safe_copy_to_buffer(pStubMsg
, pMemory
, 1);
2670 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2671 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
2675 TRACE("enum16=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2676 if (32767 < *(DWORD
*)pMemory
)
2677 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
2678 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
2684 TRACE("long=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2685 safe_copy_to_buffer(pStubMsg
, pMemory
, 4);
2689 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2690 safe_copy_to_buffer(pStubMsg
, pMemory
, 8);
2693 case RPC_FC_POINTER
:
2695 unsigned char *saved_buffer
;
2696 int pointer_buffer_mark_set
= 0;
2697 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
2698 TRACE("pStubMsg->Buffer before %p\n", pStubMsg
->Buffer
);
2699 if (*pPointer
!= RPC_FC_RP
)
2700 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
2701 saved_buffer
= pStubMsg
->Buffer
;
2702 if (pStubMsg
->PointerBufferMark
)
2704 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2705 pStubMsg
->PointerBufferMark
= NULL
;
2706 pointer_buffer_mark_set
= 1;
2708 else if (*pPointer
!= RPC_FC_RP
)
2709 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2710 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char**)pMemory
, pPointer
);
2711 if (pointer_buffer_mark_set
)
2713 STD_OVERFLOW_CHECK(pStubMsg
);
2714 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2715 pStubMsg
->Buffer
= saved_buffer
;
2716 if (*pPointer
!= RPC_FC_RP
)
2717 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2719 TRACE("pStubMsg->Buffer after %p\n", pStubMsg
->Buffer
);
2724 case RPC_FC_ALIGNM4
:
2725 ALIGN_POINTER(pMemory
, 4);
2727 case RPC_FC_ALIGNM8
:
2728 ALIGN_POINTER(pMemory
, 8);
2730 case RPC_FC_STRUCTPAD1
:
2731 case RPC_FC_STRUCTPAD2
:
2732 case RPC_FC_STRUCTPAD3
:
2733 case RPC_FC_STRUCTPAD4
:
2734 case RPC_FC_STRUCTPAD5
:
2735 case RPC_FC_STRUCTPAD6
:
2736 case RPC_FC_STRUCTPAD7
:
2737 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2739 case RPC_FC_EMBEDDED_COMPLEX
:
2740 pMemory
+= pFormat
[1];
2742 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2743 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2744 TRACE("embedded complex (size=%d) <= %p\n", size
, pMemory
);
2745 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
2748 /* for some reason interface pointers aren't generated as
2749 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2750 * they still need the derefencing treatment that pointers are
2752 if (*desc
== RPC_FC_IP
)
2753 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2755 m(pStubMsg
, pMemory
, desc
);
2757 else FIXME("no marshaller for embedded type %02x\n", *desc
);
2764 FIXME("unhandled format 0x%02x\n", *pFormat
);
2772 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2773 unsigned char *pMemory
,
2774 PFORMAT_STRING pFormat
,
2775 PFORMAT_STRING pPointer
,
2776 unsigned char fMustAlloc
)
2778 PFORMAT_STRING desc
;
2782 while (*pFormat
!= RPC_FC_END
) {
2788 safe_copy_from_buffer(pStubMsg
, pMemory
, 1);
2789 TRACE("byte=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2795 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
2796 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2800 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
2801 *(DWORD
*)pMemory
&= 0xffff;
2802 TRACE("enum16=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
2803 if (32767 < *(DWORD
*)pMemory
)
2804 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
2810 safe_copy_from_buffer(pStubMsg
, pMemory
, 4);
2811 TRACE("long=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
2815 safe_copy_from_buffer(pStubMsg
, pMemory
, 8);
2816 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2819 case RPC_FC_POINTER
:
2821 unsigned char *saved_buffer
;
2822 int pointer_buffer_mark_set
= 0;
2823 TRACE("pointer => %p\n", pMemory
);
2824 if (*pPointer
!= RPC_FC_RP
)
2825 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2826 saved_buffer
= pStubMsg
->Buffer
;
2827 if (pStubMsg
->PointerBufferMark
)
2829 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2830 pStubMsg
->PointerBufferMark
= NULL
;
2831 pointer_buffer_mark_set
= 1;
2833 else if (*pPointer
!= RPC_FC_RP
)
2834 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2836 PointerUnmarshall(pStubMsg
, saved_buffer
, (unsigned char**)pMemory
, *(unsigned char**)pMemory
, pPointer
, fMustAlloc
);
2837 if (pointer_buffer_mark_set
)
2839 STD_OVERFLOW_CHECK(pStubMsg
);
2840 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2841 pStubMsg
->Buffer
= saved_buffer
;
2842 if (*pPointer
!= RPC_FC_RP
)
2843 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2849 case RPC_FC_ALIGNM4
:
2850 ALIGN_POINTER_CLEAR(pMemory
, 4);
2852 case RPC_FC_ALIGNM8
:
2853 ALIGN_POINTER_CLEAR(pMemory
, 8);
2855 case RPC_FC_STRUCTPAD1
:
2856 case RPC_FC_STRUCTPAD2
:
2857 case RPC_FC_STRUCTPAD3
:
2858 case RPC_FC_STRUCTPAD4
:
2859 case RPC_FC_STRUCTPAD5
:
2860 case RPC_FC_STRUCTPAD6
:
2861 case RPC_FC_STRUCTPAD7
:
2862 memset(pMemory
, 0, *pFormat
- RPC_FC_STRUCTPAD1
+ 1);
2863 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2865 case RPC_FC_EMBEDDED_COMPLEX
:
2866 pMemory
+= pFormat
[1];
2868 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2869 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2870 TRACE("embedded complex (size=%d) => %p\n", size
, pMemory
);
2872 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
2873 * since the type is part of the memory block that is encompassed by
2874 * the whole complex type. Memory is forced to allocate when pointers
2875 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
2876 * clearing the memory we pass in to the unmarshaller */
2877 memset(pMemory
, 0, size
);
2878 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
2881 /* for some reason interface pointers aren't generated as
2882 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2883 * they still need the derefencing treatment that pointers are
2885 if (*desc
== RPC_FC_IP
)
2886 m(pStubMsg
, (unsigned char **)pMemory
, desc
, FALSE
);
2888 m(pStubMsg
, &pMemory
, desc
, FALSE
);
2890 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
2897 FIXME("unhandled format %d\n", *pFormat
);
2905 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2906 unsigned char *pMemory
,
2907 PFORMAT_STRING pFormat
,
2908 PFORMAT_STRING pPointer
)
2910 PFORMAT_STRING desc
;
2914 while (*pFormat
!= RPC_FC_END
) {
2920 safe_buffer_length_increment(pStubMsg
, 1);
2926 safe_buffer_length_increment(pStubMsg
, 2);
2930 safe_buffer_length_increment(pStubMsg
, 2);
2936 safe_buffer_length_increment(pStubMsg
, 4);
2940 safe_buffer_length_increment(pStubMsg
, 8);
2943 case RPC_FC_POINTER
:
2944 if (!pStubMsg
->IgnoreEmbeddedPointers
)
2946 int saved_buffer_length
= pStubMsg
->BufferLength
;
2947 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2948 pStubMsg
->PointerLength
= 0;
2949 if(!pStubMsg
->BufferLength
)
2950 ERR("BufferLength == 0??\n");
2951 PointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
2952 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2953 pStubMsg
->BufferLength
= saved_buffer_length
;
2955 if (*pPointer
!= RPC_FC_RP
)
2957 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
2958 safe_buffer_length_increment(pStubMsg
, 4);
2963 case RPC_FC_ALIGNM4
:
2964 ALIGN_POINTER(pMemory
, 4);
2966 case RPC_FC_ALIGNM8
:
2967 ALIGN_POINTER(pMemory
, 8);
2969 case RPC_FC_STRUCTPAD1
:
2970 case RPC_FC_STRUCTPAD2
:
2971 case RPC_FC_STRUCTPAD3
:
2972 case RPC_FC_STRUCTPAD4
:
2973 case RPC_FC_STRUCTPAD5
:
2974 case RPC_FC_STRUCTPAD6
:
2975 case RPC_FC_STRUCTPAD7
:
2976 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2978 case RPC_FC_EMBEDDED_COMPLEX
:
2979 pMemory
+= pFormat
[1];
2981 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2982 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2983 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
2986 /* for some reason interface pointers aren't generated as
2987 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2988 * they still need the derefencing treatment that pointers are
2990 if (*desc
== RPC_FC_IP
)
2991 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2993 m(pStubMsg
, pMemory
, desc
);
2995 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
3002 FIXME("unhandled format 0x%02x\n", *pFormat
);
3010 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
3011 unsigned char *pMemory
,
3012 PFORMAT_STRING pFormat
,
3013 PFORMAT_STRING pPointer
)
3015 PFORMAT_STRING desc
;
3019 while (*pFormat
!= RPC_FC_END
) {
3041 case RPC_FC_POINTER
:
3042 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
3046 case RPC_FC_ALIGNM4
:
3047 ALIGN_POINTER(pMemory
, 4);
3049 case RPC_FC_ALIGNM8
:
3050 ALIGN_POINTER(pMemory
, 8);
3052 case RPC_FC_STRUCTPAD1
:
3053 case RPC_FC_STRUCTPAD2
:
3054 case RPC_FC_STRUCTPAD3
:
3055 case RPC_FC_STRUCTPAD4
:
3056 case RPC_FC_STRUCTPAD5
:
3057 case RPC_FC_STRUCTPAD6
:
3058 case RPC_FC_STRUCTPAD7
:
3059 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3061 case RPC_FC_EMBEDDED_COMPLEX
:
3062 pMemory
+= pFormat
[1];
3064 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3065 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3066 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
3069 /* for some reason interface pointers aren't generated as
3070 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3071 * they still need the derefencing treatment that pointers are
3073 if (*desc
== RPC_FC_IP
)
3074 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
3076 m(pStubMsg
, pMemory
, desc
);
3084 FIXME("unhandled format 0x%02x\n", *pFormat
);
3092 static ULONG
ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3093 PFORMAT_STRING pFormat
,
3094 PFORMAT_STRING pPointer
)
3096 PFORMAT_STRING desc
;
3099 while (*pFormat
!= RPC_FC_END
) {
3106 safe_buffer_increment(pStubMsg
, 1);
3112 safe_buffer_increment(pStubMsg
, 2);
3116 safe_buffer_increment(pStubMsg
, 2);
3122 safe_buffer_increment(pStubMsg
, 4);
3126 safe_buffer_increment(pStubMsg
, 8);
3128 case RPC_FC_POINTER
:
3130 unsigned char *saved_buffer
;
3131 int pointer_buffer_mark_set
= 0;
3132 if (*pPointer
!= RPC_FC_RP
)
3133 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3134 saved_buffer
= pStubMsg
->Buffer
;
3135 if (pStubMsg
->PointerBufferMark
)
3137 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3138 pStubMsg
->PointerBufferMark
= NULL
;
3139 pointer_buffer_mark_set
= 1;
3141 else if (*pPointer
!= RPC_FC_RP
)
3142 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3144 if (!pStubMsg
->IgnoreEmbeddedPointers
)
3145 PointerMemorySize(pStubMsg
, saved_buffer
, pPointer
);
3146 if (pointer_buffer_mark_set
)
3148 STD_OVERFLOW_CHECK(pStubMsg
);
3149 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3150 pStubMsg
->Buffer
= saved_buffer
;
3151 if (*pPointer
!= RPC_FC_RP
)
3152 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3158 case RPC_FC_ALIGNM4
:
3159 ALIGN_LENGTH(size
, 4);
3161 case RPC_FC_ALIGNM8
:
3162 ALIGN_LENGTH(size
, 8);
3164 case RPC_FC_STRUCTPAD1
:
3165 case RPC_FC_STRUCTPAD2
:
3166 case RPC_FC_STRUCTPAD3
:
3167 case RPC_FC_STRUCTPAD4
:
3168 case RPC_FC_STRUCTPAD5
:
3169 case RPC_FC_STRUCTPAD6
:
3170 case RPC_FC_STRUCTPAD7
:
3171 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3173 case RPC_FC_EMBEDDED_COMPLEX
:
3176 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3177 size
+= EmbeddedComplexMemorySize(pStubMsg
, desc
);
3183 FIXME("unhandled format 0x%02x\n", *pFormat
);
3191 ULONG
ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
3193 PFORMAT_STRING desc
;
3196 while (*pFormat
!= RPC_FC_END
) {
3218 case RPC_FC_POINTER
:
3219 size
+= sizeof(void *);
3221 case RPC_FC_ALIGNM4
:
3222 ALIGN_LENGTH(size
, 4);
3224 case RPC_FC_ALIGNM8
:
3225 ALIGN_LENGTH(size
, 8);
3227 case RPC_FC_STRUCTPAD1
:
3228 case RPC_FC_STRUCTPAD2
:
3229 case RPC_FC_STRUCTPAD3
:
3230 case RPC_FC_STRUCTPAD4
:
3231 case RPC_FC_STRUCTPAD5
:
3232 case RPC_FC_STRUCTPAD6
:
3233 case RPC_FC_STRUCTPAD7
:
3234 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3236 case RPC_FC_EMBEDDED_COMPLEX
:
3239 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3240 size
+= EmbeddedComplexSize(pStubMsg
, desc
);
3246 FIXME("unhandled format 0x%02x\n", *pFormat
);
3254 /***********************************************************************
3255 * NdrComplexStructMarshall [RPCRT4.@]
3257 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3258 unsigned char *pMemory
,
3259 PFORMAT_STRING pFormat
)
3261 PFORMAT_STRING conf_array
= NULL
;
3262 PFORMAT_STRING pointer_desc
= NULL
;
3263 unsigned char *OldMemory
= pStubMsg
->Memory
;
3264 int pointer_buffer_mark_set
= 0;
3266 ULONG max_count
= 0;
3269 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3271 if (!pStubMsg
->PointerBufferMark
)
3273 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3274 /* save buffer length */
3275 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
3277 /* get the buffer pointer after complex array data, but before
3279 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
;
3280 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3281 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
3282 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3284 /* save it for use by embedded pointer code later */
3285 pStubMsg
->PointerBufferMark
= (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
;
3286 TRACE("difference = 0x%x\n", pStubMsg
->PointerBufferMark
- pStubMsg
->Buffer
);
3287 pointer_buffer_mark_set
= 1;
3289 /* restore the original buffer length */
3290 pStubMsg
->BufferLength
= saved_buffer_length
;
3293 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pFormat
[1] + 1);
3296 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3298 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3301 pStubMsg
->Memory
= pMemory
;
3305 ULONG struct_size
= ComplexStructSize(pStubMsg
, pFormat
);
3306 array_compute_and_write_conformance(conf_array
[0], pStubMsg
,
3307 pMemory
+ struct_size
, conf_array
);
3308 /* these could be changed in ComplexMarshall so save them for later */
3309 max_count
= pStubMsg
->MaxCount
;
3310 count
= pStubMsg
->ActualCount
;
3311 offset
= pStubMsg
->Offset
;
3314 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3318 pStubMsg
->MaxCount
= max_count
;
3319 pStubMsg
->ActualCount
= count
;
3320 pStubMsg
->Offset
= offset
;
3321 array_write_variance_and_marshall(conf_array
[0], pStubMsg
, pMemory
,
3322 conf_array
, TRUE
/* fHasPointers */);
3325 pStubMsg
->Memory
= OldMemory
;
3327 if (pointer_buffer_mark_set
)
3329 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3330 pStubMsg
->PointerBufferMark
= NULL
;
3333 STD_OVERFLOW_CHECK(pStubMsg
);
3338 /***********************************************************************
3339 * NdrComplexStructUnmarshall [RPCRT4.@]
3341 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3342 unsigned char **ppMemory
,
3343 PFORMAT_STRING pFormat
,
3344 unsigned char fMustAlloc
)
3346 unsigned size
= *(const WORD
*)(pFormat
+2);
3347 PFORMAT_STRING conf_array
= NULL
;
3348 PFORMAT_STRING pointer_desc
= NULL
;
3349 unsigned char *pMemory
;
3350 int pointer_buffer_mark_set
= 0;
3352 ULONG max_count
= 0;
3354 ULONG array_size
= 0;
3356 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3358 if (!pStubMsg
->PointerBufferMark
)
3360 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3361 /* save buffer pointer */
3362 unsigned char *saved_buffer
= pStubMsg
->Buffer
;
3364 /* get the buffer pointer after complex array data, but before
3366 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3367 NdrComplexStructMemorySize(pStubMsg
, pFormat
);
3368 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3370 /* save it for use by embedded pointer code later */
3371 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3372 TRACE("difference = 0x%x\n", pStubMsg
->PointerBufferMark
- saved_buffer
);
3373 pointer_buffer_mark_set
= 1;
3375 /* restore the original buffer */
3376 pStubMsg
->Buffer
= saved_buffer
;
3379 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
3382 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3384 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3389 array_size
= array_read_conformance(conf_array
[0], pStubMsg
, conf_array
);
3392 /* these could be changed in ComplexMarshall so save them for later */
3393 max_count
= pStubMsg
->MaxCount
;
3394 count
= pStubMsg
->ActualCount
;
3395 offset
= pStubMsg
->Offset
;
3398 if (!fMustAlloc
&& !*ppMemory
)
3401 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3403 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
, fMustAlloc
);
3407 pStubMsg
->MaxCount
= max_count
;
3408 pStubMsg
->ActualCount
= count
;
3409 pStubMsg
->Offset
= offset
;
3411 memset(pMemory
, 0, array_size
);
3412 array_read_variance_and_unmarshall(conf_array
[0], pStubMsg
, &pMemory
,
3414 FALSE
/* fUseBufferMemoryServer */,
3415 TRUE
/* fUnmarshall */);
3418 if (pointer_buffer_mark_set
)
3420 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3421 pStubMsg
->PointerBufferMark
= NULL
;
3427 /***********************************************************************
3428 * NdrComplexStructBufferSize [RPCRT4.@]
3430 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3431 unsigned char *pMemory
,
3432 PFORMAT_STRING pFormat
)
3434 PFORMAT_STRING conf_array
= NULL
;
3435 PFORMAT_STRING pointer_desc
= NULL
;
3436 unsigned char *OldMemory
= pStubMsg
->Memory
;
3437 int pointer_length_set
= 0;
3439 ULONG max_count
= 0;
3442 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3444 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
3446 if(!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
3448 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3449 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
3451 /* get the buffer length after complex struct data, but before
3453 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3454 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
3455 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3457 /* save it for use by embedded pointer code later */
3458 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3459 pointer_length_set
= 1;
3460 TRACE("difference = 0x%x\n", pStubMsg
->PointerLength
- saved_buffer_length
);
3462 /* restore the original buffer length */
3463 pStubMsg
->BufferLength
= saved_buffer_length
;
3467 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3469 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3472 pStubMsg
->Memory
= pMemory
;
3476 ULONG struct_size
= ComplexStructSize(pStubMsg
, pFormat
);
3477 array_compute_and_size_conformance(conf_array
[0], pStubMsg
, pMemory
+ struct_size
,
3480 /* these could be changed in ComplexMarshall so save them for later */
3481 max_count
= pStubMsg
->MaxCount
;
3482 count
= pStubMsg
->ActualCount
;
3483 offset
= pStubMsg
->Offset
;
3486 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3490 pStubMsg
->MaxCount
= max_count
;
3491 pStubMsg
->ActualCount
= count
;
3492 pStubMsg
->Offset
= offset
;
3493 array_buffer_size(conf_array
[0], pStubMsg
, pMemory
, conf_array
,
3494 TRUE
/* fHasPointers */);
3497 pStubMsg
->Memory
= OldMemory
;
3499 if(pointer_length_set
)
3501 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3502 pStubMsg
->PointerLength
= 0;
3507 /***********************************************************************
3508 * NdrComplexStructMemorySize [RPCRT4.@]
3510 ULONG WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3511 PFORMAT_STRING pFormat
)
3513 unsigned size
= *(const WORD
*)(pFormat
+2);
3514 PFORMAT_STRING conf_array
= NULL
;
3515 PFORMAT_STRING pointer_desc
= NULL
;
3517 ULONG max_count
= 0;
3520 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3522 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
3525 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3527 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3532 array_read_conformance(conf_array
[0], pStubMsg
, conf_array
);
3534 /* these could be changed in ComplexStructMemorySize so save them for
3536 max_count
= pStubMsg
->MaxCount
;
3537 count
= pStubMsg
->ActualCount
;
3538 offset
= pStubMsg
->Offset
;
3541 ComplexStructMemorySize(pStubMsg
, pFormat
, pointer_desc
);
3545 pStubMsg
->MaxCount
= max_count
;
3546 pStubMsg
->ActualCount
= count
;
3547 pStubMsg
->Offset
= offset
;
3548 array_memory_size(conf_array
[0], pStubMsg
, conf_array
,
3549 TRUE
/* fHasPointers */);
3555 /***********************************************************************
3556 * NdrComplexStructFree [RPCRT4.@]
3558 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3559 unsigned char *pMemory
,
3560 PFORMAT_STRING pFormat
)
3562 PFORMAT_STRING conf_array
= NULL
;
3563 PFORMAT_STRING pointer_desc
= NULL
;
3564 unsigned char *OldMemory
= pStubMsg
->Memory
;
3566 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3569 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3571 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3574 pStubMsg
->Memory
= pMemory
;
3576 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3579 array_free(conf_array
[0], pStubMsg
, pMemory
, conf_array
,
3580 TRUE
/* fHasPointers */);
3582 pStubMsg
->Memory
= OldMemory
;
3585 /***********************************************************************
3586 * NdrConformantArrayMarshall [RPCRT4.@]
3588 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3589 unsigned char *pMemory
,
3590 PFORMAT_STRING pFormat
)
3592 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3593 if (pFormat
[0] != RPC_FC_CARRAY
)
3595 ERR("invalid format = 0x%x\n", pFormat
[0]);
3596 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3599 array_compute_and_write_conformance(RPC_FC_CARRAY
, pStubMsg
, pMemory
,
3601 array_write_variance_and_marshall(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3602 TRUE
/* fHasPointers */);
3607 /***********************************************************************
3608 * NdrConformantArrayUnmarshall [RPCRT4.@]
3610 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3611 unsigned char **ppMemory
,
3612 PFORMAT_STRING pFormat
,
3613 unsigned char fMustAlloc
)
3615 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3616 if (pFormat
[0] != RPC_FC_CARRAY
)
3618 ERR("invalid format = 0x%x\n", pFormat
[0]);
3619 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3622 array_read_conformance(RPC_FC_CARRAY
, pStubMsg
, pFormat
);
3623 array_read_variance_and_unmarshall(RPC_FC_CARRAY
, pStubMsg
, ppMemory
, pFormat
,
3625 TRUE
/* fUseBufferMemoryServer */,
3626 TRUE
/* fUnmarshall */);
3631 /***********************************************************************
3632 * NdrConformantArrayBufferSize [RPCRT4.@]
3634 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3635 unsigned char *pMemory
,
3636 PFORMAT_STRING pFormat
)
3638 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3639 if (pFormat
[0] != RPC_FC_CARRAY
)
3641 ERR("invalid format = 0x%x\n", pFormat
[0]);
3642 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3645 array_compute_and_size_conformance(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
);
3646 array_buffer_size(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3647 TRUE
/* fHasPointers */);
3650 /***********************************************************************
3651 * NdrConformantArrayMemorySize [RPCRT4.@]
3653 ULONG WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3654 PFORMAT_STRING pFormat
)
3656 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3657 if (pFormat
[0] != RPC_FC_CARRAY
)
3659 ERR("invalid format = 0x%x\n", pFormat
[0]);
3660 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3663 array_read_conformance(RPC_FC_CARRAY
, pStubMsg
, pFormat
);
3664 array_memory_size(RPC_FC_CARRAY
, pStubMsg
, pFormat
, TRUE
/* fHasPointers */);
3666 return pStubMsg
->MemorySize
;
3669 /***********************************************************************
3670 * NdrConformantArrayFree [RPCRT4.@]
3672 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3673 unsigned char *pMemory
,
3674 PFORMAT_STRING pFormat
)
3676 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3677 if (pFormat
[0] != RPC_FC_CARRAY
)
3679 ERR("invalid format = 0x%x\n", pFormat
[0]);
3680 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3683 array_free(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3684 TRUE
/* fHasPointers */);
3688 /***********************************************************************
3689 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3691 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
3692 unsigned char* pMemory
,
3693 PFORMAT_STRING pFormat
)
3695 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3697 if (pFormat
[0] != RPC_FC_CVARRAY
)
3699 ERR("invalid format type %x\n", pFormat
[0]);
3700 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3704 array_compute_and_write_conformance(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
3706 array_write_variance_and_marshall(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
3707 pFormat
, TRUE
/* fHasPointers */);
3713 /***********************************************************************
3714 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
3716 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
3717 unsigned char** ppMemory
,
3718 PFORMAT_STRING pFormat
,
3719 unsigned char fMustAlloc
)
3721 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3723 if (pFormat
[0] != RPC_FC_CVARRAY
)
3725 ERR("invalid format type %x\n", pFormat
[0]);
3726 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3730 array_read_conformance(RPC_FC_CVARRAY
, pStubMsg
, pFormat
);
3731 array_read_variance_and_unmarshall(RPC_FC_CVARRAY
, pStubMsg
, ppMemory
,
3732 pFormat
, fMustAlloc
,
3733 TRUE
/* fUseBufferMemoryServer */,
3734 TRUE
/* fUnmarshall */);
3740 /***********************************************************************
3741 * NdrConformantVaryingArrayFree [RPCRT4.@]
3743 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
3744 unsigned char* pMemory
,
3745 PFORMAT_STRING pFormat
)
3747 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3749 if (pFormat
[0] != RPC_FC_CVARRAY
)
3751 ERR("invalid format type %x\n", pFormat
[0]);
3752 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3756 array_free(RPC_FC_CVARRAY
, pStubMsg
, pMemory
, pFormat
,
3757 TRUE
/* fHasPointers */);
3761 /***********************************************************************
3762 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
3764 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
3765 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
3767 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3769 if (pFormat
[0] != RPC_FC_CVARRAY
)
3771 ERR("invalid format type %x\n", pFormat
[0]);
3772 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3776 array_compute_and_size_conformance(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
3778 array_buffer_size(RPC_FC_CVARRAY
, pStubMsg
, pMemory
, pFormat
,
3779 TRUE
/* fHasPointers */);
3783 /***********************************************************************
3784 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
3786 ULONG WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
3787 PFORMAT_STRING pFormat
)
3789 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
3791 if (pFormat
[0] != RPC_FC_CVARRAY
)
3793 ERR("invalid format type %x\n", pFormat
[0]);
3794 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3795 return pStubMsg
->MemorySize
;
3798 array_read_conformance(RPC_FC_CVARRAY
, pStubMsg
, pFormat
);
3799 array_memory_size(RPC_FC_CVARRAY
, pStubMsg
, pFormat
,
3800 TRUE
/* fHasPointers */);
3802 return pStubMsg
->MemorySize
;
3806 /***********************************************************************
3807 * NdrComplexArrayMarshall [RPCRT4.@]
3809 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3810 unsigned char *pMemory
,
3811 PFORMAT_STRING pFormat
)
3813 ULONG i
, count
, def
;
3814 BOOL variance_present
;
3815 unsigned char alignment
;
3816 int pointer_buffer_mark_set
= 0;
3818 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3820 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3822 ERR("invalid format type %x\n", pFormat
[0]);
3823 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3827 alignment
= pFormat
[1] + 1;
3829 if (!pStubMsg
->PointerBufferMark
)
3831 /* save buffer fields that may be changed by buffer sizer functions
3832 * and that may be needed later on */
3833 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3834 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
3835 ULONG_PTR saved_max_count
= pStubMsg
->MaxCount
;
3836 ULONG saved_offset
= pStubMsg
->Offset
;
3837 ULONG saved_actual_count
= pStubMsg
->ActualCount
;
3839 /* get the buffer pointer after complex array data, but before
3841 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
;
3842 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3843 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
3844 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3846 /* save it for use by embedded pointer code later */
3847 pStubMsg
->PointerBufferMark
= (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
;
3848 TRACE("difference = 0x%x\n", pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
);
3849 pointer_buffer_mark_set
= 1;
3851 /* restore fields */
3852 pStubMsg
->ActualCount
= saved_actual_count
;
3853 pStubMsg
->Offset
= saved_offset
;
3854 pStubMsg
->MaxCount
= saved_max_count
;
3855 pStubMsg
->BufferLength
= saved_buffer_length
;
3858 def
= *(const WORD
*)&pFormat
[2];
3861 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3862 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3864 variance_present
= IsConformanceOrVariancePresent(pFormat
);
3865 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3866 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3868 WriteConformance(pStubMsg
);
3869 if (variance_present
)
3870 WriteVariance(pStubMsg
);
3872 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
3874 count
= pStubMsg
->ActualCount
;
3875 for (i
= 0; i
< count
; i
++)
3876 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
3878 STD_OVERFLOW_CHECK(pStubMsg
);
3880 if (pointer_buffer_mark_set
)
3882 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3883 pStubMsg
->PointerBufferMark
= NULL
;
3889 /***********************************************************************
3890 * NdrComplexArrayUnmarshall [RPCRT4.@]
3892 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3893 unsigned char **ppMemory
,
3894 PFORMAT_STRING pFormat
,
3895 unsigned char fMustAlloc
)
3897 ULONG i
, count
, size
;
3898 unsigned char alignment
;
3899 unsigned char *pMemory
;
3900 unsigned char *saved_buffer
;
3901 int pointer_buffer_mark_set
= 0;
3902 int saved_ignore_embedded
;
3904 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3906 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3908 ERR("invalid format type %x\n", pFormat
[0]);
3909 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3913 alignment
= pFormat
[1] + 1;
3915 saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3916 /* save buffer pointer */
3917 saved_buffer
= pStubMsg
->Buffer
;
3918 /* get the buffer pointer after complex array data, but before
3920 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3921 pStubMsg
->MemorySize
= 0;
3922 NdrComplexArrayMemorySize(pStubMsg
, pFormat
);
3923 size
= pStubMsg
->MemorySize
;
3924 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3926 TRACE("difference = 0x%x\n", pStubMsg
->Buffer
- saved_buffer
);
3927 if (!pStubMsg
->PointerBufferMark
)
3929 /* save it for use by embedded pointer code later */
3930 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3931 pointer_buffer_mark_set
= 1;
3933 /* restore the original buffer */
3934 pStubMsg
->Buffer
= saved_buffer
;
3938 pFormat
= ReadConformance(pStubMsg
, pFormat
);
3939 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3941 if (!fMustAlloc
&& !*ppMemory
)
3944 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3946 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3948 pMemory
= *ppMemory
;
3949 count
= pStubMsg
->ActualCount
;
3950 for (i
= 0; i
< count
; i
++)
3951 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
, fMustAlloc
);
3953 if (pointer_buffer_mark_set
)
3955 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3956 pStubMsg
->PointerBufferMark
= NULL
;
3962 /***********************************************************************
3963 * NdrComplexArrayBufferSize [RPCRT4.@]
3965 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3966 unsigned char *pMemory
,
3967 PFORMAT_STRING pFormat
)
3969 ULONG i
, count
, def
;
3970 unsigned char alignment
;
3971 BOOL variance_present
;
3972 int pointer_length_set
= 0;
3974 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3976 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3978 ERR("invalid format type %x\n", pFormat
[0]);
3979 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3983 alignment
= pFormat
[1] + 1;
3985 if (!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
3987 /* save buffer fields that may be changed by buffer sizer functions
3988 * and that may be needed later on */
3989 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3990 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
3991 ULONG_PTR saved_max_count
= pStubMsg
->MaxCount
;
3992 ULONG saved_offset
= pStubMsg
->Offset
;
3993 ULONG saved_actual_count
= pStubMsg
->ActualCount
;
3995 /* get the buffer pointer after complex array data, but before
3997 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3998 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
3999 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
4001 /* save it for use by embedded pointer code later */
4002 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4003 pointer_length_set
= 1;
4005 /* restore fields */
4006 pStubMsg
->ActualCount
= saved_actual_count
;
4007 pStubMsg
->Offset
= saved_offset
;
4008 pStubMsg
->MaxCount
= saved_max_count
;
4009 pStubMsg
->BufferLength
= saved_buffer_length
;
4011 def
= *(const WORD
*)&pFormat
[2];
4014 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
4015 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
4016 SizeConformance(pStubMsg
);
4018 variance_present
= IsConformanceOrVariancePresent(pFormat
);
4019 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
4020 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
4022 if (variance_present
)
4023 SizeVariance(pStubMsg
);
4025 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
4027 count
= pStubMsg
->ActualCount
;
4028 for (i
= 0; i
< count
; i
++)
4029 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
4031 if(pointer_length_set
)
4033 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4034 pStubMsg
->PointerLength
= 0;
4038 /***********************************************************************
4039 * NdrComplexArrayMemorySize [RPCRT4.@]
4041 ULONG WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4042 PFORMAT_STRING pFormat
)
4044 ULONG i
, count
, esize
, SavedMemorySize
, MemorySize
;
4045 unsigned char alignment
;
4047 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
4049 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4051 ERR("invalid format type %x\n", pFormat
[0]);
4052 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4056 alignment
= pFormat
[1] + 1;
4060 pFormat
= ReadConformance(pStubMsg
, pFormat
);
4061 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
4063 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4065 SavedMemorySize
= pStubMsg
->MemorySize
;
4067 esize
= ComplexStructSize(pStubMsg
, pFormat
);
4069 MemorySize
= safe_multiply(pStubMsg
->MaxCount
, esize
);
4071 count
= pStubMsg
->ActualCount
;
4072 for (i
= 0; i
< count
; i
++)
4073 ComplexStructMemorySize(pStubMsg
, pFormat
, NULL
);
4075 pStubMsg
->MemorySize
= SavedMemorySize
;
4077 pStubMsg
->MemorySize
+= MemorySize
;
4081 /***********************************************************************
4082 * NdrComplexArrayFree [RPCRT4.@]
4084 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4085 unsigned char *pMemory
,
4086 PFORMAT_STRING pFormat
)
4088 ULONG i
, count
, def
;
4090 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4092 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4094 ERR("invalid format type %x\n", pFormat
[0]);
4095 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4099 def
= *(const WORD
*)&pFormat
[2];
4102 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
4103 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
4105 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
4106 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
4108 count
= pStubMsg
->ActualCount
;
4109 for (i
= 0; i
< count
; i
++)
4110 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
4113 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg
,
4114 USER_MARSHAL_CB_TYPE cbtype
, PFORMAT_STRING pFormat
,
4115 USER_MARSHAL_CB
*umcb
)
4117 umcb
->Flags
= MAKELONG(pStubMsg
->dwDestContext
,
4118 pStubMsg
->RpcMsg
->DataRepresentation
);
4119 umcb
->pStubMsg
= pStubMsg
;
4120 umcb
->pReserve
= NULL
;
4121 umcb
->Signature
= USER_MARSHAL_CB_SIGNATURE
;
4122 umcb
->CBType
= cbtype
;
4123 umcb
->pFormat
= pFormat
;
4124 umcb
->pTypeFormat
= NULL
/* FIXME */;
4127 #define USER_MARSHAL_PTR_PREFIX \
4128 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4129 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4131 /***********************************************************************
4132 * NdrUserMarshalMarshall [RPCRT4.@]
4134 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4135 unsigned char *pMemory
,
4136 PFORMAT_STRING pFormat
)
4138 unsigned flags
= pFormat
[1];
4139 unsigned index
= *(const WORD
*)&pFormat
[2];
4140 unsigned char *saved_buffer
= NULL
;
4141 USER_MARSHAL_CB umcb
;
4143 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4144 TRACE("index=%d\n", index
);
4146 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_MARSHALL
, pFormat
, &umcb
);
4148 if (flags
& USER_MARSHAL_POINTER
)
4150 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
4151 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, USER_MARSHAL_PTR_PREFIX
);
4152 pStubMsg
->Buffer
+= 4;
4153 if (pStubMsg
->PointerBufferMark
)
4155 saved_buffer
= pStubMsg
->Buffer
;
4156 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4157 pStubMsg
->PointerBufferMark
= NULL
;
4159 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 8);
4162 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4165 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
4166 &umcb
.Flags
, pStubMsg
->Buffer
, pMemory
);
4170 STD_OVERFLOW_CHECK(pStubMsg
);
4171 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4172 pStubMsg
->Buffer
= saved_buffer
;
4175 STD_OVERFLOW_CHECK(pStubMsg
);
4180 /***********************************************************************
4181 * NdrUserMarshalUnmarshall [RPCRT4.@]
4183 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4184 unsigned char **ppMemory
,
4185 PFORMAT_STRING pFormat
,
4186 unsigned char fMustAlloc
)
4188 unsigned flags
= pFormat
[1];
4189 unsigned index
= *(const WORD
*)&pFormat
[2];
4190 DWORD memsize
= *(const WORD
*)&pFormat
[4];
4191 unsigned char *saved_buffer
= NULL
;
4192 USER_MARSHAL_CB umcb
;
4194 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4195 TRACE("index=%d\n", index
);
4197 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_UNMARSHALL
, pFormat
, &umcb
);
4199 if (flags
& USER_MARSHAL_POINTER
)
4201 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4202 /* skip pointer prefix */
4203 pStubMsg
->Buffer
+= 4;
4204 if (pStubMsg
->PointerBufferMark
)
4206 saved_buffer
= pStubMsg
->Buffer
;
4207 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4208 pStubMsg
->PointerBufferMark
= NULL
;
4210 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
4213 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4215 if (!fMustAlloc
&& !*ppMemory
)
4219 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
4220 memset(*ppMemory
, 0, memsize
);
4224 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
4225 &umcb
.Flags
, pStubMsg
->Buffer
, *ppMemory
);
4229 STD_OVERFLOW_CHECK(pStubMsg
);
4230 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4231 pStubMsg
->Buffer
= saved_buffer
;
4237 /***********************************************************************
4238 * NdrUserMarshalBufferSize [RPCRT4.@]
4240 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4241 unsigned char *pMemory
,
4242 PFORMAT_STRING pFormat
)
4244 unsigned flags
= pFormat
[1];
4245 unsigned index
= *(const WORD
*)&pFormat
[2];
4246 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
4247 USER_MARSHAL_CB umcb
;
4248 ULONG saved_buffer_length
= 0;
4250 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4251 TRACE("index=%d\n", index
);
4253 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_BUFFER_SIZE
, pFormat
, &umcb
);
4255 if (flags
& USER_MARSHAL_POINTER
)
4257 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
4258 /* skip pointer prefix */
4259 safe_buffer_length_increment(pStubMsg
, 4);
4260 if (pStubMsg
->IgnoreEmbeddedPointers
)
4262 if (pStubMsg
->PointerLength
)
4264 saved_buffer_length
= pStubMsg
->BufferLength
;
4265 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4266 pStubMsg
->PointerLength
= 0;
4268 ALIGN_LENGTH(pStubMsg
->BufferLength
, 8);
4271 ALIGN_LENGTH(pStubMsg
->BufferLength
, (flags
& 0xf) + 1);
4274 TRACE("size=%d\n", bufsize
);
4275 safe_buffer_length_increment(pStubMsg
, bufsize
);
4278 pStubMsg
->BufferLength
=
4279 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
4280 &umcb
.Flags
, pStubMsg
->BufferLength
, pMemory
);
4282 if (saved_buffer_length
)
4284 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4285 pStubMsg
->BufferLength
= saved_buffer_length
;
4290 /***********************************************************************
4291 * NdrUserMarshalMemorySize [RPCRT4.@]
4293 ULONG WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4294 PFORMAT_STRING pFormat
)
4296 unsigned flags
= pFormat
[1];
4297 unsigned index
= *(const WORD
*)&pFormat
[2];
4298 DWORD memsize
= *(const WORD
*)&pFormat
[4];
4299 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
4301 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
4302 TRACE("index=%d\n", index
);
4304 pStubMsg
->MemorySize
+= memsize
;
4306 if (flags
& USER_MARSHAL_POINTER
)
4308 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4309 /* skip pointer prefix */
4310 pStubMsg
->Buffer
+= 4;
4311 if (pStubMsg
->IgnoreEmbeddedPointers
)
4312 return pStubMsg
->MemorySize
;
4313 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
4316 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4319 FIXME("not implemented for varying buffer size\n");
4321 pStubMsg
->Buffer
+= bufsize
;
4323 return pStubMsg
->MemorySize
;
4326 /***********************************************************************
4327 * NdrUserMarshalFree [RPCRT4.@]
4329 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
4330 unsigned char *pMemory
,
4331 PFORMAT_STRING pFormat
)
4333 /* unsigned flags = pFormat[1]; */
4334 unsigned index
= *(const WORD
*)&pFormat
[2];
4335 USER_MARSHAL_CB umcb
;
4337 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4338 TRACE("index=%d\n", index
);
4340 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_FREE
, pFormat
, &umcb
);
4342 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
4343 &umcb
.Flags
, pMemory
);
4346 /***********************************************************************
4347 * NdrGetUserMarshalInfo [RPCRT4.@]
4349 RPC_STATUS RPC_ENTRY
NdrGetUserMarshalInfo(ULONG
*flags
, ULONG level
, NDR_USER_MARSHAL_INFO
*umi
)
4351 USER_MARSHAL_CB
*umcb
= CONTAINING_RECORD(flags
, USER_MARSHAL_CB
, Flags
);
4353 TRACE("(%p,%u,%p)\n", flags
, level
, umi
);
4356 return RPC_S_INVALID_ARG
;
4358 memset(&umi
->Level1
, 0, sizeof(umi
->Level1
));
4359 umi
->InformationLevel
= level
;
4361 if (umcb
->Signature
!= USER_MARSHAL_CB_SIGNATURE
)
4362 return RPC_S_INVALID_ARG
;
4364 umi
->Level1
.pfnAllocate
= umcb
->pStubMsg
->pfnAllocate
;
4365 umi
->Level1
.pfnFree
= umcb
->pStubMsg
->pfnFree
;
4366 umi
->Level1
.pRpcChannelBuffer
= umcb
->pStubMsg
->pRpcChannelBuffer
;
4368 switch (umcb
->CBType
)
4370 case USER_MARSHAL_CB_MARSHALL
:
4371 case USER_MARSHAL_CB_UNMARSHALL
:
4373 RPC_MESSAGE
*msg
= umcb
->pStubMsg
->RpcMsg
;
4374 unsigned char *buffer_start
= msg
->Buffer
;
4375 unsigned char *buffer_end
=
4376 (unsigned char *)msg
->Buffer
+ msg
->BufferLength
;
4378 if (umcb
->pStubMsg
->Buffer
< buffer_start
||
4379 umcb
->pStubMsg
->Buffer
> buffer_end
)
4380 return ERROR_INVALID_USER_BUFFER
;
4382 umi
->Level1
.Buffer
= umcb
->pStubMsg
->Buffer
;
4383 umi
->Level1
.BufferSize
= buffer_end
- umcb
->pStubMsg
->Buffer
;
4386 case USER_MARSHAL_CB_BUFFER_SIZE
:
4387 case USER_MARSHAL_CB_FREE
:
4390 WARN("unrecognised CBType %d\n", umcb
->CBType
);
4396 /***********************************************************************
4397 * NdrClearOutParameters [RPCRT4.@]
4399 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
4400 PFORMAT_STRING pFormat
,
4403 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
4406 /***********************************************************************
4407 * NdrConvert [RPCRT4.@]
4409 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
4411 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
4412 /* FIXME: since this stub doesn't do any converting, the proper behavior
4413 is to raise an exception */
4416 /***********************************************************************
4417 * NdrConvert2 [RPCRT4.@]
4419 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, LONG NumberParams
)
4421 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4422 pStubMsg
, pFormat
, NumberParams
);
4423 /* FIXME: since this stub doesn't do any converting, the proper behavior
4424 is to raise an exception */
4427 #include "pshpack1.h"
4428 typedef struct _NDR_CSTRUCT_FORMAT
4431 unsigned char alignment
;
4432 unsigned short memory_size
;
4433 short offset_to_array_description
;
4434 } NDR_CSTRUCT_FORMAT
, NDR_CVSTRUCT_FORMAT
;
4435 #include "poppack.h"
4437 /***********************************************************************
4438 * NdrConformantStructMarshall [RPCRT4.@]
4440 unsigned char * WINAPI
NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4441 unsigned char *pMemory
,
4442 PFORMAT_STRING pFormat
)
4444 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4445 PFORMAT_STRING pCArrayFormat
;
4446 ULONG esize
, bufsize
;
4448 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4450 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4451 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4453 ERR("invalid format type %x\n", pCStructFormat
->type
);
4454 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4458 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4459 pCStructFormat
->offset_to_array_description
;
4460 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4462 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4463 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4466 esize
= *(const WORD
*)(pCArrayFormat
+2);
4468 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4469 pCArrayFormat
+ 4, 0);
4471 WriteConformance(pStubMsg
);
4473 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4475 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4477 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4478 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4480 ERR("integer overflow of memory_size %u with bufsize %u\n",
4481 pCStructFormat
->memory_size
, bufsize
);
4482 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4484 /* copy constant sized part of struct */
4485 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4486 safe_copy_to_buffer(pStubMsg
, pMemory
, pCStructFormat
->memory_size
+ bufsize
);
4488 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4489 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4494 /***********************************************************************
4495 * NdrConformantStructUnmarshall [RPCRT4.@]
4497 unsigned char * WINAPI
NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4498 unsigned char **ppMemory
,
4499 PFORMAT_STRING pFormat
,
4500 unsigned char fMustAlloc
)
4502 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4503 PFORMAT_STRING pCArrayFormat
;
4504 ULONG esize
, bufsize
;
4505 unsigned char *saved_buffer
;
4507 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4509 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4510 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4512 ERR("invalid format type %x\n", pCStructFormat
->type
);
4513 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4516 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4517 pCStructFormat
->offset_to_array_description
;
4518 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4520 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4521 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4524 esize
= *(const WORD
*)(pCArrayFormat
+2);
4526 pCArrayFormat
= ReadConformance(pStubMsg
, pCArrayFormat
+ 4);
4528 ALIGN_POINTER(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4530 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4532 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4533 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4535 ERR("integer overflow of memory_size %u with bufsize %u\n",
4536 pCStructFormat
->memory_size
, bufsize
);
4537 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4542 SIZE_T size
= pCStructFormat
->memory_size
+ bufsize
;
4543 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4547 if (!pStubMsg
->IsClient
&& !*ppMemory
)
4548 /* for servers, we just point straight into the RPC buffer */
4549 *ppMemory
= pStubMsg
->Buffer
;
4552 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4553 safe_buffer_increment(pStubMsg
, pCStructFormat
->memory_size
+ bufsize
);
4554 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4555 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4557 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
4558 if (*ppMemory
!= saved_buffer
)
4559 memcpy(*ppMemory
, saved_buffer
, pCStructFormat
->memory_size
+ bufsize
);
4564 /***********************************************************************
4565 * NdrConformantStructBufferSize [RPCRT4.@]
4567 void WINAPI
NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4568 unsigned char *pMemory
,
4569 PFORMAT_STRING pFormat
)
4571 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4572 PFORMAT_STRING pCArrayFormat
;
4575 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4577 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4578 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4580 ERR("invalid format type %x\n", pCStructFormat
->type
);
4581 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4584 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4585 pCStructFormat
->offset_to_array_description
;
4586 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4588 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4589 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4592 esize
= *(const WORD
*)(pCArrayFormat
+2);
4594 pCArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
, pCArrayFormat
+4, 0);
4595 SizeConformance(pStubMsg
);
4597 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCStructFormat
->alignment
+ 1);
4599 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4601 safe_buffer_length_increment(pStubMsg
, pCStructFormat
->memory_size
);
4602 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
4604 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4605 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4608 /***********************************************************************
4609 * NdrConformantStructMemorySize [RPCRT4.@]
4611 ULONG WINAPI
NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4612 PFORMAT_STRING pFormat
)
4618 /***********************************************************************
4619 * NdrConformantStructFree [RPCRT4.@]
4621 void WINAPI
NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
4622 unsigned char *pMemory
,
4623 PFORMAT_STRING pFormat
)
4625 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4626 PFORMAT_STRING pCArrayFormat
;
4628 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4630 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4631 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4633 ERR("invalid format type %x\n", pCStructFormat
->type
);
4634 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4638 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4639 pCStructFormat
->offset_to_array_description
;
4640 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4642 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4643 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4647 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4648 pCArrayFormat
+ 4, 0);
4650 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4652 /* copy constant sized part of struct */
4653 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4655 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4656 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4659 /***********************************************************************
4660 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4662 unsigned char * WINAPI
NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4663 unsigned char *pMemory
,
4664 PFORMAT_STRING pFormat
)
4666 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4667 PFORMAT_STRING pCVArrayFormat
;
4669 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4671 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4672 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4674 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4675 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4679 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4680 pCVStructFormat
->offset_to_array_description
;
4682 array_compute_and_write_conformance(*pCVArrayFormat
, pStubMsg
,
4683 pMemory
+ pCVStructFormat
->memory_size
,
4686 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4688 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4690 /* write constant sized part */
4691 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4692 safe_copy_to_buffer(pStubMsg
, pMemory
, pCVStructFormat
->memory_size
);
4694 array_write_variance_and_marshall(*pCVArrayFormat
, pStubMsg
,
4695 pMemory
+ pCVStructFormat
->memory_size
,
4696 pCVArrayFormat
, FALSE
/* fHasPointers */);
4698 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4703 /***********************************************************************
4704 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4706 unsigned char * WINAPI
NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4707 unsigned char **ppMemory
,
4708 PFORMAT_STRING pFormat
,
4709 unsigned char fMustAlloc
)
4711 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4712 PFORMAT_STRING pCVArrayFormat
;
4713 ULONG memsize
, bufsize
;
4714 unsigned char *saved_buffer
, *saved_array_buffer
;
4716 unsigned char *array_memory
;
4718 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4720 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4721 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4723 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4724 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4728 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4729 pCVStructFormat
->offset_to_array_description
;
4731 memsize
= array_read_conformance(*pCVArrayFormat
, pStubMsg
,
4734 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4736 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4738 /* work out how much memory to allocate if we need to do so */
4739 if (!fMustAlloc
&& !*ppMemory
)
4743 SIZE_T size
= pCVStructFormat
->memory_size
+ memsize
;
4744 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4747 /* mark the start of the constant data */
4748 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4749 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4751 array_memory
= *ppMemory
+ pCVStructFormat
->memory_size
;
4752 bufsize
= array_read_variance_and_unmarshall(*pCVArrayFormat
, pStubMsg
,
4753 &array_memory
, pCVArrayFormat
,
4754 FALSE
/* fMustAlloc */,
4755 FALSE
/* fUseServerBufferMemory */,
4756 FALSE
/* fUnmarshall */);
4758 /* save offset in case unmarshalling pointers changes it */
4759 offset
= pStubMsg
->Offset
;
4761 /* mark the start of the array data */
4762 saved_array_buffer
= pStubMsg
->Buffer
;
4763 safe_buffer_increment(pStubMsg
, bufsize
);
4765 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4767 /* copy the constant data */
4768 memcpy(*ppMemory
, saved_buffer
, pCVStructFormat
->memory_size
);
4769 /* copy the array data */
4770 TRACE("copying %p to %p\n", saved_array_buffer
, *ppMemory
+ pCVStructFormat
->memory_size
);
4771 memcpy(*ppMemory
+ pCVStructFormat
->memory_size
+ offset
,
4772 saved_array_buffer
, bufsize
);
4774 if (*pCVArrayFormat
== RPC_FC_C_CSTRING
)
4775 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory
+ pCVStructFormat
->memory_size
)));
4776 else if (*pCVArrayFormat
== RPC_FC_C_WSTRING
)
4777 TRACE("string=%s\n", debugstr_w((WCHAR
*)(*ppMemory
+ pCVStructFormat
->memory_size
)));
4782 /***********************************************************************
4783 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
4785 void WINAPI
NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4786 unsigned char *pMemory
,
4787 PFORMAT_STRING pFormat
)
4789 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4790 PFORMAT_STRING pCVArrayFormat
;
4792 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4794 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4795 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4797 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4798 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4802 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4803 pCVStructFormat
->offset_to_array_description
;
4804 array_compute_and_size_conformance(*pCVArrayFormat
, pStubMsg
,
4805 pMemory
+ pCVStructFormat
->memory_size
,
4808 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCVStructFormat
->alignment
+ 1);
4810 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4812 safe_buffer_length_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4814 array_buffer_size(*pCVArrayFormat
, pStubMsg
,
4815 pMemory
+ pCVStructFormat
->memory_size
, pCVArrayFormat
,
4816 FALSE
/* fHasPointers */);
4818 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4821 /***********************************************************************
4822 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4824 ULONG WINAPI
NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4825 PFORMAT_STRING pFormat
)
4827 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4828 PFORMAT_STRING pCVArrayFormat
;
4830 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4832 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4833 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4835 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4836 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4840 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4841 pCVStructFormat
->offset_to_array_description
;
4842 array_read_conformance(*pCVArrayFormat
, pStubMsg
, pCVArrayFormat
);
4844 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4846 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4848 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4849 array_memory_size(*pCVArrayFormat
, pStubMsg
, pCVArrayFormat
,
4850 FALSE
/* fHasPointers */);
4852 pStubMsg
->MemorySize
+= pCVStructFormat
->memory_size
;
4854 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4856 return pStubMsg
->MemorySize
;
4859 /***********************************************************************
4860 * NdrConformantVaryingStructFree [RPCRT4.@]
4862 void WINAPI
NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
4863 unsigned char *pMemory
,
4864 PFORMAT_STRING pFormat
)
4866 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4867 PFORMAT_STRING pCVArrayFormat
;
4869 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4871 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4872 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4874 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4875 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4879 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4880 pCVStructFormat
->offset_to_array_description
;
4881 array_free(*pCVArrayFormat
, pStubMsg
,
4882 pMemory
+ pCVStructFormat
->memory_size
, pCVArrayFormat
,
4883 FALSE
/* fHasPointers */);
4885 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4887 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4890 #include "pshpack1.h"
4894 unsigned char alignment
;
4895 unsigned short total_size
;
4896 } NDR_SMFARRAY_FORMAT
;
4901 unsigned char alignment
;
4903 } NDR_LGFARRAY_FORMAT
;
4904 #include "poppack.h"
4906 /***********************************************************************
4907 * NdrFixedArrayMarshall [RPCRT4.@]
4909 unsigned char * WINAPI
NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4910 unsigned char *pMemory
,
4911 PFORMAT_STRING pFormat
)
4913 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4916 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4918 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4919 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4921 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4922 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4926 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4928 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4930 total_size
= pSmFArrayFormat
->total_size
;
4931 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4935 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4936 total_size
= pLgFArrayFormat
->total_size
;
4937 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4940 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4941 safe_copy_to_buffer(pStubMsg
, pMemory
, total_size
);
4943 pFormat
= EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4948 /***********************************************************************
4949 * NdrFixedArrayUnmarshall [RPCRT4.@]
4951 unsigned char * WINAPI
NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4952 unsigned char **ppMemory
,
4953 PFORMAT_STRING pFormat
,
4954 unsigned char fMustAlloc
)
4956 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4958 unsigned char *saved_buffer
;
4960 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4962 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4963 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4965 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4966 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4970 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4972 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4974 total_size
= pSmFArrayFormat
->total_size
;
4975 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4979 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4980 total_size
= pLgFArrayFormat
->total_size
;
4981 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4985 *ppMemory
= NdrAllocate(pStubMsg
, total_size
);
4988 if (!pStubMsg
->IsClient
&& !*ppMemory
)
4989 /* for servers, we just point straight into the RPC buffer */
4990 *ppMemory
= pStubMsg
->Buffer
;
4993 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4994 safe_buffer_increment(pStubMsg
, total_size
);
4995 pFormat
= EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4997 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
4998 if (*ppMemory
!= saved_buffer
)
4999 memcpy(*ppMemory
, saved_buffer
, total_size
);
5004 /***********************************************************************
5005 * NdrFixedArrayBufferSize [RPCRT4.@]
5007 void WINAPI
NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5008 unsigned char *pMemory
,
5009 PFORMAT_STRING pFormat
)
5011 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5014 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5016 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5017 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5019 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5020 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5024 ALIGN_LENGTH(pStubMsg
->BufferLength
, pSmFArrayFormat
->alignment
+ 1);
5026 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5028 total_size
= pSmFArrayFormat
->total_size
;
5029 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5033 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5034 total_size
= pLgFArrayFormat
->total_size
;
5035 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5037 safe_buffer_length_increment(pStubMsg
, total_size
);
5039 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5042 /***********************************************************************
5043 * NdrFixedArrayMemorySize [RPCRT4.@]
5045 ULONG WINAPI
NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5046 PFORMAT_STRING pFormat
)
5048 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5051 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5053 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5054 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5056 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5057 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5061 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
5063 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5065 total_size
= pSmFArrayFormat
->total_size
;
5066 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5070 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5071 total_size
= pLgFArrayFormat
->total_size
;
5072 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5074 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5075 safe_buffer_increment(pStubMsg
, total_size
);
5076 pStubMsg
->MemorySize
+= total_size
;
5078 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5083 /***********************************************************************
5084 * NdrFixedArrayFree [RPCRT4.@]
5086 void WINAPI
NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
5087 unsigned char *pMemory
,
5088 PFORMAT_STRING pFormat
)
5090 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5092 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5094 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5095 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5097 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5098 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5102 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5103 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5106 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5107 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5110 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5113 /***********************************************************************
5114 * NdrVaryingArrayMarshall [RPCRT4.@]
5116 unsigned char * WINAPI
NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5117 unsigned char *pMemory
,
5118 PFORMAT_STRING pFormat
)
5120 unsigned char alignment
;
5121 DWORD elements
, esize
;
5124 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5126 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5127 (pFormat
[0] != RPC_FC_LGVARRAY
))
5129 ERR("invalid format type %x\n", pFormat
[0]);
5130 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5134 alignment
= pFormat
[1] + 1;
5136 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5139 pFormat
+= sizeof(WORD
);
5140 elements
= *(const WORD
*)pFormat
;
5141 pFormat
+= sizeof(WORD
);
5146 pFormat
+= sizeof(DWORD
);
5147 elements
= *(const DWORD
*)pFormat
;
5148 pFormat
+= sizeof(DWORD
);
5151 esize
= *(const WORD
*)pFormat
;
5152 pFormat
+= sizeof(WORD
);
5154 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5155 if ((pStubMsg
->ActualCount
> elements
) ||
5156 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5158 RpcRaiseException(RPC_S_INVALID_BOUND
);
5162 WriteVariance(pStubMsg
);
5164 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
5166 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
5167 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5168 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
5170 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
5175 /***********************************************************************
5176 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5178 unsigned char * WINAPI
NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5179 unsigned char **ppMemory
,
5180 PFORMAT_STRING pFormat
,
5181 unsigned char fMustAlloc
)
5183 unsigned char alignment
;
5184 DWORD size
, elements
, esize
;
5186 unsigned char *saved_buffer
;
5189 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5191 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5192 (pFormat
[0] != RPC_FC_LGVARRAY
))
5194 ERR("invalid format type %x\n", pFormat
[0]);
5195 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5199 alignment
= pFormat
[1] + 1;
5201 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5204 size
= *(const WORD
*)pFormat
;
5205 pFormat
+= sizeof(WORD
);
5206 elements
= *(const WORD
*)pFormat
;
5207 pFormat
+= sizeof(WORD
);
5212 size
= *(const DWORD
*)pFormat
;
5213 pFormat
+= sizeof(DWORD
);
5214 elements
= *(const DWORD
*)pFormat
;
5215 pFormat
+= sizeof(DWORD
);
5218 esize
= *(const WORD
*)pFormat
;
5219 pFormat
+= sizeof(WORD
);
5221 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
5223 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
5225 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
5226 offset
= pStubMsg
->Offset
;
5228 if (!fMustAlloc
&& !*ppMemory
)
5231 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5232 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5233 safe_buffer_increment(pStubMsg
, bufsize
);
5235 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
5237 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
5242 /***********************************************************************
5243 * NdrVaryingArrayBufferSize [RPCRT4.@]
5245 void WINAPI
NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5246 unsigned char *pMemory
,
5247 PFORMAT_STRING pFormat
)
5249 unsigned char alignment
;
5250 DWORD elements
, esize
;
5252 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5254 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5255 (pFormat
[0] != RPC_FC_LGVARRAY
))
5257 ERR("invalid format type %x\n", pFormat
[0]);
5258 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5262 alignment
= pFormat
[1] + 1;
5264 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5267 pFormat
+= sizeof(WORD
);
5268 elements
= *(const WORD
*)pFormat
;
5269 pFormat
+= sizeof(WORD
);
5274 pFormat
+= sizeof(DWORD
);
5275 elements
= *(const DWORD
*)pFormat
;
5276 pFormat
+= sizeof(DWORD
);
5279 esize
= *(const WORD
*)pFormat
;
5280 pFormat
+= sizeof(WORD
);
5282 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5283 if ((pStubMsg
->ActualCount
> elements
) ||
5284 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5286 RpcRaiseException(RPC_S_INVALID_BOUND
);
5290 SizeVariance(pStubMsg
);
5292 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
5294 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
5296 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5299 /***********************************************************************
5300 * NdrVaryingArrayMemorySize [RPCRT4.@]
5302 ULONG WINAPI
NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5303 PFORMAT_STRING pFormat
)
5305 unsigned char alignment
;
5306 DWORD size
, elements
, esize
;
5308 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5310 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5311 (pFormat
[0] != RPC_FC_LGVARRAY
))
5313 ERR("invalid format type %x\n", pFormat
[0]);
5314 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5318 alignment
= pFormat
[1] + 1;
5320 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5323 size
= *(const WORD
*)pFormat
;
5324 pFormat
+= sizeof(WORD
);
5325 elements
= *(const WORD
*)pFormat
;
5326 pFormat
+= sizeof(WORD
);
5331 size
= *(const DWORD
*)pFormat
;
5332 pFormat
+= sizeof(DWORD
);
5333 elements
= *(const DWORD
*)pFormat
;
5334 pFormat
+= sizeof(DWORD
);
5337 esize
= *(const WORD
*)pFormat
;
5338 pFormat
+= sizeof(WORD
);
5340 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
5342 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
5344 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
5345 pStubMsg
->MemorySize
+= size
;
5347 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5349 return pStubMsg
->MemorySize
;
5352 /***********************************************************************
5353 * NdrVaryingArrayFree [RPCRT4.@]
5355 void WINAPI
NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
5356 unsigned char *pMemory
,
5357 PFORMAT_STRING pFormat
)
5361 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5363 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5364 (pFormat
[0] != RPC_FC_LGVARRAY
))
5366 ERR("invalid format type %x\n", pFormat
[0]);
5367 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5371 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5374 pFormat
+= sizeof(WORD
);
5375 elements
= *(const WORD
*)pFormat
;
5376 pFormat
+= sizeof(WORD
);
5381 pFormat
+= sizeof(DWORD
);
5382 elements
= *(const DWORD
*)pFormat
;
5383 pFormat
+= sizeof(DWORD
);
5386 pFormat
+= sizeof(WORD
);
5388 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5389 if ((pStubMsg
->ActualCount
> elements
) ||
5390 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5392 RpcRaiseException(RPC_S_INVALID_BOUND
);
5396 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5399 static ULONG
get_discriminant(unsigned char fc
, const unsigned char *pMemory
)
5412 return *(const USHORT
*)pMemory
;
5416 return *(const ULONG
*)pMemory
;
5418 FIXME("Unhandled base type: 0x%02x\n", fc
);
5423 static PFORMAT_STRING
get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg
,
5425 PFORMAT_STRING pFormat
)
5427 unsigned short num_arms
, arm
, type
;
5429 num_arms
= *(const SHORT
*)pFormat
& 0x0fff;
5431 for(arm
= 0; arm
< num_arms
; arm
++)
5433 if(discriminant
== *(const ULONG
*)pFormat
)
5441 type
= *(const unsigned short*)pFormat
;
5442 TRACE("type %04x\n", type
);
5443 if(arm
== num_arms
) /* default arm extras */
5447 ERR("no arm for 0x%x and no default case\n", discriminant
);
5448 RpcRaiseException(RPC_S_INVALID_TAG
);
5453 TRACE("falling back to empty default case for 0x%x\n", discriminant
);
5460 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
, ULONG discriminant
, PFORMAT_STRING pFormat
)
5462 unsigned short type
;
5466 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5470 type
= *(const unsigned short*)pFormat
;
5471 if((type
& 0xff00) == 0x8000)
5473 unsigned char basetype
= LOBYTE(type
);
5474 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &basetype
);
5478 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5479 NDR_MARSHALL m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
5482 unsigned char *saved_buffer
= NULL
;
5483 int pointer_buffer_mark_set
= 0;
5490 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
5491 saved_buffer
= pStubMsg
->Buffer
;
5492 if (pStubMsg
->PointerBufferMark
)
5494 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5495 pStubMsg
->PointerBufferMark
= NULL
;
5496 pointer_buffer_mark_set
= 1;
5499 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
5501 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char **)pMemory
, desc
);
5502 if (pointer_buffer_mark_set
)
5504 STD_OVERFLOW_CHECK(pStubMsg
);
5505 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5506 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5508 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5509 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
5510 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5512 pStubMsg
->Buffer
= saved_buffer
+ 4;
5516 m(pStubMsg
, pMemory
, desc
);
5519 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5524 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5525 unsigned char **ppMemory
,
5527 PFORMAT_STRING pFormat
,
5528 unsigned char fMustAlloc
)
5530 unsigned short type
;
5534 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5538 type
= *(const unsigned short*)pFormat
;
5539 if((type
& 0xff00) == 0x8000)
5541 unsigned char basetype
= LOBYTE(type
);
5542 return NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &basetype
, FALSE
);
5546 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5547 NDR_UNMARSHALL m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
5550 unsigned char *saved_buffer
= NULL
;
5551 int pointer_buffer_mark_set
= 0;
5558 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5559 saved_buffer
= pStubMsg
->Buffer
;
5560 if (pStubMsg
->PointerBufferMark
)
5562 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5563 pStubMsg
->PointerBufferMark
= NULL
;
5564 pointer_buffer_mark_set
= 1;
5567 pStubMsg
->Buffer
+= 4; /* for pointer ID */
5569 if (saved_buffer
+ 4 > pStubMsg
->BufferEnd
)
5571 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5572 saved_buffer
, pStubMsg
->BufferEnd
);
5573 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5576 PointerUnmarshall(pStubMsg
, saved_buffer
, *(unsigned char ***)ppMemory
, **(unsigned char ***)ppMemory
, desc
, fMustAlloc
);
5577 if (pointer_buffer_mark_set
)
5579 STD_OVERFLOW_CHECK(pStubMsg
);
5580 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5581 pStubMsg
->Buffer
= saved_buffer
+ 4;
5585 m(pStubMsg
, ppMemory
, desc
, fMustAlloc
);
5588 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5593 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg
,
5594 unsigned char *pMemory
,
5596 PFORMAT_STRING pFormat
)
5598 unsigned short type
;
5602 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5606 type
= *(const unsigned short*)pFormat
;
5607 if((type
& 0xff00) == 0x8000)
5609 unsigned char basetype
= LOBYTE(type
);
5610 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &basetype
);
5614 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5615 NDR_BUFFERSIZE m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
5624 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
5625 safe_buffer_length_increment(pStubMsg
, 4); /* for pointer ID */
5626 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5628 int saved_buffer_length
= pStubMsg
->BufferLength
;
5629 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
5630 pStubMsg
->PointerLength
= 0;
5631 if(!pStubMsg
->BufferLength
)
5632 ERR("BufferLength == 0??\n");
5633 PointerBufferSize(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5634 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
5635 pStubMsg
->BufferLength
= saved_buffer_length
;
5639 m(pStubMsg
, pMemory
, desc
);
5642 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
5646 static ULONG
union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg
,
5648 PFORMAT_STRING pFormat
)
5650 unsigned short type
, size
;
5652 size
= *(const unsigned short*)pFormat
;
5653 pStubMsg
->Memory
+= size
;
5656 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5660 type
= *(const unsigned short*)pFormat
;
5661 if((type
& 0xff00) == 0x8000)
5663 return NdrBaseTypeMemorySize(pStubMsg
, pFormat
);
5667 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5668 NDR_MEMORYSIZE m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
5669 unsigned char *saved_buffer
;
5678 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5679 saved_buffer
= pStubMsg
->Buffer
;
5680 safe_buffer_increment(pStubMsg
, 4);
5681 ALIGN_LENGTH(pStubMsg
->MemorySize
, 4);
5682 pStubMsg
->MemorySize
+= 4;
5683 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5684 PointerMemorySize(pStubMsg
, saved_buffer
, pFormat
);
5687 return m(pStubMsg
, desc
);
5690 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5693 TRACE("size %d\n", size
);
5697 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg
,
5698 unsigned char *pMemory
,
5700 PFORMAT_STRING pFormat
)
5702 unsigned short type
;
5706 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5710 type
= *(const unsigned short*)pFormat
;
5711 if((type
& 0xff00) != 0x8000)
5713 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5714 NDR_FREE m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
5723 PointerFree(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5726 m(pStubMsg
, pMemory
, desc
);
5732 /***********************************************************************
5733 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5735 unsigned char * WINAPI
NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5736 unsigned char *pMemory
,
5737 PFORMAT_STRING pFormat
)
5739 unsigned char switch_type
;
5740 unsigned char increment
;
5743 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5746 switch_type
= *pFormat
& 0xf;
5747 increment
= (*pFormat
& 0xf0) >> 4;
5750 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, increment
);
5752 switch_value
= get_discriminant(switch_type
, pMemory
);
5753 TRACE("got switch value 0x%x\n", switch_value
);
5755 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &switch_type
);
5756 pMemory
+= increment
;
5758 return union_arm_marshall(pStubMsg
, pMemory
, switch_value
, pFormat
);
5761 /***********************************************************************
5762 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5764 unsigned char * WINAPI
NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5765 unsigned char **ppMemory
,
5766 PFORMAT_STRING pFormat
,
5767 unsigned char fMustAlloc
)
5769 unsigned char switch_type
;
5770 unsigned char increment
;
5772 unsigned short size
;
5773 unsigned char *pMemoryArm
;
5775 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5778 switch_type
= *pFormat
& 0xf;
5779 increment
= (*pFormat
& 0xf0) >> 4;
5782 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
5783 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
5784 TRACE("got switch value 0x%x\n", switch_value
);
5786 size
= *(const unsigned short*)pFormat
+ increment
;
5787 if (!fMustAlloc
&& !*ppMemory
)
5790 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5792 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
5793 * since the arm is part of the memory block that is encompassed by
5794 * the whole union. Memory is forced to allocate when pointers
5795 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
5796 * clearing the memory we pass in to the unmarshaller */
5798 memset(*ppMemory
, 0, size
);
5800 NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &switch_type
, FALSE
);
5801 pMemoryArm
= *ppMemory
+ increment
;
5803 return union_arm_unmarshall(pStubMsg
, &pMemoryArm
, switch_value
, pFormat
, FALSE
);
5806 /***********************************************************************
5807 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5809 void WINAPI
NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5810 unsigned char *pMemory
,
5811 PFORMAT_STRING pFormat
)
5813 unsigned char switch_type
;
5814 unsigned char increment
;
5817 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5820 switch_type
= *pFormat
& 0xf;
5821 increment
= (*pFormat
& 0xf0) >> 4;
5824 ALIGN_LENGTH(pStubMsg
->BufferLength
, increment
);
5825 switch_value
= get_discriminant(switch_type
, pMemory
);
5826 TRACE("got switch value 0x%x\n", switch_value
);
5828 /* Add discriminant size */
5829 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&switch_value
, &switch_type
);
5830 pMemory
+= increment
;
5832 union_arm_buffer_size(pStubMsg
, pMemory
, switch_value
, pFormat
);
5835 /***********************************************************************
5836 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5838 ULONG WINAPI
NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5839 PFORMAT_STRING pFormat
)
5841 unsigned char switch_type
;
5842 unsigned char increment
;
5845 switch_type
= *pFormat
& 0xf;
5846 increment
= (*pFormat
& 0xf0) >> 4;
5849 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
5850 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
5851 TRACE("got switch value 0x%x\n", switch_value
);
5853 pStubMsg
->Memory
+= increment
;
5855 return increment
+ union_arm_memory_size(pStubMsg
, switch_value
, pFormat
+ *(const SHORT
*)pFormat
);
5858 /***********************************************************************
5859 * NdrEncapsulatedUnionFree [RPCRT4.@]
5861 void WINAPI
NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
5862 unsigned char *pMemory
,
5863 PFORMAT_STRING pFormat
)
5865 unsigned char switch_type
;
5866 unsigned char increment
;
5869 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5872 switch_type
= *pFormat
& 0xf;
5873 increment
= (*pFormat
& 0xf0) >> 4;
5876 switch_value
= get_discriminant(switch_type
, pMemory
);
5877 TRACE("got switch value 0x%x\n", switch_value
);
5879 pMemory
+= increment
;
5881 union_arm_free(pStubMsg
, pMemory
, switch_value
, pFormat
);
5884 /***********************************************************************
5885 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5887 unsigned char * WINAPI
NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5888 unsigned char *pMemory
,
5889 PFORMAT_STRING pFormat
)
5891 unsigned char switch_type
;
5893 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5896 switch_type
= *pFormat
;
5899 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5900 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5901 /* Marshall discriminant */
5902 NdrBaseTypeMarshall(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
5904 return union_arm_marshall(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5907 static LONG
unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg
,
5908 PFORMAT_STRING
*ppFormat
)
5910 LONG discriminant
= 0;
5920 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5929 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5930 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5938 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
5939 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5944 FIXME("Unhandled base type: 0x%02x\n", **ppFormat
);
5948 if (pStubMsg
->fHasNewCorrDesc
)
5952 return discriminant
;
5955 /**********************************************************************
5956 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5958 unsigned char * WINAPI
NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5959 unsigned char **ppMemory
,
5960 PFORMAT_STRING pFormat
,
5961 unsigned char fMustAlloc
)
5964 unsigned short size
;
5966 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5969 /* Unmarshall discriminant */
5970 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
5971 TRACE("unmarshalled discriminant %x\n", discriminant
);
5973 pFormat
+= *(const SHORT
*)pFormat
;
5975 size
= *(const unsigned short*)pFormat
;
5977 if (!fMustAlloc
&& !*ppMemory
)
5980 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5982 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
5983 * since the arm is part of the memory block that is encompassed by
5984 * the whole union. Memory is forced to allocate when pointers
5985 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
5986 * clearing the memory we pass in to the unmarshaller */
5988 memset(*ppMemory
, 0, size
);
5990 return union_arm_unmarshall(pStubMsg
, ppMemory
, discriminant
, pFormat
, FALSE
);
5993 /***********************************************************************
5994 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5996 void WINAPI
NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5997 unsigned char *pMemory
,
5998 PFORMAT_STRING pFormat
)
6000 unsigned char switch_type
;
6002 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6005 switch_type
= *pFormat
;
6008 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6009 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6010 /* Add discriminant size */
6011 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
6013 union_arm_buffer_size(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6016 /***********************************************************************
6017 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
6019 ULONG WINAPI
NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6020 PFORMAT_STRING pFormat
)
6025 /* Unmarshall discriminant */
6026 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
6027 TRACE("unmarshalled discriminant 0x%x\n", discriminant
);
6029 return union_arm_memory_size(pStubMsg
, discriminant
, pFormat
+ *(const SHORT
*)pFormat
);
6032 /***********************************************************************
6033 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6035 void WINAPI
NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
6036 unsigned char *pMemory
,
6037 PFORMAT_STRING pFormat
)
6039 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6043 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6044 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6046 union_arm_free(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6049 /***********************************************************************
6050 * NdrByteCountPointerMarshall [RPCRT4.@]
6052 unsigned char * WINAPI
NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6053 unsigned char *pMemory
,
6054 PFORMAT_STRING pFormat
)
6060 /***********************************************************************
6061 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6063 unsigned char * WINAPI
NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6064 unsigned char **ppMemory
,
6065 PFORMAT_STRING pFormat
,
6066 unsigned char fMustAlloc
)
6072 /***********************************************************************
6073 * NdrByteCountPointerBufferSize [RPCRT4.@]
6075 void WINAPI
NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6076 unsigned char *pMemory
,
6077 PFORMAT_STRING pFormat
)
6082 /***********************************************************************
6083 * NdrByteCountPointerMemorySize [internal]
6085 static ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6086 PFORMAT_STRING pFormat
)
6092 /***********************************************************************
6093 * NdrByteCountPointerFree [RPCRT4.@]
6095 void WINAPI
NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
6096 unsigned char *pMemory
,
6097 PFORMAT_STRING pFormat
)
6102 /***********************************************************************
6103 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6105 unsigned char * WINAPI
NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6106 unsigned char *pMemory
,
6107 PFORMAT_STRING pFormat
)
6113 /***********************************************************************
6114 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6116 unsigned char * WINAPI
NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6117 unsigned char **ppMemory
,
6118 PFORMAT_STRING pFormat
,
6119 unsigned char fMustAlloc
)
6125 /***********************************************************************
6126 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6128 void WINAPI
NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6129 unsigned char *pMemory
,
6130 PFORMAT_STRING pFormat
)
6135 /***********************************************************************
6136 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6138 ULONG WINAPI
NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6139 PFORMAT_STRING pFormat
)
6145 /***********************************************************************
6146 * NdrXmitOrRepAsFree [RPCRT4.@]
6148 void WINAPI
NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg
,
6149 unsigned char *pMemory
,
6150 PFORMAT_STRING pFormat
)
6155 /***********************************************************************
6156 * NdrRangeMarshall [internal]
6158 static unsigned char *WINAPI
NdrRangeMarshall(
6159 PMIDL_STUB_MESSAGE pStubMsg
,
6160 unsigned char *pMemory
,
6161 PFORMAT_STRING pFormat
)
6163 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
6164 unsigned char base_type
;
6166 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6168 if (pRange
->type
!= RPC_FC_RANGE
)
6170 ERR("invalid format type %x\n", pRange
->type
);
6171 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6175 base_type
= pRange
->flags_type
& 0xf;
6177 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &base_type
);
6180 /***********************************************************************
6181 * NdrRangeUnmarshall [RPCRT4.@]
6183 unsigned char *WINAPI
NdrRangeUnmarshall(
6184 PMIDL_STUB_MESSAGE pStubMsg
,
6185 unsigned char **ppMemory
,
6186 PFORMAT_STRING pFormat
,
6187 unsigned char fMustAlloc
)
6189 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
6190 unsigned char base_type
;
6192 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6194 if (pRange
->type
!= RPC_FC_RANGE
)
6196 ERR("invalid format type %x\n", pRange
->type
);
6197 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6200 base_type
= pRange
->flags_type
& 0xf;
6202 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6203 base_type
, pRange
->low_value
, pRange
->high_value
);
6205 #define RANGE_UNMARSHALL(mem_type, wire_type, format_spec) \
6208 ALIGN_POINTER(pStubMsg->Buffer, sizeof(wire_type)); \
6209 if (!fMustAlloc && !*ppMemory) \
6210 fMustAlloc = TRUE; \
6212 *ppMemory = NdrAllocate(pStubMsg, sizeof(mem_type)); \
6213 if (pStubMsg->Buffer + sizeof(wire_type) > pStubMsg->BufferEnd) \
6215 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6216 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6217 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6219 if ((*(wire_type *)pStubMsg->Buffer < (mem_type)pRange->low_value) || \
6220 (*(wire_type *)pStubMsg->Buffer > (mem_type)pRange->high_value)) \
6222 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6223 *(wire_type *)pStubMsg->Buffer, (mem_type)pRange->low_value, \
6224 (mem_type)pRange->high_value); \
6225 RpcRaiseException(RPC_S_INVALID_BOUND); \
6228 TRACE("*ppMemory: %p\n", *ppMemory); \
6229 **(mem_type **)ppMemory = *(wire_type *)pStubMsg->Buffer; \
6230 pStubMsg->Buffer += sizeof(wire_type); \
6237 RANGE_UNMARSHALL(UCHAR
, UCHAR
, "%d");
6238 TRACE("value: 0x%02x\n", **ppMemory
);
6242 RANGE_UNMARSHALL(CHAR
, CHAR
, "%u");
6243 TRACE("value: 0x%02x\n", **ppMemory
);
6245 case RPC_FC_WCHAR
: /* FIXME: valid? */
6247 RANGE_UNMARSHALL(USHORT
, USHORT
, "%u");
6248 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6251 RANGE_UNMARSHALL(SHORT
, SHORT
, "%d");
6252 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6256 RANGE_UNMARSHALL(LONG
, LONG
, "%d");
6257 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6260 RANGE_UNMARSHALL(ULONG
, ULONG
, "%u");
6261 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6264 RANGE_UNMARSHALL(UINT
, USHORT
, "%u");
6265 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
6271 ERR("invalid range base type: 0x%02x\n", base_type
);
6272 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6278 /***********************************************************************
6279 * NdrRangeBufferSize [internal]
6281 static void WINAPI
NdrRangeBufferSize(
6282 PMIDL_STUB_MESSAGE pStubMsg
,
6283 unsigned char *pMemory
,
6284 PFORMAT_STRING pFormat
)
6286 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
6287 unsigned char base_type
;
6289 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6291 if (pRange
->type
!= RPC_FC_RANGE
)
6293 ERR("invalid format type %x\n", pRange
->type
);
6294 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6296 base_type
= pRange
->flags_type
& 0xf;
6298 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &base_type
);
6301 /***********************************************************************
6302 * NdrRangeMemorySize [internal]
6304 static ULONG WINAPI
NdrRangeMemorySize(
6305 PMIDL_STUB_MESSAGE pStubMsg
,
6306 PFORMAT_STRING pFormat
)
6308 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
6309 unsigned char base_type
;
6311 if (pRange
->type
!= RPC_FC_RANGE
)
6313 ERR("invalid format type %x\n", pRange
->type
);
6314 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6317 base_type
= pRange
->flags_type
& 0xf;
6319 return NdrBaseTypeMemorySize(pStubMsg
, &base_type
);
6322 /***********************************************************************
6323 * NdrRangeFree [internal]
6325 static void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6326 unsigned char *pMemory
,
6327 PFORMAT_STRING pFormat
)
6329 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6334 /***********************************************************************
6335 * NdrBaseTypeMarshall [internal]
6337 static unsigned char *WINAPI
NdrBaseTypeMarshall(
6338 PMIDL_STUB_MESSAGE pStubMsg
,
6339 unsigned char *pMemory
,
6340 PFORMAT_STRING pFormat
)
6342 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6350 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(UCHAR
));
6351 TRACE("value: 0x%02x\n", *pMemory
);
6356 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(USHORT
));
6357 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(USHORT
));
6358 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
6362 case RPC_FC_ERROR_STATUS_T
:
6364 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(ULONG
));
6365 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONG
));
6366 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
6369 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(float));
6370 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
6373 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(double));
6374 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
6377 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(ULONGLONG
));
6378 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONGLONG
));
6379 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
6382 /* only 16-bits on the wire, so do a sanity check */
6383 if (*(UINT
*)pMemory
> SHRT_MAX
)
6384 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
6385 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(USHORT
));
6386 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6387 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6388 *(USHORT
*)pStubMsg
->Buffer
= *(UINT
*)pMemory
;
6389 pStubMsg
->Buffer
+= sizeof(USHORT
);
6390 TRACE("value: 0x%04x\n", *(UINT
*)pMemory
);
6395 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6398 /* FIXME: what is the correct return value? */
6402 /***********************************************************************
6403 * NdrBaseTypeUnmarshall [internal]
6405 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(
6406 PMIDL_STUB_MESSAGE pStubMsg
,
6407 unsigned char **ppMemory
,
6408 PFORMAT_STRING pFormat
,
6409 unsigned char fMustAlloc
)
6411 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6413 #define BASE_TYPE_UNMARSHALL(type) \
6414 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6415 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6417 *ppMemory = pStubMsg->Buffer; \
6418 TRACE("*ppMemory: %p\n", *ppMemory); \
6419 safe_buffer_increment(pStubMsg, sizeof(type)); \
6424 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6425 TRACE("*ppMemory: %p\n", *ppMemory); \
6426 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6435 BASE_TYPE_UNMARSHALL(UCHAR
);
6436 TRACE("value: 0x%02x\n", **ppMemory
);
6441 BASE_TYPE_UNMARSHALL(USHORT
);
6442 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6446 case RPC_FC_ERROR_STATUS_T
:
6448 BASE_TYPE_UNMARSHALL(ULONG
);
6449 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6452 BASE_TYPE_UNMARSHALL(float);
6453 TRACE("value: %f\n", **(float **)ppMemory
);
6456 BASE_TYPE_UNMARSHALL(double);
6457 TRACE("value: %f\n", **(double **)ppMemory
);
6460 BASE_TYPE_UNMARSHALL(ULONGLONG
);
6461 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG
**)ppMemory
));
6464 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
6465 if (!fMustAlloc
&& !*ppMemory
)
6468 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT
));
6469 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > pStubMsg
->BufferEnd
)
6470 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6471 TRACE("*ppMemory: %p\n", *ppMemory
);
6472 /* 16-bits on the wire, but int in memory */
6473 **(UINT
**)ppMemory
= *(USHORT
*)pStubMsg
->Buffer
;
6474 pStubMsg
->Buffer
+= sizeof(USHORT
);
6475 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
6480 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6482 #undef BASE_TYPE_UNMARSHALL
6484 /* FIXME: what is the correct return value? */
6489 /***********************************************************************
6490 * NdrBaseTypeBufferSize [internal]
6492 static void WINAPI
NdrBaseTypeBufferSize(
6493 PMIDL_STUB_MESSAGE pStubMsg
,
6494 unsigned char *pMemory
,
6495 PFORMAT_STRING pFormat
)
6497 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6505 safe_buffer_length_increment(pStubMsg
, sizeof(UCHAR
));
6511 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(USHORT
));
6512 safe_buffer_length_increment(pStubMsg
, sizeof(USHORT
));
6517 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONG
));
6518 safe_buffer_length_increment(pStubMsg
, sizeof(ULONG
));
6521 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(float));
6522 safe_buffer_length_increment(pStubMsg
, sizeof(float));
6525 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(double));
6526 safe_buffer_length_increment(pStubMsg
, sizeof(double));
6529 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONGLONG
));
6530 safe_buffer_length_increment(pStubMsg
, sizeof(ULONGLONG
));
6532 case RPC_FC_ERROR_STATUS_T
:
6533 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(error_status_t
));
6534 safe_buffer_length_increment(pStubMsg
, sizeof(error_status_t
));
6539 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6543 /***********************************************************************
6544 * NdrBaseTypeMemorySize [internal]
6546 static ULONG WINAPI
NdrBaseTypeMemorySize(
6547 PMIDL_STUB_MESSAGE pStubMsg
,
6548 PFORMAT_STRING pFormat
)
6550 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg
, *pFormat
);
6558 safe_buffer_increment(pStubMsg
, sizeof(UCHAR
));
6559 pStubMsg
->MemorySize
+= sizeof(UCHAR
);
6560 return sizeof(UCHAR
);
6564 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6565 pStubMsg
->MemorySize
+= sizeof(USHORT
);
6566 return sizeof(USHORT
);
6570 safe_buffer_increment(pStubMsg
, sizeof(ULONG
));
6571 pStubMsg
->MemorySize
+= sizeof(ULONG
);
6572 return sizeof(ULONG
);
6574 safe_buffer_increment(pStubMsg
, sizeof(float));
6575 pStubMsg
->MemorySize
+= sizeof(float);
6576 return sizeof(float);
6578 safe_buffer_increment(pStubMsg
, sizeof(double));
6579 pStubMsg
->MemorySize
+= sizeof(double);
6580 return sizeof(double);
6582 safe_buffer_increment(pStubMsg
, sizeof(ULONGLONG
));
6583 pStubMsg
->MemorySize
+= sizeof(ULONGLONG
);
6584 return sizeof(ULONGLONG
);
6585 case RPC_FC_ERROR_STATUS_T
:
6586 safe_buffer_increment(pStubMsg
, sizeof(error_status_t
));
6587 pStubMsg
->MemorySize
+= sizeof(error_status_t
);
6588 return sizeof(error_status_t
);
6590 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6591 pStubMsg
->MemorySize
+= sizeof(UINT
);
6592 return sizeof(UINT
);
6594 pStubMsg
->MemorySize
+= sizeof(void *);
6595 return sizeof(void *);
6597 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6602 /***********************************************************************
6603 * NdrBaseTypeFree [internal]
6605 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6606 unsigned char *pMemory
,
6607 PFORMAT_STRING pFormat
)
6609 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6614 /***********************************************************************
6615 * NdrContextHandleBufferSize [internal]
6617 static void WINAPI
NdrContextHandleBufferSize(
6618 PMIDL_STUB_MESSAGE pStubMsg
,
6619 unsigned char *pMemory
,
6620 PFORMAT_STRING pFormat
)
6622 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6624 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6626 ERR("invalid format type %x\n", *pFormat
);
6627 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6629 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
6630 safe_buffer_length_increment(pStubMsg
, cbNDRContext
);
6633 /***********************************************************************
6634 * NdrContextHandleMarshall [internal]
6636 static unsigned char *WINAPI
NdrContextHandleMarshall(
6637 PMIDL_STUB_MESSAGE pStubMsg
,
6638 unsigned char *pMemory
,
6639 PFORMAT_STRING pFormat
)
6641 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6643 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6645 ERR("invalid format type %x\n", *pFormat
);
6646 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6648 TRACE("flags: 0x%02x\n", pFormat
[1]);
6650 if (pFormat
[1] & 0x80)
6651 NdrClientContextMarshall(pStubMsg
, *(NDR_CCONTEXT
**)pMemory
, FALSE
);
6653 NdrClientContextMarshall(pStubMsg
, pMemory
, FALSE
);
6658 /***********************************************************************
6659 * NdrContextHandleUnmarshall [internal]
6661 static unsigned char *WINAPI
NdrContextHandleUnmarshall(
6662 PMIDL_STUB_MESSAGE pStubMsg
,
6663 unsigned char **ppMemory
,
6664 PFORMAT_STRING pFormat
,
6665 unsigned char fMustAlloc
)
6667 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg
,
6668 ppMemory
, pFormat
, fMustAlloc
? "TRUE": "FALSE");
6670 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6672 ERR("invalid format type %x\n", *pFormat
);
6673 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6675 TRACE("flags: 0x%02x\n", pFormat
[1]);
6677 /* [out]-only or [ret] param */
6678 if ((pFormat
[1] & 0x60) == 0x20)
6679 **(NDR_CCONTEXT
**)ppMemory
= NULL
;
6680 NdrClientContextUnmarshall(pStubMsg
, *(NDR_CCONTEXT
**)ppMemory
, pStubMsg
->RpcMsg
->Handle
);
6685 /***********************************************************************
6686 * NdrClientContextMarshall [RPCRT4.@]
6688 void WINAPI
NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6689 NDR_CCONTEXT ContextHandle
,
6692 TRACE("(%p, %p, %d)\n", pStubMsg
, ContextHandle
, fCheck
);
6694 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
6696 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6698 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6699 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6700 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6703 /* FIXME: what does fCheck do? */
6704 NDRCContextMarshall(ContextHandle
,
6707 pStubMsg
->Buffer
+= cbNDRContext
;
6710 /***********************************************************************
6711 * NdrClientContextUnmarshall [RPCRT4.@]
6713 void WINAPI
NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6714 NDR_CCONTEXT
* pContextHandle
,
6715 RPC_BINDING_HANDLE BindHandle
)
6717 TRACE("(%p, %p, %p)\n", pStubMsg
, pContextHandle
, BindHandle
);
6719 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6721 if (pStubMsg
->Buffer
+ cbNDRContext
> pStubMsg
->BufferEnd
)
6722 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6724 NDRCContextUnmarshall(pContextHandle
,
6727 pStubMsg
->RpcMsg
->DataRepresentation
);
6729 pStubMsg
->Buffer
+= cbNDRContext
;
6732 void WINAPI
NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6733 NDR_SCONTEXT ContextHandle
,
6734 NDR_RUNDOWN RundownRoutine
)
6736 TRACE("(%p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
);
6738 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6740 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6742 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6743 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6744 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6747 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
6748 pStubMsg
->Buffer
, RundownRoutine
, NULL
,
6749 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
6750 pStubMsg
->Buffer
+= cbNDRContext
;
6753 NDR_SCONTEXT WINAPI
NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
)
6755 NDR_SCONTEXT ContextHandle
;
6757 TRACE("(%p)\n", pStubMsg
);
6759 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6761 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6763 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6764 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6765 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6768 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
6770 pStubMsg
->RpcMsg
->DataRepresentation
,
6771 NULL
, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
6772 pStubMsg
->Buffer
+= cbNDRContext
;
6774 return ContextHandle
;
6777 void WINAPI
NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg
,
6778 unsigned char* pMemory
,
6779 PFORMAT_STRING pFormat
)
6781 FIXME("(%p, %p, %p): stub\n", pStubMsg
, pMemory
, pFormat
);
6784 NDR_SCONTEXT WINAPI
NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg
,
6785 PFORMAT_STRING pFormat
)
6787 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6788 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6790 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
6792 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
6793 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
6794 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
6795 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
6796 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
6798 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
6799 if_id
= &sif
->InterfaceId
;
6802 return NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
, NULL
,
6803 pStubMsg
->RpcMsg
->DataRepresentation
, if_id
,
6807 void WINAPI
NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6808 NDR_SCONTEXT ContextHandle
,
6809 NDR_RUNDOWN RundownRoutine
,
6810 PFORMAT_STRING pFormat
)
6812 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6813 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6815 TRACE("(%p, %p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
, pFormat
);
6817 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6819 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6821 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6822 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6823 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6826 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
6827 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
6828 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
6829 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
6830 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
6832 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
6833 if_id
= &sif
->InterfaceId
;
6836 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
6837 pStubMsg
->Buffer
, RundownRoutine
, if_id
, flags
);
6838 pStubMsg
->Buffer
+= cbNDRContext
;
6841 NDR_SCONTEXT WINAPI
NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6842 PFORMAT_STRING pFormat
)
6844 NDR_SCONTEXT ContextHandle
;
6845 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6846 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6848 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
6850 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6852 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6854 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6855 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6856 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6859 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
6860 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
6861 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
6862 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
6863 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
6865 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
6866 if_id
= &sif
->InterfaceId
;
6869 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
6871 pStubMsg
->RpcMsg
->DataRepresentation
,
6873 pStubMsg
->Buffer
+= cbNDRContext
;
6875 return ContextHandle
;
6878 /***********************************************************************
6879 * NdrCorrelationInitialize [RPCRT4.@]
6881 * Initializes correlation validity checking.
6884 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6885 * pMemory [I] Pointer to memory to use as a cache.
6886 * CacheSize [I] Size of the memory pointed to by pMemory.
6887 * Flags [I] Reserved. Set to zero.
6892 void WINAPI
NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg
, void *pMemory
, ULONG CacheSize
, ULONG Flags
)
6894 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg
, pMemory
, CacheSize
, Flags
);
6895 pStubMsg
->fHasNewCorrDesc
= TRUE
;
6898 /***********************************************************************
6899 * NdrCorrelationPass [RPCRT4.@]
6901 * Performs correlation validity checking.
6904 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6909 void WINAPI
NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg
)
6911 FIXME("(%p): stub\n", pStubMsg
);
6914 /***********************************************************************
6915 * NdrCorrelationFree [RPCRT4.@]
6917 * Frees any resources used while unmarshalling parameters that need
6918 * correlation validity checking.
6921 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6926 void WINAPI
NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg
)
6928 FIXME("(%p): stub\n", pStubMsg
);