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 unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1002 unsigned char *Buffer
,
1003 PFORMAT_STRING pFormat
)
1005 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1006 PFORMAT_STRING desc
;
1008 DWORD pointer_id
= 0;
1009 int pointer_needs_sizing
;
1011 TRACE("(%p,%p,%p)\n", pStubMsg
, Buffer
, pFormat
);
1012 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1014 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1015 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1018 case RPC_FC_RP
: /* ref pointer (always non-null) */
1019 pointer_needs_sizing
= 1;
1021 case RPC_FC_UP
: /* unique pointer */
1022 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
1023 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1024 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1026 pointer_needs_sizing
= 1;
1028 pointer_needs_sizing
= 0;
1033 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1034 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1035 pointer_needs_sizing
= !NdrFullPointerQueryRefId(
1036 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, &pointer
);
1040 FIXME("unhandled ptr type=%02x\n", type
);
1041 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1045 if (attr
& RPC_FC_P_DEREF
) {
1049 if (pointer_needs_sizing
) {
1050 m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
1051 if (m
) m(pStubMsg
, desc
);
1052 else FIXME("no memorysizer for data type=%02x\n", *desc
);
1055 return pStubMsg
->MemorySize
;
1058 /***********************************************************************
1059 * PointerFree [internal]
1061 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1062 unsigned char *Pointer
,
1063 PFORMAT_STRING pFormat
)
1065 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1066 PFORMAT_STRING desc
;
1068 unsigned char *current_pointer
= Pointer
;
1070 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1071 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1072 if (attr
& RPC_FC_P_DONTFREE
) return;
1074 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1075 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1077 if (!Pointer
) return;
1079 if (type
== RPC_FC_FP
) {
1080 int pointer_needs_freeing
= NdrFullPointerFree(
1081 pStubMsg
->FullPtrXlatTables
, Pointer
);
1082 if (!pointer_needs_freeing
)
1086 if (attr
& RPC_FC_P_DEREF
) {
1087 current_pointer
= *(unsigned char**)Pointer
;
1088 TRACE("deref => %p\n", current_pointer
);
1091 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
1092 if (m
) m(pStubMsg
, current_pointer
, desc
);
1094 /* this check stops us from trying to free buffer memory. we don't have to
1095 * worry about clients, since they won't call this function.
1096 * we don't have to check for the buffer being reallocated because
1097 * BufferStart and BufferEnd won't be reset when allocating memory for
1098 * sending the response. we don't have to check for the new buffer here as
1099 * it won't be used a type memory, only for buffer memory */
1100 if (Pointer
>= pStubMsg
->BufferStart
&& Pointer
< pStubMsg
->BufferEnd
)
1103 if (attr
& RPC_FC_P_ONSTACK
) {
1104 TRACE("not freeing stack ptr %p\n", Pointer
);
1107 TRACE("freeing %p\n", Pointer
);
1108 NdrFree(pStubMsg
, Pointer
);
1111 TRACE("not freeing %p\n", Pointer
);
1114 /***********************************************************************
1115 * EmbeddedPointerMarshall
1117 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1118 unsigned char *pMemory
,
1119 PFORMAT_STRING pFormat
)
1121 unsigned char *Mark
= pStubMsg
->BufferMark
;
1122 unsigned rep
, count
, stride
;
1124 unsigned char *saved_buffer
= NULL
;
1126 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1128 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1131 if (pStubMsg
->PointerBufferMark
)
1133 saved_buffer
= pStubMsg
->Buffer
;
1134 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1135 pStubMsg
->PointerBufferMark
= NULL
;
1138 while (pFormat
[0] != RPC_FC_END
) {
1139 switch (pFormat
[0]) {
1141 FIXME("unknown repeat type %d\n", pFormat
[0]);
1142 case RPC_FC_NO_REPEAT
:
1148 case RPC_FC_FIXED_REPEAT
:
1149 rep
= *(const WORD
*)&pFormat
[2];
1150 stride
= *(const WORD
*)&pFormat
[4];
1151 count
= *(const WORD
*)&pFormat
[8];
1154 case RPC_FC_VARIABLE_REPEAT
:
1155 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1156 stride
= *(const WORD
*)&pFormat
[2];
1157 count
= *(const WORD
*)&pFormat
[6];
1161 for (i
= 0; i
< rep
; i
++) {
1162 PFORMAT_STRING info
= pFormat
;
1163 unsigned char *membase
= pMemory
+ (i
* stride
);
1164 unsigned char *bufbase
= Mark
+ (i
* stride
);
1167 for (u
=0; u
<count
; u
++,info
+=8) {
1168 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1169 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1170 unsigned char *saved_memory
= pStubMsg
->Memory
;
1172 pStubMsg
->Memory
= pMemory
;
1173 PointerMarshall(pStubMsg
, bufptr
, *(unsigned char**)memptr
, info
+4);
1174 pStubMsg
->Memory
= saved_memory
;
1177 pFormat
+= 8 * count
;
1182 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1183 pStubMsg
->Buffer
= saved_buffer
;
1186 STD_OVERFLOW_CHECK(pStubMsg
);
1191 /***********************************************************************
1192 * EmbeddedPointerUnmarshall
1194 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1195 unsigned char *pDstBuffer
,
1196 unsigned char *pSrcMemoryPtrs
,
1197 PFORMAT_STRING pFormat
,
1198 unsigned char fMustAlloc
)
1200 unsigned char *Mark
= pStubMsg
->BufferMark
;
1201 unsigned rep
, count
, stride
;
1203 unsigned char *saved_buffer
= NULL
;
1205 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg
, pDstBuffer
, pSrcMemoryPtrs
, pFormat
, fMustAlloc
);
1207 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1210 if (pStubMsg
->PointerBufferMark
)
1212 saved_buffer
= pStubMsg
->Buffer
;
1213 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1214 pStubMsg
->PointerBufferMark
= NULL
;
1217 while (pFormat
[0] != RPC_FC_END
) {
1218 TRACE("pFormat[0] = 0x%x\n", pFormat
[0]);
1219 switch (pFormat
[0]) {
1221 FIXME("unknown repeat type %d\n", pFormat
[0]);
1222 case RPC_FC_NO_REPEAT
:
1228 case RPC_FC_FIXED_REPEAT
:
1229 rep
= *(const WORD
*)&pFormat
[2];
1230 stride
= *(const WORD
*)&pFormat
[4];
1231 count
= *(const WORD
*)&pFormat
[8];
1234 case RPC_FC_VARIABLE_REPEAT
:
1235 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1236 stride
= *(const WORD
*)&pFormat
[2];
1237 count
= *(const WORD
*)&pFormat
[6];
1241 for (i
= 0; i
< rep
; i
++) {
1242 PFORMAT_STRING info
= pFormat
;
1243 unsigned char *bufdstbase
= pDstBuffer
+ (i
* stride
);
1244 unsigned char *memsrcbase
= pSrcMemoryPtrs
+ (i
* stride
);
1245 unsigned char *bufbase
= Mark
+ (i
* stride
);
1248 for (u
=0; u
<count
; u
++,info
+=8) {
1249 unsigned char **bufdstptr
= (unsigned char **)(bufdstbase
+ *(const SHORT
*)&info
[2]);
1250 unsigned char **memsrcptr
= (unsigned char **)(memsrcbase
+ *(const SHORT
*)&info
[0]);
1251 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1252 PointerUnmarshall(pStubMsg
, bufptr
, bufdstptr
, *memsrcptr
, info
+4, fMustAlloc
);
1255 pFormat
+= 8 * count
;
1260 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1261 pStubMsg
->Buffer
= saved_buffer
;
1267 /***********************************************************************
1268 * EmbeddedPointerBufferSize
1270 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1271 unsigned char *pMemory
,
1272 PFORMAT_STRING pFormat
)
1274 unsigned rep
, count
, stride
;
1276 ULONG saved_buffer_length
= 0;
1278 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1280 if (pStubMsg
->IgnoreEmbeddedPointers
) return;
1282 if (*pFormat
!= RPC_FC_PP
) return;
1285 if (pStubMsg
->PointerLength
)
1287 saved_buffer_length
= pStubMsg
->BufferLength
;
1288 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
1289 pStubMsg
->PointerLength
= 0;
1292 while (pFormat
[0] != RPC_FC_END
) {
1293 switch (pFormat
[0]) {
1295 FIXME("unknown repeat type %d\n", pFormat
[0]);
1296 case RPC_FC_NO_REPEAT
:
1302 case RPC_FC_FIXED_REPEAT
:
1303 rep
= *(const WORD
*)&pFormat
[2];
1304 stride
= *(const WORD
*)&pFormat
[4];
1305 count
= *(const WORD
*)&pFormat
[8];
1308 case RPC_FC_VARIABLE_REPEAT
:
1309 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1310 stride
= *(const WORD
*)&pFormat
[2];
1311 count
= *(const WORD
*)&pFormat
[6];
1315 for (i
= 0; i
< rep
; i
++) {
1316 PFORMAT_STRING info
= pFormat
;
1317 unsigned char *membase
= pMemory
+ (i
* stride
);
1320 for (u
=0; u
<count
; u
++,info
+=8) {
1321 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1322 unsigned char *saved_memory
= pStubMsg
->Memory
;
1324 pStubMsg
->Memory
= pMemory
;
1325 PointerBufferSize(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1326 pStubMsg
->Memory
= saved_memory
;
1329 pFormat
+= 8 * count
;
1332 if (saved_buffer_length
)
1334 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
1335 pStubMsg
->BufferLength
= saved_buffer_length
;
1339 /***********************************************************************
1340 * EmbeddedPointerMemorySize [internal]
1342 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1343 PFORMAT_STRING pFormat
)
1345 unsigned char *Mark
= pStubMsg
->BufferMark
;
1346 unsigned rep
, count
, stride
;
1348 unsigned char *saved_buffer
= NULL
;
1350 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1352 if (pStubMsg
->IgnoreEmbeddedPointers
) return 0;
1354 if (pStubMsg
->PointerBufferMark
)
1356 saved_buffer
= pStubMsg
->Buffer
;
1357 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1358 pStubMsg
->PointerBufferMark
= NULL
;
1361 if (*pFormat
!= RPC_FC_PP
) return 0;
1364 while (pFormat
[0] != RPC_FC_END
) {
1365 switch (pFormat
[0]) {
1367 FIXME("unknown repeat type %d\n", pFormat
[0]);
1368 case RPC_FC_NO_REPEAT
:
1374 case RPC_FC_FIXED_REPEAT
:
1375 rep
= *(const WORD
*)&pFormat
[2];
1376 stride
= *(const WORD
*)&pFormat
[4];
1377 count
= *(const WORD
*)&pFormat
[8];
1380 case RPC_FC_VARIABLE_REPEAT
:
1381 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1382 stride
= *(const WORD
*)&pFormat
[2];
1383 count
= *(const WORD
*)&pFormat
[6];
1387 for (i
= 0; i
< rep
; i
++) {
1388 PFORMAT_STRING info
= pFormat
;
1389 unsigned char *bufbase
= Mark
+ (i
* stride
);
1391 for (u
=0; u
<count
; u
++,info
+=8) {
1392 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1393 PointerMemorySize(pStubMsg
, bufptr
, info
+4);
1396 pFormat
+= 8 * count
;
1401 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1402 pStubMsg
->Buffer
= saved_buffer
;
1408 /***********************************************************************
1409 * EmbeddedPointerFree [internal]
1411 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1412 unsigned char *pMemory
,
1413 PFORMAT_STRING pFormat
)
1415 unsigned rep
, count
, stride
;
1418 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1419 if (*pFormat
!= RPC_FC_PP
) return;
1422 while (pFormat
[0] != RPC_FC_END
) {
1423 switch (pFormat
[0]) {
1425 FIXME("unknown repeat type %d\n", pFormat
[0]);
1426 case RPC_FC_NO_REPEAT
:
1432 case RPC_FC_FIXED_REPEAT
:
1433 rep
= *(const WORD
*)&pFormat
[2];
1434 stride
= *(const WORD
*)&pFormat
[4];
1435 count
= *(const WORD
*)&pFormat
[8];
1438 case RPC_FC_VARIABLE_REPEAT
:
1439 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1440 stride
= *(const WORD
*)&pFormat
[2];
1441 count
= *(const WORD
*)&pFormat
[6];
1445 for (i
= 0; i
< rep
; i
++) {
1446 PFORMAT_STRING info
= pFormat
;
1447 unsigned char *membase
= pMemory
+ (i
* stride
);
1450 for (u
=0; u
<count
; u
++,info
+=8) {
1451 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1452 unsigned char *saved_memory
= pStubMsg
->Memory
;
1454 pStubMsg
->Memory
= pMemory
;
1455 PointerFree(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1456 pStubMsg
->Memory
= saved_memory
;
1459 pFormat
+= 8 * count
;
1463 /***********************************************************************
1464 * NdrPointerMarshall [RPCRT4.@]
1466 unsigned char * WINAPI
NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1467 unsigned char *pMemory
,
1468 PFORMAT_STRING pFormat
)
1470 unsigned char *Buffer
;
1472 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1474 /* Increment the buffer here instead of in PointerMarshall,
1475 * as that is used by embedded pointers which already handle the incrementing
1476 * the buffer, and shouldn't write any additional pointer data to the wire */
1477 if (*pFormat
!= RPC_FC_RP
)
1479 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
1480 Buffer
= pStubMsg
->Buffer
;
1481 safe_buffer_increment(pStubMsg
, 4);
1484 Buffer
= pStubMsg
->Buffer
;
1486 PointerMarshall(pStubMsg
, Buffer
, pMemory
, pFormat
);
1491 /***********************************************************************
1492 * NdrPointerUnmarshall [RPCRT4.@]
1494 unsigned char * WINAPI
NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1495 unsigned char **ppMemory
,
1496 PFORMAT_STRING pFormat
,
1497 unsigned char fMustAlloc
)
1499 unsigned char *Buffer
;
1501 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1503 if (*pFormat
== RPC_FC_RP
)
1505 Buffer
= pStubMsg
->Buffer
;
1506 /* Do the NULL ref pointer check here because embedded pointers can be
1507 * NULL if the type the pointer is embedded in was allocated rather than
1508 * being passed in by the client */
1509 if (pStubMsg
->IsClient
&& !*ppMemory
)
1511 ERR("NULL ref pointer is not allowed\n");
1512 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
1517 /* Increment the buffer here instead of in PointerUnmarshall,
1518 * as that is used by embedded pointers which already handle the incrementing
1519 * the buffer, and shouldn't read any additional pointer data from the
1521 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1522 Buffer
= pStubMsg
->Buffer
;
1523 safe_buffer_increment(pStubMsg
, 4);
1526 PointerUnmarshall(pStubMsg
, Buffer
, ppMemory
, *ppMemory
, pFormat
, fMustAlloc
);
1531 /***********************************************************************
1532 * NdrPointerBufferSize [RPCRT4.@]
1534 void WINAPI
NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1535 unsigned char *pMemory
,
1536 PFORMAT_STRING pFormat
)
1538 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1540 /* Increment the buffer length here instead of in PointerBufferSize,
1541 * as that is used by embedded pointers which already handle the buffer
1542 * length, and shouldn't write anything more to the wire */
1543 if (*pFormat
!= RPC_FC_RP
)
1545 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
1546 safe_buffer_length_increment(pStubMsg
, 4);
1549 PointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1552 /***********************************************************************
1553 * NdrPointerMemorySize [RPCRT4.@]
1555 ULONG WINAPI
NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1556 PFORMAT_STRING pFormat
)
1558 /* unsigned size = *(LPWORD)(pFormat+2); */
1559 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1560 PointerMemorySize(pStubMsg
, pStubMsg
->Buffer
, pFormat
);
1564 /***********************************************************************
1565 * NdrPointerFree [RPCRT4.@]
1567 void WINAPI
NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1568 unsigned char *pMemory
,
1569 PFORMAT_STRING pFormat
)
1571 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1572 PointerFree(pStubMsg
, pMemory
, pFormat
);
1575 /***********************************************************************
1576 * NdrSimpleTypeMarshall [RPCRT4.@]
1578 void WINAPI
NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1579 unsigned char FormatChar
)
1581 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &FormatChar
);
1584 /***********************************************************************
1585 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1587 * Unmarshall a base type.
1590 * Doesn't check that the buffer is long enough before copying, so the caller
1593 void WINAPI
NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1594 unsigned char FormatChar
)
1596 #define BASE_TYPE_UNMARSHALL(type) \
1597 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
1598 TRACE("pMemory: %p\n", pMemory); \
1599 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1600 pStubMsg->Buffer += sizeof(type);
1608 BASE_TYPE_UNMARSHALL(UCHAR
);
1609 TRACE("value: 0x%02x\n", *pMemory
);
1614 BASE_TYPE_UNMARSHALL(USHORT
);
1615 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
1619 case RPC_FC_ERROR_STATUS_T
:
1621 BASE_TYPE_UNMARSHALL(ULONG
);
1622 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
1625 BASE_TYPE_UNMARSHALL(float);
1626 TRACE("value: %f\n", *(float *)pMemory
);
1629 BASE_TYPE_UNMARSHALL(double);
1630 TRACE("value: %f\n", *(double *)pMemory
);
1633 BASE_TYPE_UNMARSHALL(ULONGLONG
);
1634 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
1637 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
1638 TRACE("pMemory: %p\n", pMemory
);
1639 /* 16-bits on the wire, but int in memory */
1640 *(UINT
*)pMemory
= *(USHORT
*)pStubMsg
->Buffer
;
1641 pStubMsg
->Buffer
+= sizeof(USHORT
);
1642 TRACE("value: 0x%08x\n", *(UINT
*)pMemory
);
1647 FIXME("Unhandled base type: 0x%02x\n", FormatChar
);
1649 #undef BASE_TYPE_UNMARSHALL
1652 /***********************************************************************
1653 * NdrSimpleStructMarshall [RPCRT4.@]
1655 unsigned char * WINAPI
NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1656 unsigned char *pMemory
,
1657 PFORMAT_STRING pFormat
)
1659 unsigned size
= *(const WORD
*)(pFormat
+2);
1660 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1662 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pFormat
[1] + 1);
1664 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1665 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
1667 if (pFormat
[0] != RPC_FC_STRUCT
)
1668 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
+4);
1673 /***********************************************************************
1674 * NdrSimpleStructUnmarshall [RPCRT4.@]
1676 unsigned char * WINAPI
NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1677 unsigned char **ppMemory
,
1678 PFORMAT_STRING pFormat
,
1679 unsigned char fMustAlloc
)
1681 unsigned size
= *(const WORD
*)(pFormat
+2);
1682 unsigned char *saved_buffer
;
1683 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1685 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1688 *ppMemory
= NdrAllocate(pStubMsg
, size
);
1691 if (!pStubMsg
->IsClient
&& !*ppMemory
)
1692 /* for servers, we just point straight into the RPC buffer */
1693 *ppMemory
= pStubMsg
->Buffer
;
1696 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1697 safe_buffer_increment(pStubMsg
, size
);
1698 if (pFormat
[0] == RPC_FC_PSTRUCT
)
1699 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
+4, fMustAlloc
);
1701 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
1702 if (*ppMemory
!= saved_buffer
)
1703 memcpy(*ppMemory
, saved_buffer
, size
);
1708 /***********************************************************************
1709 * NdrSimpleStructBufferSize [RPCRT4.@]
1711 void WINAPI
NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1712 unsigned char *pMemory
,
1713 PFORMAT_STRING pFormat
)
1715 unsigned size
= *(const WORD
*)(pFormat
+2);
1716 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1718 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
1720 safe_buffer_length_increment(pStubMsg
, size
);
1721 if (pFormat
[0] != RPC_FC_STRUCT
)
1722 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
+4);
1725 /***********************************************************************
1726 * NdrSimpleStructMemorySize [RPCRT4.@]
1728 ULONG WINAPI
NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1729 PFORMAT_STRING pFormat
)
1731 unsigned short size
= *(const WORD
*)(pFormat
+2);
1733 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1735 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1736 pStubMsg
->MemorySize
+= size
;
1737 safe_buffer_increment(pStubMsg
, size
);
1739 if (pFormat
[0] != RPC_FC_STRUCT
)
1740 EmbeddedPointerMemorySize(pStubMsg
, pFormat
+4);
1741 return pStubMsg
->MemorySize
;
1744 /***********************************************************************
1745 * NdrSimpleStructFree [RPCRT4.@]
1747 void WINAPI
NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
1748 unsigned char *pMemory
,
1749 PFORMAT_STRING pFormat
)
1751 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1752 if (pFormat
[0] != RPC_FC_STRUCT
)
1753 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
+4);
1758 static inline void array_compute_and_size_conformance(
1759 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1760 PFORMAT_STRING pFormat
)
1765 ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1766 SizeConformance(pStubMsg
);
1768 case RPC_FC_CVARRAY
:
1769 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, 0);
1770 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
1771 SizeConformance(pStubMsg
);
1773 case RPC_FC_C_CSTRING
:
1774 case RPC_FC_C_WSTRING
:
1775 if (pFormat
[0] == RPC_FC_C_CSTRING
)
1777 TRACE("string=%s\n", debugstr_a((const char *)pMemory
));
1778 pStubMsg
->ActualCount
= strlen((const char *)pMemory
)+1;
1782 TRACE("string=%s\n", debugstr_w((LPCWSTR
)pMemory
));
1783 pStubMsg
->ActualCount
= strlenW((LPCWSTR
)pMemory
)+1;
1786 if (fc
== RPC_FC_STRING_SIZED
)
1787 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
1789 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
1791 SizeConformance(pStubMsg
);
1794 ERR("unknown array format 0x%x\n", fc
);
1795 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1799 static inline void array_buffer_size(
1800 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1801 PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
1805 unsigned char alignment
;
1810 esize
= *(const WORD
*)(pFormat
+2);
1811 alignment
= pFormat
[1] + 1;
1813 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1815 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
1817 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
1818 /* conformance value plus array */
1819 safe_buffer_length_increment(pStubMsg
, size
);
1822 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1824 case RPC_FC_CVARRAY
:
1825 esize
= *(const WORD
*)(pFormat
+2);
1826 alignment
= pFormat
[1] + 1;
1828 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1829 pFormat
= SkipConformance(pStubMsg
, pFormat
);
1831 SizeVariance(pStubMsg
);
1833 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
1835 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1836 safe_buffer_length_increment(pStubMsg
, size
);
1839 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1841 case RPC_FC_C_CSTRING
:
1842 case RPC_FC_C_WSTRING
:
1843 if (fc
== RPC_FC_C_CSTRING
)
1848 SizeVariance(pStubMsg
);
1850 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1851 safe_buffer_length_increment(pStubMsg
, size
);
1854 ERR("unknown array format 0x%x\n", fc
);
1855 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1859 static inline void array_compute_and_write_conformance(
1860 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1861 PFORMAT_STRING pFormat
)
1866 ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1867 WriteConformance(pStubMsg
);
1869 case RPC_FC_CVARRAY
:
1870 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, 0);
1871 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
1872 WriteConformance(pStubMsg
);
1874 case RPC_FC_C_CSTRING
:
1875 case RPC_FC_C_WSTRING
:
1876 if (fc
== RPC_FC_C_CSTRING
)
1878 TRACE("string=%s\n", debugstr_a((const char *)pMemory
));
1879 pStubMsg
->ActualCount
= strlen((const char *)pMemory
)+1;
1883 TRACE("string=%s\n", debugstr_w((LPCWSTR
)pMemory
));
1884 pStubMsg
->ActualCount
= strlenW((LPCWSTR
)pMemory
)+1;
1886 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
1887 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
1889 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
1890 pStubMsg
->Offset
= 0;
1891 WriteConformance(pStubMsg
);
1894 ERR("unknown array format 0x%x\n", fc
);
1895 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1899 static inline void array_write_variance_and_marshall(
1900 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1901 PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
1905 unsigned char alignment
;
1910 esize
= *(const WORD
*)(pFormat
+2);
1911 alignment
= pFormat
[1] + 1;
1913 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1915 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
1917 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
1919 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1920 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
1923 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
1925 case RPC_FC_CVARRAY
:
1926 esize
= *(const WORD
*)(pFormat
+2);
1927 alignment
= pFormat
[1] + 1;
1930 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1932 pFormat
= SkipConformance(pStubMsg
, pFormat
);
1934 WriteVariance(pStubMsg
);
1936 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
1938 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1941 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1942 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, size
);
1945 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
1947 case RPC_FC_C_CSTRING
:
1948 case RPC_FC_C_WSTRING
:
1949 if (fc
== RPC_FC_C_CSTRING
)
1954 WriteVariance(pStubMsg
);
1956 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1957 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
1960 ERR("unknown array format 0x%x\n", fc
);
1961 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1965 static inline ULONG
array_read_conformance(
1966 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
1973 esize
= *(const WORD
*)(pFormat
+2);
1974 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
1975 return safe_multiply(esize
, pStubMsg
->MaxCount
);
1976 case RPC_FC_CVARRAY
:
1977 esize
= *(const WORD
*)(pFormat
+2);
1978 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
1979 return safe_multiply(esize
, pStubMsg
->MaxCount
);
1980 case RPC_FC_C_CSTRING
:
1981 case RPC_FC_C_WSTRING
:
1982 if (fc
== RPC_FC_C_CSTRING
)
1987 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
1988 ReadConformance(pStubMsg
, pFormat
+ 2);
1990 ReadConformance(pStubMsg
, NULL
);
1991 return safe_multiply(esize
, pStubMsg
->MaxCount
);
1993 ERR("unknown array format 0x%x\n", fc
);
1994 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1998 static inline ULONG
array_read_variance_and_unmarshall(
1999 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char **ppMemory
,
2000 PFORMAT_STRING pFormat
, unsigned char fMustAlloc
,
2001 unsigned char fUseBufferMemoryServer
, unsigned char fUnmarshall
)
2003 ULONG bufsize
, memsize
;
2005 unsigned char alignment
;
2006 unsigned char *saved_buffer
;
2012 esize
= *(const WORD
*)(pFormat
+2);
2013 alignment
= pFormat
[1] + 1;
2015 bufsize
= memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2017 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2019 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2024 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2027 if (fUseBufferMemoryServer
&& !pStubMsg
->IsClient
&& !*ppMemory
)
2028 /* for servers, we just point straight into the RPC buffer */
2029 *ppMemory
= pStubMsg
->Buffer
;
2032 saved_buffer
= pStubMsg
->Buffer
;
2033 safe_buffer_increment(pStubMsg
, bufsize
);
2035 pStubMsg
->BufferMark
= saved_buffer
;
2036 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
2038 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
2039 if (*ppMemory
!= saved_buffer
)
2040 memcpy(*ppMemory
, saved_buffer
, bufsize
);
2043 case RPC_FC_CVARRAY
:
2044 esize
= *(const WORD
*)(pFormat
+2);
2045 alignment
= pFormat
[1] + 1;
2047 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2049 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2051 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2053 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2054 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2058 offset
= pStubMsg
->Offset
;
2060 if (!fMustAlloc
&& !*ppMemory
)
2063 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2064 saved_buffer
= pStubMsg
->Buffer
;
2065 safe_buffer_increment(pStubMsg
, bufsize
);
2067 pStubMsg
->BufferMark
= saved_buffer
;
2068 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
,
2071 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
2074 case RPC_FC_C_CSTRING
:
2075 case RPC_FC_C_WSTRING
:
2076 if (fc
== RPC_FC_C_CSTRING
)
2081 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
2083 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
2085 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2086 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
2087 RpcRaiseException(RPC_S_INVALID_BOUND
);
2089 if (pStubMsg
->Offset
)
2091 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2092 RpcRaiseException(RPC_S_INVALID_BOUND
);
2095 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2096 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2098 validate_string_data(pStubMsg
, bufsize
, esize
);
2103 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2106 if (fUseBufferMemoryServer
&& !pStubMsg
->IsClient
&&
2107 !*ppMemory
&& (pStubMsg
->MaxCount
== pStubMsg
->ActualCount
))
2108 /* if the data in the RPC buffer is big enough, we just point
2109 * straight into it */
2110 *ppMemory
= pStubMsg
->Buffer
;
2111 else if (!*ppMemory
)
2112 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2115 if (*ppMemory
== pStubMsg
->Buffer
)
2116 safe_buffer_increment(pStubMsg
, bufsize
);
2118 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
2120 if (*pFormat
== RPC_FC_C_CSTRING
)
2121 TRACE("string=%s\n", debugstr_a((char*)*ppMemory
));
2123 TRACE("string=%s\n", debugstr_w((LPWSTR
)*ppMemory
));
2127 ERR("unknown array format 0x%x\n", fc
);
2128 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2132 static inline void array_memory_size(
2133 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
,
2134 unsigned char fHasPointers
)
2136 ULONG bufsize
, memsize
;
2138 unsigned char alignment
;
2143 esize
= *(const WORD
*)(pFormat
+2);
2144 alignment
= pFormat
[1] + 1;
2146 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2148 bufsize
= memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2149 pStubMsg
->MemorySize
+= memsize
;
2151 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2153 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2154 safe_buffer_increment(pStubMsg
, bufsize
);
2157 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2159 case RPC_FC_CVARRAY
:
2160 esize
= *(const WORD
*)(pFormat
+2);
2161 alignment
= pFormat
[1] + 1;
2163 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2165 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2167 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2168 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2169 pStubMsg
->MemorySize
+= memsize
;
2171 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2173 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2174 safe_buffer_increment(pStubMsg
, bufsize
);
2177 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2179 case RPC_FC_C_CSTRING
:
2180 case RPC_FC_C_WSTRING
:
2181 if (fc
== RPC_FC_C_CSTRING
)
2186 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
2188 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
2190 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2191 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
2192 RpcRaiseException(RPC_S_INVALID_BOUND
);
2194 if (pStubMsg
->Offset
)
2196 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2197 RpcRaiseException(RPC_S_INVALID_BOUND
);
2200 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2201 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2203 validate_string_data(pStubMsg
, bufsize
, esize
);
2205 safe_buffer_increment(pStubMsg
, bufsize
);
2206 pStubMsg
->MemorySize
+= memsize
;
2209 ERR("unknown array format 0x%x\n", fc
);
2210 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2214 static inline void array_free(
2215 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
,
2216 unsigned char *pMemory
, PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
2221 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2223 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2225 case RPC_FC_CVARRAY
:
2226 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2227 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2229 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2231 case RPC_FC_C_CSTRING
:
2232 case RPC_FC_C_WSTRING
:
2233 /* No embedded pointers so nothing to do */
2236 ERR("unknown array format 0x%x\n", fc
);
2237 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2242 * NdrConformantString:
2244 * What MS calls a ConformantString is, in DCE terminology,
2245 * a Varying-Conformant String.
2247 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2248 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2249 * into unmarshalled string)
2250 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2252 * data: CHARTYPE[maxlen]
2254 * ], where CHARTYPE is the appropriate character type (specified externally)
2258 /***********************************************************************
2259 * NdrConformantStringMarshall [RPCRT4.@]
2261 unsigned char *WINAPI
NdrConformantStringMarshall(MIDL_STUB_MESSAGE
*pStubMsg
,
2262 unsigned char *pszMessage
, PFORMAT_STRING pFormat
)
2264 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg
, pszMessage
, pFormat
);
2266 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2267 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2268 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2271 /* allow compiler to optimise inline function by passing constant into
2272 * these functions */
2273 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2274 array_compute_and_write_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pszMessage
,
2276 array_write_variance_and_marshall(RPC_FC_C_CSTRING
, pStubMsg
, pszMessage
,
2277 pFormat
, TRUE
/* fHasPointers */);
2279 array_compute_and_write_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pszMessage
,
2281 array_write_variance_and_marshall(RPC_FC_C_WSTRING
, pStubMsg
, pszMessage
,
2282 pFormat
, TRUE
/* fHasPointers */);
2288 /***********************************************************************
2289 * NdrConformantStringBufferSize [RPCRT4.@]
2291 void WINAPI
NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2292 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
2294 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2296 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2297 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2298 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2301 /* allow compiler to optimise inline function by passing constant into
2302 * these functions */
2303 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2304 array_compute_and_size_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pMemory
,
2306 array_buffer_size(RPC_FC_C_CSTRING
, pStubMsg
, pMemory
, pFormat
,
2307 TRUE
/* fHasPointers */);
2309 array_compute_and_size_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pMemory
,
2311 array_buffer_size(RPC_FC_C_WSTRING
, pStubMsg
, pMemory
, pFormat
,
2312 TRUE
/* fHasPointers */);
2316 /************************************************************************
2317 * NdrConformantStringMemorySize [RPCRT4.@]
2319 ULONG WINAPI
NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
2320 PFORMAT_STRING pFormat
)
2322 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
2324 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2325 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2326 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2329 /* allow compiler to optimise inline function by passing constant into
2330 * these functions */
2331 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2332 array_read_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
);
2333 array_memory_size(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
,
2334 TRUE
/* fHasPointers */);
2336 array_read_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
);
2337 array_memory_size(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
,
2338 TRUE
/* fHasPointers */);
2341 return pStubMsg
->MemorySize
;
2344 /************************************************************************
2345 * NdrConformantStringUnmarshall [RPCRT4.@]
2347 unsigned char *WINAPI
NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2348 unsigned char** ppMemory
, PFORMAT_STRING pFormat
, unsigned char fMustAlloc
)
2350 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2351 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
2353 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2354 ERR("Unhandled string type: %#x\n", *pFormat
);
2355 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2358 /* allow compiler to optimise inline function by passing constant into
2359 * these functions */
2360 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2361 array_read_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
);
2362 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING
, pStubMsg
, ppMemory
,
2363 pFormat
, fMustAlloc
,
2364 TRUE
/* fUseBufferMemoryServer */,
2365 TRUE
/* fUnmarshall */);
2367 array_read_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
);
2368 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING
, pStubMsg
, ppMemory
,
2369 pFormat
, fMustAlloc
,
2370 TRUE
/* fUseBufferMemoryServer */,
2371 TRUE
/* fUnmarshall */);
2377 /***********************************************************************
2378 * NdrNonConformantStringMarshall [RPCRT4.@]
2380 unsigned char * WINAPI
NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2381 unsigned char *pMemory
,
2382 PFORMAT_STRING pFormat
)
2384 ULONG esize
, size
, maxsize
;
2386 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2388 maxsize
= *(USHORT
*)&pFormat
[2];
2390 if (*pFormat
== RPC_FC_CSTRING
)
2393 const char *str
= (const char *)pMemory
;
2394 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
2396 TRACE("string=%s\n", debugstr_an(str
, i
));
2397 pStubMsg
->ActualCount
= i
+ 1;
2400 else if (*pFormat
== RPC_FC_WSTRING
)
2403 const WCHAR
*str
= (const WCHAR
*)pMemory
;
2404 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
2406 TRACE("string=%s\n", debugstr_wn(str
, i
));
2407 pStubMsg
->ActualCount
= i
+ 1;
2412 ERR("Unhandled string type: %#x\n", *pFormat
);
2413 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2416 pStubMsg
->Offset
= 0;
2417 WriteVariance(pStubMsg
);
2419 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2420 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
2425 /***********************************************************************
2426 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2428 unsigned char * WINAPI
NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2429 unsigned char **ppMemory
,
2430 PFORMAT_STRING pFormat
,
2431 unsigned char fMustAlloc
)
2433 ULONG bufsize
, memsize
, esize
, maxsize
;
2435 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2436 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
2438 maxsize
= *(USHORT
*)&pFormat
[2];
2440 ReadVariance(pStubMsg
, NULL
, maxsize
);
2441 if (pStubMsg
->Offset
)
2443 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2444 RpcRaiseException(RPC_S_INVALID_BOUND
);
2447 if (*pFormat
== RPC_FC_CSTRING
) esize
= 1;
2448 else if (*pFormat
== RPC_FC_WSTRING
) esize
= 2;
2451 ERR("Unhandled string type: %#x\n", *pFormat
);
2452 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2455 memsize
= esize
* maxsize
;
2456 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2458 validate_string_data(pStubMsg
, bufsize
, esize
);
2460 if (!fMustAlloc
&& !*ppMemory
)
2463 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2465 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
2467 if (*pFormat
== RPC_FC_CSTRING
) {
2468 TRACE("string=%s\n", debugstr_an((char*)*ppMemory
, pStubMsg
->ActualCount
));
2470 else if (*pFormat
== RPC_FC_WSTRING
) {
2471 TRACE("string=%s\n", debugstr_wn((LPWSTR
)*ppMemory
, pStubMsg
->ActualCount
));
2477 /***********************************************************************
2478 * NdrNonConformantStringBufferSize [RPCRT4.@]
2480 void WINAPI
NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2481 unsigned char *pMemory
,
2482 PFORMAT_STRING pFormat
)
2484 ULONG esize
, maxsize
;
2486 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2488 maxsize
= *(USHORT
*)&pFormat
[2];
2490 SizeVariance(pStubMsg
);
2492 if (*pFormat
== RPC_FC_CSTRING
)
2495 const char *str
= (const char *)pMemory
;
2496 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
2498 TRACE("string=%s\n", debugstr_an(str
, i
));
2499 pStubMsg
->ActualCount
= i
+ 1;
2502 else if (*pFormat
== RPC_FC_WSTRING
)
2505 const WCHAR
*str
= (const WCHAR
*)pMemory
;
2506 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
2508 TRACE("string=%s\n", debugstr_wn(str
, i
));
2509 pStubMsg
->ActualCount
= i
+ 1;
2514 ERR("Unhandled string type: %#x\n", *pFormat
);
2515 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2518 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
2521 /***********************************************************************
2522 * NdrNonConformantStringMemorySize [RPCRT4.@]
2524 ULONG WINAPI
NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2525 PFORMAT_STRING pFormat
)
2527 ULONG bufsize
, memsize
, esize
, maxsize
;
2529 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
2531 maxsize
= *(USHORT
*)&pFormat
[2];
2533 ReadVariance(pStubMsg
, NULL
, maxsize
);
2535 if (pStubMsg
->Offset
)
2537 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2538 RpcRaiseException(RPC_S_INVALID_BOUND
);
2541 if (*pFormat
== RPC_FC_CSTRING
) esize
= 1;
2542 else if (*pFormat
== RPC_FC_WSTRING
) esize
= 2;
2545 ERR("Unhandled string type: %#x\n", *pFormat
);
2546 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2549 memsize
= esize
* maxsize
;
2550 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2552 validate_string_data(pStubMsg
, bufsize
, esize
);
2554 safe_buffer_increment(pStubMsg
, bufsize
);
2555 pStubMsg
->MemorySize
+= memsize
;
2557 return pStubMsg
->MemorySize
;
2562 #include "pshpack1.h"
2566 unsigned char flags_type
; /* flags in upper nibble, type in lower nibble */
2570 #include "poppack.h"
2572 static unsigned long EmbeddedComplexSize(MIDL_STUB_MESSAGE
*pStubMsg
,
2573 PFORMAT_STRING pFormat
)
2577 case RPC_FC_PSTRUCT
:
2578 case RPC_FC_CSTRUCT
:
2579 case RPC_FC_BOGUS_STRUCT
:
2580 case RPC_FC_SMFARRAY
:
2581 case RPC_FC_SMVARRAY
:
2582 case RPC_FC_CSTRING
:
2583 return *(const WORD
*)&pFormat
[2];
2584 case RPC_FC_USER_MARSHAL
:
2585 return *(const WORD
*)&pFormat
[4];
2586 case RPC_FC_RANGE
: {
2587 switch (((const NDR_RANGE
*)pFormat
)->flags_type
& 0xf) {
2592 return sizeof(UCHAR
);
2596 return sizeof(USHORT
);
2600 return sizeof(ULONG
);
2602 return sizeof(float);
2604 return sizeof(double);
2606 return sizeof(ULONGLONG
);
2608 return sizeof(UINT
);
2610 ERR("unknown type 0x%x\n", ((const NDR_RANGE
*)pFormat
)->flags_type
& 0xf);
2611 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2614 case RPC_FC_NON_ENCAPSULATED_UNION
:
2616 if (pStubMsg
->fHasNewCorrDesc
)
2621 pFormat
+= *(const SHORT
*)pFormat
;
2622 return *(const SHORT
*)pFormat
;
2624 return sizeof(void *);
2625 case RPC_FC_WSTRING
:
2626 return *(const WORD
*)&pFormat
[2] * 2;
2628 FIXME("unhandled embedded type %02x\n", *pFormat
);
2634 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2635 PFORMAT_STRING pFormat
)
2637 NDR_MEMORYSIZE m
= NdrMemorySizer
[*pFormat
& NDR_TABLE_MASK
];
2641 FIXME("no memorysizer for data type=%02x\n", *pFormat
);
2645 return m(pStubMsg
, pFormat
);
2649 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2650 unsigned char *pMemory
,
2651 PFORMAT_STRING pFormat
,
2652 PFORMAT_STRING pPointer
)
2654 PFORMAT_STRING desc
;
2658 while (*pFormat
!= RPC_FC_END
) {
2664 TRACE("byte=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2665 safe_copy_to_buffer(pStubMsg
, pMemory
, 1);
2671 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2672 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
2676 TRACE("enum16=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2677 if (32767 < *(DWORD
*)pMemory
)
2678 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
2679 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
2685 TRACE("long=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2686 safe_copy_to_buffer(pStubMsg
, pMemory
, 4);
2690 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2691 safe_copy_to_buffer(pStubMsg
, pMemory
, 8);
2694 case RPC_FC_POINTER
:
2696 unsigned char *saved_buffer
;
2697 int pointer_buffer_mark_set
= 0;
2698 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
2699 TRACE("pStubMsg->Buffer before %p\n", pStubMsg
->Buffer
);
2700 if (*pPointer
!= RPC_FC_RP
)
2701 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
2702 saved_buffer
= pStubMsg
->Buffer
;
2703 if (pStubMsg
->PointerBufferMark
)
2705 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2706 pStubMsg
->PointerBufferMark
= NULL
;
2707 pointer_buffer_mark_set
= 1;
2709 else if (*pPointer
!= RPC_FC_RP
)
2710 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2711 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char**)pMemory
, pPointer
);
2712 if (pointer_buffer_mark_set
)
2714 STD_OVERFLOW_CHECK(pStubMsg
);
2715 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2716 pStubMsg
->Buffer
= saved_buffer
;
2717 if (*pPointer
!= RPC_FC_RP
)
2718 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2720 TRACE("pStubMsg->Buffer after %p\n", pStubMsg
->Buffer
);
2725 case RPC_FC_ALIGNM4
:
2726 ALIGN_POINTER(pMemory
, 4);
2728 case RPC_FC_ALIGNM8
:
2729 ALIGN_POINTER(pMemory
, 8);
2731 case RPC_FC_STRUCTPAD1
:
2732 case RPC_FC_STRUCTPAD2
:
2733 case RPC_FC_STRUCTPAD3
:
2734 case RPC_FC_STRUCTPAD4
:
2735 case RPC_FC_STRUCTPAD5
:
2736 case RPC_FC_STRUCTPAD6
:
2737 case RPC_FC_STRUCTPAD7
:
2738 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2740 case RPC_FC_EMBEDDED_COMPLEX
:
2741 pMemory
+= pFormat
[1];
2743 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2744 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2745 TRACE("embedded complex (size=%ld) <= %p\n", size
, pMemory
);
2746 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
2749 /* for some reason interface pointers aren't generated as
2750 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2751 * they still need the derefencing treatment that pointers are
2753 if (*desc
== RPC_FC_IP
)
2754 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2756 m(pStubMsg
, pMemory
, desc
);
2758 else FIXME("no marshaller for embedded type %02x\n", *desc
);
2765 FIXME("unhandled format 0x%02x\n", *pFormat
);
2773 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2774 unsigned char *pMemory
,
2775 PFORMAT_STRING pFormat
,
2776 PFORMAT_STRING pPointer
,
2777 unsigned char fMustAlloc
)
2779 PFORMAT_STRING desc
;
2783 while (*pFormat
!= RPC_FC_END
) {
2789 safe_copy_from_buffer(pStubMsg
, pMemory
, 1);
2790 TRACE("byte=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2796 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
2797 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2801 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
2802 *(DWORD
*)pMemory
&= 0xffff;
2803 TRACE("enum16=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
2804 if (32767 < *(DWORD
*)pMemory
)
2805 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
2811 safe_copy_from_buffer(pStubMsg
, pMemory
, 4);
2812 TRACE("long=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
2816 safe_copy_from_buffer(pStubMsg
, pMemory
, 8);
2817 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2820 case RPC_FC_POINTER
:
2822 unsigned char *saved_buffer
;
2823 int pointer_buffer_mark_set
= 0;
2824 TRACE("pointer => %p\n", pMemory
);
2825 if (*pPointer
!= RPC_FC_RP
)
2826 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2827 saved_buffer
= pStubMsg
->Buffer
;
2828 if (pStubMsg
->PointerBufferMark
)
2830 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2831 pStubMsg
->PointerBufferMark
= NULL
;
2832 pointer_buffer_mark_set
= 1;
2834 else if (*pPointer
!= RPC_FC_RP
)
2835 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2837 PointerUnmarshall(pStubMsg
, saved_buffer
, (unsigned char**)pMemory
, *(unsigned char**)pMemory
, pPointer
, fMustAlloc
);
2838 if (pointer_buffer_mark_set
)
2840 STD_OVERFLOW_CHECK(pStubMsg
);
2841 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2842 pStubMsg
->Buffer
= saved_buffer
;
2843 if (*pPointer
!= RPC_FC_RP
)
2844 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2850 case RPC_FC_ALIGNM4
:
2851 ALIGN_POINTER_CLEAR(pMemory
, 4);
2853 case RPC_FC_ALIGNM8
:
2854 ALIGN_POINTER_CLEAR(pMemory
, 8);
2856 case RPC_FC_STRUCTPAD1
:
2857 case RPC_FC_STRUCTPAD2
:
2858 case RPC_FC_STRUCTPAD3
:
2859 case RPC_FC_STRUCTPAD4
:
2860 case RPC_FC_STRUCTPAD5
:
2861 case RPC_FC_STRUCTPAD6
:
2862 case RPC_FC_STRUCTPAD7
:
2863 memset(pMemory
, 0, *pFormat
- RPC_FC_STRUCTPAD1
+ 1);
2864 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2866 case RPC_FC_EMBEDDED_COMPLEX
:
2867 pMemory
+= pFormat
[1];
2869 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2870 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2871 TRACE("embedded complex (size=%ld) => %p\n", size
, pMemory
);
2873 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
2874 * since the type is part of the memory block that is encompassed by
2875 * the whole complex type. Memory is forced to allocate when pointers
2876 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
2877 * clearing the memory we pass in to the unmarshaller */
2878 memset(pMemory
, 0, size
);
2879 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
2882 /* for some reason interface pointers aren't generated as
2883 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2884 * they still need the derefencing treatment that pointers are
2886 if (*desc
== RPC_FC_IP
)
2887 m(pStubMsg
, (unsigned char **)pMemory
, desc
, FALSE
);
2889 m(pStubMsg
, &pMemory
, desc
, FALSE
);
2891 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
2898 FIXME("unhandled format %d\n", *pFormat
);
2906 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2907 unsigned char *pMemory
,
2908 PFORMAT_STRING pFormat
,
2909 PFORMAT_STRING pPointer
)
2911 PFORMAT_STRING desc
;
2915 while (*pFormat
!= RPC_FC_END
) {
2921 safe_buffer_length_increment(pStubMsg
, 1);
2927 safe_buffer_length_increment(pStubMsg
, 2);
2931 safe_buffer_length_increment(pStubMsg
, 2);
2937 safe_buffer_length_increment(pStubMsg
, 4);
2941 safe_buffer_length_increment(pStubMsg
, 8);
2944 case RPC_FC_POINTER
:
2945 if (!pStubMsg
->IgnoreEmbeddedPointers
)
2947 int saved_buffer_length
= pStubMsg
->BufferLength
;
2948 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2949 pStubMsg
->PointerLength
= 0;
2950 if(!pStubMsg
->BufferLength
)
2951 ERR("BufferLength == 0??\n");
2952 PointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
2953 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2954 pStubMsg
->BufferLength
= saved_buffer_length
;
2956 if (*pPointer
!= RPC_FC_RP
)
2958 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
2959 safe_buffer_length_increment(pStubMsg
, 4);
2964 case RPC_FC_ALIGNM4
:
2965 ALIGN_POINTER(pMemory
, 4);
2967 case RPC_FC_ALIGNM8
:
2968 ALIGN_POINTER(pMemory
, 8);
2970 case RPC_FC_STRUCTPAD1
:
2971 case RPC_FC_STRUCTPAD2
:
2972 case RPC_FC_STRUCTPAD3
:
2973 case RPC_FC_STRUCTPAD4
:
2974 case RPC_FC_STRUCTPAD5
:
2975 case RPC_FC_STRUCTPAD6
:
2976 case RPC_FC_STRUCTPAD7
:
2977 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2979 case RPC_FC_EMBEDDED_COMPLEX
:
2980 pMemory
+= pFormat
[1];
2982 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2983 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2984 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
2987 /* for some reason interface pointers aren't generated as
2988 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2989 * they still need the derefencing treatment that pointers are
2991 if (*desc
== RPC_FC_IP
)
2992 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2994 m(pStubMsg
, pMemory
, desc
);
2996 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
3003 FIXME("unhandled format 0x%02x\n", *pFormat
);
3011 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
3012 unsigned char *pMemory
,
3013 PFORMAT_STRING pFormat
,
3014 PFORMAT_STRING pPointer
)
3016 PFORMAT_STRING desc
;
3020 while (*pFormat
!= RPC_FC_END
) {
3042 case RPC_FC_POINTER
:
3043 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
3047 case RPC_FC_ALIGNM4
:
3048 ALIGN_POINTER(pMemory
, 4);
3050 case RPC_FC_ALIGNM8
:
3051 ALIGN_POINTER(pMemory
, 8);
3053 case RPC_FC_STRUCTPAD1
:
3054 case RPC_FC_STRUCTPAD2
:
3055 case RPC_FC_STRUCTPAD3
:
3056 case RPC_FC_STRUCTPAD4
:
3057 case RPC_FC_STRUCTPAD5
:
3058 case RPC_FC_STRUCTPAD6
:
3059 case RPC_FC_STRUCTPAD7
:
3060 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3062 case RPC_FC_EMBEDDED_COMPLEX
:
3063 pMemory
+= pFormat
[1];
3065 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3066 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3067 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
3070 /* for some reason interface pointers aren't generated as
3071 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3072 * they still need the derefencing treatment that pointers are
3074 if (*desc
== RPC_FC_IP
)
3075 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
3077 m(pStubMsg
, pMemory
, desc
);
3085 FIXME("unhandled format 0x%02x\n", *pFormat
);
3093 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3094 PFORMAT_STRING pFormat
,
3095 PFORMAT_STRING pPointer
)
3097 PFORMAT_STRING desc
;
3098 unsigned long size
= 0;
3100 while (*pFormat
!= RPC_FC_END
) {
3107 safe_buffer_increment(pStubMsg
, 1);
3113 safe_buffer_increment(pStubMsg
, 2);
3117 safe_buffer_increment(pStubMsg
, 2);
3123 safe_buffer_increment(pStubMsg
, 4);
3127 safe_buffer_increment(pStubMsg
, 8);
3129 case RPC_FC_POINTER
:
3131 unsigned char *saved_buffer
;
3132 int pointer_buffer_mark_set
= 0;
3133 if (*pPointer
!= RPC_FC_RP
)
3134 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3135 saved_buffer
= pStubMsg
->Buffer
;
3136 if (pStubMsg
->PointerBufferMark
)
3138 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3139 pStubMsg
->PointerBufferMark
= NULL
;
3140 pointer_buffer_mark_set
= 1;
3142 else if (*pPointer
!= RPC_FC_RP
)
3143 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3145 if (!pStubMsg
->IgnoreEmbeddedPointers
)
3146 PointerMemorySize(pStubMsg
, saved_buffer
, pPointer
);
3147 if (pointer_buffer_mark_set
)
3149 STD_OVERFLOW_CHECK(pStubMsg
);
3150 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3151 pStubMsg
->Buffer
= saved_buffer
;
3152 if (*pPointer
!= RPC_FC_RP
)
3153 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3159 case RPC_FC_ALIGNM4
:
3160 ALIGN_LENGTH(size
, 4);
3162 case RPC_FC_ALIGNM8
:
3163 ALIGN_LENGTH(size
, 8);
3165 case RPC_FC_STRUCTPAD1
:
3166 case RPC_FC_STRUCTPAD2
:
3167 case RPC_FC_STRUCTPAD3
:
3168 case RPC_FC_STRUCTPAD4
:
3169 case RPC_FC_STRUCTPAD5
:
3170 case RPC_FC_STRUCTPAD6
:
3171 case RPC_FC_STRUCTPAD7
:
3172 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3174 case RPC_FC_EMBEDDED_COMPLEX
:
3177 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3178 size
+= EmbeddedComplexMemorySize(pStubMsg
, desc
);
3184 FIXME("unhandled format 0x%02x\n", *pFormat
);
3192 unsigned long ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg
,
3193 PFORMAT_STRING pFormat
)
3195 PFORMAT_STRING desc
;
3196 unsigned long size
= 0;
3198 while (*pFormat
!= RPC_FC_END
) {
3220 case RPC_FC_POINTER
:
3221 size
+= sizeof(void *);
3223 case RPC_FC_ALIGNM4
:
3224 ALIGN_LENGTH(size
, 4);
3226 case RPC_FC_ALIGNM8
:
3227 ALIGN_LENGTH(size
, 8);
3229 case RPC_FC_STRUCTPAD1
:
3230 case RPC_FC_STRUCTPAD2
:
3231 case RPC_FC_STRUCTPAD3
:
3232 case RPC_FC_STRUCTPAD4
:
3233 case RPC_FC_STRUCTPAD5
:
3234 case RPC_FC_STRUCTPAD6
:
3235 case RPC_FC_STRUCTPAD7
:
3236 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3238 case RPC_FC_EMBEDDED_COMPLEX
:
3241 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3242 size
+= EmbeddedComplexSize(pStubMsg
, desc
);
3248 FIXME("unhandled format 0x%02x\n", *pFormat
);
3256 /***********************************************************************
3257 * NdrComplexStructMarshall [RPCRT4.@]
3259 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3260 unsigned char *pMemory
,
3261 PFORMAT_STRING pFormat
)
3263 PFORMAT_STRING conf_array
= NULL
;
3264 PFORMAT_STRING pointer_desc
= NULL
;
3265 unsigned char *OldMemory
= pStubMsg
->Memory
;
3266 int pointer_buffer_mark_set
= 0;
3268 ULONG max_count
= 0;
3271 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3273 if (!pStubMsg
->PointerBufferMark
)
3275 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3276 /* save buffer length */
3277 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
3279 /* get the buffer pointer after complex array data, but before
3281 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
;
3282 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3283 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
3284 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3286 /* save it for use by embedded pointer code later */
3287 pStubMsg
->PointerBufferMark
= (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
;
3288 TRACE("difference = 0x%x\n", pStubMsg
->PointerBufferMark
- pStubMsg
->Buffer
);
3289 pointer_buffer_mark_set
= 1;
3291 /* restore the original buffer length */
3292 pStubMsg
->BufferLength
= saved_buffer_length
;
3295 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pFormat
[1] + 1);
3298 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3300 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3303 pStubMsg
->Memory
= pMemory
;
3307 unsigned long struct_size
= ComplexStructSize(pStubMsg
, pFormat
);
3308 array_compute_and_write_conformance(conf_array
[0], pStubMsg
,
3309 pMemory
+ struct_size
, conf_array
);
3310 /* these could be changed in ComplexMarshall so save them for later */
3311 max_count
= pStubMsg
->MaxCount
;
3312 count
= pStubMsg
->ActualCount
;
3313 offset
= pStubMsg
->Offset
;
3316 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3320 pStubMsg
->MaxCount
= max_count
;
3321 pStubMsg
->ActualCount
= count
;
3322 pStubMsg
->Offset
= offset
;
3323 array_write_variance_and_marshall(conf_array
[0], pStubMsg
, pMemory
,
3324 conf_array
, TRUE
/* fHasPointers */);
3327 pStubMsg
->Memory
= OldMemory
;
3329 if (pointer_buffer_mark_set
)
3331 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3332 pStubMsg
->PointerBufferMark
= NULL
;
3335 STD_OVERFLOW_CHECK(pStubMsg
);
3340 /***********************************************************************
3341 * NdrComplexStructUnmarshall [RPCRT4.@]
3343 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3344 unsigned char **ppMemory
,
3345 PFORMAT_STRING pFormat
,
3346 unsigned char fMustAlloc
)
3348 unsigned size
= *(const WORD
*)(pFormat
+2);
3349 PFORMAT_STRING conf_array
= NULL
;
3350 PFORMAT_STRING pointer_desc
= NULL
;
3351 unsigned char *pMemory
;
3352 int pointer_buffer_mark_set
= 0;
3354 ULONG max_count
= 0;
3356 ULONG array_size
= 0;
3358 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3360 if (!pStubMsg
->PointerBufferMark
)
3362 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3363 /* save buffer pointer */
3364 unsigned char *saved_buffer
= pStubMsg
->Buffer
;
3366 /* get the buffer pointer after complex array data, but before
3368 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3369 NdrComplexStructMemorySize(pStubMsg
, pFormat
);
3370 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3372 /* save it for use by embedded pointer code later */
3373 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3374 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->PointerBufferMark
- saved_buffer
));
3375 pointer_buffer_mark_set
= 1;
3377 /* restore the original buffer */
3378 pStubMsg
->Buffer
= saved_buffer
;
3381 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
3384 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3386 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3391 array_size
= array_read_conformance(conf_array
[0], pStubMsg
, conf_array
);
3394 /* these could be changed in ComplexMarshall so save them for later */
3395 max_count
= pStubMsg
->MaxCount
;
3396 count
= pStubMsg
->ActualCount
;
3397 offset
= pStubMsg
->Offset
;
3400 if (!fMustAlloc
&& !*ppMemory
)
3403 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3405 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
, fMustAlloc
);
3409 pStubMsg
->MaxCount
= max_count
;
3410 pStubMsg
->ActualCount
= count
;
3411 pStubMsg
->Offset
= offset
;
3413 memset(pMemory
, 0, array_size
);
3414 array_read_variance_and_unmarshall(conf_array
[0], pStubMsg
, &pMemory
,
3416 FALSE
/* fUseBufferMemoryServer */,
3417 TRUE
/* fUnmarshall */);
3420 if (pointer_buffer_mark_set
)
3422 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3423 pStubMsg
->PointerBufferMark
= NULL
;
3429 /***********************************************************************
3430 * NdrComplexStructBufferSize [RPCRT4.@]
3432 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3433 unsigned char *pMemory
,
3434 PFORMAT_STRING pFormat
)
3436 PFORMAT_STRING conf_array
= NULL
;
3437 PFORMAT_STRING pointer_desc
= NULL
;
3438 unsigned char *OldMemory
= pStubMsg
->Memory
;
3439 int pointer_length_set
= 0;
3441 ULONG max_count
= 0;
3444 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3446 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
3448 if(!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
3450 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3451 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
3453 /* get the buffer length after complex struct data, but before
3455 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3456 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
3457 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3459 /* save it for use by embedded pointer code later */
3460 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3461 pointer_length_set
= 1;
3462 TRACE("difference = 0x%lx\n", pStubMsg
->PointerLength
- saved_buffer_length
);
3464 /* restore the original buffer length */
3465 pStubMsg
->BufferLength
= saved_buffer_length
;
3469 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3471 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3474 pStubMsg
->Memory
= pMemory
;
3478 unsigned long struct_size
= ComplexStructSize(pStubMsg
, pFormat
);
3479 array_compute_and_size_conformance(conf_array
[0], pStubMsg
, pMemory
+ struct_size
,
3482 /* these could be changed in ComplexMarshall so save them for later */
3483 max_count
= pStubMsg
->MaxCount
;
3484 count
= pStubMsg
->ActualCount
;
3485 offset
= pStubMsg
->Offset
;
3488 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3492 pStubMsg
->MaxCount
= max_count
;
3493 pStubMsg
->ActualCount
= count
;
3494 pStubMsg
->Offset
= offset
;
3495 array_buffer_size(conf_array
[0], pStubMsg
, pMemory
, conf_array
,
3496 TRUE
/* fHasPointers */);
3499 pStubMsg
->Memory
= OldMemory
;
3501 if(pointer_length_set
)
3503 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3504 pStubMsg
->PointerLength
= 0;
3509 /***********************************************************************
3510 * NdrComplexStructMemorySize [RPCRT4.@]
3512 ULONG WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3513 PFORMAT_STRING pFormat
)
3515 unsigned size
= *(const WORD
*)(pFormat
+2);
3516 PFORMAT_STRING conf_array
= NULL
;
3517 PFORMAT_STRING pointer_desc
= NULL
;
3519 ULONG max_count
= 0;
3522 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3524 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
3527 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3529 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3534 array_read_conformance(conf_array
[0], pStubMsg
, conf_array
);
3536 /* these could be changed in ComplexStructMemorySize so save them for
3538 max_count
= pStubMsg
->MaxCount
;
3539 count
= pStubMsg
->ActualCount
;
3540 offset
= pStubMsg
->Offset
;
3543 ComplexStructMemorySize(pStubMsg
, pFormat
, pointer_desc
);
3547 pStubMsg
->MaxCount
= max_count
;
3548 pStubMsg
->ActualCount
= count
;
3549 pStubMsg
->Offset
= offset
;
3550 array_memory_size(conf_array
[0], pStubMsg
, conf_array
,
3551 TRUE
/* fHasPointers */);
3557 /***********************************************************************
3558 * NdrComplexStructFree [RPCRT4.@]
3560 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3561 unsigned char *pMemory
,
3562 PFORMAT_STRING pFormat
)
3564 PFORMAT_STRING conf_array
= NULL
;
3565 PFORMAT_STRING pointer_desc
= NULL
;
3566 unsigned char *OldMemory
= pStubMsg
->Memory
;
3568 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3571 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3573 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3576 pStubMsg
->Memory
= pMemory
;
3578 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3581 array_free(conf_array
[0], pStubMsg
, pMemory
, conf_array
,
3582 TRUE
/* fHasPointers */);
3584 pStubMsg
->Memory
= OldMemory
;
3587 /***********************************************************************
3588 * NdrConformantArrayMarshall [RPCRT4.@]
3590 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3591 unsigned char *pMemory
,
3592 PFORMAT_STRING pFormat
)
3594 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3595 if (pFormat
[0] != RPC_FC_CARRAY
)
3597 ERR("invalid format = 0x%x\n", pFormat
[0]);
3598 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3601 array_compute_and_write_conformance(RPC_FC_CARRAY
, pStubMsg
, pMemory
,
3603 array_write_variance_and_marshall(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3604 TRUE
/* fHasPointers */);
3609 /***********************************************************************
3610 * NdrConformantArrayUnmarshall [RPCRT4.@]
3612 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3613 unsigned char **ppMemory
,
3614 PFORMAT_STRING pFormat
,
3615 unsigned char fMustAlloc
)
3617 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3618 if (pFormat
[0] != RPC_FC_CARRAY
)
3620 ERR("invalid format = 0x%x\n", pFormat
[0]);
3621 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3624 array_read_conformance(RPC_FC_CARRAY
, pStubMsg
, pFormat
);
3625 array_read_variance_and_unmarshall(RPC_FC_CARRAY
, pStubMsg
, ppMemory
, pFormat
,
3627 TRUE
/* fUseBufferMemoryServer */,
3628 TRUE
/* fUnmarshall */);
3633 /***********************************************************************
3634 * NdrConformantArrayBufferSize [RPCRT4.@]
3636 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3637 unsigned char *pMemory
,
3638 PFORMAT_STRING pFormat
)
3640 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3641 if (pFormat
[0] != RPC_FC_CARRAY
)
3643 ERR("invalid format = 0x%x\n", pFormat
[0]);
3644 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3647 array_compute_and_size_conformance(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
);
3648 array_buffer_size(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3649 TRUE
/* fHasPointers */);
3652 /***********************************************************************
3653 * NdrConformantArrayMemorySize [RPCRT4.@]
3655 ULONG WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3656 PFORMAT_STRING pFormat
)
3658 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3659 if (pFormat
[0] != RPC_FC_CARRAY
)
3661 ERR("invalid format = 0x%x\n", pFormat
[0]);
3662 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3665 array_read_conformance(RPC_FC_CARRAY
, pStubMsg
, pFormat
);
3666 array_memory_size(RPC_FC_CARRAY
, pStubMsg
, pFormat
, TRUE
/* fHasPointers */);
3668 return pStubMsg
->MemorySize
;
3671 /***********************************************************************
3672 * NdrConformantArrayFree [RPCRT4.@]
3674 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3675 unsigned char *pMemory
,
3676 PFORMAT_STRING pFormat
)
3678 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3679 if (pFormat
[0] != RPC_FC_CARRAY
)
3681 ERR("invalid format = 0x%x\n", pFormat
[0]);
3682 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3685 array_free(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3686 TRUE
/* fHasPointers */);
3690 /***********************************************************************
3691 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3693 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
3694 unsigned char* pMemory
,
3695 PFORMAT_STRING pFormat
)
3697 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3699 if (pFormat
[0] != RPC_FC_CVARRAY
)
3701 ERR("invalid format type %x\n", pFormat
[0]);
3702 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3706 array_compute_and_write_conformance(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
3708 array_write_variance_and_marshall(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
3709 pFormat
, TRUE
/* fHasPointers */);
3715 /***********************************************************************
3716 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
3718 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
3719 unsigned char** ppMemory
,
3720 PFORMAT_STRING pFormat
,
3721 unsigned char fMustAlloc
)
3723 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3725 if (pFormat
[0] != RPC_FC_CVARRAY
)
3727 ERR("invalid format type %x\n", pFormat
[0]);
3728 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3732 array_read_conformance(RPC_FC_CVARRAY
, pStubMsg
, pFormat
);
3733 array_read_variance_and_unmarshall(RPC_FC_CVARRAY
, pStubMsg
, ppMemory
,
3734 pFormat
, fMustAlloc
,
3735 TRUE
/* fUseBufferMemoryServer */,
3736 TRUE
/* fUnmarshall */);
3742 /***********************************************************************
3743 * NdrConformantVaryingArrayFree [RPCRT4.@]
3745 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
3746 unsigned char* pMemory
,
3747 PFORMAT_STRING pFormat
)
3749 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3751 if (pFormat
[0] != RPC_FC_CVARRAY
)
3753 ERR("invalid format type %x\n", pFormat
[0]);
3754 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3758 array_free(RPC_FC_CVARRAY
, pStubMsg
, pMemory
, pFormat
,
3759 TRUE
/* fHasPointers */);
3763 /***********************************************************************
3764 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
3766 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
3767 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
3769 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3771 if (pFormat
[0] != RPC_FC_CVARRAY
)
3773 ERR("invalid format type %x\n", pFormat
[0]);
3774 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3778 array_compute_and_size_conformance(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
3780 array_buffer_size(RPC_FC_CVARRAY
, pStubMsg
, pMemory
, pFormat
,
3781 TRUE
/* fHasPointers */);
3785 /***********************************************************************
3786 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
3788 ULONG WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
3789 PFORMAT_STRING pFormat
)
3791 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
3793 if (pFormat
[0] != RPC_FC_CVARRAY
)
3795 ERR("invalid format type %x\n", pFormat
[0]);
3796 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3797 return pStubMsg
->MemorySize
;
3800 array_read_conformance(RPC_FC_CVARRAY
, pStubMsg
, pFormat
);
3801 array_memory_size(RPC_FC_CVARRAY
, pStubMsg
, pFormat
,
3802 TRUE
/* fHasPointers */);
3804 return pStubMsg
->MemorySize
;
3808 /***********************************************************************
3809 * NdrComplexArrayMarshall [RPCRT4.@]
3811 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3812 unsigned char *pMemory
,
3813 PFORMAT_STRING pFormat
)
3815 ULONG i
, count
, def
;
3816 BOOL variance_present
;
3817 unsigned char alignment
;
3818 int pointer_buffer_mark_set
= 0;
3820 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3822 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3824 ERR("invalid format type %x\n", pFormat
[0]);
3825 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3829 alignment
= pFormat
[1] + 1;
3831 if (!pStubMsg
->PointerBufferMark
)
3833 /* save buffer fields that may be changed by buffer sizer functions
3834 * and that may be needed later on */
3835 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3836 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
3837 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
3838 unsigned long saved_offset
= pStubMsg
->Offset
;
3839 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
3841 /* get the buffer pointer after complex array data, but before
3843 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
;
3844 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3845 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
3846 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3848 /* save it for use by embedded pointer code later */
3849 pStubMsg
->PointerBufferMark
= (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
;
3850 TRACE("difference = 0x%x\n", pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
);
3851 pointer_buffer_mark_set
= 1;
3853 /* restore fields */
3854 pStubMsg
->ActualCount
= saved_actual_count
;
3855 pStubMsg
->Offset
= saved_offset
;
3856 pStubMsg
->MaxCount
= saved_max_count
;
3857 pStubMsg
->BufferLength
= saved_buffer_length
;
3860 def
= *(const WORD
*)&pFormat
[2];
3863 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3864 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3866 variance_present
= IsConformanceOrVariancePresent(pFormat
);
3867 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3868 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3870 WriteConformance(pStubMsg
);
3871 if (variance_present
)
3872 WriteVariance(pStubMsg
);
3874 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
3876 count
= pStubMsg
->ActualCount
;
3877 for (i
= 0; i
< count
; i
++)
3878 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
3880 STD_OVERFLOW_CHECK(pStubMsg
);
3882 if (pointer_buffer_mark_set
)
3884 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3885 pStubMsg
->PointerBufferMark
= NULL
;
3891 /***********************************************************************
3892 * NdrComplexArrayUnmarshall [RPCRT4.@]
3894 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3895 unsigned char **ppMemory
,
3896 PFORMAT_STRING pFormat
,
3897 unsigned char fMustAlloc
)
3899 ULONG i
, count
, size
;
3900 unsigned char alignment
;
3901 unsigned char *pMemory
;
3902 unsigned char *saved_buffer
;
3903 int pointer_buffer_mark_set
= 0;
3904 int saved_ignore_embedded
;
3906 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3908 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3910 ERR("invalid format type %x\n", pFormat
[0]);
3911 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3915 alignment
= pFormat
[1] + 1;
3917 saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3918 /* save buffer pointer */
3919 saved_buffer
= pStubMsg
->Buffer
;
3920 /* get the buffer pointer after complex array data, but before
3922 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3923 pStubMsg
->MemorySize
= 0;
3924 NdrComplexArrayMemorySize(pStubMsg
, pFormat
);
3925 size
= pStubMsg
->MemorySize
;
3926 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3928 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->Buffer
- saved_buffer
));
3929 if (!pStubMsg
->PointerBufferMark
)
3931 /* save it for use by embedded pointer code later */
3932 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3933 pointer_buffer_mark_set
= 1;
3935 /* restore the original buffer */
3936 pStubMsg
->Buffer
= saved_buffer
;
3940 pFormat
= ReadConformance(pStubMsg
, pFormat
);
3941 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3943 if (!fMustAlloc
&& !*ppMemory
)
3946 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3948 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3950 pMemory
= *ppMemory
;
3951 count
= pStubMsg
->ActualCount
;
3952 for (i
= 0; i
< count
; i
++)
3953 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
, fMustAlloc
);
3955 if (pointer_buffer_mark_set
)
3957 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3958 pStubMsg
->PointerBufferMark
= NULL
;
3964 /***********************************************************************
3965 * NdrComplexArrayBufferSize [RPCRT4.@]
3967 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3968 unsigned char *pMemory
,
3969 PFORMAT_STRING pFormat
)
3971 ULONG i
, count
, def
;
3972 unsigned char alignment
;
3973 BOOL variance_present
;
3974 int pointer_length_set
= 0;
3976 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3978 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3980 ERR("invalid format type %x\n", pFormat
[0]);
3981 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3985 alignment
= pFormat
[1] + 1;
3987 if (!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
3989 /* save buffer fields that may be changed by buffer sizer functions
3990 * and that may be needed later on */
3991 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3992 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
3993 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
3994 unsigned long saved_offset
= pStubMsg
->Offset
;
3995 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
3997 /* get the buffer pointer after complex array data, but before
3999 pStubMsg
->IgnoreEmbeddedPointers
= 1;
4000 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
4001 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
4003 /* save it for use by embedded pointer code later */
4004 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4005 pointer_length_set
= 1;
4007 /* restore fields */
4008 pStubMsg
->ActualCount
= saved_actual_count
;
4009 pStubMsg
->Offset
= saved_offset
;
4010 pStubMsg
->MaxCount
= saved_max_count
;
4011 pStubMsg
->BufferLength
= saved_buffer_length
;
4013 def
= *(const WORD
*)&pFormat
[2];
4016 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
4017 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
4018 SizeConformance(pStubMsg
);
4020 variance_present
= IsConformanceOrVariancePresent(pFormat
);
4021 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
4022 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
4024 if (variance_present
)
4025 SizeVariance(pStubMsg
);
4027 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
4029 count
= pStubMsg
->ActualCount
;
4030 for (i
= 0; i
< count
; i
++)
4031 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
4033 if(pointer_length_set
)
4035 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4036 pStubMsg
->PointerLength
= 0;
4040 /***********************************************************************
4041 * NdrComplexArrayMemorySize [RPCRT4.@]
4043 ULONG WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4044 PFORMAT_STRING pFormat
)
4046 ULONG i
, count
, esize
, SavedMemorySize
, MemorySize
;
4047 unsigned char alignment
;
4049 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
4051 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4053 ERR("invalid format type %x\n", pFormat
[0]);
4054 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4058 alignment
= pFormat
[1] + 1;
4062 pFormat
= ReadConformance(pStubMsg
, pFormat
);
4063 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
4065 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4067 SavedMemorySize
= pStubMsg
->MemorySize
;
4069 esize
= ComplexStructSize(pStubMsg
, pFormat
);
4071 MemorySize
= safe_multiply(pStubMsg
->MaxCount
, esize
);
4073 count
= pStubMsg
->ActualCount
;
4074 for (i
= 0; i
< count
; i
++)
4075 ComplexStructMemorySize(pStubMsg
, pFormat
, NULL
);
4077 pStubMsg
->MemorySize
= SavedMemorySize
;
4079 pStubMsg
->MemorySize
+= MemorySize
;
4083 /***********************************************************************
4084 * NdrComplexArrayFree [RPCRT4.@]
4086 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4087 unsigned char *pMemory
,
4088 PFORMAT_STRING pFormat
)
4090 ULONG i
, count
, def
;
4092 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4094 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4096 ERR("invalid format type %x\n", pFormat
[0]);
4097 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4101 def
= *(const WORD
*)&pFormat
[2];
4104 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
4105 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
4107 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
4108 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
4110 count
= pStubMsg
->ActualCount
;
4111 for (i
= 0; i
< count
; i
++)
4112 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
4115 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg
,
4116 USER_MARSHAL_CB_TYPE cbtype
, PFORMAT_STRING pFormat
,
4117 USER_MARSHAL_CB
*umcb
)
4119 umcb
->Flags
= MAKELONG(pStubMsg
->dwDestContext
,
4120 pStubMsg
->RpcMsg
->DataRepresentation
);
4121 umcb
->pStubMsg
= pStubMsg
;
4122 umcb
->pReserve
= NULL
;
4123 umcb
->Signature
= USER_MARSHAL_CB_SIGNATURE
;
4124 umcb
->CBType
= cbtype
;
4125 umcb
->pFormat
= pFormat
;
4126 umcb
->pTypeFormat
= NULL
/* FIXME */;
4129 #define USER_MARSHAL_PTR_PREFIX \
4130 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4131 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4133 /***********************************************************************
4134 * NdrUserMarshalMarshall [RPCRT4.@]
4136 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4137 unsigned char *pMemory
,
4138 PFORMAT_STRING pFormat
)
4140 unsigned flags
= pFormat
[1];
4141 unsigned index
= *(const WORD
*)&pFormat
[2];
4142 unsigned char *saved_buffer
= NULL
;
4143 USER_MARSHAL_CB umcb
;
4145 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4146 TRACE("index=%d\n", index
);
4148 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_MARSHALL
, pFormat
, &umcb
);
4150 if (flags
& USER_MARSHAL_POINTER
)
4152 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
4153 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, USER_MARSHAL_PTR_PREFIX
);
4154 pStubMsg
->Buffer
+= 4;
4155 if (pStubMsg
->PointerBufferMark
)
4157 saved_buffer
= pStubMsg
->Buffer
;
4158 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4159 pStubMsg
->PointerBufferMark
= NULL
;
4161 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 8);
4164 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4167 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
4168 &umcb
.Flags
, pStubMsg
->Buffer
, pMemory
);
4172 STD_OVERFLOW_CHECK(pStubMsg
);
4173 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4174 pStubMsg
->Buffer
= saved_buffer
;
4177 STD_OVERFLOW_CHECK(pStubMsg
);
4182 /***********************************************************************
4183 * NdrUserMarshalUnmarshall [RPCRT4.@]
4185 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4186 unsigned char **ppMemory
,
4187 PFORMAT_STRING pFormat
,
4188 unsigned char fMustAlloc
)
4190 unsigned flags
= pFormat
[1];
4191 unsigned index
= *(const WORD
*)&pFormat
[2];
4192 DWORD memsize
= *(const WORD
*)&pFormat
[4];
4193 unsigned char *saved_buffer
= NULL
;
4194 USER_MARSHAL_CB umcb
;
4196 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4197 TRACE("index=%d\n", index
);
4199 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_UNMARSHALL
, pFormat
, &umcb
);
4201 if (flags
& USER_MARSHAL_POINTER
)
4203 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4204 /* skip pointer prefix */
4205 pStubMsg
->Buffer
+= 4;
4206 if (pStubMsg
->PointerBufferMark
)
4208 saved_buffer
= pStubMsg
->Buffer
;
4209 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4210 pStubMsg
->PointerBufferMark
= NULL
;
4212 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
4215 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4217 if (!fMustAlloc
&& !*ppMemory
)
4221 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
4222 memset(*ppMemory
, 0, memsize
);
4226 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
4227 &umcb
.Flags
, pStubMsg
->Buffer
, *ppMemory
);
4231 STD_OVERFLOW_CHECK(pStubMsg
);
4232 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4233 pStubMsg
->Buffer
= saved_buffer
;
4239 /***********************************************************************
4240 * NdrUserMarshalBufferSize [RPCRT4.@]
4242 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4243 unsigned char *pMemory
,
4244 PFORMAT_STRING pFormat
)
4246 unsigned flags
= pFormat
[1];
4247 unsigned index
= *(const WORD
*)&pFormat
[2];
4248 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
4249 USER_MARSHAL_CB umcb
;
4250 unsigned long saved_buffer_length
= 0;
4252 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4253 TRACE("index=%d\n", index
);
4255 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_BUFFER_SIZE
, pFormat
, &umcb
);
4257 if (flags
& USER_MARSHAL_POINTER
)
4259 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
4260 /* skip pointer prefix */
4261 safe_buffer_length_increment(pStubMsg
, 4);
4262 if (pStubMsg
->IgnoreEmbeddedPointers
)
4264 if (pStubMsg
->PointerLength
)
4266 saved_buffer_length
= pStubMsg
->BufferLength
;
4267 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4268 pStubMsg
->PointerLength
= 0;
4270 ALIGN_LENGTH(pStubMsg
->BufferLength
, 8);
4273 ALIGN_LENGTH(pStubMsg
->BufferLength
, (flags
& 0xf) + 1);
4276 TRACE("size=%d\n", bufsize
);
4277 safe_buffer_length_increment(pStubMsg
, bufsize
);
4280 pStubMsg
->BufferLength
=
4281 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
4282 &umcb
.Flags
, pStubMsg
->BufferLength
, pMemory
);
4284 if (saved_buffer_length
)
4286 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4287 pStubMsg
->BufferLength
= saved_buffer_length
;
4292 /***********************************************************************
4293 * NdrUserMarshalMemorySize [RPCRT4.@]
4295 ULONG WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4296 PFORMAT_STRING pFormat
)
4298 unsigned flags
= pFormat
[1];
4299 unsigned index
= *(const WORD
*)&pFormat
[2];
4300 DWORD memsize
= *(const WORD
*)&pFormat
[4];
4301 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
4303 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
4304 TRACE("index=%d\n", index
);
4306 pStubMsg
->MemorySize
+= memsize
;
4308 if (flags
& USER_MARSHAL_POINTER
)
4310 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4311 /* skip pointer prefix */
4312 pStubMsg
->Buffer
+= 4;
4313 if (pStubMsg
->IgnoreEmbeddedPointers
)
4314 return pStubMsg
->MemorySize
;
4315 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
4318 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4321 FIXME("not implemented for varying buffer size\n");
4323 pStubMsg
->Buffer
+= bufsize
;
4325 return pStubMsg
->MemorySize
;
4328 /***********************************************************************
4329 * NdrUserMarshalFree [RPCRT4.@]
4331 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
4332 unsigned char *pMemory
,
4333 PFORMAT_STRING pFormat
)
4335 /* unsigned flags = pFormat[1]; */
4336 unsigned index
= *(const WORD
*)&pFormat
[2];
4337 USER_MARSHAL_CB umcb
;
4339 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4340 TRACE("index=%d\n", index
);
4342 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_FREE
, pFormat
, &umcb
);
4344 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
4345 &umcb
.Flags
, pMemory
);
4348 /***********************************************************************
4349 * NdrGetUserMarshalInfo [RPCRT4.@]
4351 RPC_STATUS RPC_ENTRY
NdrGetUserMarshalInfo(ULONG
*flags
, ULONG level
, NDR_USER_MARSHAL_INFO
*umi
)
4353 USER_MARSHAL_CB
*umcb
= CONTAINING_RECORD(flags
, USER_MARSHAL_CB
, Flags
);
4355 TRACE("(%p,%u,%p)\n", flags
, level
, umi
);
4358 return RPC_S_INVALID_ARG
;
4360 memset(&umi
->Level1
, 0, sizeof(umi
->Level1
));
4361 umi
->InformationLevel
= level
;
4363 if (umcb
->Signature
!= USER_MARSHAL_CB_SIGNATURE
)
4364 return RPC_S_INVALID_ARG
;
4366 umi
->Level1
.pfnAllocate
= umcb
->pStubMsg
->pfnAllocate
;
4367 umi
->Level1
.pfnFree
= umcb
->pStubMsg
->pfnFree
;
4368 umi
->Level1
.pRpcChannelBuffer
= umcb
->pStubMsg
->pRpcChannelBuffer
;
4370 switch (umcb
->CBType
)
4372 case USER_MARSHAL_CB_MARSHALL
:
4373 case USER_MARSHAL_CB_UNMARSHALL
:
4375 RPC_MESSAGE
*msg
= umcb
->pStubMsg
->RpcMsg
;
4376 unsigned char *buffer_start
= msg
->Buffer
;
4377 unsigned char *buffer_end
=
4378 (unsigned char *)msg
->Buffer
+ msg
->BufferLength
;
4380 if (umcb
->pStubMsg
->Buffer
< buffer_start
||
4381 umcb
->pStubMsg
->Buffer
> buffer_end
)
4382 return ERROR_INVALID_USER_BUFFER
;
4384 umi
->Level1
.Buffer
= umcb
->pStubMsg
->Buffer
;
4385 umi
->Level1
.BufferSize
= buffer_end
- umcb
->pStubMsg
->Buffer
;
4388 case USER_MARSHAL_CB_BUFFER_SIZE
:
4389 case USER_MARSHAL_CB_FREE
:
4392 WARN("unrecognised CBType %d\n", umcb
->CBType
);
4398 /***********************************************************************
4399 * NdrClearOutParameters [RPCRT4.@]
4401 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
4402 PFORMAT_STRING pFormat
,
4405 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
4408 /***********************************************************************
4409 * NdrConvert [RPCRT4.@]
4411 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
4413 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
4414 /* FIXME: since this stub doesn't do any converting, the proper behavior
4415 is to raise an exception */
4418 /***********************************************************************
4419 * NdrConvert2 [RPCRT4.@]
4421 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, LONG NumberParams
)
4423 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4424 pStubMsg
, pFormat
, NumberParams
);
4425 /* FIXME: since this stub doesn't do any converting, the proper behavior
4426 is to raise an exception */
4429 #include "pshpack1.h"
4430 typedef struct _NDR_CSTRUCT_FORMAT
4433 unsigned char alignment
;
4434 unsigned short memory_size
;
4435 short offset_to_array_description
;
4436 } NDR_CSTRUCT_FORMAT
, NDR_CVSTRUCT_FORMAT
;
4437 #include "poppack.h"
4439 /***********************************************************************
4440 * NdrConformantStructMarshall [RPCRT4.@]
4442 unsigned char * WINAPI
NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4443 unsigned char *pMemory
,
4444 PFORMAT_STRING pFormat
)
4446 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4447 PFORMAT_STRING pCArrayFormat
;
4448 ULONG esize
, bufsize
;
4450 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4452 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4453 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4455 ERR("invalid format type %x\n", pCStructFormat
->type
);
4456 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4460 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4461 pCStructFormat
->offset_to_array_description
;
4462 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4464 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4465 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4468 esize
= *(const WORD
*)(pCArrayFormat
+2);
4470 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4471 pCArrayFormat
+ 4, 0);
4473 WriteConformance(pStubMsg
);
4475 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4477 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4479 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4480 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4482 ERR("integer overflow of memory_size %u with bufsize %u\n",
4483 pCStructFormat
->memory_size
, bufsize
);
4484 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4486 /* copy constant sized part of struct */
4487 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4488 safe_copy_to_buffer(pStubMsg
, pMemory
, pCStructFormat
->memory_size
+ bufsize
);
4490 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4491 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4496 /***********************************************************************
4497 * NdrConformantStructUnmarshall [RPCRT4.@]
4499 unsigned char * WINAPI
NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4500 unsigned char **ppMemory
,
4501 PFORMAT_STRING pFormat
,
4502 unsigned char fMustAlloc
)
4504 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4505 PFORMAT_STRING pCArrayFormat
;
4506 ULONG esize
, bufsize
;
4507 unsigned char *saved_buffer
;
4509 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4511 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4512 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4514 ERR("invalid format type %x\n", pCStructFormat
->type
);
4515 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4518 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4519 pCStructFormat
->offset_to_array_description
;
4520 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4522 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4523 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4526 esize
= *(const WORD
*)(pCArrayFormat
+2);
4528 pCArrayFormat
= ReadConformance(pStubMsg
, pCArrayFormat
+ 4);
4530 ALIGN_POINTER(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4532 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4534 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4535 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4537 ERR("integer overflow of memory_size %u with bufsize %u\n",
4538 pCStructFormat
->memory_size
, bufsize
);
4539 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4544 SIZE_T size
= pCStructFormat
->memory_size
+ bufsize
;
4545 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4549 if (!pStubMsg
->IsClient
&& !*ppMemory
)
4550 /* for servers, we just point straight into the RPC buffer */
4551 *ppMemory
= pStubMsg
->Buffer
;
4554 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4555 safe_buffer_increment(pStubMsg
, pCStructFormat
->memory_size
+ bufsize
);
4556 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4557 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4559 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
4560 if (*ppMemory
!= saved_buffer
)
4561 memcpy(*ppMemory
, saved_buffer
, pCStructFormat
->memory_size
+ bufsize
);
4566 /***********************************************************************
4567 * NdrConformantStructBufferSize [RPCRT4.@]
4569 void WINAPI
NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4570 unsigned char *pMemory
,
4571 PFORMAT_STRING pFormat
)
4573 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4574 PFORMAT_STRING pCArrayFormat
;
4577 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4579 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4580 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4582 ERR("invalid format type %x\n", pCStructFormat
->type
);
4583 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4586 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4587 pCStructFormat
->offset_to_array_description
;
4588 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4590 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4591 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4594 esize
= *(const WORD
*)(pCArrayFormat
+2);
4596 pCArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
, pCArrayFormat
+4, 0);
4597 SizeConformance(pStubMsg
);
4599 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCStructFormat
->alignment
+ 1);
4601 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4603 safe_buffer_length_increment(pStubMsg
, pCStructFormat
->memory_size
);
4604 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
4606 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4607 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4610 /***********************************************************************
4611 * NdrConformantStructMemorySize [RPCRT4.@]
4613 ULONG WINAPI
NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4614 PFORMAT_STRING pFormat
)
4620 /***********************************************************************
4621 * NdrConformantStructFree [RPCRT4.@]
4623 void WINAPI
NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
4624 unsigned char *pMemory
,
4625 PFORMAT_STRING pFormat
)
4627 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4628 PFORMAT_STRING pCArrayFormat
;
4630 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4632 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4633 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4635 ERR("invalid format type %x\n", pCStructFormat
->type
);
4636 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4640 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4641 pCStructFormat
->offset_to_array_description
;
4642 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4644 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4645 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4649 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4650 pCArrayFormat
+ 4, 0);
4652 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4654 /* copy constant sized part of struct */
4655 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4657 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4658 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4661 /***********************************************************************
4662 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4664 unsigned char * WINAPI
NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4665 unsigned char *pMemory
,
4666 PFORMAT_STRING pFormat
)
4668 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4669 PFORMAT_STRING pCVArrayFormat
;
4671 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4673 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4674 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4676 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4677 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4681 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4682 pCVStructFormat
->offset_to_array_description
;
4684 array_compute_and_write_conformance(*pCVArrayFormat
, pStubMsg
,
4685 pMemory
+ pCVStructFormat
->memory_size
,
4688 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4690 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4692 /* write constant sized part */
4693 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4694 safe_copy_to_buffer(pStubMsg
, pMemory
, pCVStructFormat
->memory_size
);
4696 array_write_variance_and_marshall(*pCVArrayFormat
, pStubMsg
,
4697 pMemory
+ pCVStructFormat
->memory_size
,
4698 pCVArrayFormat
, FALSE
/* fHasPointers */);
4700 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4705 /***********************************************************************
4706 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4708 unsigned char * WINAPI
NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4709 unsigned char **ppMemory
,
4710 PFORMAT_STRING pFormat
,
4711 unsigned char fMustAlloc
)
4713 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4714 PFORMAT_STRING pCVArrayFormat
;
4715 ULONG memsize
, bufsize
;
4716 unsigned char *saved_buffer
, *saved_array_buffer
;
4718 unsigned char *array_memory
;
4720 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4722 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4723 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4725 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4726 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4730 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4731 pCVStructFormat
->offset_to_array_description
;
4733 memsize
= array_read_conformance(*pCVArrayFormat
, pStubMsg
,
4736 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4738 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4740 /* work out how much memory to allocate if we need to do so */
4741 if (!fMustAlloc
&& !*ppMemory
)
4745 SIZE_T size
= pCVStructFormat
->memory_size
+ memsize
;
4746 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4749 /* mark the start of the constant data */
4750 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4751 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4753 array_memory
= *ppMemory
+ pCVStructFormat
->memory_size
;
4754 bufsize
= array_read_variance_and_unmarshall(*pCVArrayFormat
, pStubMsg
,
4755 &array_memory
, pCVArrayFormat
,
4756 FALSE
/* fMustAlloc */,
4757 FALSE
/* fUseServerBufferMemory */,
4758 FALSE
/* fUnmarshall */);
4760 /* save offset in case unmarshalling pointers changes it */
4761 offset
= pStubMsg
->Offset
;
4763 /* mark the start of the array data */
4764 saved_array_buffer
= pStubMsg
->Buffer
;
4765 safe_buffer_increment(pStubMsg
, bufsize
);
4767 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4769 /* copy the constant data */
4770 memcpy(*ppMemory
, saved_buffer
, pCVStructFormat
->memory_size
);
4771 /* copy the array data */
4772 TRACE("copying %p to %p\n", saved_array_buffer
, *ppMemory
+ pCVStructFormat
->memory_size
);
4773 memcpy(*ppMemory
+ pCVStructFormat
->memory_size
+ offset
,
4774 saved_array_buffer
, bufsize
);
4776 if (*pCVArrayFormat
== RPC_FC_C_CSTRING
)
4777 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory
+ pCVStructFormat
->memory_size
)));
4778 else if (*pCVArrayFormat
== RPC_FC_C_WSTRING
)
4779 TRACE("string=%s\n", debugstr_w((WCHAR
*)(*ppMemory
+ pCVStructFormat
->memory_size
)));
4784 /***********************************************************************
4785 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
4787 void WINAPI
NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4788 unsigned char *pMemory
,
4789 PFORMAT_STRING pFormat
)
4791 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4792 PFORMAT_STRING pCVArrayFormat
;
4794 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4796 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4797 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4799 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4800 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4804 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4805 pCVStructFormat
->offset_to_array_description
;
4806 array_compute_and_size_conformance(*pCVArrayFormat
, pStubMsg
,
4807 pMemory
+ pCVStructFormat
->memory_size
,
4810 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCVStructFormat
->alignment
+ 1);
4812 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4814 safe_buffer_length_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4816 array_buffer_size(*pCVArrayFormat
, pStubMsg
,
4817 pMemory
+ pCVStructFormat
->memory_size
, pCVArrayFormat
,
4818 FALSE
/* fHasPointers */);
4820 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4823 /***********************************************************************
4824 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4826 ULONG WINAPI
NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4827 PFORMAT_STRING pFormat
)
4829 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4830 PFORMAT_STRING pCVArrayFormat
;
4832 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4834 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4835 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4837 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4838 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4842 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4843 pCVStructFormat
->offset_to_array_description
;
4844 array_read_conformance(*pCVArrayFormat
, pStubMsg
, pCVArrayFormat
);
4846 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4848 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4850 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4851 array_memory_size(*pCVArrayFormat
, pStubMsg
, pCVArrayFormat
,
4852 FALSE
/* fHasPointers */);
4854 pStubMsg
->MemorySize
+= pCVStructFormat
->memory_size
;
4856 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4858 return pStubMsg
->MemorySize
;
4861 /***********************************************************************
4862 * NdrConformantVaryingStructFree [RPCRT4.@]
4864 void WINAPI
NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
4865 unsigned char *pMemory
,
4866 PFORMAT_STRING pFormat
)
4868 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4869 PFORMAT_STRING pCVArrayFormat
;
4871 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4873 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4874 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4876 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4877 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4881 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4882 pCVStructFormat
->offset_to_array_description
;
4883 array_free(*pCVArrayFormat
, pStubMsg
,
4884 pMemory
+ pCVStructFormat
->memory_size
, pCVArrayFormat
,
4885 FALSE
/* fHasPointers */);
4887 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4889 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4892 #include "pshpack1.h"
4896 unsigned char alignment
;
4897 unsigned short total_size
;
4898 } NDR_SMFARRAY_FORMAT
;
4903 unsigned char alignment
;
4904 unsigned long total_size
;
4905 } NDR_LGFARRAY_FORMAT
;
4906 #include "poppack.h"
4908 /***********************************************************************
4909 * NdrFixedArrayMarshall [RPCRT4.@]
4911 unsigned char * WINAPI
NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4912 unsigned char *pMemory
,
4913 PFORMAT_STRING pFormat
)
4915 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4916 unsigned long total_size
;
4918 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4920 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4921 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4923 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4924 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4928 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4930 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4932 total_size
= pSmFArrayFormat
->total_size
;
4933 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4937 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4938 total_size
= pLgFArrayFormat
->total_size
;
4939 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4942 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4943 safe_copy_to_buffer(pStubMsg
, pMemory
, total_size
);
4945 pFormat
= EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4950 /***********************************************************************
4951 * NdrFixedArrayUnmarshall [RPCRT4.@]
4953 unsigned char * WINAPI
NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4954 unsigned char **ppMemory
,
4955 PFORMAT_STRING pFormat
,
4956 unsigned char fMustAlloc
)
4958 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4959 unsigned long total_size
;
4960 unsigned char *saved_buffer
;
4962 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4964 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4965 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4967 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4968 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4972 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4974 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4976 total_size
= pSmFArrayFormat
->total_size
;
4977 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4981 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4982 total_size
= pLgFArrayFormat
->total_size
;
4983 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4987 *ppMemory
= NdrAllocate(pStubMsg
, total_size
);
4990 if (!pStubMsg
->IsClient
&& !*ppMemory
)
4991 /* for servers, we just point straight into the RPC buffer */
4992 *ppMemory
= pStubMsg
->Buffer
;
4995 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4996 safe_buffer_increment(pStubMsg
, total_size
);
4997 pFormat
= EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4999 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
5000 if (*ppMemory
!= saved_buffer
)
5001 memcpy(*ppMemory
, saved_buffer
, total_size
);
5006 /***********************************************************************
5007 * NdrFixedArrayBufferSize [RPCRT4.@]
5009 void WINAPI
NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5010 unsigned char *pMemory
,
5011 PFORMAT_STRING pFormat
)
5013 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5014 unsigned long total_size
;
5016 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5018 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5019 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5021 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5022 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5026 ALIGN_LENGTH(pStubMsg
->BufferLength
, pSmFArrayFormat
->alignment
+ 1);
5028 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5030 total_size
= pSmFArrayFormat
->total_size
;
5031 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5035 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5036 total_size
= pLgFArrayFormat
->total_size
;
5037 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5039 safe_buffer_length_increment(pStubMsg
, total_size
);
5041 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5044 /***********************************************************************
5045 * NdrFixedArrayMemorySize [RPCRT4.@]
5047 ULONG WINAPI
NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5048 PFORMAT_STRING pFormat
)
5050 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5053 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5055 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5056 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5058 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5059 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5063 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
5065 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5067 total_size
= pSmFArrayFormat
->total_size
;
5068 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5072 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5073 total_size
= pLgFArrayFormat
->total_size
;
5074 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5076 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5077 safe_buffer_increment(pStubMsg
, total_size
);
5078 pStubMsg
->MemorySize
+= total_size
;
5080 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5085 /***********************************************************************
5086 * NdrFixedArrayFree [RPCRT4.@]
5088 void WINAPI
NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
5089 unsigned char *pMemory
,
5090 PFORMAT_STRING pFormat
)
5092 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5094 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5096 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5097 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5099 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5100 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5104 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5105 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5108 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5109 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5112 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5115 /***********************************************************************
5116 * NdrVaryingArrayMarshall [RPCRT4.@]
5118 unsigned char * WINAPI
NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5119 unsigned char *pMemory
,
5120 PFORMAT_STRING pFormat
)
5122 unsigned char alignment
;
5123 DWORD elements
, esize
;
5126 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5128 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5129 (pFormat
[0] != RPC_FC_LGVARRAY
))
5131 ERR("invalid format type %x\n", pFormat
[0]);
5132 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5136 alignment
= pFormat
[1] + 1;
5138 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5141 pFormat
+= sizeof(WORD
);
5142 elements
= *(const WORD
*)pFormat
;
5143 pFormat
+= sizeof(WORD
);
5148 pFormat
+= sizeof(DWORD
);
5149 elements
= *(const DWORD
*)pFormat
;
5150 pFormat
+= sizeof(DWORD
);
5153 esize
= *(const WORD
*)pFormat
;
5154 pFormat
+= sizeof(WORD
);
5156 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5157 if ((pStubMsg
->ActualCount
> elements
) ||
5158 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5160 RpcRaiseException(RPC_S_INVALID_BOUND
);
5164 WriteVariance(pStubMsg
);
5166 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
5168 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
5169 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5170 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
5172 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
5177 /***********************************************************************
5178 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5180 unsigned char * WINAPI
NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5181 unsigned char **ppMemory
,
5182 PFORMAT_STRING pFormat
,
5183 unsigned char fMustAlloc
)
5185 unsigned char alignment
;
5186 DWORD size
, elements
, esize
;
5188 unsigned char *saved_buffer
;
5191 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5193 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5194 (pFormat
[0] != RPC_FC_LGVARRAY
))
5196 ERR("invalid format type %x\n", pFormat
[0]);
5197 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5201 alignment
= pFormat
[1] + 1;
5203 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5206 size
= *(const WORD
*)pFormat
;
5207 pFormat
+= sizeof(WORD
);
5208 elements
= *(const WORD
*)pFormat
;
5209 pFormat
+= sizeof(WORD
);
5214 size
= *(const DWORD
*)pFormat
;
5215 pFormat
+= sizeof(DWORD
);
5216 elements
= *(const DWORD
*)pFormat
;
5217 pFormat
+= sizeof(DWORD
);
5220 esize
= *(const WORD
*)pFormat
;
5221 pFormat
+= sizeof(WORD
);
5223 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
5225 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
5227 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
5228 offset
= pStubMsg
->Offset
;
5230 if (!fMustAlloc
&& !*ppMemory
)
5233 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5234 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5235 safe_buffer_increment(pStubMsg
, bufsize
);
5237 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
5239 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
5244 /***********************************************************************
5245 * NdrVaryingArrayBufferSize [RPCRT4.@]
5247 void WINAPI
NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5248 unsigned char *pMemory
,
5249 PFORMAT_STRING pFormat
)
5251 unsigned char alignment
;
5252 DWORD elements
, esize
;
5254 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5256 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5257 (pFormat
[0] != RPC_FC_LGVARRAY
))
5259 ERR("invalid format type %x\n", pFormat
[0]);
5260 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5264 alignment
= pFormat
[1] + 1;
5266 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5269 pFormat
+= sizeof(WORD
);
5270 elements
= *(const WORD
*)pFormat
;
5271 pFormat
+= sizeof(WORD
);
5276 pFormat
+= sizeof(DWORD
);
5277 elements
= *(const DWORD
*)pFormat
;
5278 pFormat
+= sizeof(DWORD
);
5281 esize
= *(const WORD
*)pFormat
;
5282 pFormat
+= sizeof(WORD
);
5284 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5285 if ((pStubMsg
->ActualCount
> elements
) ||
5286 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5288 RpcRaiseException(RPC_S_INVALID_BOUND
);
5292 SizeVariance(pStubMsg
);
5294 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
5296 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
5298 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5301 /***********************************************************************
5302 * NdrVaryingArrayMemorySize [RPCRT4.@]
5304 ULONG WINAPI
NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5305 PFORMAT_STRING pFormat
)
5307 unsigned char alignment
;
5308 DWORD size
, elements
, esize
;
5310 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5312 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5313 (pFormat
[0] != RPC_FC_LGVARRAY
))
5315 ERR("invalid format type %x\n", pFormat
[0]);
5316 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5320 alignment
= pFormat
[1] + 1;
5322 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5325 size
= *(const WORD
*)pFormat
;
5326 pFormat
+= sizeof(WORD
);
5327 elements
= *(const WORD
*)pFormat
;
5328 pFormat
+= sizeof(WORD
);
5333 size
= *(const DWORD
*)pFormat
;
5334 pFormat
+= sizeof(DWORD
);
5335 elements
= *(const DWORD
*)pFormat
;
5336 pFormat
+= sizeof(DWORD
);
5339 esize
= *(const WORD
*)pFormat
;
5340 pFormat
+= sizeof(WORD
);
5342 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
5344 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
5346 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
5347 pStubMsg
->MemorySize
+= size
;
5349 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5351 return pStubMsg
->MemorySize
;
5354 /***********************************************************************
5355 * NdrVaryingArrayFree [RPCRT4.@]
5357 void WINAPI
NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
5358 unsigned char *pMemory
,
5359 PFORMAT_STRING pFormat
)
5363 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5365 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5366 (pFormat
[0] != RPC_FC_LGVARRAY
))
5368 ERR("invalid format type %x\n", pFormat
[0]);
5369 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5373 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5376 pFormat
+= sizeof(WORD
);
5377 elements
= *(const WORD
*)pFormat
;
5378 pFormat
+= sizeof(WORD
);
5383 pFormat
+= sizeof(DWORD
);
5384 elements
= *(const DWORD
*)pFormat
;
5385 pFormat
+= sizeof(DWORD
);
5388 pFormat
+= sizeof(WORD
);
5390 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5391 if ((pStubMsg
->ActualCount
> elements
) ||
5392 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5394 RpcRaiseException(RPC_S_INVALID_BOUND
);
5398 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5401 static ULONG
get_discriminant(unsigned char fc
, const unsigned char *pMemory
)
5414 return *(const USHORT
*)pMemory
;
5418 return *(const ULONG
*)pMemory
;
5420 FIXME("Unhandled base type: 0x%02x\n", fc
);
5425 static PFORMAT_STRING
get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg
,
5426 unsigned long discriminant
,
5427 PFORMAT_STRING pFormat
)
5429 unsigned short num_arms
, arm
, type
;
5431 num_arms
= *(const SHORT
*)pFormat
& 0x0fff;
5433 for(arm
= 0; arm
< num_arms
; arm
++)
5435 if(discriminant
== *(const ULONG
*)pFormat
)
5443 type
= *(const unsigned short*)pFormat
;
5444 TRACE("type %04x\n", type
);
5445 if(arm
== num_arms
) /* default arm extras */
5449 ERR("no arm for 0x%lx and no default case\n", discriminant
);
5450 RpcRaiseException(RPC_S_INVALID_TAG
);
5455 TRACE("falling back to empty default case for 0x%lx\n", discriminant
);
5462 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
, ULONG discriminant
, PFORMAT_STRING pFormat
)
5464 unsigned short type
;
5468 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5472 type
= *(const unsigned short*)pFormat
;
5473 if((type
& 0xff00) == 0x8000)
5475 unsigned char basetype
= LOBYTE(type
);
5476 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &basetype
);
5480 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5481 NDR_MARSHALL m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
5484 unsigned char *saved_buffer
= NULL
;
5485 int pointer_buffer_mark_set
= 0;
5492 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
5493 saved_buffer
= pStubMsg
->Buffer
;
5494 if (pStubMsg
->PointerBufferMark
)
5496 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5497 pStubMsg
->PointerBufferMark
= NULL
;
5498 pointer_buffer_mark_set
= 1;
5501 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
5503 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char **)pMemory
, desc
);
5504 if (pointer_buffer_mark_set
)
5506 STD_OVERFLOW_CHECK(pStubMsg
);
5507 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5508 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5510 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5511 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
5512 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5514 pStubMsg
->Buffer
= saved_buffer
+ 4;
5518 m(pStubMsg
, pMemory
, desc
);
5521 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5526 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5527 unsigned char **ppMemory
,
5529 PFORMAT_STRING pFormat
,
5530 unsigned char fMustAlloc
)
5532 unsigned short type
;
5536 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5540 type
= *(const unsigned short*)pFormat
;
5541 if((type
& 0xff00) == 0x8000)
5543 unsigned char basetype
= LOBYTE(type
);
5544 return NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &basetype
, FALSE
);
5548 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5549 NDR_UNMARSHALL m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
5552 unsigned char *saved_buffer
= NULL
;
5553 int pointer_buffer_mark_set
= 0;
5560 **(void***)ppMemory
= NULL
;
5561 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5562 saved_buffer
= pStubMsg
->Buffer
;
5563 if (pStubMsg
->PointerBufferMark
)
5565 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5566 pStubMsg
->PointerBufferMark
= NULL
;
5567 pointer_buffer_mark_set
= 1;
5570 pStubMsg
->Buffer
+= 4; /* for pointer ID */
5572 if (saved_buffer
+ 4 > pStubMsg
->BufferEnd
)
5574 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5575 saved_buffer
, pStubMsg
->BufferEnd
);
5576 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5579 PointerUnmarshall(pStubMsg
, saved_buffer
, *(unsigned char ***)ppMemory
, **(unsigned char ***)ppMemory
, desc
, fMustAlloc
);
5580 if (pointer_buffer_mark_set
)
5582 STD_OVERFLOW_CHECK(pStubMsg
);
5583 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5584 pStubMsg
->Buffer
= saved_buffer
+ 4;
5588 m(pStubMsg
, ppMemory
, desc
, fMustAlloc
);
5591 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5596 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg
,
5597 unsigned char *pMemory
,
5599 PFORMAT_STRING pFormat
)
5601 unsigned short type
;
5605 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5609 type
= *(const unsigned short*)pFormat
;
5610 if((type
& 0xff00) == 0x8000)
5612 unsigned char basetype
= LOBYTE(type
);
5613 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &basetype
);
5617 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5618 NDR_BUFFERSIZE m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
5627 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
5628 safe_buffer_length_increment(pStubMsg
, 4); /* for pointer ID */
5629 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5631 int saved_buffer_length
= pStubMsg
->BufferLength
;
5632 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
5633 pStubMsg
->PointerLength
= 0;
5634 if(!pStubMsg
->BufferLength
)
5635 ERR("BufferLength == 0??\n");
5636 PointerBufferSize(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5637 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
5638 pStubMsg
->BufferLength
= saved_buffer_length
;
5642 m(pStubMsg
, pMemory
, desc
);
5645 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
5649 static ULONG
union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg
,
5651 PFORMAT_STRING pFormat
)
5653 unsigned short type
, size
;
5655 size
= *(const unsigned short*)pFormat
;
5656 pStubMsg
->Memory
+= size
;
5659 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5663 type
= *(const unsigned short*)pFormat
;
5664 if((type
& 0xff00) == 0x8000)
5666 return NdrBaseTypeMemorySize(pStubMsg
, pFormat
);
5670 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5671 NDR_MEMORYSIZE m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
5672 unsigned char *saved_buffer
;
5681 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5682 saved_buffer
= pStubMsg
->Buffer
;
5683 safe_buffer_increment(pStubMsg
, 4);
5684 ALIGN_LENGTH(pStubMsg
->MemorySize
, 4);
5685 pStubMsg
->MemorySize
+= 4;
5686 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5687 PointerMemorySize(pStubMsg
, saved_buffer
, pFormat
);
5690 return m(pStubMsg
, desc
);
5693 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5696 TRACE("size %d\n", size
);
5700 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg
,
5701 unsigned char *pMemory
,
5703 PFORMAT_STRING pFormat
)
5705 unsigned short type
;
5709 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5713 type
= *(const unsigned short*)pFormat
;
5714 if((type
& 0xff00) != 0x8000)
5716 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5717 NDR_FREE m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
5726 PointerFree(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5729 m(pStubMsg
, pMemory
, desc
);
5735 /***********************************************************************
5736 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5738 unsigned char * WINAPI
NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5739 unsigned char *pMemory
,
5740 PFORMAT_STRING pFormat
)
5742 unsigned char switch_type
;
5743 unsigned char increment
;
5746 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5749 switch_type
= *pFormat
& 0xf;
5750 increment
= (*pFormat
& 0xf0) >> 4;
5753 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, increment
);
5755 switch_value
= get_discriminant(switch_type
, pMemory
);
5756 TRACE("got switch value 0x%x\n", switch_value
);
5758 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &switch_type
);
5759 pMemory
+= increment
;
5761 return union_arm_marshall(pStubMsg
, pMemory
, switch_value
, pFormat
);
5764 /***********************************************************************
5765 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5767 unsigned char * WINAPI
NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5768 unsigned char **ppMemory
,
5769 PFORMAT_STRING pFormat
,
5770 unsigned char fMustAlloc
)
5772 unsigned char switch_type
;
5773 unsigned char increment
;
5775 unsigned short size
;
5776 unsigned char *pMemoryArm
;
5778 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5781 switch_type
= *pFormat
& 0xf;
5782 increment
= (*pFormat
& 0xf0) >> 4;
5785 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
5786 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
5787 TRACE("got switch value 0x%x\n", switch_value
);
5789 size
= *(const unsigned short*)pFormat
+ increment
;
5790 if (!fMustAlloc
&& !*ppMemory
)
5793 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5795 NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &switch_type
, FALSE
);
5796 pMemoryArm
= *ppMemory
+ increment
;
5798 return union_arm_unmarshall(pStubMsg
, &pMemoryArm
, switch_value
, pFormat
, fMustAlloc
);
5801 /***********************************************************************
5802 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5804 void WINAPI
NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5805 unsigned char *pMemory
,
5806 PFORMAT_STRING pFormat
)
5808 unsigned char switch_type
;
5809 unsigned char increment
;
5812 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5815 switch_type
= *pFormat
& 0xf;
5816 increment
= (*pFormat
& 0xf0) >> 4;
5819 ALIGN_LENGTH(pStubMsg
->BufferLength
, increment
);
5820 switch_value
= get_discriminant(switch_type
, pMemory
);
5821 TRACE("got switch value 0x%x\n", switch_value
);
5823 /* Add discriminant size */
5824 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&switch_value
, &switch_type
);
5825 pMemory
+= increment
;
5827 union_arm_buffer_size(pStubMsg
, pMemory
, switch_value
, pFormat
);
5830 /***********************************************************************
5831 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5833 ULONG WINAPI
NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5834 PFORMAT_STRING pFormat
)
5836 unsigned char switch_type
;
5837 unsigned char increment
;
5840 switch_type
= *pFormat
& 0xf;
5841 increment
= (*pFormat
& 0xf0) >> 4;
5844 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
5845 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
5846 TRACE("got switch value 0x%x\n", switch_value
);
5848 pStubMsg
->Memory
+= increment
;
5850 return increment
+ union_arm_memory_size(pStubMsg
, switch_value
, pFormat
+ *(const SHORT
*)pFormat
);
5853 /***********************************************************************
5854 * NdrEncapsulatedUnionFree [RPCRT4.@]
5856 void WINAPI
NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
5857 unsigned char *pMemory
,
5858 PFORMAT_STRING pFormat
)
5860 unsigned char switch_type
;
5861 unsigned char increment
;
5864 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5867 switch_type
= *pFormat
& 0xf;
5868 increment
= (*pFormat
& 0xf0) >> 4;
5871 switch_value
= get_discriminant(switch_type
, pMemory
);
5872 TRACE("got switch value 0x%x\n", switch_value
);
5874 pMemory
+= increment
;
5876 union_arm_free(pStubMsg
, pMemory
, switch_value
, pFormat
);
5879 /***********************************************************************
5880 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5882 unsigned char * WINAPI
NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5883 unsigned char *pMemory
,
5884 PFORMAT_STRING pFormat
)
5886 unsigned char switch_type
;
5888 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5891 switch_type
= *pFormat
;
5894 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5895 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5896 /* Marshall discriminant */
5897 NdrBaseTypeMarshall(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
5899 return union_arm_marshall(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5902 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg
,
5903 PFORMAT_STRING
*ppFormat
)
5905 long discriminant
= 0;
5915 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5924 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5925 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5933 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
5934 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5939 FIXME("Unhandled base type: 0x%02x\n", **ppFormat
);
5943 if (pStubMsg
->fHasNewCorrDesc
)
5947 return discriminant
;
5950 /**********************************************************************
5951 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5953 unsigned char * WINAPI
NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5954 unsigned char **ppMemory
,
5955 PFORMAT_STRING pFormat
,
5956 unsigned char fMustAlloc
)
5959 unsigned short size
;
5961 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5964 /* Unmarshall discriminant */
5965 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
5966 TRACE("unmarshalled discriminant %lx\n", discriminant
);
5968 pFormat
+= *(const SHORT
*)pFormat
;
5970 size
= *(const unsigned short*)pFormat
;
5972 if (!fMustAlloc
&& !*ppMemory
)
5975 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5977 return union_arm_unmarshall(pStubMsg
, ppMemory
, discriminant
, pFormat
, fMustAlloc
);
5980 /***********************************************************************
5981 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5983 void WINAPI
NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5984 unsigned char *pMemory
,
5985 PFORMAT_STRING pFormat
)
5987 unsigned char switch_type
;
5989 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5992 switch_type
= *pFormat
;
5995 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5996 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5997 /* Add discriminant size */
5998 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
6000 union_arm_buffer_size(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6003 /***********************************************************************
6004 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
6006 ULONG WINAPI
NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6007 PFORMAT_STRING pFormat
)
6012 /* Unmarshall discriminant */
6013 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
6014 TRACE("unmarshalled discriminant 0x%x\n", discriminant
);
6016 return union_arm_memory_size(pStubMsg
, discriminant
, pFormat
+ *(const SHORT
*)pFormat
);
6019 /***********************************************************************
6020 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6022 void WINAPI
NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
6023 unsigned char *pMemory
,
6024 PFORMAT_STRING pFormat
)
6026 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6030 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6031 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6033 union_arm_free(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6036 /***********************************************************************
6037 * NdrByteCountPointerMarshall [RPCRT4.@]
6039 unsigned char * WINAPI
NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6040 unsigned char *pMemory
,
6041 PFORMAT_STRING pFormat
)
6047 /***********************************************************************
6048 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6050 unsigned char * WINAPI
NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6051 unsigned char **ppMemory
,
6052 PFORMAT_STRING pFormat
,
6053 unsigned char fMustAlloc
)
6059 /***********************************************************************
6060 * NdrByteCountPointerBufferSize [RPCRT4.@]
6062 void WINAPI
NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6063 unsigned char *pMemory
,
6064 PFORMAT_STRING pFormat
)
6069 /***********************************************************************
6070 * NdrByteCountPointerMemorySize [internal]
6072 static ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6073 PFORMAT_STRING pFormat
)
6079 /***********************************************************************
6080 * NdrByteCountPointerFree [RPCRT4.@]
6082 void WINAPI
NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
6083 unsigned char *pMemory
,
6084 PFORMAT_STRING pFormat
)
6089 /***********************************************************************
6090 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6092 unsigned char * WINAPI
NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6093 unsigned char *pMemory
,
6094 PFORMAT_STRING pFormat
)
6100 /***********************************************************************
6101 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6103 unsigned char * WINAPI
NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6104 unsigned char **ppMemory
,
6105 PFORMAT_STRING pFormat
,
6106 unsigned char fMustAlloc
)
6112 /***********************************************************************
6113 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6115 void WINAPI
NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6116 unsigned char *pMemory
,
6117 PFORMAT_STRING pFormat
)
6122 /***********************************************************************
6123 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6125 ULONG WINAPI
NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6126 PFORMAT_STRING pFormat
)
6132 /***********************************************************************
6133 * NdrXmitOrRepAsFree [RPCRT4.@]
6135 void WINAPI
NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg
,
6136 unsigned char *pMemory
,
6137 PFORMAT_STRING pFormat
)
6142 /***********************************************************************
6143 * NdrRangeMarshall [internal]
6145 static unsigned char *WINAPI
NdrRangeMarshall(
6146 PMIDL_STUB_MESSAGE pStubMsg
,
6147 unsigned char *pMemory
,
6148 PFORMAT_STRING pFormat
)
6150 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
6151 unsigned char base_type
;
6153 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6155 if (pRange
->type
!= RPC_FC_RANGE
)
6157 ERR("invalid format type %x\n", pRange
->type
);
6158 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6162 base_type
= pRange
->flags_type
& 0xf;
6164 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &base_type
);
6167 /***********************************************************************
6168 * NdrRangeUnmarshall [RPCRT4.@]
6170 unsigned char *WINAPI
NdrRangeUnmarshall(
6171 PMIDL_STUB_MESSAGE pStubMsg
,
6172 unsigned char **ppMemory
,
6173 PFORMAT_STRING pFormat
,
6174 unsigned char fMustAlloc
)
6176 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
6177 unsigned char base_type
;
6179 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6181 if (pRange
->type
!= RPC_FC_RANGE
)
6183 ERR("invalid format type %x\n", pRange
->type
);
6184 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6187 base_type
= pRange
->flags_type
& 0xf;
6189 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6190 base_type
, pRange
->low_value
, pRange
->high_value
);
6192 #define RANGE_UNMARSHALL(type, format_spec) \
6195 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6196 if (!fMustAlloc && !*ppMemory) \
6197 fMustAlloc = TRUE; \
6199 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6200 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
6202 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6203 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6204 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6206 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
6207 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
6209 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6210 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
6211 (type)pRange->high_value); \
6212 RpcRaiseException(RPC_S_INVALID_BOUND); \
6215 TRACE("*ppMemory: %p\n", *ppMemory); \
6216 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
6217 pStubMsg->Buffer += sizeof(type); \
6224 RANGE_UNMARSHALL(UCHAR
, "%d");
6225 TRACE("value: 0x%02x\n", **ppMemory
);
6229 RANGE_UNMARSHALL(CHAR
, "%u");
6230 TRACE("value: 0x%02x\n", **ppMemory
);
6232 case RPC_FC_WCHAR
: /* FIXME: valid? */
6234 RANGE_UNMARSHALL(USHORT
, "%u");
6235 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6238 RANGE_UNMARSHALL(SHORT
, "%d");
6239 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6242 RANGE_UNMARSHALL(LONG
, "%d");
6243 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6246 RANGE_UNMARSHALL(ULONG
, "%u");
6247 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6251 FIXME("Unhandled enum type\n");
6253 case RPC_FC_ERROR_STATUS_T
: /* FIXME: valid? */
6258 ERR("invalid range base type: 0x%02x\n", base_type
);
6259 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6265 /***********************************************************************
6266 * NdrRangeBufferSize [internal]
6268 static void WINAPI
NdrRangeBufferSize(
6269 PMIDL_STUB_MESSAGE pStubMsg
,
6270 unsigned char *pMemory
,
6271 PFORMAT_STRING pFormat
)
6273 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
6274 unsigned char base_type
;
6276 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6278 if (pRange
->type
!= RPC_FC_RANGE
)
6280 ERR("invalid format type %x\n", pRange
->type
);
6281 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6283 base_type
= pRange
->flags_type
& 0xf;
6285 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &base_type
);
6288 /***********************************************************************
6289 * NdrRangeMemorySize [internal]
6291 static ULONG WINAPI
NdrRangeMemorySize(
6292 PMIDL_STUB_MESSAGE pStubMsg
,
6293 PFORMAT_STRING pFormat
)
6295 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
6296 unsigned char base_type
;
6298 if (pRange
->type
!= RPC_FC_RANGE
)
6300 ERR("invalid format type %x\n", pRange
->type
);
6301 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6304 base_type
= pRange
->flags_type
& 0xf;
6306 return NdrBaseTypeMemorySize(pStubMsg
, &base_type
);
6309 /***********************************************************************
6310 * NdrRangeFree [internal]
6312 static void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6313 unsigned char *pMemory
,
6314 PFORMAT_STRING pFormat
)
6316 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6321 /***********************************************************************
6322 * NdrBaseTypeMarshall [internal]
6324 static unsigned char *WINAPI
NdrBaseTypeMarshall(
6325 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
);
6337 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(UCHAR
));
6338 TRACE("value: 0x%02x\n", *pMemory
);
6343 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(USHORT
));
6344 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(USHORT
));
6345 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
6349 case RPC_FC_ERROR_STATUS_T
:
6351 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(ULONG
));
6352 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONG
));
6353 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
6356 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(float));
6357 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
6360 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(double));
6361 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
6364 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(ULONGLONG
));
6365 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONGLONG
));
6366 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
6369 /* only 16-bits on the wire, so do a sanity check */
6370 if (*(UINT
*)pMemory
> SHRT_MAX
)
6371 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
6372 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(USHORT
));
6373 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6374 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6375 *(USHORT
*)pStubMsg
->Buffer
= *(UINT
*)pMemory
;
6376 pStubMsg
->Buffer
+= sizeof(USHORT
);
6377 TRACE("value: 0x%04x\n", *(UINT
*)pMemory
);
6382 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6385 /* FIXME: what is the correct return value? */
6389 /***********************************************************************
6390 * NdrBaseTypeUnmarshall [internal]
6392 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(
6393 PMIDL_STUB_MESSAGE pStubMsg
,
6394 unsigned char **ppMemory
,
6395 PFORMAT_STRING pFormat
,
6396 unsigned char fMustAlloc
)
6398 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6400 #define BASE_TYPE_UNMARSHALL(type) \
6401 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6402 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6404 *ppMemory = pStubMsg->Buffer; \
6405 TRACE("*ppMemory: %p\n", *ppMemory); \
6406 safe_buffer_increment(pStubMsg, sizeof(type)); \
6411 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6412 TRACE("*ppMemory: %p\n", *ppMemory); \
6413 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6422 BASE_TYPE_UNMARSHALL(UCHAR
);
6423 TRACE("value: 0x%02x\n", **ppMemory
);
6428 BASE_TYPE_UNMARSHALL(USHORT
);
6429 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6433 case RPC_FC_ERROR_STATUS_T
:
6435 BASE_TYPE_UNMARSHALL(ULONG
);
6436 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6439 BASE_TYPE_UNMARSHALL(float);
6440 TRACE("value: %f\n", **(float **)ppMemory
);
6443 BASE_TYPE_UNMARSHALL(double);
6444 TRACE("value: %f\n", **(double **)ppMemory
);
6447 BASE_TYPE_UNMARSHALL(ULONGLONG
);
6448 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG
**)ppMemory
));
6451 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
6452 if (!fMustAlloc
&& !*ppMemory
)
6455 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT
));
6456 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > pStubMsg
->BufferEnd
)
6457 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6458 TRACE("*ppMemory: %p\n", *ppMemory
);
6459 /* 16-bits on the wire, but int in memory */
6460 **(UINT
**)ppMemory
= *(USHORT
*)pStubMsg
->Buffer
;
6461 pStubMsg
->Buffer
+= sizeof(USHORT
);
6462 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
6467 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6469 #undef BASE_TYPE_UNMARSHALL
6471 /* FIXME: what is the correct return value? */
6476 /***********************************************************************
6477 * NdrBaseTypeBufferSize [internal]
6479 static void WINAPI
NdrBaseTypeBufferSize(
6480 PMIDL_STUB_MESSAGE pStubMsg
,
6481 unsigned char *pMemory
,
6482 PFORMAT_STRING pFormat
)
6484 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6492 safe_buffer_length_increment(pStubMsg
, sizeof(UCHAR
));
6498 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(USHORT
));
6499 safe_buffer_length_increment(pStubMsg
, sizeof(USHORT
));
6504 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONG
));
6505 safe_buffer_length_increment(pStubMsg
, sizeof(ULONG
));
6508 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(float));
6509 safe_buffer_length_increment(pStubMsg
, sizeof(float));
6512 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(double));
6513 safe_buffer_length_increment(pStubMsg
, sizeof(double));
6516 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONGLONG
));
6517 safe_buffer_length_increment(pStubMsg
, sizeof(ULONGLONG
));
6519 case RPC_FC_ERROR_STATUS_T
:
6520 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(error_status_t
));
6521 safe_buffer_length_increment(pStubMsg
, sizeof(error_status_t
));
6526 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6530 /***********************************************************************
6531 * NdrBaseTypeMemorySize [internal]
6533 static ULONG WINAPI
NdrBaseTypeMemorySize(
6534 PMIDL_STUB_MESSAGE pStubMsg
,
6535 PFORMAT_STRING pFormat
)
6537 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg
, *pFormat
);
6545 safe_buffer_increment(pStubMsg
, sizeof(UCHAR
));
6546 pStubMsg
->MemorySize
+= sizeof(UCHAR
);
6547 return sizeof(UCHAR
);
6551 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6552 pStubMsg
->MemorySize
+= sizeof(USHORT
);
6553 return sizeof(USHORT
);
6557 safe_buffer_increment(pStubMsg
, sizeof(ULONG
));
6558 pStubMsg
->MemorySize
+= sizeof(ULONG
);
6559 return sizeof(ULONG
);
6561 safe_buffer_increment(pStubMsg
, sizeof(float));
6562 pStubMsg
->MemorySize
+= sizeof(float);
6563 return sizeof(float);
6565 safe_buffer_increment(pStubMsg
, sizeof(double));
6566 pStubMsg
->MemorySize
+= sizeof(double);
6567 return sizeof(double);
6569 safe_buffer_increment(pStubMsg
, sizeof(ULONGLONG
));
6570 pStubMsg
->MemorySize
+= sizeof(ULONGLONG
);
6571 return sizeof(ULONGLONG
);
6572 case RPC_FC_ERROR_STATUS_T
:
6573 safe_buffer_increment(pStubMsg
, sizeof(error_status_t
));
6574 pStubMsg
->MemorySize
+= sizeof(error_status_t
);
6575 return sizeof(error_status_t
);
6577 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6578 pStubMsg
->MemorySize
+= sizeof(UINT
);
6579 return sizeof(UINT
);
6581 pStubMsg
->MemorySize
+= sizeof(void *);
6582 return sizeof(void *);
6584 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6589 /***********************************************************************
6590 * NdrBaseTypeFree [internal]
6592 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6593 unsigned char *pMemory
,
6594 PFORMAT_STRING pFormat
)
6596 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6601 /***********************************************************************
6602 * NdrContextHandleBufferSize [internal]
6604 static void WINAPI
NdrContextHandleBufferSize(
6605 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
);
6611 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6613 ERR("invalid format type %x\n", *pFormat
);
6614 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6616 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
6617 safe_buffer_length_increment(pStubMsg
, cbNDRContext
);
6620 /***********************************************************************
6621 * NdrContextHandleMarshall [internal]
6623 static unsigned char *WINAPI
NdrContextHandleMarshall(
6624 PMIDL_STUB_MESSAGE pStubMsg
,
6625 unsigned char *pMemory
,
6626 PFORMAT_STRING pFormat
)
6628 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6630 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6632 ERR("invalid format type %x\n", *pFormat
);
6633 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6635 TRACE("flags: 0x%02x\n", pFormat
[1]);
6637 if (pFormat
[1] & 0x80)
6638 NdrClientContextMarshall(pStubMsg
, *(NDR_CCONTEXT
**)pMemory
, FALSE
);
6640 NdrClientContextMarshall(pStubMsg
, pMemory
, FALSE
);
6645 /***********************************************************************
6646 * NdrContextHandleUnmarshall [internal]
6648 static unsigned char *WINAPI
NdrContextHandleUnmarshall(
6649 PMIDL_STUB_MESSAGE pStubMsg
,
6650 unsigned char **ppMemory
,
6651 PFORMAT_STRING pFormat
,
6652 unsigned char fMustAlloc
)
6654 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg
,
6655 ppMemory
, pFormat
, fMustAlloc
? "TRUE": "FALSE");
6657 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6659 ERR("invalid format type %x\n", *pFormat
);
6660 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6662 TRACE("flags: 0x%02x\n", pFormat
[1]);
6664 /* [out]-only or [ret] param */
6665 if ((pFormat
[1] & 0x60) == 0x20)
6666 **(NDR_CCONTEXT
**)ppMemory
= NULL
;
6667 NdrClientContextUnmarshall(pStubMsg
, *(NDR_CCONTEXT
**)ppMemory
, pStubMsg
->RpcMsg
->Handle
);
6672 /***********************************************************************
6673 * NdrClientContextMarshall [RPCRT4.@]
6675 void WINAPI
NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6676 NDR_CCONTEXT ContextHandle
,
6679 TRACE("(%p, %p, %d)\n", pStubMsg
, ContextHandle
, fCheck
);
6681 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
6683 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6685 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6686 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6687 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6690 /* FIXME: what does fCheck do? */
6691 NDRCContextMarshall(ContextHandle
,
6694 pStubMsg
->Buffer
+= cbNDRContext
;
6697 /***********************************************************************
6698 * NdrClientContextUnmarshall [RPCRT4.@]
6700 void WINAPI
NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6701 NDR_CCONTEXT
* pContextHandle
,
6702 RPC_BINDING_HANDLE BindHandle
)
6704 TRACE("(%p, %p, %p)\n", pStubMsg
, pContextHandle
, BindHandle
);
6706 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6708 if (pStubMsg
->Buffer
+ cbNDRContext
> pStubMsg
->BufferEnd
)
6709 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6711 NDRCContextUnmarshall(pContextHandle
,
6714 pStubMsg
->RpcMsg
->DataRepresentation
);
6716 pStubMsg
->Buffer
+= cbNDRContext
;
6719 void WINAPI
NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6720 NDR_SCONTEXT ContextHandle
,
6721 NDR_RUNDOWN RundownRoutine
)
6723 TRACE("(%p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
);
6725 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6727 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6729 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6730 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6731 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6734 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
6735 pStubMsg
->Buffer
, RundownRoutine
, NULL
,
6736 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
6737 pStubMsg
->Buffer
+= cbNDRContext
;
6740 NDR_SCONTEXT WINAPI
NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
)
6742 NDR_SCONTEXT ContextHandle
;
6744 TRACE("(%p)\n", pStubMsg
);
6746 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6748 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6750 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6751 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6752 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6755 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
6757 pStubMsg
->RpcMsg
->DataRepresentation
,
6758 NULL
, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
6759 pStubMsg
->Buffer
+= cbNDRContext
;
6761 return ContextHandle
;
6764 void WINAPI
NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg
,
6765 unsigned char* pMemory
,
6766 PFORMAT_STRING pFormat
)
6768 FIXME("(%p, %p, %p): stub\n", pStubMsg
, pMemory
, pFormat
);
6771 NDR_SCONTEXT WINAPI
NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg
,
6772 PFORMAT_STRING pFormat
)
6774 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6775 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6777 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
6779 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
6780 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
6781 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
6782 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
6783 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
6785 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
6786 if_id
= &sif
->InterfaceId
;
6789 return NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
, NULL
,
6790 pStubMsg
->RpcMsg
->DataRepresentation
, if_id
,
6794 void WINAPI
NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6795 NDR_SCONTEXT ContextHandle
,
6796 NDR_RUNDOWN RundownRoutine
,
6797 PFORMAT_STRING pFormat
)
6799 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6800 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6802 TRACE("(%p, %p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
, pFormat
);
6804 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6806 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6808 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6809 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6810 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6813 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
6814 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
6815 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
6816 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
6817 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
6819 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
6820 if_id
= &sif
->InterfaceId
;
6823 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
6824 pStubMsg
->Buffer
, RundownRoutine
, if_id
, flags
);
6825 pStubMsg
->Buffer
+= cbNDRContext
;
6828 NDR_SCONTEXT WINAPI
NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6829 PFORMAT_STRING pFormat
)
6831 NDR_SCONTEXT ContextHandle
;
6832 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6833 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6835 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
6837 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6839 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6841 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6842 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6843 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6846 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
6847 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
6848 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
6849 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
6850 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
6852 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
6853 if_id
= &sif
->InterfaceId
;
6856 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
6858 pStubMsg
->RpcMsg
->DataRepresentation
,
6860 pStubMsg
->Buffer
+= cbNDRContext
;
6862 return ContextHandle
;
6865 /***********************************************************************
6866 * NdrCorrelationInitialize [RPCRT4.@]
6868 * Initializes correlation validity checking.
6871 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6872 * pMemory [I] Pointer to memory to use as a cache.
6873 * CacheSize [I] Size of the memory pointed to by pMemory.
6874 * Flags [I] Reserved. Set to zero.
6879 void WINAPI
NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg
, void *pMemory
, ULONG CacheSize
, ULONG Flags
)
6881 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg
, pMemory
, CacheSize
, Flags
);
6882 pStubMsg
->fHasNewCorrDesc
= TRUE
;
6885 /***********************************************************************
6886 * NdrCorrelationPass [RPCRT4.@]
6888 * Performs correlation validity checking.
6891 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6896 void WINAPI
NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg
)
6898 FIXME("(%p): stub\n", pStubMsg
);
6901 /***********************************************************************
6902 * NdrCorrelationFree [RPCRT4.@]
6904 * Frees any resources used while unmarshalling parameters that need
6905 * correlation validity checking.
6908 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6913 void WINAPI
NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg
)
6915 FIXME("(%p): stub\n", pStubMsg
);