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 /* Increment the buffer here instead of in PointerUnmarshall,
1504 * as that is used by embedded pointers which already handle the incrementing
1505 * the buffer, and shouldn't read any additional pointer data from the
1507 if (*pFormat
!= RPC_FC_RP
)
1509 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1510 Buffer
= pStubMsg
->Buffer
;
1511 safe_buffer_increment(pStubMsg
, 4);
1514 Buffer
= pStubMsg
->Buffer
;
1516 PointerUnmarshall(pStubMsg
, Buffer
, ppMemory
, *ppMemory
, pFormat
, fMustAlloc
);
1521 /***********************************************************************
1522 * NdrPointerBufferSize [RPCRT4.@]
1524 void WINAPI
NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1525 unsigned char *pMemory
,
1526 PFORMAT_STRING pFormat
)
1528 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1530 /* Increment the buffer length here instead of in PointerBufferSize,
1531 * as that is used by embedded pointers which already handle the buffer
1532 * length, and shouldn't write anything more to the wire */
1533 if (*pFormat
!= RPC_FC_RP
)
1535 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
1536 safe_buffer_length_increment(pStubMsg
, 4);
1539 PointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1542 /***********************************************************************
1543 * NdrPointerMemorySize [RPCRT4.@]
1545 ULONG WINAPI
NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1546 PFORMAT_STRING pFormat
)
1548 /* unsigned size = *(LPWORD)(pFormat+2); */
1549 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1550 PointerMemorySize(pStubMsg
, pStubMsg
->Buffer
, pFormat
);
1554 /***********************************************************************
1555 * NdrPointerFree [RPCRT4.@]
1557 void WINAPI
NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1558 unsigned char *pMemory
,
1559 PFORMAT_STRING pFormat
)
1561 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1562 PointerFree(pStubMsg
, pMemory
, pFormat
);
1565 /***********************************************************************
1566 * NdrSimpleTypeMarshall [RPCRT4.@]
1568 void WINAPI
NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1569 unsigned char FormatChar
)
1571 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &FormatChar
);
1574 /***********************************************************************
1575 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1577 * Unmarshall a base type.
1580 * Doesn't check that the buffer is long enough before copying, so the caller
1583 void WINAPI
NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1584 unsigned char FormatChar
)
1586 #define BASE_TYPE_UNMARSHALL(type) \
1587 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
1588 TRACE("pMemory: %p\n", pMemory); \
1589 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1590 pStubMsg->Buffer += sizeof(type);
1598 BASE_TYPE_UNMARSHALL(UCHAR
);
1599 TRACE("value: 0x%02x\n", *pMemory
);
1604 BASE_TYPE_UNMARSHALL(USHORT
);
1605 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
1609 case RPC_FC_ERROR_STATUS_T
:
1611 BASE_TYPE_UNMARSHALL(ULONG
);
1612 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
1615 BASE_TYPE_UNMARSHALL(float);
1616 TRACE("value: %f\n", *(float *)pMemory
);
1619 BASE_TYPE_UNMARSHALL(double);
1620 TRACE("value: %f\n", *(double *)pMemory
);
1623 BASE_TYPE_UNMARSHALL(ULONGLONG
);
1624 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
1627 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
1628 TRACE("pMemory: %p\n", pMemory
);
1629 /* 16-bits on the wire, but int in memory */
1630 *(UINT
*)pMemory
= *(USHORT
*)pStubMsg
->Buffer
;
1631 pStubMsg
->Buffer
+= sizeof(USHORT
);
1632 TRACE("value: 0x%08x\n", *(UINT
*)pMemory
);
1637 FIXME("Unhandled base type: 0x%02x\n", FormatChar
);
1639 #undef BASE_TYPE_UNMARSHALL
1642 /***********************************************************************
1643 * NdrSimpleStructMarshall [RPCRT4.@]
1645 unsigned char * WINAPI
NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1646 unsigned char *pMemory
,
1647 PFORMAT_STRING pFormat
)
1649 unsigned size
= *(const WORD
*)(pFormat
+2);
1650 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1652 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pFormat
[1] + 1);
1654 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1655 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
1657 if (pFormat
[0] != RPC_FC_STRUCT
)
1658 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
+4);
1663 /***********************************************************************
1664 * NdrSimpleStructUnmarshall [RPCRT4.@]
1666 unsigned char * WINAPI
NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1667 unsigned char **ppMemory
,
1668 PFORMAT_STRING pFormat
,
1669 unsigned char fMustAlloc
)
1671 unsigned size
= *(const WORD
*)(pFormat
+2);
1672 unsigned char *saved_buffer
;
1673 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1675 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1678 *ppMemory
= NdrAllocate(pStubMsg
, size
);
1681 if (!pStubMsg
->IsClient
&& !*ppMemory
)
1682 /* for servers, we just point straight into the RPC buffer */
1683 *ppMemory
= pStubMsg
->Buffer
;
1686 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1687 safe_buffer_increment(pStubMsg
, size
);
1688 if (pFormat
[0] == RPC_FC_PSTRUCT
)
1689 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
+4, fMustAlloc
);
1691 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
1692 if (*ppMemory
!= saved_buffer
)
1693 memcpy(*ppMemory
, saved_buffer
, size
);
1698 /***********************************************************************
1699 * NdrSimpleStructBufferSize [RPCRT4.@]
1701 void WINAPI
NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1702 unsigned char *pMemory
,
1703 PFORMAT_STRING pFormat
)
1705 unsigned size
= *(const WORD
*)(pFormat
+2);
1706 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1708 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
1710 safe_buffer_length_increment(pStubMsg
, size
);
1711 if (pFormat
[0] != RPC_FC_STRUCT
)
1712 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
+4);
1715 /***********************************************************************
1716 * NdrSimpleStructMemorySize [RPCRT4.@]
1718 ULONG WINAPI
NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1719 PFORMAT_STRING pFormat
)
1721 unsigned short size
= *(const WORD
*)(pFormat
+2);
1723 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1725 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1726 pStubMsg
->MemorySize
+= size
;
1727 safe_buffer_increment(pStubMsg
, size
);
1729 if (pFormat
[0] != RPC_FC_STRUCT
)
1730 EmbeddedPointerMemorySize(pStubMsg
, pFormat
+4);
1731 return pStubMsg
->MemorySize
;
1734 /***********************************************************************
1735 * NdrSimpleStructFree [RPCRT4.@]
1737 void WINAPI
NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
1738 unsigned char *pMemory
,
1739 PFORMAT_STRING pFormat
)
1741 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1742 if (pFormat
[0] != RPC_FC_STRUCT
)
1743 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
+4);
1748 static inline void array_compute_and_size_conformance(
1749 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1750 PFORMAT_STRING pFormat
)
1755 ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1756 SizeConformance(pStubMsg
);
1758 case RPC_FC_CVARRAY
:
1759 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, 0);
1760 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
1761 SizeConformance(pStubMsg
);
1763 case RPC_FC_C_CSTRING
:
1764 case RPC_FC_C_WSTRING
:
1765 if (pFormat
[0] == RPC_FC_C_CSTRING
)
1767 TRACE("string=%s\n", debugstr_a((const char *)pMemory
));
1768 pStubMsg
->ActualCount
= strlen((const char *)pMemory
)+1;
1772 TRACE("string=%s\n", debugstr_w((LPCWSTR
)pMemory
));
1773 pStubMsg
->ActualCount
= strlenW((LPCWSTR
)pMemory
)+1;
1776 if (fc
== RPC_FC_STRING_SIZED
)
1777 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
1779 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
1781 SizeConformance(pStubMsg
);
1784 ERR("unknown array format 0x%x\n", fc
);
1785 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1789 static inline void array_buffer_size(
1790 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1791 PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
1795 unsigned char alignment
;
1800 esize
= *(const WORD
*)(pFormat
+2);
1801 alignment
= pFormat
[1] + 1;
1803 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1805 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
1807 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
1808 /* conformance value plus array */
1809 safe_buffer_length_increment(pStubMsg
, size
);
1812 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1814 case RPC_FC_CVARRAY
:
1815 esize
= *(const WORD
*)(pFormat
+2);
1816 alignment
= pFormat
[1] + 1;
1818 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1819 pFormat
= SkipConformance(pStubMsg
, pFormat
);
1821 SizeVariance(pStubMsg
);
1823 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
1825 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1826 safe_buffer_length_increment(pStubMsg
, size
);
1829 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1831 case RPC_FC_C_CSTRING
:
1832 case RPC_FC_C_WSTRING
:
1833 if (fc
== RPC_FC_C_CSTRING
)
1838 SizeVariance(pStubMsg
);
1840 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1841 safe_buffer_length_increment(pStubMsg
, size
);
1844 ERR("unknown array format 0x%x\n", fc
);
1845 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1849 static inline void array_compute_and_write_conformance(
1850 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1851 PFORMAT_STRING pFormat
)
1856 ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1857 WriteConformance(pStubMsg
);
1859 case RPC_FC_CVARRAY
:
1860 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, 0);
1861 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
1862 WriteConformance(pStubMsg
);
1864 case RPC_FC_C_CSTRING
:
1865 case RPC_FC_C_WSTRING
:
1866 if (fc
== RPC_FC_C_CSTRING
)
1868 TRACE("string=%s\n", debugstr_a((const char *)pMemory
));
1869 pStubMsg
->ActualCount
= strlen((const char *)pMemory
)+1;
1873 TRACE("string=%s\n", debugstr_w((LPCWSTR
)pMemory
));
1874 pStubMsg
->ActualCount
= strlenW((LPCWSTR
)pMemory
)+1;
1876 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
1877 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
1879 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
1880 pStubMsg
->Offset
= 0;
1881 WriteConformance(pStubMsg
);
1884 ERR("unknown array format 0x%x\n", fc
);
1885 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1889 static inline void array_write_variance_and_marshall(
1890 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1891 PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
1895 unsigned char alignment
;
1900 esize
= *(const WORD
*)(pFormat
+2);
1901 alignment
= pFormat
[1] + 1;
1903 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1905 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
1907 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
1909 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1910 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
1913 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
1915 case RPC_FC_CVARRAY
:
1916 esize
= *(const WORD
*)(pFormat
+2);
1917 alignment
= pFormat
[1] + 1;
1920 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1922 pFormat
= SkipConformance(pStubMsg
, pFormat
);
1924 WriteVariance(pStubMsg
);
1926 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
1928 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1931 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1932 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, size
);
1935 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
1937 case RPC_FC_C_CSTRING
:
1938 case RPC_FC_C_WSTRING
:
1939 if (fc
== RPC_FC_C_CSTRING
)
1944 WriteVariance(pStubMsg
);
1946 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1947 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
1950 ERR("unknown array format 0x%x\n", fc
);
1951 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1955 static inline ULONG
array_read_conformance(
1956 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
1963 esize
= *(const WORD
*)(pFormat
+2);
1964 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
1965 return safe_multiply(esize
, pStubMsg
->MaxCount
);
1966 case RPC_FC_CVARRAY
:
1967 esize
= *(const WORD
*)(pFormat
+2);
1968 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
1969 return safe_multiply(esize
, pStubMsg
->MaxCount
);
1970 case RPC_FC_C_CSTRING
:
1971 case RPC_FC_C_WSTRING
:
1972 if (fc
== RPC_FC_C_CSTRING
)
1977 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
1978 ReadConformance(pStubMsg
, pFormat
+ 2);
1980 ReadConformance(pStubMsg
, NULL
);
1981 return safe_multiply(esize
, pStubMsg
->MaxCount
);
1983 ERR("unknown array format 0x%x\n", fc
);
1984 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1988 static inline ULONG
array_read_variance_and_unmarshall(
1989 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char **ppMemory
,
1990 PFORMAT_STRING pFormat
, unsigned char fMustAlloc
,
1991 unsigned char fUseBufferMemoryServer
, unsigned char fUnmarshall
)
1993 ULONG bufsize
, memsize
;
1995 unsigned char alignment
;
1996 unsigned char *saved_buffer
;
2002 esize
= *(const WORD
*)(pFormat
+2);
2003 alignment
= pFormat
[1] + 1;
2005 bufsize
= memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2007 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2009 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2014 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2017 if (fUseBufferMemoryServer
&& !pStubMsg
->IsClient
&& !*ppMemory
)
2018 /* for servers, we just point straight into the RPC buffer */
2019 *ppMemory
= pStubMsg
->Buffer
;
2022 saved_buffer
= pStubMsg
->Buffer
;
2023 safe_buffer_increment(pStubMsg
, bufsize
);
2025 pStubMsg
->BufferMark
= saved_buffer
;
2026 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
2028 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
2029 if (*ppMemory
!= saved_buffer
)
2030 memcpy(*ppMemory
, saved_buffer
, bufsize
);
2033 case RPC_FC_CVARRAY
:
2034 esize
= *(const WORD
*)(pFormat
+2);
2035 alignment
= pFormat
[1] + 1;
2037 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2039 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2041 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2043 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2044 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2048 offset
= pStubMsg
->Offset
;
2050 if (!fMustAlloc
&& !*ppMemory
)
2053 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2054 saved_buffer
= pStubMsg
->Buffer
;
2055 safe_buffer_increment(pStubMsg
, bufsize
);
2057 pStubMsg
->BufferMark
= saved_buffer
;
2058 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
,
2061 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
2064 case RPC_FC_C_CSTRING
:
2065 case RPC_FC_C_WSTRING
:
2066 if (fc
== RPC_FC_C_CSTRING
)
2071 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
2073 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
2075 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2076 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
2077 RpcRaiseException(RPC_S_INVALID_BOUND
);
2079 if (pStubMsg
->Offset
)
2081 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2082 RpcRaiseException(RPC_S_INVALID_BOUND
);
2085 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2086 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2088 validate_string_data(pStubMsg
, bufsize
, esize
);
2093 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2096 if (fUseBufferMemoryServer
&& !pStubMsg
->IsClient
&&
2097 !*ppMemory
&& (pStubMsg
->MaxCount
== pStubMsg
->ActualCount
))
2098 /* if the data in the RPC buffer is big enough, we just point
2099 * straight into it */
2100 *ppMemory
= pStubMsg
->Buffer
;
2101 else if (!*ppMemory
)
2102 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2105 if (*ppMemory
== pStubMsg
->Buffer
)
2106 safe_buffer_increment(pStubMsg
, bufsize
);
2108 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
2110 if (*pFormat
== RPC_FC_C_CSTRING
)
2111 TRACE("string=%s\n", debugstr_a((char*)*ppMemory
));
2113 TRACE("string=%s\n", debugstr_w((LPWSTR
)*ppMemory
));
2117 ERR("unknown array format 0x%x\n", fc
);
2118 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2122 static inline void array_memory_size(
2123 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
,
2124 unsigned char fHasPointers
)
2126 ULONG bufsize
, memsize
;
2128 unsigned char alignment
;
2133 esize
= *(const WORD
*)(pFormat
+2);
2134 alignment
= pFormat
[1] + 1;
2136 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2138 bufsize
= memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2139 pStubMsg
->MemorySize
+= memsize
;
2141 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2143 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2144 safe_buffer_increment(pStubMsg
, bufsize
);
2147 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2149 case RPC_FC_CVARRAY
:
2150 esize
= *(const WORD
*)(pFormat
+2);
2151 alignment
= pFormat
[1] + 1;
2153 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2155 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2157 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2158 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2159 pStubMsg
->MemorySize
+= memsize
;
2161 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2163 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2164 safe_buffer_increment(pStubMsg
, bufsize
);
2167 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2169 case RPC_FC_C_CSTRING
:
2170 case RPC_FC_C_WSTRING
:
2171 if (fc
== RPC_FC_C_CSTRING
)
2176 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
2178 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
2180 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2181 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
2182 RpcRaiseException(RPC_S_INVALID_BOUND
);
2184 if (pStubMsg
->Offset
)
2186 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2187 RpcRaiseException(RPC_S_INVALID_BOUND
);
2190 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2191 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2193 validate_string_data(pStubMsg
, bufsize
, esize
);
2195 safe_buffer_increment(pStubMsg
, bufsize
);
2196 pStubMsg
->MemorySize
+= memsize
;
2199 ERR("unknown array format 0x%x\n", fc
);
2200 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2204 static inline void array_free(
2205 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
,
2206 unsigned char *pMemory
, PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
2211 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2213 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2215 case RPC_FC_CVARRAY
:
2216 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2217 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2219 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2221 case RPC_FC_C_CSTRING
:
2222 case RPC_FC_C_WSTRING
:
2223 /* No embedded pointers so nothing to do */
2226 ERR("unknown array format 0x%x\n", fc
);
2227 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2232 * NdrConformantString:
2234 * What MS calls a ConformantString is, in DCE terminology,
2235 * a Varying-Conformant String.
2237 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2238 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2239 * into unmarshalled string)
2240 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2242 * data: CHARTYPE[maxlen]
2244 * ], where CHARTYPE is the appropriate character type (specified externally)
2248 /***********************************************************************
2249 * NdrConformantStringMarshall [RPCRT4.@]
2251 unsigned char *WINAPI
NdrConformantStringMarshall(MIDL_STUB_MESSAGE
*pStubMsg
,
2252 unsigned char *pszMessage
, PFORMAT_STRING pFormat
)
2254 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg
, pszMessage
, pFormat
);
2256 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2257 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2258 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2261 /* allow compiler to optimise inline function by passing constant into
2262 * these functions */
2263 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2264 array_compute_and_write_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pszMessage
,
2266 array_write_variance_and_marshall(RPC_FC_C_CSTRING
, pStubMsg
, pszMessage
,
2267 pFormat
, TRUE
/* fHasPointers */);
2269 array_compute_and_write_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pszMessage
,
2271 array_write_variance_and_marshall(RPC_FC_C_WSTRING
, pStubMsg
, pszMessage
,
2272 pFormat
, TRUE
/* fHasPointers */);
2278 /***********************************************************************
2279 * NdrConformantStringBufferSize [RPCRT4.@]
2281 void WINAPI
NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2282 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
2284 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2286 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2287 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2288 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2291 /* allow compiler to optimise inline function by passing constant into
2292 * these functions */
2293 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2294 array_compute_and_size_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pMemory
,
2296 array_buffer_size(RPC_FC_C_CSTRING
, pStubMsg
, pMemory
, pFormat
,
2297 TRUE
/* fHasPointers */);
2299 array_compute_and_size_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pMemory
,
2301 array_buffer_size(RPC_FC_C_WSTRING
, pStubMsg
, pMemory
, pFormat
,
2302 TRUE
/* fHasPointers */);
2306 /************************************************************************
2307 * NdrConformantStringMemorySize [RPCRT4.@]
2309 ULONG WINAPI
NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
2310 PFORMAT_STRING pFormat
)
2312 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
2314 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2315 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2316 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2319 /* allow compiler to optimise inline function by passing constant into
2320 * these functions */
2321 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2322 array_read_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
);
2323 array_memory_size(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
,
2324 TRUE
/* fHasPointers */);
2326 array_read_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
);
2327 array_memory_size(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
,
2328 TRUE
/* fHasPointers */);
2331 return pStubMsg
->MemorySize
;
2334 /************************************************************************
2335 * NdrConformantStringUnmarshall [RPCRT4.@]
2337 unsigned char *WINAPI
NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2338 unsigned char** ppMemory
, PFORMAT_STRING pFormat
, unsigned char fMustAlloc
)
2340 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2341 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
2343 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2344 ERR("Unhandled string type: %#x\n", *pFormat
);
2345 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2348 /* allow compiler to optimise inline function by passing constant into
2349 * these functions */
2350 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2351 array_read_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
);
2352 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING
, pStubMsg
, ppMemory
,
2353 pFormat
, fMustAlloc
,
2354 TRUE
/* fUseBufferMemoryServer */,
2355 TRUE
/* fUnmarshall */);
2357 array_read_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
);
2358 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING
, pStubMsg
, ppMemory
,
2359 pFormat
, fMustAlloc
,
2360 TRUE
/* fUseBufferMemoryServer */,
2361 TRUE
/* fUnmarshall */);
2367 /***********************************************************************
2368 * NdrNonConformantStringMarshall [RPCRT4.@]
2370 unsigned char * WINAPI
NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2371 unsigned char *pMemory
,
2372 PFORMAT_STRING pFormat
)
2374 ULONG esize
, size
, maxsize
;
2376 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2378 maxsize
= *(USHORT
*)&pFormat
[2];
2380 if (*pFormat
== RPC_FC_CSTRING
)
2383 const char *str
= (const char *)pMemory
;
2384 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
2386 TRACE("string=%s\n", debugstr_an(str
, i
));
2387 pStubMsg
->ActualCount
= i
+ 1;
2390 else if (*pFormat
== RPC_FC_WSTRING
)
2393 const WCHAR
*str
= (const WCHAR
*)pMemory
;
2394 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
2396 TRACE("string=%s\n", debugstr_wn(str
, i
));
2397 pStubMsg
->ActualCount
= i
+ 1;
2402 ERR("Unhandled string type: %#x\n", *pFormat
);
2403 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2406 pStubMsg
->Offset
= 0;
2407 WriteVariance(pStubMsg
);
2409 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2410 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
2415 /***********************************************************************
2416 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2418 unsigned char * WINAPI
NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2419 unsigned char **ppMemory
,
2420 PFORMAT_STRING pFormat
,
2421 unsigned char fMustAlloc
)
2423 ULONG bufsize
, memsize
, esize
, maxsize
;
2425 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2426 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
2428 maxsize
= *(USHORT
*)&pFormat
[2];
2430 ReadVariance(pStubMsg
, NULL
, maxsize
);
2431 if (pStubMsg
->Offset
)
2433 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2434 RpcRaiseException(RPC_S_INVALID_BOUND
);
2437 if (*pFormat
== RPC_FC_CSTRING
) esize
= 1;
2438 else if (*pFormat
== RPC_FC_WSTRING
) esize
= 2;
2441 ERR("Unhandled string type: %#x\n", *pFormat
);
2442 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2445 memsize
= esize
* maxsize
;
2446 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2448 validate_string_data(pStubMsg
, bufsize
, esize
);
2450 if (!fMustAlloc
&& !*ppMemory
)
2453 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2455 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
2457 if (*pFormat
== RPC_FC_CSTRING
) {
2458 TRACE("string=%s\n", debugstr_an((char*)*ppMemory
, pStubMsg
->ActualCount
));
2460 else if (*pFormat
== RPC_FC_WSTRING
) {
2461 TRACE("string=%s\n", debugstr_wn((LPWSTR
)*ppMemory
, pStubMsg
->ActualCount
));
2467 /***********************************************************************
2468 * NdrNonConformantStringBufferSize [RPCRT4.@]
2470 void WINAPI
NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2471 unsigned char *pMemory
,
2472 PFORMAT_STRING pFormat
)
2474 ULONG esize
, maxsize
;
2476 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2478 maxsize
= *(USHORT
*)&pFormat
[2];
2480 SizeVariance(pStubMsg
);
2482 if (*pFormat
== RPC_FC_CSTRING
)
2485 const char *str
= (const char *)pMemory
;
2486 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
2488 TRACE("string=%s\n", debugstr_an(str
, i
));
2489 pStubMsg
->ActualCount
= i
+ 1;
2492 else if (*pFormat
== RPC_FC_WSTRING
)
2495 const WCHAR
*str
= (const WCHAR
*)pMemory
;
2496 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
2498 TRACE("string=%s\n", debugstr_wn(str
, i
));
2499 pStubMsg
->ActualCount
= i
+ 1;
2504 ERR("Unhandled string type: %#x\n", *pFormat
);
2505 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2508 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
2511 /***********************************************************************
2512 * NdrNonConformantStringMemorySize [RPCRT4.@]
2514 ULONG WINAPI
NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2515 PFORMAT_STRING pFormat
)
2517 ULONG bufsize
, memsize
, esize
, maxsize
;
2519 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
2521 maxsize
= *(USHORT
*)&pFormat
[2];
2523 ReadVariance(pStubMsg
, NULL
, maxsize
);
2525 if (pStubMsg
->Offset
)
2527 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2528 RpcRaiseException(RPC_S_INVALID_BOUND
);
2531 if (*pFormat
== RPC_FC_CSTRING
) esize
= 1;
2532 else if (*pFormat
== RPC_FC_WSTRING
) esize
= 2;
2535 ERR("Unhandled string type: %#x\n", *pFormat
);
2536 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2539 memsize
= esize
* maxsize
;
2540 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2542 validate_string_data(pStubMsg
, bufsize
, esize
);
2544 safe_buffer_increment(pStubMsg
, bufsize
);
2545 pStubMsg
->MemorySize
+= memsize
;
2547 return pStubMsg
->MemorySize
;
2552 #include "pshpack1.h"
2556 unsigned char flags_type
; /* flags in upper nibble, type in lower nibble */
2560 #include "poppack.h"
2562 static unsigned long EmbeddedComplexSize(MIDL_STUB_MESSAGE
*pStubMsg
,
2563 PFORMAT_STRING pFormat
)
2567 case RPC_FC_PSTRUCT
:
2568 case RPC_FC_CSTRUCT
:
2569 case RPC_FC_BOGUS_STRUCT
:
2570 case RPC_FC_SMFARRAY
:
2571 case RPC_FC_SMVARRAY
:
2572 case RPC_FC_CSTRING
:
2573 return *(const WORD
*)&pFormat
[2];
2574 case RPC_FC_USER_MARSHAL
:
2575 return *(const WORD
*)&pFormat
[4];
2576 case RPC_FC_RANGE
: {
2577 switch (((const NDR_RANGE
*)pFormat
)->flags_type
& 0xf) {
2582 return sizeof(UCHAR
);
2586 return sizeof(USHORT
);
2590 return sizeof(ULONG
);
2592 return sizeof(float);
2594 return sizeof(double);
2596 return sizeof(ULONGLONG
);
2598 return sizeof(UINT
);
2600 ERR("unknown type 0x%x\n", ((const NDR_RANGE
*)pFormat
)->flags_type
& 0xf);
2601 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2604 case RPC_FC_NON_ENCAPSULATED_UNION
:
2606 if (pStubMsg
->fHasNewCorrDesc
)
2611 pFormat
+= *(const SHORT
*)pFormat
;
2612 return *(const SHORT
*)pFormat
;
2614 return sizeof(void *);
2615 case RPC_FC_WSTRING
:
2616 return *(const WORD
*)&pFormat
[2] * 2;
2618 FIXME("unhandled embedded type %02x\n", *pFormat
);
2624 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2625 PFORMAT_STRING pFormat
)
2627 NDR_MEMORYSIZE m
= NdrMemorySizer
[*pFormat
& NDR_TABLE_MASK
];
2631 FIXME("no memorysizer for data type=%02x\n", *pFormat
);
2635 return m(pStubMsg
, pFormat
);
2639 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2640 unsigned char *pMemory
,
2641 PFORMAT_STRING pFormat
,
2642 PFORMAT_STRING pPointer
)
2644 PFORMAT_STRING desc
;
2648 while (*pFormat
!= RPC_FC_END
) {
2654 TRACE("byte=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2655 safe_copy_to_buffer(pStubMsg
, pMemory
, 1);
2661 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2662 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
2666 TRACE("enum16=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2667 if (32767 < *(DWORD
*)pMemory
)
2668 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
2669 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
2675 TRACE("long=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2676 safe_copy_to_buffer(pStubMsg
, pMemory
, 4);
2680 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2681 safe_copy_to_buffer(pStubMsg
, pMemory
, 8);
2684 case RPC_FC_POINTER
:
2686 unsigned char *saved_buffer
;
2687 int pointer_buffer_mark_set
= 0;
2688 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
2689 TRACE("pStubMsg->Buffer before %p\n", pStubMsg
->Buffer
);
2690 if (*pPointer
!= RPC_FC_RP
)
2691 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
2692 saved_buffer
= pStubMsg
->Buffer
;
2693 if (pStubMsg
->PointerBufferMark
)
2695 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2696 pStubMsg
->PointerBufferMark
= NULL
;
2697 pointer_buffer_mark_set
= 1;
2699 else if (*pPointer
!= RPC_FC_RP
)
2700 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2701 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char**)pMemory
, pPointer
);
2702 if (pointer_buffer_mark_set
)
2704 STD_OVERFLOW_CHECK(pStubMsg
);
2705 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2706 pStubMsg
->Buffer
= saved_buffer
;
2707 if (*pPointer
!= RPC_FC_RP
)
2708 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2710 TRACE("pStubMsg->Buffer after %p\n", pStubMsg
->Buffer
);
2715 case RPC_FC_ALIGNM4
:
2716 ALIGN_POINTER(pMemory
, 4);
2718 case RPC_FC_ALIGNM8
:
2719 ALIGN_POINTER(pMemory
, 8);
2721 case RPC_FC_STRUCTPAD1
:
2722 case RPC_FC_STRUCTPAD2
:
2723 case RPC_FC_STRUCTPAD3
:
2724 case RPC_FC_STRUCTPAD4
:
2725 case RPC_FC_STRUCTPAD5
:
2726 case RPC_FC_STRUCTPAD6
:
2727 case RPC_FC_STRUCTPAD7
:
2728 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2730 case RPC_FC_EMBEDDED_COMPLEX
:
2731 pMemory
+= pFormat
[1];
2733 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2734 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2735 TRACE("embedded complex (size=%ld) <= %p\n", size
, pMemory
);
2736 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
2739 /* for some reason interface pointers aren't generated as
2740 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2741 * they still need the derefencing treatment that pointers are
2743 if (*desc
== RPC_FC_IP
)
2744 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2746 m(pStubMsg
, pMemory
, desc
);
2748 else FIXME("no marshaller for embedded type %02x\n", *desc
);
2755 FIXME("unhandled format 0x%02x\n", *pFormat
);
2763 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2764 unsigned char *pMemory
,
2765 PFORMAT_STRING pFormat
,
2766 PFORMAT_STRING pPointer
,
2767 unsigned char fMustAlloc
)
2769 PFORMAT_STRING desc
;
2773 while (*pFormat
!= RPC_FC_END
) {
2779 safe_copy_from_buffer(pStubMsg
, pMemory
, 1);
2780 TRACE("byte=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2786 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
2787 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2791 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
2792 *(DWORD
*)pMemory
&= 0xffff;
2793 TRACE("enum16=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
2794 if (32767 < *(DWORD
*)pMemory
)
2795 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
2801 safe_copy_from_buffer(pStubMsg
, pMemory
, 4);
2802 TRACE("long=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
2806 safe_copy_from_buffer(pStubMsg
, pMemory
, 8);
2807 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2810 case RPC_FC_POINTER
:
2812 unsigned char *saved_buffer
;
2813 int pointer_buffer_mark_set
= 0;
2814 TRACE("pointer => %p\n", pMemory
);
2815 if (*pPointer
!= RPC_FC_RP
)
2816 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2817 saved_buffer
= pStubMsg
->Buffer
;
2818 if (pStubMsg
->PointerBufferMark
)
2820 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2821 pStubMsg
->PointerBufferMark
= NULL
;
2822 pointer_buffer_mark_set
= 1;
2824 else if (*pPointer
!= RPC_FC_RP
)
2825 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2827 PointerUnmarshall(pStubMsg
, saved_buffer
, (unsigned char**)pMemory
, *(unsigned char**)pMemory
, pPointer
, fMustAlloc
);
2828 if (pointer_buffer_mark_set
)
2830 STD_OVERFLOW_CHECK(pStubMsg
);
2831 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2832 pStubMsg
->Buffer
= saved_buffer
;
2833 if (*pPointer
!= RPC_FC_RP
)
2834 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2840 case RPC_FC_ALIGNM4
:
2841 ALIGN_POINTER_CLEAR(pMemory
, 4);
2843 case RPC_FC_ALIGNM8
:
2844 ALIGN_POINTER_CLEAR(pMemory
, 8);
2846 case RPC_FC_STRUCTPAD1
:
2847 case RPC_FC_STRUCTPAD2
:
2848 case RPC_FC_STRUCTPAD3
:
2849 case RPC_FC_STRUCTPAD4
:
2850 case RPC_FC_STRUCTPAD5
:
2851 case RPC_FC_STRUCTPAD6
:
2852 case RPC_FC_STRUCTPAD7
:
2853 memset(pMemory
, 0, *pFormat
- RPC_FC_STRUCTPAD1
+ 1);
2854 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2856 case RPC_FC_EMBEDDED_COMPLEX
:
2857 pMemory
+= pFormat
[1];
2859 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2860 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2861 TRACE("embedded complex (size=%ld) => %p\n", size
, pMemory
);
2863 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
2864 * since the type is part of the memory block that is encompassed by
2865 * the whole complex type. Memory is forced to allocate when pointers
2866 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
2867 * clearing the memory we pass in to the unmarshaller */
2868 memset(pMemory
, 0, size
);
2869 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
2872 /* for some reason interface pointers aren't generated as
2873 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2874 * they still need the derefencing treatment that pointers are
2876 if (*desc
== RPC_FC_IP
)
2877 m(pStubMsg
, (unsigned char **)pMemory
, desc
, FALSE
);
2879 m(pStubMsg
, &pMemory
, desc
, FALSE
);
2881 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
2888 FIXME("unhandled format %d\n", *pFormat
);
2896 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2897 unsigned char *pMemory
,
2898 PFORMAT_STRING pFormat
,
2899 PFORMAT_STRING pPointer
)
2901 PFORMAT_STRING desc
;
2905 while (*pFormat
!= RPC_FC_END
) {
2911 safe_buffer_length_increment(pStubMsg
, 1);
2917 safe_buffer_length_increment(pStubMsg
, 2);
2921 safe_buffer_length_increment(pStubMsg
, 2);
2927 safe_buffer_length_increment(pStubMsg
, 4);
2931 safe_buffer_length_increment(pStubMsg
, 8);
2934 case RPC_FC_POINTER
:
2935 if (!pStubMsg
->IgnoreEmbeddedPointers
)
2937 int saved_buffer_length
= pStubMsg
->BufferLength
;
2938 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2939 pStubMsg
->PointerLength
= 0;
2940 if(!pStubMsg
->BufferLength
)
2941 ERR("BufferLength == 0??\n");
2942 PointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
2943 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2944 pStubMsg
->BufferLength
= saved_buffer_length
;
2946 if (*pPointer
!= RPC_FC_RP
)
2948 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
2949 safe_buffer_length_increment(pStubMsg
, 4);
2954 case RPC_FC_ALIGNM4
:
2955 ALIGN_POINTER(pMemory
, 4);
2957 case RPC_FC_ALIGNM8
:
2958 ALIGN_POINTER(pMemory
, 8);
2960 case RPC_FC_STRUCTPAD1
:
2961 case RPC_FC_STRUCTPAD2
:
2962 case RPC_FC_STRUCTPAD3
:
2963 case RPC_FC_STRUCTPAD4
:
2964 case RPC_FC_STRUCTPAD5
:
2965 case RPC_FC_STRUCTPAD6
:
2966 case RPC_FC_STRUCTPAD7
:
2967 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2969 case RPC_FC_EMBEDDED_COMPLEX
:
2970 pMemory
+= pFormat
[1];
2972 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2973 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2974 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
2977 /* for some reason interface pointers aren't generated as
2978 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2979 * they still need the derefencing treatment that pointers are
2981 if (*desc
== RPC_FC_IP
)
2982 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2984 m(pStubMsg
, pMemory
, desc
);
2986 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
2993 FIXME("unhandled format 0x%02x\n", *pFormat
);
3001 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
3002 unsigned char *pMemory
,
3003 PFORMAT_STRING pFormat
,
3004 PFORMAT_STRING pPointer
)
3006 PFORMAT_STRING desc
;
3010 while (*pFormat
!= RPC_FC_END
) {
3032 case RPC_FC_POINTER
:
3033 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
3037 case RPC_FC_ALIGNM4
:
3038 ALIGN_POINTER(pMemory
, 4);
3040 case RPC_FC_ALIGNM8
:
3041 ALIGN_POINTER(pMemory
, 8);
3043 case RPC_FC_STRUCTPAD1
:
3044 case RPC_FC_STRUCTPAD2
:
3045 case RPC_FC_STRUCTPAD3
:
3046 case RPC_FC_STRUCTPAD4
:
3047 case RPC_FC_STRUCTPAD5
:
3048 case RPC_FC_STRUCTPAD6
:
3049 case RPC_FC_STRUCTPAD7
:
3050 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3052 case RPC_FC_EMBEDDED_COMPLEX
:
3053 pMemory
+= pFormat
[1];
3055 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3056 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3057 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
3060 /* for some reason interface pointers aren't generated as
3061 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3062 * they still need the derefencing treatment that pointers are
3064 if (*desc
== RPC_FC_IP
)
3065 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
3067 m(pStubMsg
, pMemory
, desc
);
3075 FIXME("unhandled format 0x%02x\n", *pFormat
);
3083 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3084 PFORMAT_STRING pFormat
,
3085 PFORMAT_STRING pPointer
)
3087 PFORMAT_STRING desc
;
3088 unsigned long size
= 0;
3090 while (*pFormat
!= RPC_FC_END
) {
3097 safe_buffer_increment(pStubMsg
, 1);
3103 safe_buffer_increment(pStubMsg
, 2);
3107 safe_buffer_increment(pStubMsg
, 2);
3113 safe_buffer_increment(pStubMsg
, 4);
3117 safe_buffer_increment(pStubMsg
, 8);
3119 case RPC_FC_POINTER
:
3121 unsigned char *saved_buffer
;
3122 int pointer_buffer_mark_set
= 0;
3123 if (*pPointer
!= RPC_FC_RP
)
3124 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3125 saved_buffer
= pStubMsg
->Buffer
;
3126 if (pStubMsg
->PointerBufferMark
)
3128 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3129 pStubMsg
->PointerBufferMark
= NULL
;
3130 pointer_buffer_mark_set
= 1;
3132 else if (*pPointer
!= RPC_FC_RP
)
3133 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3135 if (!pStubMsg
->IgnoreEmbeddedPointers
)
3136 PointerMemorySize(pStubMsg
, saved_buffer
, pPointer
);
3137 if (pointer_buffer_mark_set
)
3139 STD_OVERFLOW_CHECK(pStubMsg
);
3140 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3141 pStubMsg
->Buffer
= saved_buffer
;
3142 if (*pPointer
!= RPC_FC_RP
)
3143 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3149 case RPC_FC_ALIGNM4
:
3150 ALIGN_LENGTH(size
, 4);
3152 case RPC_FC_ALIGNM8
:
3153 ALIGN_LENGTH(size
, 8);
3155 case RPC_FC_STRUCTPAD1
:
3156 case RPC_FC_STRUCTPAD2
:
3157 case RPC_FC_STRUCTPAD3
:
3158 case RPC_FC_STRUCTPAD4
:
3159 case RPC_FC_STRUCTPAD5
:
3160 case RPC_FC_STRUCTPAD6
:
3161 case RPC_FC_STRUCTPAD7
:
3162 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3164 case RPC_FC_EMBEDDED_COMPLEX
:
3167 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3168 size
+= EmbeddedComplexMemorySize(pStubMsg
, desc
);
3174 FIXME("unhandled format 0x%02x\n", *pFormat
);
3182 unsigned long ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg
,
3183 PFORMAT_STRING pFormat
)
3185 PFORMAT_STRING desc
;
3186 unsigned long size
= 0;
3188 while (*pFormat
!= RPC_FC_END
) {
3210 case RPC_FC_POINTER
:
3211 size
+= sizeof(void *);
3213 case RPC_FC_ALIGNM4
:
3214 ALIGN_LENGTH(size
, 4);
3216 case RPC_FC_ALIGNM8
:
3217 ALIGN_LENGTH(size
, 8);
3219 case RPC_FC_STRUCTPAD1
:
3220 case RPC_FC_STRUCTPAD2
:
3221 case RPC_FC_STRUCTPAD3
:
3222 case RPC_FC_STRUCTPAD4
:
3223 case RPC_FC_STRUCTPAD5
:
3224 case RPC_FC_STRUCTPAD6
:
3225 case RPC_FC_STRUCTPAD7
:
3226 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3228 case RPC_FC_EMBEDDED_COMPLEX
:
3231 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3232 size
+= EmbeddedComplexSize(pStubMsg
, desc
);
3238 FIXME("unhandled format 0x%02x\n", *pFormat
);
3246 /***********************************************************************
3247 * NdrComplexStructMarshall [RPCRT4.@]
3249 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3250 unsigned char *pMemory
,
3251 PFORMAT_STRING pFormat
)
3253 PFORMAT_STRING conf_array
= NULL
;
3254 PFORMAT_STRING pointer_desc
= NULL
;
3255 unsigned char *OldMemory
= pStubMsg
->Memory
;
3256 int pointer_buffer_mark_set
= 0;
3258 ULONG max_count
= 0;
3261 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3263 if (!pStubMsg
->PointerBufferMark
)
3265 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3266 /* save buffer length */
3267 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
3269 /* get the buffer pointer after complex array data, but before
3271 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- pStubMsg
->BufferStart
;
3272 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3273 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
3274 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3276 /* save it for use by embedded pointer code later */
3277 pStubMsg
->PointerBufferMark
= pStubMsg
->BufferStart
+ pStubMsg
->BufferLength
;
3278 TRACE("difference = 0x%x\n", pStubMsg
->PointerBufferMark
- pStubMsg
->Buffer
);
3279 pointer_buffer_mark_set
= 1;
3281 /* restore the original buffer length */
3282 pStubMsg
->BufferLength
= saved_buffer_length
;
3285 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pFormat
[1] + 1);
3288 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3290 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3293 pStubMsg
->Memory
= pMemory
;
3297 unsigned long struct_size
= ComplexStructSize(pStubMsg
, pFormat
);
3298 array_compute_and_write_conformance(conf_array
[0], pStubMsg
,
3299 pMemory
+ struct_size
, conf_array
);
3300 /* these could be changed in ComplexMarshall so save them for later */
3301 max_count
= pStubMsg
->MaxCount
;
3302 count
= pStubMsg
->ActualCount
;
3303 offset
= pStubMsg
->Offset
;
3306 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3310 pStubMsg
->MaxCount
= max_count
;
3311 pStubMsg
->ActualCount
= count
;
3312 pStubMsg
->Offset
= offset
;
3313 array_write_variance_and_marshall(conf_array
[0], pStubMsg
, pMemory
,
3314 conf_array
, TRUE
/* fHasPointers */);
3317 pStubMsg
->Memory
= OldMemory
;
3319 if (pointer_buffer_mark_set
)
3321 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3322 pStubMsg
->PointerBufferMark
= NULL
;
3325 STD_OVERFLOW_CHECK(pStubMsg
);
3330 /***********************************************************************
3331 * NdrComplexStructUnmarshall [RPCRT4.@]
3333 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3334 unsigned char **ppMemory
,
3335 PFORMAT_STRING pFormat
,
3336 unsigned char fMustAlloc
)
3338 unsigned size
= *(const WORD
*)(pFormat
+2);
3339 PFORMAT_STRING conf_array
= NULL
;
3340 PFORMAT_STRING pointer_desc
= NULL
;
3341 unsigned char *pMemory
;
3342 int pointer_buffer_mark_set
= 0;
3344 ULONG max_count
= 0;
3346 ULONG array_size
= 0;
3348 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3350 if (!pStubMsg
->PointerBufferMark
)
3352 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3353 /* save buffer pointer */
3354 unsigned char *saved_buffer
= pStubMsg
->Buffer
;
3356 /* get the buffer pointer after complex array data, but before
3358 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3359 NdrComplexStructMemorySize(pStubMsg
, pFormat
);
3360 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3362 /* save it for use by embedded pointer code later */
3363 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3364 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->PointerBufferMark
- saved_buffer
));
3365 pointer_buffer_mark_set
= 1;
3367 /* restore the original buffer */
3368 pStubMsg
->Buffer
= saved_buffer
;
3371 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
3374 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3376 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3381 array_size
= array_read_conformance(conf_array
[0], pStubMsg
, conf_array
);
3384 /* these could be changed in ComplexMarshall so save them for later */
3385 max_count
= pStubMsg
->MaxCount
;
3386 count
= pStubMsg
->ActualCount
;
3387 offset
= pStubMsg
->Offset
;
3390 if (!fMustAlloc
&& !*ppMemory
)
3393 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3395 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
, fMustAlloc
);
3399 pStubMsg
->MaxCount
= max_count
;
3400 pStubMsg
->ActualCount
= count
;
3401 pStubMsg
->Offset
= offset
;
3403 memset(pMemory
, 0, array_size
);
3404 array_read_variance_and_unmarshall(conf_array
[0], pStubMsg
, &pMemory
,
3406 FALSE
/* fUseBufferMemoryServer */,
3407 TRUE
/* fUnmarshall */);
3410 if (pointer_buffer_mark_set
)
3412 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3413 pStubMsg
->PointerBufferMark
= NULL
;
3419 /***********************************************************************
3420 * NdrComplexStructBufferSize [RPCRT4.@]
3422 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3423 unsigned char *pMemory
,
3424 PFORMAT_STRING pFormat
)
3426 PFORMAT_STRING conf_array
= NULL
;
3427 PFORMAT_STRING pointer_desc
= NULL
;
3428 unsigned char *OldMemory
= pStubMsg
->Memory
;
3429 int pointer_length_set
= 0;
3431 ULONG max_count
= 0;
3434 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3436 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
3438 if(!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
3440 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3441 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
3443 /* get the buffer length after complex struct data, but before
3445 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3446 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
3447 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3449 /* save it for use by embedded pointer code later */
3450 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3451 pointer_length_set
= 1;
3452 TRACE("difference = 0x%lx\n", pStubMsg
->PointerLength
- saved_buffer_length
);
3454 /* restore the original buffer length */
3455 pStubMsg
->BufferLength
= saved_buffer_length
;
3459 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3461 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3464 pStubMsg
->Memory
= pMemory
;
3468 unsigned long struct_size
= ComplexStructSize(pStubMsg
, pFormat
);
3469 array_compute_and_size_conformance(conf_array
[0], pStubMsg
, pMemory
+ struct_size
,
3472 /* these could be changed in ComplexMarshall so save them for later */
3473 max_count
= pStubMsg
->MaxCount
;
3474 count
= pStubMsg
->ActualCount
;
3475 offset
= pStubMsg
->Offset
;
3478 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3482 pStubMsg
->MaxCount
= max_count
;
3483 pStubMsg
->ActualCount
= count
;
3484 pStubMsg
->Offset
= offset
;
3485 array_buffer_size(conf_array
[0], pStubMsg
, pMemory
, conf_array
,
3486 TRUE
/* fHasPointers */);
3489 pStubMsg
->Memory
= OldMemory
;
3491 if(pointer_length_set
)
3493 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3494 pStubMsg
->PointerLength
= 0;
3499 /***********************************************************************
3500 * NdrComplexStructMemorySize [RPCRT4.@]
3502 ULONG WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3503 PFORMAT_STRING pFormat
)
3505 unsigned size
= *(const WORD
*)(pFormat
+2);
3506 PFORMAT_STRING conf_array
= NULL
;
3507 PFORMAT_STRING pointer_desc
= NULL
;
3509 ULONG max_count
= 0;
3512 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3514 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
3517 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3519 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3524 array_read_conformance(conf_array
[0], pStubMsg
, conf_array
);
3526 /* these could be changed in ComplexStructMemorySize so save them for
3528 max_count
= pStubMsg
->MaxCount
;
3529 count
= pStubMsg
->ActualCount
;
3530 offset
= pStubMsg
->Offset
;
3533 ComplexStructMemorySize(pStubMsg
, pFormat
, pointer_desc
);
3537 pStubMsg
->MaxCount
= max_count
;
3538 pStubMsg
->ActualCount
= count
;
3539 pStubMsg
->Offset
= offset
;
3540 array_memory_size(conf_array
[0], pStubMsg
, conf_array
,
3541 TRUE
/* fHasPointers */);
3547 /***********************************************************************
3548 * NdrComplexStructFree [RPCRT4.@]
3550 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3551 unsigned char *pMemory
,
3552 PFORMAT_STRING pFormat
)
3554 PFORMAT_STRING conf_array
= NULL
;
3555 PFORMAT_STRING pointer_desc
= NULL
;
3556 unsigned char *OldMemory
= pStubMsg
->Memory
;
3558 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3561 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3563 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3566 pStubMsg
->Memory
= pMemory
;
3568 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3571 array_free(conf_array
[0], pStubMsg
, pMemory
, conf_array
,
3572 TRUE
/* fHasPointers */);
3574 pStubMsg
->Memory
= OldMemory
;
3577 /***********************************************************************
3578 * NdrConformantArrayMarshall [RPCRT4.@]
3580 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3581 unsigned char *pMemory
,
3582 PFORMAT_STRING pFormat
)
3584 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3585 if (pFormat
[0] != RPC_FC_CARRAY
)
3587 ERR("invalid format = 0x%x\n", pFormat
[0]);
3588 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3591 array_compute_and_write_conformance(RPC_FC_CARRAY
, pStubMsg
, pMemory
,
3593 array_write_variance_and_marshall(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3594 TRUE
/* fHasPointers */);
3599 /***********************************************************************
3600 * NdrConformantArrayUnmarshall [RPCRT4.@]
3602 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3603 unsigned char **ppMemory
,
3604 PFORMAT_STRING pFormat
,
3605 unsigned char fMustAlloc
)
3607 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3608 if (pFormat
[0] != RPC_FC_CARRAY
)
3610 ERR("invalid format = 0x%x\n", pFormat
[0]);
3611 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3614 array_read_conformance(RPC_FC_CARRAY
, pStubMsg
, pFormat
);
3615 array_read_variance_and_unmarshall(RPC_FC_CARRAY
, pStubMsg
, ppMemory
, pFormat
,
3617 TRUE
/* fUseBufferMemoryServer */,
3618 TRUE
/* fUnmarshall */);
3623 /***********************************************************************
3624 * NdrConformantArrayBufferSize [RPCRT4.@]
3626 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3627 unsigned char *pMemory
,
3628 PFORMAT_STRING pFormat
)
3630 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3631 if (pFormat
[0] != RPC_FC_CARRAY
)
3633 ERR("invalid format = 0x%x\n", pFormat
[0]);
3634 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3637 array_compute_and_size_conformance(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
);
3638 array_buffer_size(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3639 TRUE
/* fHasPointers */);
3642 /***********************************************************************
3643 * NdrConformantArrayMemorySize [RPCRT4.@]
3645 ULONG WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3646 PFORMAT_STRING pFormat
)
3648 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3649 if (pFormat
[0] != RPC_FC_CARRAY
)
3651 ERR("invalid format = 0x%x\n", pFormat
[0]);
3652 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3655 array_read_conformance(RPC_FC_CARRAY
, pStubMsg
, pFormat
);
3656 array_memory_size(RPC_FC_CARRAY
, pStubMsg
, pFormat
, TRUE
/* fHasPointers */);
3658 return pStubMsg
->MemorySize
;
3661 /***********************************************************************
3662 * NdrConformantArrayFree [RPCRT4.@]
3664 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3665 unsigned char *pMemory
,
3666 PFORMAT_STRING pFormat
)
3668 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3669 if (pFormat
[0] != RPC_FC_CARRAY
)
3671 ERR("invalid format = 0x%x\n", pFormat
[0]);
3672 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3675 array_free(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3676 TRUE
/* fHasPointers */);
3680 /***********************************************************************
3681 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3683 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
3684 unsigned char* pMemory
,
3685 PFORMAT_STRING pFormat
)
3687 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3689 if (pFormat
[0] != RPC_FC_CVARRAY
)
3691 ERR("invalid format type %x\n", pFormat
[0]);
3692 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3696 array_compute_and_write_conformance(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
3698 array_write_variance_and_marshall(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
3699 pFormat
, TRUE
/* fHasPointers */);
3705 /***********************************************************************
3706 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
3708 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
3709 unsigned char** ppMemory
,
3710 PFORMAT_STRING pFormat
,
3711 unsigned char fMustAlloc
)
3713 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3715 if (pFormat
[0] != RPC_FC_CVARRAY
)
3717 ERR("invalid format type %x\n", pFormat
[0]);
3718 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3722 array_read_conformance(RPC_FC_CVARRAY
, pStubMsg
, pFormat
);
3723 array_read_variance_and_unmarshall(RPC_FC_CVARRAY
, pStubMsg
, ppMemory
,
3724 pFormat
, fMustAlloc
,
3725 TRUE
/* fUseBufferMemoryServer */,
3726 TRUE
/* fUnmarshall */);
3732 /***********************************************************************
3733 * NdrConformantVaryingArrayFree [RPCRT4.@]
3735 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
3736 unsigned char* pMemory
,
3737 PFORMAT_STRING pFormat
)
3739 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3741 if (pFormat
[0] != RPC_FC_CVARRAY
)
3743 ERR("invalid format type %x\n", pFormat
[0]);
3744 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3748 array_free(RPC_FC_CVARRAY
, pStubMsg
, pMemory
, pFormat
,
3749 TRUE
/* fHasPointers */);
3753 /***********************************************************************
3754 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
3756 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
3757 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
3759 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3761 if (pFormat
[0] != RPC_FC_CVARRAY
)
3763 ERR("invalid format type %x\n", pFormat
[0]);
3764 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3768 array_compute_and_size_conformance(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
3770 array_buffer_size(RPC_FC_CVARRAY
, pStubMsg
, pMemory
, pFormat
,
3771 TRUE
/* fHasPointers */);
3775 /***********************************************************************
3776 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
3778 ULONG WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
3779 PFORMAT_STRING pFormat
)
3781 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
3783 if (pFormat
[0] != RPC_FC_CVARRAY
)
3785 ERR("invalid format type %x\n", pFormat
[0]);
3786 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3787 return pStubMsg
->MemorySize
;
3790 array_read_conformance(RPC_FC_CVARRAY
, pStubMsg
, pFormat
);
3791 array_memory_size(RPC_FC_CVARRAY
, pStubMsg
, pFormat
,
3792 TRUE
/* fHasPointers */);
3794 return pStubMsg
->MemorySize
;
3798 /***********************************************************************
3799 * NdrComplexArrayMarshall [RPCRT4.@]
3801 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3802 unsigned char *pMemory
,
3803 PFORMAT_STRING pFormat
)
3805 ULONG i
, count
, def
;
3806 BOOL variance_present
;
3807 unsigned char alignment
;
3808 int pointer_buffer_mark_set
= 0;
3810 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3812 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3814 ERR("invalid format type %x\n", pFormat
[0]);
3815 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3819 alignment
= pFormat
[1] + 1;
3821 if (!pStubMsg
->PointerBufferMark
)
3823 /* save buffer fields that may be changed by buffer sizer functions
3824 * and that may be needed later on */
3825 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3826 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
3827 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
3828 unsigned long saved_offset
= pStubMsg
->Offset
;
3829 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
3831 /* get the buffer pointer after complex array data, but before
3833 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- pStubMsg
->BufferStart
;
3834 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3835 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
3836 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3838 /* save it for use by embedded pointer code later */
3839 pStubMsg
->PointerBufferMark
= pStubMsg
->BufferStart
+ pStubMsg
->BufferLength
;
3840 TRACE("difference = 0x%x\n", pStubMsg
->Buffer
- pStubMsg
->BufferStart
);
3841 pointer_buffer_mark_set
= 1;
3843 /* restore fields */
3844 pStubMsg
->ActualCount
= saved_actual_count
;
3845 pStubMsg
->Offset
= saved_offset
;
3846 pStubMsg
->MaxCount
= saved_max_count
;
3847 pStubMsg
->BufferLength
= saved_buffer_length
;
3850 def
= *(const WORD
*)&pFormat
[2];
3853 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3854 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3856 variance_present
= IsConformanceOrVariancePresent(pFormat
);
3857 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3858 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3860 WriteConformance(pStubMsg
);
3861 if (variance_present
)
3862 WriteVariance(pStubMsg
);
3864 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
3866 count
= pStubMsg
->ActualCount
;
3867 for (i
= 0; i
< count
; i
++)
3868 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
3870 STD_OVERFLOW_CHECK(pStubMsg
);
3872 if (pointer_buffer_mark_set
)
3874 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3875 pStubMsg
->PointerBufferMark
= NULL
;
3881 /***********************************************************************
3882 * NdrComplexArrayUnmarshall [RPCRT4.@]
3884 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3885 unsigned char **ppMemory
,
3886 PFORMAT_STRING pFormat
,
3887 unsigned char fMustAlloc
)
3889 ULONG i
, count
, size
;
3890 unsigned char alignment
;
3891 unsigned char *pMemory
;
3892 unsigned char *saved_buffer
;
3893 int pointer_buffer_mark_set
= 0;
3894 int saved_ignore_embedded
;
3896 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3898 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3900 ERR("invalid format type %x\n", pFormat
[0]);
3901 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3905 alignment
= pFormat
[1] + 1;
3907 saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3908 /* save buffer pointer */
3909 saved_buffer
= pStubMsg
->Buffer
;
3910 /* get the buffer pointer after complex array data, but before
3912 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3913 pStubMsg
->MemorySize
= 0;
3914 NdrComplexArrayMemorySize(pStubMsg
, pFormat
);
3915 size
= pStubMsg
->MemorySize
;
3916 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3918 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->Buffer
- saved_buffer
));
3919 if (!pStubMsg
->PointerBufferMark
)
3921 /* save it for use by embedded pointer code later */
3922 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3923 pointer_buffer_mark_set
= 1;
3925 /* restore the original buffer */
3926 pStubMsg
->Buffer
= saved_buffer
;
3930 pFormat
= ReadConformance(pStubMsg
, pFormat
);
3931 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3933 if (!fMustAlloc
&& !*ppMemory
)
3936 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3938 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3940 pMemory
= *ppMemory
;
3941 count
= pStubMsg
->ActualCount
;
3942 for (i
= 0; i
< count
; i
++)
3943 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
, fMustAlloc
);
3945 if (pointer_buffer_mark_set
)
3947 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3948 pStubMsg
->PointerBufferMark
= NULL
;
3954 /***********************************************************************
3955 * NdrComplexArrayBufferSize [RPCRT4.@]
3957 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3958 unsigned char *pMemory
,
3959 PFORMAT_STRING pFormat
)
3961 ULONG i
, count
, def
;
3962 unsigned char alignment
;
3963 BOOL variance_present
;
3964 int pointer_length_set
= 0;
3966 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3968 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3970 ERR("invalid format type %x\n", pFormat
[0]);
3971 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3975 alignment
= pFormat
[1] + 1;
3977 if (!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
3979 /* save buffer fields that may be changed by buffer sizer functions
3980 * and that may be needed later on */
3981 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3982 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
3983 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
3984 unsigned long saved_offset
= pStubMsg
->Offset
;
3985 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
3987 /* get the buffer pointer after complex array data, but before
3989 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3990 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
3991 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3993 /* save it for use by embedded pointer code later */
3994 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3995 pointer_length_set
= 1;
3997 /* restore fields */
3998 pStubMsg
->ActualCount
= saved_actual_count
;
3999 pStubMsg
->Offset
= saved_offset
;
4000 pStubMsg
->MaxCount
= saved_max_count
;
4001 pStubMsg
->BufferLength
= saved_buffer_length
;
4003 def
= *(const WORD
*)&pFormat
[2];
4006 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
4007 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
4008 SizeConformance(pStubMsg
);
4010 variance_present
= IsConformanceOrVariancePresent(pFormat
);
4011 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
4012 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
4014 if (variance_present
)
4015 SizeVariance(pStubMsg
);
4017 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
4019 count
= pStubMsg
->ActualCount
;
4020 for (i
= 0; i
< count
; i
++)
4021 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
4023 if(pointer_length_set
)
4025 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4026 pStubMsg
->PointerLength
= 0;
4030 /***********************************************************************
4031 * NdrComplexArrayMemorySize [RPCRT4.@]
4033 ULONG WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4034 PFORMAT_STRING pFormat
)
4036 ULONG i
, count
, esize
, SavedMemorySize
, MemorySize
;
4037 unsigned char alignment
;
4039 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
4041 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4043 ERR("invalid format type %x\n", pFormat
[0]);
4044 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4048 alignment
= pFormat
[1] + 1;
4052 pFormat
= ReadConformance(pStubMsg
, pFormat
);
4053 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
4055 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4057 SavedMemorySize
= pStubMsg
->MemorySize
;
4059 esize
= ComplexStructSize(pStubMsg
, pFormat
);
4061 MemorySize
= safe_multiply(pStubMsg
->MaxCount
, esize
);
4063 count
= pStubMsg
->ActualCount
;
4064 for (i
= 0; i
< count
; i
++)
4065 ComplexStructMemorySize(pStubMsg
, pFormat
, NULL
);
4067 pStubMsg
->MemorySize
= SavedMemorySize
;
4069 pStubMsg
->MemorySize
+= MemorySize
;
4073 /***********************************************************************
4074 * NdrComplexArrayFree [RPCRT4.@]
4076 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4077 unsigned char *pMemory
,
4078 PFORMAT_STRING pFormat
)
4080 ULONG i
, count
, def
;
4082 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4084 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4086 ERR("invalid format type %x\n", pFormat
[0]);
4087 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4091 def
= *(const WORD
*)&pFormat
[2];
4094 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
4095 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
4097 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
4098 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
4100 count
= pStubMsg
->ActualCount
;
4101 for (i
= 0; i
< count
; i
++)
4102 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
4105 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg
,
4106 USER_MARSHAL_CB_TYPE cbtype
, PFORMAT_STRING pFormat
,
4107 USER_MARSHAL_CB
*umcb
)
4109 umcb
->Flags
= MAKELONG(pStubMsg
->dwDestContext
,
4110 pStubMsg
->RpcMsg
->DataRepresentation
);
4111 umcb
->pStubMsg
= pStubMsg
;
4112 umcb
->pReserve
= NULL
;
4113 umcb
->Signature
= USER_MARSHAL_CB_SIGNATURE
;
4114 umcb
->CBType
= cbtype
;
4115 umcb
->pFormat
= pFormat
;
4116 umcb
->pTypeFormat
= NULL
/* FIXME */;
4119 #define USER_MARSHAL_PTR_PREFIX \
4120 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4121 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4123 /***********************************************************************
4124 * NdrUserMarshalMarshall [RPCRT4.@]
4126 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4127 unsigned char *pMemory
,
4128 PFORMAT_STRING pFormat
)
4130 unsigned flags
= pFormat
[1];
4131 unsigned index
= *(const WORD
*)&pFormat
[2];
4132 unsigned char *saved_buffer
= NULL
;
4133 USER_MARSHAL_CB umcb
;
4135 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4136 TRACE("index=%d\n", index
);
4138 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_MARSHALL
, pFormat
, &umcb
);
4140 if (flags
& USER_MARSHAL_POINTER
)
4142 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
4143 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, USER_MARSHAL_PTR_PREFIX
);
4144 pStubMsg
->Buffer
+= 4;
4145 if (pStubMsg
->PointerBufferMark
)
4147 saved_buffer
= pStubMsg
->Buffer
;
4148 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4149 pStubMsg
->PointerBufferMark
= NULL
;
4151 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 8);
4154 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4157 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
4158 &umcb
.Flags
, pStubMsg
->Buffer
, pMemory
);
4162 STD_OVERFLOW_CHECK(pStubMsg
);
4163 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4164 pStubMsg
->Buffer
= saved_buffer
;
4167 STD_OVERFLOW_CHECK(pStubMsg
);
4172 /***********************************************************************
4173 * NdrUserMarshalUnmarshall [RPCRT4.@]
4175 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4176 unsigned char **ppMemory
,
4177 PFORMAT_STRING pFormat
,
4178 unsigned char fMustAlloc
)
4180 unsigned flags
= pFormat
[1];
4181 unsigned index
= *(const WORD
*)&pFormat
[2];
4182 DWORD memsize
= *(const WORD
*)&pFormat
[4];
4183 unsigned char *saved_buffer
= NULL
;
4184 USER_MARSHAL_CB umcb
;
4186 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4187 TRACE("index=%d\n", index
);
4189 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_UNMARSHALL
, pFormat
, &umcb
);
4191 if (flags
& USER_MARSHAL_POINTER
)
4193 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4194 /* skip pointer prefix */
4195 pStubMsg
->Buffer
+= 4;
4196 if (pStubMsg
->PointerBufferMark
)
4198 saved_buffer
= pStubMsg
->Buffer
;
4199 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4200 pStubMsg
->PointerBufferMark
= NULL
;
4202 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
4205 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4207 if (!fMustAlloc
&& !*ppMemory
)
4211 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
4212 memset(*ppMemory
, 0, memsize
);
4216 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
4217 &umcb
.Flags
, pStubMsg
->Buffer
, *ppMemory
);
4221 STD_OVERFLOW_CHECK(pStubMsg
);
4222 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4223 pStubMsg
->Buffer
= saved_buffer
;
4229 /***********************************************************************
4230 * NdrUserMarshalBufferSize [RPCRT4.@]
4232 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4233 unsigned char *pMemory
,
4234 PFORMAT_STRING pFormat
)
4236 unsigned flags
= pFormat
[1];
4237 unsigned index
= *(const WORD
*)&pFormat
[2];
4238 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
4239 USER_MARSHAL_CB umcb
;
4240 unsigned long saved_buffer_length
= 0;
4242 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4243 TRACE("index=%d\n", index
);
4245 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_BUFFER_SIZE
, pFormat
, &umcb
);
4247 if (flags
& USER_MARSHAL_POINTER
)
4249 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
4250 /* skip pointer prefix */
4251 safe_buffer_length_increment(pStubMsg
, 4);
4252 if (pStubMsg
->IgnoreEmbeddedPointers
)
4254 if (pStubMsg
->PointerLength
)
4256 saved_buffer_length
= pStubMsg
->BufferLength
;
4257 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4258 pStubMsg
->PointerLength
= 0;
4260 ALIGN_LENGTH(pStubMsg
->BufferLength
, 8);
4263 ALIGN_LENGTH(pStubMsg
->BufferLength
, (flags
& 0xf) + 1);
4266 TRACE("size=%d\n", bufsize
);
4267 safe_buffer_length_increment(pStubMsg
, bufsize
);
4270 pStubMsg
->BufferLength
=
4271 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
4272 &umcb
.Flags
, pStubMsg
->BufferLength
, pMemory
);
4274 if (saved_buffer_length
)
4276 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4277 pStubMsg
->BufferLength
= saved_buffer_length
;
4282 /***********************************************************************
4283 * NdrUserMarshalMemorySize [RPCRT4.@]
4285 ULONG WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4286 PFORMAT_STRING pFormat
)
4288 unsigned flags
= pFormat
[1];
4289 unsigned index
= *(const WORD
*)&pFormat
[2];
4290 DWORD memsize
= *(const WORD
*)&pFormat
[4];
4291 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
4293 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
4294 TRACE("index=%d\n", index
);
4296 pStubMsg
->MemorySize
+= memsize
;
4298 if (flags
& USER_MARSHAL_POINTER
)
4300 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4301 /* skip pointer prefix */
4302 pStubMsg
->Buffer
+= 4;
4303 if (pStubMsg
->IgnoreEmbeddedPointers
)
4304 return pStubMsg
->MemorySize
;
4305 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
4308 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4311 FIXME("not implemented for varying buffer size\n");
4313 pStubMsg
->Buffer
+= bufsize
;
4315 return pStubMsg
->MemorySize
;
4318 /***********************************************************************
4319 * NdrUserMarshalFree [RPCRT4.@]
4321 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
4322 unsigned char *pMemory
,
4323 PFORMAT_STRING pFormat
)
4325 /* unsigned flags = pFormat[1]; */
4326 unsigned index
= *(const WORD
*)&pFormat
[2];
4327 USER_MARSHAL_CB umcb
;
4329 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4330 TRACE("index=%d\n", index
);
4332 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_FREE
, pFormat
, &umcb
);
4334 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
4335 &umcb
.Flags
, pMemory
);
4338 /***********************************************************************
4339 * NdrGetUserMarshalInfo [RPCRT4.@]
4341 RPC_STATUS RPC_ENTRY
NdrGetUserMarshalInfo(ULONG
*flags
, ULONG level
, NDR_USER_MARSHAL_INFO
*umi
)
4343 USER_MARSHAL_CB
*umcb
= CONTAINING_RECORD(flags
, USER_MARSHAL_CB
, Flags
);
4345 TRACE("(%p,%u,%p)\n", flags
, level
, umi
);
4348 return RPC_S_INVALID_ARG
;
4350 memset(&umi
->Level1
, 0, sizeof(umi
->Level1
));
4351 umi
->InformationLevel
= level
;
4353 if (umcb
->Signature
!= USER_MARSHAL_CB_SIGNATURE
)
4354 return RPC_S_INVALID_ARG
;
4356 umi
->Level1
.pfnAllocate
= umcb
->pStubMsg
->pfnAllocate
;
4357 umi
->Level1
.pfnFree
= umcb
->pStubMsg
->pfnFree
;
4358 umi
->Level1
.pRpcChannelBuffer
= umcb
->pStubMsg
->pRpcChannelBuffer
;
4360 switch (umcb
->CBType
)
4362 case USER_MARSHAL_CB_MARSHALL
:
4363 case USER_MARSHAL_CB_UNMARSHALL
:
4365 RPC_MESSAGE
*msg
= umcb
->pStubMsg
->RpcMsg
;
4366 unsigned char *buffer_start
= msg
->Buffer
;
4367 unsigned char *buffer_end
=
4368 (unsigned char *)msg
->Buffer
+ msg
->BufferLength
;
4370 if (umcb
->pStubMsg
->Buffer
< buffer_start
||
4371 umcb
->pStubMsg
->Buffer
> buffer_end
)
4372 return ERROR_INVALID_USER_BUFFER
;
4374 umi
->Level1
.Buffer
= umcb
->pStubMsg
->Buffer
;
4375 umi
->Level1
.BufferSize
= buffer_end
- umcb
->pStubMsg
->Buffer
;
4378 case USER_MARSHAL_CB_BUFFER_SIZE
:
4379 case USER_MARSHAL_CB_FREE
:
4382 WARN("unrecognised CBType %d\n", umcb
->CBType
);
4388 /***********************************************************************
4389 * NdrClearOutParameters [RPCRT4.@]
4391 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
4392 PFORMAT_STRING pFormat
,
4395 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
4398 /***********************************************************************
4399 * NdrConvert [RPCRT4.@]
4401 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
4403 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
4404 /* FIXME: since this stub doesn't do any converting, the proper behavior
4405 is to raise an exception */
4408 /***********************************************************************
4409 * NdrConvert2 [RPCRT4.@]
4411 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, LONG NumberParams
)
4413 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4414 pStubMsg
, pFormat
, NumberParams
);
4415 /* FIXME: since this stub doesn't do any converting, the proper behavior
4416 is to raise an exception */
4419 #include "pshpack1.h"
4420 typedef struct _NDR_CSTRUCT_FORMAT
4423 unsigned char alignment
;
4424 unsigned short memory_size
;
4425 short offset_to_array_description
;
4426 } NDR_CSTRUCT_FORMAT
, NDR_CVSTRUCT_FORMAT
;
4427 #include "poppack.h"
4429 /***********************************************************************
4430 * NdrConformantStructMarshall [RPCRT4.@]
4432 unsigned char * WINAPI
NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4433 unsigned char *pMemory
,
4434 PFORMAT_STRING pFormat
)
4436 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4437 PFORMAT_STRING pCArrayFormat
;
4438 ULONG esize
, bufsize
;
4440 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4442 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4443 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4445 ERR("invalid format type %x\n", pCStructFormat
->type
);
4446 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4450 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4451 pCStructFormat
->offset_to_array_description
;
4452 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4454 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4455 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4458 esize
= *(const WORD
*)(pCArrayFormat
+2);
4460 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4461 pCArrayFormat
+ 4, 0);
4463 WriteConformance(pStubMsg
);
4465 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4467 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4469 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4470 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4472 ERR("integer overflow of memory_size %u with bufsize %u\n",
4473 pCStructFormat
->memory_size
, bufsize
);
4474 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4476 /* copy constant sized part of struct */
4477 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4478 safe_copy_to_buffer(pStubMsg
, pMemory
, pCStructFormat
->memory_size
+ bufsize
);
4480 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4481 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4486 /***********************************************************************
4487 * NdrConformantStructUnmarshall [RPCRT4.@]
4489 unsigned char * WINAPI
NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4490 unsigned char **ppMemory
,
4491 PFORMAT_STRING pFormat
,
4492 unsigned char fMustAlloc
)
4494 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4495 PFORMAT_STRING pCArrayFormat
;
4496 ULONG esize
, bufsize
;
4497 unsigned char *saved_buffer
;
4499 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4501 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4502 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4504 ERR("invalid format type %x\n", pCStructFormat
->type
);
4505 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4508 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4509 pCStructFormat
->offset_to_array_description
;
4510 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4512 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4513 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4516 esize
= *(const WORD
*)(pCArrayFormat
+2);
4518 pCArrayFormat
= ReadConformance(pStubMsg
, pCArrayFormat
+ 4);
4520 ALIGN_POINTER(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4522 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4524 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4525 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4527 ERR("integer overflow of memory_size %u with bufsize %u\n",
4528 pCStructFormat
->memory_size
, bufsize
);
4529 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4534 SIZE_T size
= pCStructFormat
->memory_size
+ bufsize
;
4535 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4539 if (!pStubMsg
->IsClient
&& !*ppMemory
)
4540 /* for servers, we just point straight into the RPC buffer */
4541 *ppMemory
= pStubMsg
->Buffer
;
4544 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4545 safe_buffer_increment(pStubMsg
, pCStructFormat
->memory_size
+ bufsize
);
4546 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4547 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4549 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
4550 if (*ppMemory
!= saved_buffer
)
4551 memcpy(*ppMemory
, saved_buffer
, pCStructFormat
->memory_size
+ bufsize
);
4556 /***********************************************************************
4557 * NdrConformantStructBufferSize [RPCRT4.@]
4559 void WINAPI
NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4560 unsigned char *pMemory
,
4561 PFORMAT_STRING pFormat
)
4563 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4564 PFORMAT_STRING pCArrayFormat
;
4567 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4569 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4570 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4572 ERR("invalid format type %x\n", pCStructFormat
->type
);
4573 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4576 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4577 pCStructFormat
->offset_to_array_description
;
4578 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4580 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4581 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4584 esize
= *(const WORD
*)(pCArrayFormat
+2);
4586 pCArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
, pCArrayFormat
+4, 0);
4587 SizeConformance(pStubMsg
);
4589 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCStructFormat
->alignment
+ 1);
4591 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4593 safe_buffer_length_increment(pStubMsg
, pCStructFormat
->memory_size
);
4594 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
4596 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4597 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4600 /***********************************************************************
4601 * NdrConformantStructMemorySize [RPCRT4.@]
4603 ULONG WINAPI
NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4604 PFORMAT_STRING pFormat
)
4610 /***********************************************************************
4611 * NdrConformantStructFree [RPCRT4.@]
4613 void WINAPI
NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
4614 unsigned char *pMemory
,
4615 PFORMAT_STRING pFormat
)
4617 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4618 PFORMAT_STRING pCArrayFormat
;
4620 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4622 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4623 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4625 ERR("invalid format type %x\n", pCStructFormat
->type
);
4626 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4630 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4631 pCStructFormat
->offset_to_array_description
;
4632 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4634 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4635 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4639 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4640 pCArrayFormat
+ 4, 0);
4642 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4644 /* copy constant sized part of struct */
4645 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4647 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4648 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4651 /***********************************************************************
4652 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4654 unsigned char * WINAPI
NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4655 unsigned char *pMemory
,
4656 PFORMAT_STRING pFormat
)
4658 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4659 PFORMAT_STRING pCVArrayFormat
;
4661 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4663 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4664 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4666 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4667 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4671 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4672 pCVStructFormat
->offset_to_array_description
;
4674 array_compute_and_write_conformance(*pCVArrayFormat
, pStubMsg
,
4675 pMemory
+ pCVStructFormat
->memory_size
,
4678 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4680 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4682 /* write constant sized part */
4683 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4684 safe_copy_to_buffer(pStubMsg
, pMemory
, pCVStructFormat
->memory_size
);
4686 array_write_variance_and_marshall(*pCVArrayFormat
, pStubMsg
,
4687 pMemory
+ pCVStructFormat
->memory_size
,
4688 pCVArrayFormat
, FALSE
/* fHasPointers */);
4690 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4695 /***********************************************************************
4696 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4698 unsigned char * WINAPI
NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4699 unsigned char **ppMemory
,
4700 PFORMAT_STRING pFormat
,
4701 unsigned char fMustAlloc
)
4703 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4704 PFORMAT_STRING pCVArrayFormat
;
4705 ULONG memsize
, bufsize
;
4706 unsigned char *saved_buffer
, *saved_array_buffer
;
4708 unsigned char *array_memory
;
4710 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4712 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4713 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4715 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4716 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4720 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4721 pCVStructFormat
->offset_to_array_description
;
4723 memsize
= array_read_conformance(*pCVArrayFormat
, pStubMsg
,
4726 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4728 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4730 /* work out how much memory to allocate if we need to do so */
4731 if (!fMustAlloc
&& !*ppMemory
)
4735 SIZE_T size
= pCVStructFormat
->memory_size
+ memsize
;
4736 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4739 /* mark the start of the constant data */
4740 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4741 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4743 array_memory
= *ppMemory
+ pCVStructFormat
->memory_size
;
4744 bufsize
= array_read_variance_and_unmarshall(*pCVArrayFormat
, pStubMsg
,
4745 &array_memory
, pCVArrayFormat
,
4746 FALSE
/* fMustAlloc */,
4747 FALSE
/* fUseServerBufferMemory */,
4748 FALSE
/* fUnmarshall */);
4750 /* save offset in case unmarshalling pointers changes it */
4751 offset
= pStubMsg
->Offset
;
4753 /* mark the start of the array data */
4754 saved_array_buffer
= pStubMsg
->Buffer
;
4755 safe_buffer_increment(pStubMsg
, bufsize
);
4757 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4759 /* copy the constant data */
4760 memcpy(*ppMemory
, saved_buffer
, pCVStructFormat
->memory_size
);
4761 /* copy the array data */
4762 TRACE("copying %p to %p\n", saved_array_buffer
, *ppMemory
+ pCVStructFormat
->memory_size
);
4763 memcpy(*ppMemory
+ pCVStructFormat
->memory_size
+ offset
,
4764 saved_array_buffer
, bufsize
);
4766 if (*pCVArrayFormat
== RPC_FC_C_CSTRING
)
4767 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory
+ pCVStructFormat
->memory_size
)));
4768 else if (*pCVArrayFormat
== RPC_FC_C_WSTRING
)
4769 TRACE("string=%s\n", debugstr_w((WCHAR
*)(*ppMemory
+ pCVStructFormat
->memory_size
)));
4774 /***********************************************************************
4775 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
4777 void WINAPI
NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4778 unsigned char *pMemory
,
4779 PFORMAT_STRING pFormat
)
4781 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4782 PFORMAT_STRING pCVArrayFormat
;
4784 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4786 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4787 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4789 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4790 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4794 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4795 pCVStructFormat
->offset_to_array_description
;
4796 array_compute_and_size_conformance(*pCVArrayFormat
, pStubMsg
,
4797 pMemory
+ pCVStructFormat
->memory_size
,
4800 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCVStructFormat
->alignment
+ 1);
4802 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4804 safe_buffer_length_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4806 array_buffer_size(*pCVArrayFormat
, pStubMsg
,
4807 pMemory
+ pCVStructFormat
->memory_size
, pCVArrayFormat
,
4808 FALSE
/* fHasPointers */);
4810 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4813 /***********************************************************************
4814 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4816 ULONG WINAPI
NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4817 PFORMAT_STRING pFormat
)
4819 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4820 PFORMAT_STRING pCVArrayFormat
;
4822 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4824 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4825 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4827 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4828 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4832 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4833 pCVStructFormat
->offset_to_array_description
;
4834 array_read_conformance(*pCVArrayFormat
, pStubMsg
, pCVArrayFormat
);
4836 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4838 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4840 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4841 array_memory_size(*pCVArrayFormat
, pStubMsg
, pCVArrayFormat
,
4842 FALSE
/* fHasPointers */);
4844 pStubMsg
->MemorySize
+= pCVStructFormat
->memory_size
;
4846 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4848 return pStubMsg
->MemorySize
;
4851 /***********************************************************************
4852 * NdrConformantVaryingStructFree [RPCRT4.@]
4854 void WINAPI
NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
4855 unsigned char *pMemory
,
4856 PFORMAT_STRING pFormat
)
4858 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4859 PFORMAT_STRING pCVArrayFormat
;
4861 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4863 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4864 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4866 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4867 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4871 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4872 pCVStructFormat
->offset_to_array_description
;
4873 array_free(*pCVArrayFormat
, pStubMsg
,
4874 pMemory
+ pCVStructFormat
->memory_size
, pCVArrayFormat
,
4875 FALSE
/* fHasPointers */);
4877 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4879 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4882 #include "pshpack1.h"
4886 unsigned char alignment
;
4887 unsigned short total_size
;
4888 } NDR_SMFARRAY_FORMAT
;
4893 unsigned char alignment
;
4894 unsigned long total_size
;
4895 } NDR_LGFARRAY_FORMAT
;
4896 #include "poppack.h"
4898 /***********************************************************************
4899 * NdrFixedArrayMarshall [RPCRT4.@]
4901 unsigned char * WINAPI
NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4902 unsigned char *pMemory
,
4903 PFORMAT_STRING pFormat
)
4905 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4906 unsigned long total_size
;
4908 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4910 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4911 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4913 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4914 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4918 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4920 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4922 total_size
= pSmFArrayFormat
->total_size
;
4923 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4927 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4928 total_size
= pLgFArrayFormat
->total_size
;
4929 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4932 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4933 safe_copy_to_buffer(pStubMsg
, pMemory
, total_size
);
4935 pFormat
= EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4940 /***********************************************************************
4941 * NdrFixedArrayUnmarshall [RPCRT4.@]
4943 unsigned char * WINAPI
NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4944 unsigned char **ppMemory
,
4945 PFORMAT_STRING pFormat
,
4946 unsigned char fMustAlloc
)
4948 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4949 unsigned long total_size
;
4950 unsigned char *saved_buffer
;
4952 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4954 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4955 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4957 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4958 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4962 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4964 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4966 total_size
= pSmFArrayFormat
->total_size
;
4967 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4971 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4972 total_size
= pLgFArrayFormat
->total_size
;
4973 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4977 *ppMemory
= NdrAllocate(pStubMsg
, total_size
);
4980 if (!pStubMsg
->IsClient
&& !*ppMemory
)
4981 /* for servers, we just point straight into the RPC buffer */
4982 *ppMemory
= pStubMsg
->Buffer
;
4985 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4986 safe_buffer_increment(pStubMsg
, total_size
);
4987 pFormat
= EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4989 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
4990 if (*ppMemory
!= saved_buffer
)
4991 memcpy(*ppMemory
, saved_buffer
, total_size
);
4996 /***********************************************************************
4997 * NdrFixedArrayBufferSize [RPCRT4.@]
4999 void WINAPI
NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5000 unsigned char *pMemory
,
5001 PFORMAT_STRING pFormat
)
5003 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5004 unsigned long total_size
;
5006 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5008 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5009 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5011 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5012 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5016 ALIGN_LENGTH(pStubMsg
->BufferLength
, pSmFArrayFormat
->alignment
+ 1);
5018 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5020 total_size
= pSmFArrayFormat
->total_size
;
5021 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5025 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5026 total_size
= pLgFArrayFormat
->total_size
;
5027 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5029 safe_buffer_length_increment(pStubMsg
, total_size
);
5031 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5034 /***********************************************************************
5035 * NdrFixedArrayMemorySize [RPCRT4.@]
5037 ULONG WINAPI
NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5038 PFORMAT_STRING pFormat
)
5040 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5043 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5045 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5046 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5048 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5049 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5053 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
5055 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5057 total_size
= pSmFArrayFormat
->total_size
;
5058 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5062 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5063 total_size
= pLgFArrayFormat
->total_size
;
5064 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5066 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5067 safe_buffer_increment(pStubMsg
, total_size
);
5068 pStubMsg
->MemorySize
+= total_size
;
5070 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5075 /***********************************************************************
5076 * NdrFixedArrayFree [RPCRT4.@]
5078 void WINAPI
NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
5079 unsigned char *pMemory
,
5080 PFORMAT_STRING pFormat
)
5082 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5084 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5086 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5087 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5089 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5090 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5094 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5095 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5098 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5099 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5102 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5105 /***********************************************************************
5106 * NdrVaryingArrayMarshall [RPCRT4.@]
5108 unsigned char * WINAPI
NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5109 unsigned char *pMemory
,
5110 PFORMAT_STRING pFormat
)
5112 unsigned char alignment
;
5113 DWORD elements
, esize
;
5116 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5118 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5119 (pFormat
[0] != RPC_FC_LGVARRAY
))
5121 ERR("invalid format type %x\n", pFormat
[0]);
5122 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5126 alignment
= pFormat
[1] + 1;
5128 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5131 pFormat
+= sizeof(WORD
);
5132 elements
= *(const WORD
*)pFormat
;
5133 pFormat
+= sizeof(WORD
);
5138 pFormat
+= sizeof(DWORD
);
5139 elements
= *(const DWORD
*)pFormat
;
5140 pFormat
+= sizeof(DWORD
);
5143 esize
= *(const WORD
*)pFormat
;
5144 pFormat
+= sizeof(WORD
);
5146 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5147 if ((pStubMsg
->ActualCount
> elements
) ||
5148 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5150 RpcRaiseException(RPC_S_INVALID_BOUND
);
5154 WriteVariance(pStubMsg
);
5156 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
5158 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
5159 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5160 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
5162 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
5167 /***********************************************************************
5168 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5170 unsigned char * WINAPI
NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5171 unsigned char **ppMemory
,
5172 PFORMAT_STRING pFormat
,
5173 unsigned char fMustAlloc
)
5175 unsigned char alignment
;
5176 DWORD size
, elements
, esize
;
5178 unsigned char *saved_buffer
;
5181 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5183 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5184 (pFormat
[0] != RPC_FC_LGVARRAY
))
5186 ERR("invalid format type %x\n", pFormat
[0]);
5187 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5191 alignment
= pFormat
[1] + 1;
5193 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5196 size
= *(const WORD
*)pFormat
;
5197 pFormat
+= sizeof(WORD
);
5198 elements
= *(const WORD
*)pFormat
;
5199 pFormat
+= sizeof(WORD
);
5204 size
= *(const DWORD
*)pFormat
;
5205 pFormat
+= sizeof(DWORD
);
5206 elements
= *(const DWORD
*)pFormat
;
5207 pFormat
+= sizeof(DWORD
);
5210 esize
= *(const WORD
*)pFormat
;
5211 pFormat
+= sizeof(WORD
);
5213 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
5215 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
5217 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
5218 offset
= pStubMsg
->Offset
;
5220 if (!fMustAlloc
&& !*ppMemory
)
5223 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5224 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5225 safe_buffer_increment(pStubMsg
, bufsize
);
5227 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
5229 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
5234 /***********************************************************************
5235 * NdrVaryingArrayBufferSize [RPCRT4.@]
5237 void WINAPI
NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5238 unsigned char *pMemory
,
5239 PFORMAT_STRING pFormat
)
5241 unsigned char alignment
;
5242 DWORD elements
, esize
;
5244 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5246 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5247 (pFormat
[0] != RPC_FC_LGVARRAY
))
5249 ERR("invalid format type %x\n", pFormat
[0]);
5250 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5254 alignment
= pFormat
[1] + 1;
5256 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5259 pFormat
+= sizeof(WORD
);
5260 elements
= *(const WORD
*)pFormat
;
5261 pFormat
+= sizeof(WORD
);
5266 pFormat
+= sizeof(DWORD
);
5267 elements
= *(const DWORD
*)pFormat
;
5268 pFormat
+= sizeof(DWORD
);
5271 esize
= *(const WORD
*)pFormat
;
5272 pFormat
+= sizeof(WORD
);
5274 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5275 if ((pStubMsg
->ActualCount
> elements
) ||
5276 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5278 RpcRaiseException(RPC_S_INVALID_BOUND
);
5282 SizeVariance(pStubMsg
);
5284 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
5286 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
5288 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5291 /***********************************************************************
5292 * NdrVaryingArrayMemorySize [RPCRT4.@]
5294 ULONG WINAPI
NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5295 PFORMAT_STRING pFormat
)
5297 unsigned char alignment
;
5298 DWORD size
, elements
, esize
;
5300 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5302 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5303 (pFormat
[0] != RPC_FC_LGVARRAY
))
5305 ERR("invalid format type %x\n", pFormat
[0]);
5306 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5310 alignment
= pFormat
[1] + 1;
5312 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5315 size
= *(const WORD
*)pFormat
;
5316 pFormat
+= sizeof(WORD
);
5317 elements
= *(const WORD
*)pFormat
;
5318 pFormat
+= sizeof(WORD
);
5323 size
= *(const DWORD
*)pFormat
;
5324 pFormat
+= sizeof(DWORD
);
5325 elements
= *(const DWORD
*)pFormat
;
5326 pFormat
+= sizeof(DWORD
);
5329 esize
= *(const WORD
*)pFormat
;
5330 pFormat
+= sizeof(WORD
);
5332 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
5334 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
5336 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
5337 pStubMsg
->MemorySize
+= size
;
5339 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5341 return pStubMsg
->MemorySize
;
5344 /***********************************************************************
5345 * NdrVaryingArrayFree [RPCRT4.@]
5347 void WINAPI
NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
5348 unsigned char *pMemory
,
5349 PFORMAT_STRING pFormat
)
5353 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5355 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5356 (pFormat
[0] != RPC_FC_LGVARRAY
))
5358 ERR("invalid format type %x\n", pFormat
[0]);
5359 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5363 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5366 pFormat
+= sizeof(WORD
);
5367 elements
= *(const WORD
*)pFormat
;
5368 pFormat
+= sizeof(WORD
);
5373 pFormat
+= sizeof(DWORD
);
5374 elements
= *(const DWORD
*)pFormat
;
5375 pFormat
+= sizeof(DWORD
);
5378 pFormat
+= sizeof(WORD
);
5380 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5381 if ((pStubMsg
->ActualCount
> elements
) ||
5382 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5384 RpcRaiseException(RPC_S_INVALID_BOUND
);
5388 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5391 static ULONG
get_discriminant(unsigned char fc
, const unsigned char *pMemory
)
5404 return *(const USHORT
*)pMemory
;
5408 return *(const ULONG
*)pMemory
;
5410 FIXME("Unhandled base type: 0x%02x\n", fc
);
5415 static PFORMAT_STRING
get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg
,
5416 unsigned long discriminant
,
5417 PFORMAT_STRING pFormat
)
5419 unsigned short num_arms
, arm
, type
;
5421 num_arms
= *(const SHORT
*)pFormat
& 0x0fff;
5423 for(arm
= 0; arm
< num_arms
; arm
++)
5425 if(discriminant
== *(const ULONG
*)pFormat
)
5433 type
= *(const unsigned short*)pFormat
;
5434 TRACE("type %04x\n", type
);
5435 if(arm
== num_arms
) /* default arm extras */
5439 ERR("no arm for 0x%lx and no default case\n", discriminant
);
5440 RpcRaiseException(RPC_S_INVALID_TAG
);
5445 TRACE("falling back to empty default case for 0x%lx\n", discriminant
);
5452 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
, ULONG discriminant
, PFORMAT_STRING pFormat
)
5454 unsigned short type
;
5458 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5462 type
= *(const unsigned short*)pFormat
;
5463 if((type
& 0xff00) == 0x8000)
5465 unsigned char basetype
= LOBYTE(type
);
5466 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &basetype
);
5470 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5471 NDR_MARSHALL m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
5474 unsigned char *saved_buffer
= NULL
;
5475 int pointer_buffer_mark_set
= 0;
5482 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
5483 saved_buffer
= pStubMsg
->Buffer
;
5484 if (pStubMsg
->PointerBufferMark
)
5486 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5487 pStubMsg
->PointerBufferMark
= NULL
;
5488 pointer_buffer_mark_set
= 1;
5491 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
5493 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char **)pMemory
, desc
);
5494 if (pointer_buffer_mark_set
)
5496 STD_OVERFLOW_CHECK(pStubMsg
);
5497 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5498 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5500 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5501 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
5502 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5504 pStubMsg
->Buffer
= saved_buffer
+ 4;
5508 m(pStubMsg
, pMemory
, desc
);
5511 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5516 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5517 unsigned char **ppMemory
,
5519 PFORMAT_STRING pFormat
,
5520 unsigned char fMustAlloc
)
5522 unsigned short type
;
5526 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5530 type
= *(const unsigned short*)pFormat
;
5531 if((type
& 0xff00) == 0x8000)
5533 unsigned char basetype
= LOBYTE(type
);
5534 return NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &basetype
, FALSE
);
5538 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5539 NDR_UNMARSHALL m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
5542 unsigned char *saved_buffer
= NULL
;
5543 int pointer_buffer_mark_set
= 0;
5550 **(void***)ppMemory
= NULL
;
5551 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5552 saved_buffer
= pStubMsg
->Buffer
;
5553 if (pStubMsg
->PointerBufferMark
)
5555 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5556 pStubMsg
->PointerBufferMark
= NULL
;
5557 pointer_buffer_mark_set
= 1;
5560 pStubMsg
->Buffer
+= 4; /* for pointer ID */
5562 if (saved_buffer
+ 4 > pStubMsg
->BufferEnd
)
5564 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5565 saved_buffer
, pStubMsg
->BufferEnd
);
5566 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5569 PointerUnmarshall(pStubMsg
, saved_buffer
, *(unsigned char ***)ppMemory
, **(unsigned char ***)ppMemory
, desc
, fMustAlloc
);
5570 if (pointer_buffer_mark_set
)
5572 STD_OVERFLOW_CHECK(pStubMsg
);
5573 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5574 pStubMsg
->Buffer
= saved_buffer
+ 4;
5578 m(pStubMsg
, ppMemory
, desc
, fMustAlloc
);
5581 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5586 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg
,
5587 unsigned char *pMemory
,
5589 PFORMAT_STRING pFormat
)
5591 unsigned short type
;
5595 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5599 type
= *(const unsigned short*)pFormat
;
5600 if((type
& 0xff00) == 0x8000)
5602 unsigned char basetype
= LOBYTE(type
);
5603 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &basetype
);
5607 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5608 NDR_BUFFERSIZE m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
5617 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
5618 safe_buffer_length_increment(pStubMsg
, 4); /* for pointer ID */
5619 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5621 int saved_buffer_length
= pStubMsg
->BufferLength
;
5622 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
5623 pStubMsg
->PointerLength
= 0;
5624 if(!pStubMsg
->BufferLength
)
5625 ERR("BufferLength == 0??\n");
5626 PointerBufferSize(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5627 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
5628 pStubMsg
->BufferLength
= saved_buffer_length
;
5632 m(pStubMsg
, pMemory
, desc
);
5635 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
5639 static ULONG
union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg
,
5641 PFORMAT_STRING pFormat
)
5643 unsigned short type
, size
;
5645 size
= *(const unsigned short*)pFormat
;
5646 pStubMsg
->Memory
+= size
;
5649 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5653 type
= *(const unsigned short*)pFormat
;
5654 if((type
& 0xff00) == 0x8000)
5656 return NdrBaseTypeMemorySize(pStubMsg
, pFormat
);
5660 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5661 NDR_MEMORYSIZE m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
5662 unsigned char *saved_buffer
;
5671 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5672 saved_buffer
= pStubMsg
->Buffer
;
5673 safe_buffer_increment(pStubMsg
, 4);
5674 ALIGN_LENGTH(pStubMsg
->MemorySize
, 4);
5675 pStubMsg
->MemorySize
+= 4;
5676 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5677 PointerMemorySize(pStubMsg
, saved_buffer
, pFormat
);
5680 return m(pStubMsg
, desc
);
5683 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5686 TRACE("size %d\n", size
);
5690 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg
,
5691 unsigned char *pMemory
,
5693 PFORMAT_STRING pFormat
)
5695 unsigned short type
;
5699 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5703 type
= *(const unsigned short*)pFormat
;
5704 if((type
& 0xff00) != 0x8000)
5706 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5707 NDR_FREE m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
5716 PointerFree(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5719 m(pStubMsg
, pMemory
, desc
);
5725 /***********************************************************************
5726 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5728 unsigned char * WINAPI
NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5729 unsigned char *pMemory
,
5730 PFORMAT_STRING pFormat
)
5732 unsigned char switch_type
;
5733 unsigned char increment
;
5736 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5739 switch_type
= *pFormat
& 0xf;
5740 increment
= (*pFormat
& 0xf0) >> 4;
5743 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, increment
);
5745 switch_value
= get_discriminant(switch_type
, pMemory
);
5746 TRACE("got switch value 0x%x\n", switch_value
);
5748 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &switch_type
);
5749 pMemory
+= increment
;
5751 return union_arm_marshall(pStubMsg
, pMemory
, switch_value
, pFormat
);
5754 /***********************************************************************
5755 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5757 unsigned char * WINAPI
NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5758 unsigned char **ppMemory
,
5759 PFORMAT_STRING pFormat
,
5760 unsigned char fMustAlloc
)
5762 unsigned char switch_type
;
5763 unsigned char increment
;
5765 unsigned short size
;
5766 unsigned char *pMemoryArm
;
5768 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5771 switch_type
= *pFormat
& 0xf;
5772 increment
= (*pFormat
& 0xf0) >> 4;
5775 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
5776 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
5777 TRACE("got switch value 0x%x\n", switch_value
);
5779 size
= *(const unsigned short*)pFormat
+ increment
;
5780 if (!fMustAlloc
&& !*ppMemory
)
5783 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5785 NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &switch_type
, FALSE
);
5786 pMemoryArm
= *ppMemory
+ increment
;
5788 return union_arm_unmarshall(pStubMsg
, &pMemoryArm
, switch_value
, pFormat
, fMustAlloc
);
5791 /***********************************************************************
5792 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5794 void WINAPI
NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5795 unsigned char *pMemory
,
5796 PFORMAT_STRING pFormat
)
5798 unsigned char switch_type
;
5799 unsigned char increment
;
5802 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5805 switch_type
= *pFormat
& 0xf;
5806 increment
= (*pFormat
& 0xf0) >> 4;
5809 ALIGN_LENGTH(pStubMsg
->BufferLength
, increment
);
5810 switch_value
= get_discriminant(switch_type
, pMemory
);
5811 TRACE("got switch value 0x%x\n", switch_value
);
5813 /* Add discriminant size */
5814 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&switch_value
, &switch_type
);
5815 pMemory
+= increment
;
5817 union_arm_buffer_size(pStubMsg
, pMemory
, switch_value
, pFormat
);
5820 /***********************************************************************
5821 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5823 ULONG WINAPI
NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5824 PFORMAT_STRING pFormat
)
5826 unsigned char switch_type
;
5827 unsigned char increment
;
5830 switch_type
= *pFormat
& 0xf;
5831 increment
= (*pFormat
& 0xf0) >> 4;
5834 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
5835 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
5836 TRACE("got switch value 0x%x\n", switch_value
);
5838 pStubMsg
->Memory
+= increment
;
5840 return increment
+ union_arm_memory_size(pStubMsg
, switch_value
, pFormat
+ *(const SHORT
*)pFormat
);
5843 /***********************************************************************
5844 * NdrEncapsulatedUnionFree [RPCRT4.@]
5846 void WINAPI
NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
5847 unsigned char *pMemory
,
5848 PFORMAT_STRING pFormat
)
5850 unsigned char switch_type
;
5851 unsigned char increment
;
5854 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5857 switch_type
= *pFormat
& 0xf;
5858 increment
= (*pFormat
& 0xf0) >> 4;
5861 switch_value
= get_discriminant(switch_type
, pMemory
);
5862 TRACE("got switch value 0x%x\n", switch_value
);
5864 pMemory
+= increment
;
5866 union_arm_free(pStubMsg
, pMemory
, switch_value
, pFormat
);
5869 /***********************************************************************
5870 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5872 unsigned char * WINAPI
NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5873 unsigned char *pMemory
,
5874 PFORMAT_STRING pFormat
)
5876 unsigned char switch_type
;
5878 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5881 switch_type
= *pFormat
;
5884 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5885 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5886 /* Marshall discriminant */
5887 NdrBaseTypeMarshall(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
5889 return union_arm_marshall(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5892 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg
,
5893 PFORMAT_STRING
*ppFormat
)
5895 long discriminant
= 0;
5905 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5914 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5915 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5923 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
5924 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5929 FIXME("Unhandled base type: 0x%02x\n", **ppFormat
);
5933 if (pStubMsg
->fHasNewCorrDesc
)
5937 return discriminant
;
5940 /**********************************************************************
5941 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5943 unsigned char * WINAPI
NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5944 unsigned char **ppMemory
,
5945 PFORMAT_STRING pFormat
,
5946 unsigned char fMustAlloc
)
5949 unsigned short size
;
5951 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5954 /* Unmarshall discriminant */
5955 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
5956 TRACE("unmarshalled discriminant %lx\n", discriminant
);
5958 pFormat
+= *(const SHORT
*)pFormat
;
5960 size
= *(const unsigned short*)pFormat
;
5962 if (!fMustAlloc
&& !*ppMemory
)
5965 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5967 return union_arm_unmarshall(pStubMsg
, ppMemory
, discriminant
, pFormat
, fMustAlloc
);
5970 /***********************************************************************
5971 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5973 void WINAPI
NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5974 unsigned char *pMemory
,
5975 PFORMAT_STRING pFormat
)
5977 unsigned char switch_type
;
5979 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5982 switch_type
= *pFormat
;
5985 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5986 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5987 /* Add discriminant size */
5988 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
5990 union_arm_buffer_size(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5993 /***********************************************************************
5994 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5996 ULONG WINAPI
NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5997 PFORMAT_STRING pFormat
)
6002 /* Unmarshall discriminant */
6003 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
6004 TRACE("unmarshalled discriminant 0x%x\n", discriminant
);
6006 return union_arm_memory_size(pStubMsg
, discriminant
, pFormat
+ *(const SHORT
*)pFormat
);
6009 /***********************************************************************
6010 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6012 void WINAPI
NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
6013 unsigned char *pMemory
,
6014 PFORMAT_STRING pFormat
)
6016 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6020 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6021 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6023 union_arm_free(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6026 /***********************************************************************
6027 * NdrByteCountPointerMarshall [RPCRT4.@]
6029 unsigned char * WINAPI
NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6030 unsigned char *pMemory
,
6031 PFORMAT_STRING pFormat
)
6037 /***********************************************************************
6038 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6040 unsigned char * WINAPI
NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6041 unsigned char **ppMemory
,
6042 PFORMAT_STRING pFormat
,
6043 unsigned char fMustAlloc
)
6049 /***********************************************************************
6050 * NdrByteCountPointerBufferSize [RPCRT4.@]
6052 void WINAPI
NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6053 unsigned char *pMemory
,
6054 PFORMAT_STRING pFormat
)
6059 /***********************************************************************
6060 * NdrByteCountPointerMemorySize [internal]
6062 static ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6063 PFORMAT_STRING pFormat
)
6069 /***********************************************************************
6070 * NdrByteCountPointerFree [RPCRT4.@]
6072 void WINAPI
NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
6073 unsigned char *pMemory
,
6074 PFORMAT_STRING pFormat
)
6079 /***********************************************************************
6080 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6082 unsigned char * WINAPI
NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6083 unsigned char *pMemory
,
6084 PFORMAT_STRING pFormat
)
6090 /***********************************************************************
6091 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6093 unsigned char * WINAPI
NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6094 unsigned char **ppMemory
,
6095 PFORMAT_STRING pFormat
,
6096 unsigned char fMustAlloc
)
6102 /***********************************************************************
6103 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6105 void WINAPI
NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6106 unsigned char *pMemory
,
6107 PFORMAT_STRING pFormat
)
6112 /***********************************************************************
6113 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6115 ULONG WINAPI
NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6116 PFORMAT_STRING pFormat
)
6122 /***********************************************************************
6123 * NdrXmitOrRepAsFree [RPCRT4.@]
6125 void WINAPI
NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg
,
6126 unsigned char *pMemory
,
6127 PFORMAT_STRING pFormat
)
6132 /***********************************************************************
6133 * NdrRangeMarshall [internal]
6135 static unsigned char *WINAPI
NdrRangeMarshall(
6136 PMIDL_STUB_MESSAGE pStubMsg
,
6137 unsigned char *pMemory
,
6138 PFORMAT_STRING pFormat
)
6140 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
6141 unsigned char base_type
;
6143 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6145 if (pRange
->type
!= RPC_FC_RANGE
)
6147 ERR("invalid format type %x\n", pRange
->type
);
6148 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6152 base_type
= pRange
->flags_type
& 0xf;
6154 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &base_type
);
6157 /***********************************************************************
6158 * NdrRangeUnmarshall [RPCRT4.@]
6160 unsigned char *WINAPI
NdrRangeUnmarshall(
6161 PMIDL_STUB_MESSAGE pStubMsg
,
6162 unsigned char **ppMemory
,
6163 PFORMAT_STRING pFormat
,
6164 unsigned char fMustAlloc
)
6166 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
6167 unsigned char base_type
;
6169 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6171 if (pRange
->type
!= RPC_FC_RANGE
)
6173 ERR("invalid format type %x\n", pRange
->type
);
6174 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6177 base_type
= pRange
->flags_type
& 0xf;
6179 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6180 base_type
, pRange
->low_value
, pRange
->high_value
);
6182 #define RANGE_UNMARSHALL(type, format_spec) \
6185 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6186 if (!fMustAlloc && !*ppMemory) \
6187 fMustAlloc = TRUE; \
6189 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6190 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
6192 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6193 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6194 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6196 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
6197 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
6199 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6200 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
6201 (type)pRange->high_value); \
6202 RpcRaiseException(RPC_S_INVALID_BOUND); \
6205 TRACE("*ppMemory: %p\n", *ppMemory); \
6206 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
6207 pStubMsg->Buffer += sizeof(type); \
6214 RANGE_UNMARSHALL(UCHAR
, "%d");
6215 TRACE("value: 0x%02x\n", **ppMemory
);
6219 RANGE_UNMARSHALL(CHAR
, "%u");
6220 TRACE("value: 0x%02x\n", **ppMemory
);
6222 case RPC_FC_WCHAR
: /* FIXME: valid? */
6224 RANGE_UNMARSHALL(USHORT
, "%u");
6225 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6228 RANGE_UNMARSHALL(SHORT
, "%d");
6229 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6232 RANGE_UNMARSHALL(LONG
, "%d");
6233 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6236 RANGE_UNMARSHALL(ULONG
, "%u");
6237 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6241 FIXME("Unhandled enum type\n");
6243 case RPC_FC_ERROR_STATUS_T
: /* FIXME: valid? */
6248 ERR("invalid range base type: 0x%02x\n", base_type
);
6249 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6255 /***********************************************************************
6256 * NdrRangeBufferSize [internal]
6258 static void WINAPI
NdrRangeBufferSize(
6259 PMIDL_STUB_MESSAGE pStubMsg
,
6260 unsigned char *pMemory
,
6261 PFORMAT_STRING pFormat
)
6263 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
6264 unsigned char base_type
;
6266 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6268 if (pRange
->type
!= RPC_FC_RANGE
)
6270 ERR("invalid format type %x\n", pRange
->type
);
6271 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6273 base_type
= pRange
->flags_type
& 0xf;
6275 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &base_type
);
6278 /***********************************************************************
6279 * NdrRangeMemorySize [internal]
6281 static ULONG WINAPI
NdrRangeMemorySize(
6282 PMIDL_STUB_MESSAGE pStubMsg
,
6283 PFORMAT_STRING pFormat
)
6285 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
6286 unsigned char base_type
;
6288 if (pRange
->type
!= RPC_FC_RANGE
)
6290 ERR("invalid format type %x\n", pRange
->type
);
6291 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6294 base_type
= pRange
->flags_type
& 0xf;
6296 return NdrBaseTypeMemorySize(pStubMsg
, &base_type
);
6299 /***********************************************************************
6300 * NdrRangeFree [internal]
6302 static void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6303 unsigned char *pMemory
,
6304 PFORMAT_STRING pFormat
)
6306 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6311 /***********************************************************************
6312 * NdrBaseTypeMarshall [internal]
6314 static unsigned char *WINAPI
NdrBaseTypeMarshall(
6315 PMIDL_STUB_MESSAGE pStubMsg
,
6316 unsigned char *pMemory
,
6317 PFORMAT_STRING pFormat
)
6319 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6327 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(UCHAR
));
6328 TRACE("value: 0x%02x\n", *pMemory
);
6333 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(USHORT
));
6334 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(USHORT
));
6335 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
6339 case RPC_FC_ERROR_STATUS_T
:
6341 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(ULONG
));
6342 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONG
));
6343 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
6346 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(float));
6347 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
6350 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(double));
6351 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
6354 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(ULONGLONG
));
6355 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONGLONG
));
6356 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
6359 /* only 16-bits on the wire, so do a sanity check */
6360 if (*(UINT
*)pMemory
> SHRT_MAX
)
6361 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
6362 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(USHORT
));
6363 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6364 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6365 *(USHORT
*)pStubMsg
->Buffer
= *(UINT
*)pMemory
;
6366 pStubMsg
->Buffer
+= sizeof(USHORT
);
6367 TRACE("value: 0x%04x\n", *(UINT
*)pMemory
);
6372 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6375 /* FIXME: what is the correct return value? */
6379 /***********************************************************************
6380 * NdrBaseTypeUnmarshall [internal]
6382 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(
6383 PMIDL_STUB_MESSAGE pStubMsg
,
6384 unsigned char **ppMemory
,
6385 PFORMAT_STRING pFormat
,
6386 unsigned char fMustAlloc
)
6388 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6390 #define BASE_TYPE_UNMARSHALL(type) \
6391 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6392 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6394 *ppMemory = pStubMsg->Buffer; \
6395 TRACE("*ppMemory: %p\n", *ppMemory); \
6396 safe_buffer_increment(pStubMsg, sizeof(type)); \
6401 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6402 TRACE("*ppMemory: %p\n", *ppMemory); \
6403 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6412 BASE_TYPE_UNMARSHALL(UCHAR
);
6413 TRACE("value: 0x%02x\n", **ppMemory
);
6418 BASE_TYPE_UNMARSHALL(USHORT
);
6419 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6423 case RPC_FC_ERROR_STATUS_T
:
6425 BASE_TYPE_UNMARSHALL(ULONG
);
6426 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6429 BASE_TYPE_UNMARSHALL(float);
6430 TRACE("value: %f\n", **(float **)ppMemory
);
6433 BASE_TYPE_UNMARSHALL(double);
6434 TRACE("value: %f\n", **(double **)ppMemory
);
6437 BASE_TYPE_UNMARSHALL(ULONGLONG
);
6438 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG
**)ppMemory
));
6441 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
6442 if (!fMustAlloc
&& !*ppMemory
)
6445 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT
));
6446 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > pStubMsg
->BufferEnd
)
6447 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6448 TRACE("*ppMemory: %p\n", *ppMemory
);
6449 /* 16-bits on the wire, but int in memory */
6450 **(UINT
**)ppMemory
= *(USHORT
*)pStubMsg
->Buffer
;
6451 pStubMsg
->Buffer
+= sizeof(USHORT
);
6452 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
6457 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6459 #undef BASE_TYPE_UNMARSHALL
6461 /* FIXME: what is the correct return value? */
6466 /***********************************************************************
6467 * NdrBaseTypeBufferSize [internal]
6469 static void WINAPI
NdrBaseTypeBufferSize(
6470 PMIDL_STUB_MESSAGE pStubMsg
,
6471 unsigned char *pMemory
,
6472 PFORMAT_STRING pFormat
)
6474 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6482 safe_buffer_length_increment(pStubMsg
, sizeof(UCHAR
));
6488 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(USHORT
));
6489 safe_buffer_length_increment(pStubMsg
, sizeof(USHORT
));
6494 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONG
));
6495 safe_buffer_length_increment(pStubMsg
, sizeof(ULONG
));
6498 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(float));
6499 safe_buffer_length_increment(pStubMsg
, sizeof(float));
6502 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(double));
6503 safe_buffer_length_increment(pStubMsg
, sizeof(double));
6506 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONGLONG
));
6507 safe_buffer_length_increment(pStubMsg
, sizeof(ULONGLONG
));
6509 case RPC_FC_ERROR_STATUS_T
:
6510 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(error_status_t
));
6511 safe_buffer_length_increment(pStubMsg
, sizeof(error_status_t
));
6516 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6520 /***********************************************************************
6521 * NdrBaseTypeMemorySize [internal]
6523 static ULONG WINAPI
NdrBaseTypeMemorySize(
6524 PMIDL_STUB_MESSAGE pStubMsg
,
6525 PFORMAT_STRING pFormat
)
6527 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg
, *pFormat
);
6535 safe_buffer_increment(pStubMsg
, sizeof(UCHAR
));
6536 pStubMsg
->MemorySize
+= sizeof(UCHAR
);
6537 return sizeof(UCHAR
);
6541 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6542 pStubMsg
->MemorySize
+= sizeof(USHORT
);
6543 return sizeof(USHORT
);
6547 safe_buffer_increment(pStubMsg
, sizeof(ULONG
));
6548 pStubMsg
->MemorySize
+= sizeof(ULONG
);
6549 return sizeof(ULONG
);
6551 safe_buffer_increment(pStubMsg
, sizeof(float));
6552 pStubMsg
->MemorySize
+= sizeof(float);
6553 return sizeof(float);
6555 safe_buffer_increment(pStubMsg
, sizeof(double));
6556 pStubMsg
->MemorySize
+= sizeof(double);
6557 return sizeof(double);
6559 safe_buffer_increment(pStubMsg
, sizeof(ULONGLONG
));
6560 pStubMsg
->MemorySize
+= sizeof(ULONGLONG
);
6561 return sizeof(ULONGLONG
);
6562 case RPC_FC_ERROR_STATUS_T
:
6563 safe_buffer_increment(pStubMsg
, sizeof(error_status_t
));
6564 pStubMsg
->MemorySize
+= sizeof(error_status_t
);
6565 return sizeof(error_status_t
);
6567 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6568 pStubMsg
->MemorySize
+= sizeof(UINT
);
6569 return sizeof(UINT
);
6571 pStubMsg
->MemorySize
+= sizeof(void *);
6572 return sizeof(void *);
6574 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6579 /***********************************************************************
6580 * NdrBaseTypeFree [internal]
6582 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6583 unsigned char *pMemory
,
6584 PFORMAT_STRING pFormat
)
6586 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6591 /***********************************************************************
6592 * NdrContextHandleBufferSize [internal]
6594 static void WINAPI
NdrContextHandleBufferSize(
6595 PMIDL_STUB_MESSAGE pStubMsg
,
6596 unsigned char *pMemory
,
6597 PFORMAT_STRING pFormat
)
6599 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6601 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6603 ERR("invalid format type %x\n", *pFormat
);
6604 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6606 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
6607 safe_buffer_length_increment(pStubMsg
, cbNDRContext
);
6610 /***********************************************************************
6611 * NdrContextHandleMarshall [internal]
6613 static unsigned char *WINAPI
NdrContextHandleMarshall(
6614 PMIDL_STUB_MESSAGE pStubMsg
,
6615 unsigned char *pMemory
,
6616 PFORMAT_STRING pFormat
)
6618 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6620 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6622 ERR("invalid format type %x\n", *pFormat
);
6623 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6625 TRACE("flags: 0x%02x\n", pFormat
[1]);
6627 if (pFormat
[1] & 0x80)
6628 NdrClientContextMarshall(pStubMsg
, *(NDR_CCONTEXT
**)pMemory
, FALSE
);
6630 NdrClientContextMarshall(pStubMsg
, (NDR_CCONTEXT
*)pMemory
, FALSE
);
6635 /***********************************************************************
6636 * NdrContextHandleUnmarshall [internal]
6638 static unsigned char *WINAPI
NdrContextHandleUnmarshall(
6639 PMIDL_STUB_MESSAGE pStubMsg
,
6640 unsigned char **ppMemory
,
6641 PFORMAT_STRING pFormat
,
6642 unsigned char fMustAlloc
)
6644 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg
,
6645 ppMemory
, pFormat
, fMustAlloc
? "TRUE": "FALSE");
6647 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6649 ERR("invalid format type %x\n", *pFormat
);
6650 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6652 TRACE("flags: 0x%02x\n", pFormat
[1]);
6654 /* [out]-only or [ret] param */
6655 if ((pFormat
[1] & 0x60) == 0x20)
6656 **(NDR_CCONTEXT
**)ppMemory
= NULL
;
6657 NdrClientContextUnmarshall(pStubMsg
, *(NDR_CCONTEXT
**)ppMemory
, pStubMsg
->RpcMsg
->Handle
);
6662 /***********************************************************************
6663 * NdrClientContextMarshall [RPCRT4.@]
6665 void WINAPI
NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6666 NDR_CCONTEXT ContextHandle
,
6669 TRACE("(%p, %p, %d)\n", pStubMsg
, ContextHandle
, fCheck
);
6671 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
6673 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6675 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6676 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6677 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6680 /* FIXME: what does fCheck do? */
6681 NDRCContextMarshall(ContextHandle
,
6684 pStubMsg
->Buffer
+= cbNDRContext
;
6687 /***********************************************************************
6688 * NdrClientContextUnmarshall [RPCRT4.@]
6690 void WINAPI
NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6691 NDR_CCONTEXT
* pContextHandle
,
6692 RPC_BINDING_HANDLE BindHandle
)
6694 TRACE("(%p, %p, %p)\n", pStubMsg
, pContextHandle
, BindHandle
);
6696 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6698 if (pStubMsg
->Buffer
+ cbNDRContext
> pStubMsg
->BufferEnd
)
6699 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6701 NDRCContextUnmarshall(pContextHandle
,
6704 pStubMsg
->RpcMsg
->DataRepresentation
);
6706 pStubMsg
->Buffer
+= cbNDRContext
;
6709 void WINAPI
NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6710 NDR_SCONTEXT ContextHandle
,
6711 NDR_RUNDOWN RundownRoutine
)
6713 TRACE("(%p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
);
6715 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6717 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6719 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6720 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6721 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6724 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
6725 pStubMsg
->Buffer
, RundownRoutine
, NULL
,
6726 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
6727 pStubMsg
->Buffer
+= cbNDRContext
;
6730 NDR_SCONTEXT WINAPI
NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
)
6732 NDR_SCONTEXT ContextHandle
;
6734 TRACE("(%p)\n", pStubMsg
);
6736 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6738 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6740 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6741 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6742 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6745 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
6747 pStubMsg
->RpcMsg
->DataRepresentation
,
6748 NULL
, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
6749 pStubMsg
->Buffer
+= cbNDRContext
;
6751 return ContextHandle
;
6754 void WINAPI
NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg
,
6755 unsigned char* pMemory
,
6756 PFORMAT_STRING pFormat
)
6758 FIXME("(%p, %p, %p): stub\n", pStubMsg
, pMemory
, pFormat
);
6761 NDR_SCONTEXT WINAPI
NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg
,
6762 PFORMAT_STRING pFormat
)
6764 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6765 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6767 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
6769 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
6770 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
6771 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
6772 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
6773 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
6775 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
6776 if_id
= &sif
->InterfaceId
;
6779 return NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
, NULL
,
6780 pStubMsg
->RpcMsg
->DataRepresentation
, if_id
,
6784 void WINAPI
NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6785 NDR_SCONTEXT ContextHandle
,
6786 NDR_RUNDOWN RundownRoutine
,
6787 PFORMAT_STRING pFormat
)
6789 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6790 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6792 TRACE("(%p, %p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
, pFormat
);
6794 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6796 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6798 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6799 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6800 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6803 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
6804 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
6805 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
6806 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
6807 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
6809 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
6810 if_id
= &sif
->InterfaceId
;
6813 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
6814 pStubMsg
->Buffer
, RundownRoutine
, if_id
, flags
);
6815 pStubMsg
->Buffer
+= cbNDRContext
;
6818 NDR_SCONTEXT WINAPI
NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6819 PFORMAT_STRING pFormat
)
6821 NDR_SCONTEXT ContextHandle
;
6822 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6823 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6825 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
6827 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6829 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6831 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6832 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6833 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6836 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
6837 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
6838 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
6839 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
6840 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
6842 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
6843 if_id
= &sif
->InterfaceId
;
6846 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
6848 pStubMsg
->RpcMsg
->DataRepresentation
,
6850 pStubMsg
->Buffer
+= cbNDRContext
;
6852 return ContextHandle
;
6855 /***********************************************************************
6856 * NdrCorrelationInitialize [RPCRT4.@]
6858 * Initializes correlation validity checking.
6861 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6862 * pMemory [I] Pointer to memory to use as a cache.
6863 * CacheSize [I] Size of the memory pointed to by pMemory.
6864 * Flags [I] Reserved. Set to zero.
6869 void WINAPI
NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg
, void *pMemory
, ULONG CacheSize
, ULONG Flags
)
6871 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg
, pMemory
, CacheSize
, Flags
);
6872 pStubMsg
->fHasNewCorrDesc
= TRUE
;
6875 /***********************************************************************
6876 * NdrCorrelationPass [RPCRT4.@]
6878 * Performs correlation validity checking.
6881 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6886 void WINAPI
NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg
)
6888 FIXME("(%p): stub\n", pStubMsg
);
6891 /***********************************************************************
6892 * NdrCorrelationFree [RPCRT4.@]
6894 * Frees any resources used while unmarshalling parameters that need
6895 * correlation validity checking.
6898 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6903 void WINAPI
NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg
)
6905 FIXME("(%p): stub\n", pStubMsg
);