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)), \
62 (uint32)) /* allow as r-value */
64 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
66 MAKEWORD(*(pchar), *((pchar)+1)), \
67 MAKEWORD(*((pchar)+2), *((pchar)+3))))
70 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
71 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
72 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
73 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
74 *(pchar) = HIBYTE(HIWORD(uint32)), \
75 (uint32)) /* allow as r-value */
77 #define BIG_ENDIAN_UINT32_READ(pchar) \
79 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
80 MAKEWORD(*((pchar)+1), *(pchar))))
82 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
83 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
84 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
85 # define NDR_LOCAL_UINT32_READ(pchar) \
86 BIG_ENDIAN_UINT32_READ(pchar)
88 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
89 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
90 # define NDR_LOCAL_UINT32_READ(pchar) \
91 LITTLE_ENDIAN_UINT32_READ(pchar)
94 /* _Align must be the desired alignment,
95 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
96 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
97 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
98 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
99 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
100 #define ALIGN_POINTER_CLEAR(_Ptr, _Align) \
102 memset((_Ptr), 0, ((_Align) - (ULONG_PTR)(_Ptr)) & ((_Align) - 1)); \
103 ALIGN_POINTER(_Ptr, _Align); \
106 #define STD_OVERFLOW_CHECK(_Msg) do { \
107 TRACE("buffer=%d/%d\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
108 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
109 ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
112 #define NDR_POINTER_ID_BASE 0x20000
113 #define NDR_POINTER_ID(pStubMsg) (NDR_POINTER_ID_BASE + ((pStubMsg)->UniquePtrCount++) * 4)
114 #define NDR_TABLE_SIZE 128
115 #define NDR_TABLE_MASK 127
117 static unsigned char *WINAPI
NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
118 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
119 static void WINAPI
NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
120 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
121 static ULONG WINAPI
NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
123 static unsigned char *WINAPI
NdrContextHandleMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
124 static void WINAPI
NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
125 static unsigned char *WINAPI
NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
127 const NDR_MARSHALL NdrMarshaller
[NDR_TABLE_SIZE
] = {
129 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
130 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
131 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
132 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
136 NdrPointerMarshall
, NdrPointerMarshall
,
137 NdrPointerMarshall
, NdrPointerMarshall
,
139 NdrSimpleStructMarshall
, NdrSimpleStructMarshall
,
140 NdrConformantStructMarshall
, NdrConformantStructMarshall
,
141 NdrConformantVaryingStructMarshall
,
142 NdrComplexStructMarshall
,
144 NdrConformantArrayMarshall
,
145 NdrConformantVaryingArrayMarshall
,
146 NdrFixedArrayMarshall
, NdrFixedArrayMarshall
,
147 NdrVaryingArrayMarshall
, NdrVaryingArrayMarshall
,
148 NdrComplexArrayMarshall
,
150 NdrConformantStringMarshall
, 0, 0,
151 NdrConformantStringMarshall
,
152 NdrNonConformantStringMarshall
, 0, 0, 0,
154 NdrEncapsulatedUnionMarshall
,
155 NdrNonEncapsulatedUnionMarshall
,
156 NdrByteCountPointerMarshall
,
157 NdrXmitOrRepAsMarshall
, NdrXmitOrRepAsMarshall
,
159 NdrInterfacePointerMarshall
,
161 NdrContextHandleMarshall
,
164 NdrUserMarshalMarshall
,
169 const NDR_UNMARSHALL NdrUnmarshaller
[NDR_TABLE_SIZE
] = {
171 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
172 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
173 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
174 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
176 NdrBaseTypeUnmarshall
,
178 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
179 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
181 NdrSimpleStructUnmarshall
, NdrSimpleStructUnmarshall
,
182 NdrConformantStructUnmarshall
, NdrConformantStructUnmarshall
,
183 NdrConformantVaryingStructUnmarshall
,
184 NdrComplexStructUnmarshall
,
186 NdrConformantArrayUnmarshall
,
187 NdrConformantVaryingArrayUnmarshall
,
188 NdrFixedArrayUnmarshall
, NdrFixedArrayUnmarshall
,
189 NdrVaryingArrayUnmarshall
, NdrVaryingArrayUnmarshall
,
190 NdrComplexArrayUnmarshall
,
192 NdrConformantStringUnmarshall
, 0, 0,
193 NdrConformantStringUnmarshall
,
194 NdrNonConformantStringUnmarshall
, 0, 0, 0,
196 NdrEncapsulatedUnionUnmarshall
,
197 NdrNonEncapsulatedUnionUnmarshall
,
198 NdrByteCountPointerUnmarshall
,
199 NdrXmitOrRepAsUnmarshall
, NdrXmitOrRepAsUnmarshall
,
201 NdrInterfacePointerUnmarshall
,
203 NdrContextHandleUnmarshall
,
206 NdrUserMarshalUnmarshall
,
211 const NDR_BUFFERSIZE NdrBufferSizer
[NDR_TABLE_SIZE
] = {
213 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
214 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
215 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
216 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
218 NdrBaseTypeBufferSize
,
220 NdrPointerBufferSize
, NdrPointerBufferSize
,
221 NdrPointerBufferSize
, NdrPointerBufferSize
,
223 NdrSimpleStructBufferSize
, NdrSimpleStructBufferSize
,
224 NdrConformantStructBufferSize
, NdrConformantStructBufferSize
,
225 NdrConformantVaryingStructBufferSize
,
226 NdrComplexStructBufferSize
,
228 NdrConformantArrayBufferSize
,
229 NdrConformantVaryingArrayBufferSize
,
230 NdrFixedArrayBufferSize
, NdrFixedArrayBufferSize
,
231 NdrVaryingArrayBufferSize
, NdrVaryingArrayBufferSize
,
232 NdrComplexArrayBufferSize
,
234 NdrConformantStringBufferSize
, 0, 0,
235 NdrConformantStringBufferSize
,
236 NdrNonConformantStringBufferSize
, 0, 0, 0,
238 NdrEncapsulatedUnionBufferSize
,
239 NdrNonEncapsulatedUnionBufferSize
,
240 NdrByteCountPointerBufferSize
,
241 NdrXmitOrRepAsBufferSize
, NdrXmitOrRepAsBufferSize
,
243 NdrInterfacePointerBufferSize
,
245 NdrContextHandleBufferSize
,
248 NdrUserMarshalBufferSize
,
253 const NDR_MEMORYSIZE NdrMemorySizer
[NDR_TABLE_SIZE
] = {
255 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
256 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
257 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
258 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
260 NdrBaseTypeMemorySize
,
262 NdrPointerMemorySize
, NdrPointerMemorySize
,
263 NdrPointerMemorySize
, NdrPointerMemorySize
,
265 NdrSimpleStructMemorySize
, NdrSimpleStructMemorySize
,
266 NdrConformantStructMemorySize
, NdrConformantStructMemorySize
,
267 NdrConformantVaryingStructMemorySize
,
268 NdrComplexStructMemorySize
,
270 NdrConformantArrayMemorySize
,
271 NdrConformantVaryingArrayMemorySize
,
272 NdrFixedArrayMemorySize
, NdrFixedArrayMemorySize
,
273 NdrVaryingArrayMemorySize
, NdrVaryingArrayMemorySize
,
274 NdrComplexArrayMemorySize
,
276 NdrConformantStringMemorySize
, 0, 0,
277 NdrConformantStringMemorySize
,
278 NdrNonConformantStringMemorySize
, 0, 0, 0,
280 NdrEncapsulatedUnionMemorySize
,
281 NdrNonEncapsulatedUnionMemorySize
,
282 NdrByteCountPointerMemorySize
,
283 NdrXmitOrRepAsMemorySize
, NdrXmitOrRepAsMemorySize
,
285 NdrInterfacePointerMemorySize
,
290 NdrUserMarshalMemorySize
,
295 const NDR_FREE NdrFreer
[NDR_TABLE_SIZE
] = {
297 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
298 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
299 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
300 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
304 NdrPointerFree
, NdrPointerFree
,
305 NdrPointerFree
, NdrPointerFree
,
307 NdrSimpleStructFree
, NdrSimpleStructFree
,
308 NdrConformantStructFree
, NdrConformantStructFree
,
309 NdrConformantVaryingStructFree
,
310 NdrComplexStructFree
,
312 NdrConformantArrayFree
,
313 NdrConformantVaryingArrayFree
,
314 NdrFixedArrayFree
, NdrFixedArrayFree
,
315 NdrVaryingArrayFree
, NdrVaryingArrayFree
,
321 NdrEncapsulatedUnionFree
,
322 NdrNonEncapsulatedUnionFree
,
324 NdrXmitOrRepAsFree
, NdrXmitOrRepAsFree
,
326 NdrInterfacePointerFree
,
337 typedef struct _NDR_MEMORY_LIST
342 struct _NDR_MEMORY_LIST
*next
;
345 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
347 /***********************************************************************
348 * NdrAllocate [RPCRT4.@]
350 * Allocates a block of memory using pStubMsg->pfnAllocate.
353 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
354 * len [I] Size of memory block to allocate.
357 * The memory block of size len that was allocated.
360 * The memory block is always 8-byte aligned.
361 * If the function is unable to allocate memory an ERROR_OUTOFMEMORY
362 * exception is raised.
364 void * WINAPI
NdrAllocate(MIDL_STUB_MESSAGE
*pStubMsg
, SIZE_T len
)
369 NDR_MEMORY_LIST
*mem_list
;
371 aligned_len
= ALIGNED_LENGTH(len
, 8);
372 adjusted_len
= aligned_len
+ sizeof(NDR_MEMORY_LIST
);
373 /* check for overflow */
374 if (adjusted_len
< len
)
376 ERR("overflow of adjusted_len %ld, len %ld\n", adjusted_len
, len
);
377 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
380 p
= pStubMsg
->pfnAllocate(adjusted_len
);
381 if (!p
) RpcRaiseException(ERROR_OUTOFMEMORY
);
383 mem_list
= (NDR_MEMORY_LIST
*)((char *)p
+ aligned_len
);
384 mem_list
->magic
= MEML_MAGIC
;
385 mem_list
->size
= aligned_len
;
386 mem_list
->reserved
= 0;
387 mem_list
->next
= pStubMsg
->pMemoryList
;
388 pStubMsg
->pMemoryList
= mem_list
;
394 static void WINAPI
NdrFree(MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *Pointer
)
396 TRACE("(%p, %p)\n", pStubMsg
, Pointer
);
398 pStubMsg
->pfnFree(Pointer
);
401 static inline BOOL
IsConformanceOrVariancePresent(PFORMAT_STRING pFormat
)
403 return (*(const ULONG
*)pFormat
!= -1);
406 static PFORMAT_STRING
ReadConformance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
)
408 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
409 if (pStubMsg
->Buffer
+ 4 > pStubMsg
->BufferEnd
)
410 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
411 pStubMsg
->MaxCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
412 pStubMsg
->Buffer
+= 4;
413 TRACE("unmarshalled conformance is %ld\n", pStubMsg
->MaxCount
);
414 if (pStubMsg
->fHasNewCorrDesc
)
420 static inline PFORMAT_STRING
ReadVariance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
, ULONG MaxValue
)
422 if (pFormat
&& !IsConformanceOrVariancePresent(pFormat
))
424 pStubMsg
->Offset
= 0;
425 pStubMsg
->ActualCount
= pStubMsg
->MaxCount
;
429 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
430 if (pStubMsg
->Buffer
+ 8 > pStubMsg
->BufferEnd
)
431 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
432 pStubMsg
->Offset
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
433 pStubMsg
->Buffer
+= 4;
434 TRACE("offset is %d\n", pStubMsg
->Offset
);
435 pStubMsg
->ActualCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
436 pStubMsg
->Buffer
+= 4;
437 TRACE("variance is %d\n", pStubMsg
->ActualCount
);
439 if ((pStubMsg
->ActualCount
> MaxValue
) ||
440 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> MaxValue
))
442 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
443 pStubMsg
->ActualCount
, pStubMsg
->Offset
, MaxValue
);
444 RpcRaiseException(RPC_S_INVALID_BOUND
);
449 if (pStubMsg
->fHasNewCorrDesc
)
455 /* writes the conformance value to the buffer */
456 static inline void WriteConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
458 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
459 if (pStubMsg
->Buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
460 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
461 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->MaxCount
);
462 pStubMsg
->Buffer
+= 4;
465 /* writes the variance values to the buffer */
466 static inline void WriteVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
468 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
469 if (pStubMsg
->Buffer
+ 8 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
470 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
471 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->Offset
);
472 pStubMsg
->Buffer
+= 4;
473 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->ActualCount
);
474 pStubMsg
->Buffer
+= 4;
477 /* requests buffer space for the conformance value */
478 static inline void SizeConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
480 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
481 if (pStubMsg
->BufferLength
+ 4 < pStubMsg
->BufferLength
)
482 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
483 pStubMsg
->BufferLength
+= 4;
486 /* requests buffer space for the variance values */
487 static inline void SizeVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
489 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
490 if (pStubMsg
->BufferLength
+ 8 < pStubMsg
->BufferLength
)
491 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
492 pStubMsg
->BufferLength
+= 8;
495 PFORMAT_STRING
ComputeConformanceOrVariance(
496 MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *pMemory
,
497 PFORMAT_STRING pFormat
, ULONG_PTR def
, ULONG_PTR
*pCount
)
499 BYTE dtype
= pFormat
[0] & 0xf;
500 short ofs
= *(const short *)&pFormat
[2];
504 if (!IsConformanceOrVariancePresent(pFormat
)) {
505 /* null descriptor */
510 switch (pFormat
[0] & 0xf0) {
511 case RPC_FC_NORMAL_CONFORMANCE
:
512 TRACE("normal conformance, ofs=%d\n", ofs
);
515 case RPC_FC_POINTER_CONFORMANCE
:
516 TRACE("pointer conformance, ofs=%d\n", ofs
);
517 ptr
= pStubMsg
->Memory
;
519 case RPC_FC_TOP_LEVEL_CONFORMANCE
:
520 TRACE("toplevel conformance, ofs=%d\n", ofs
);
521 if (pStubMsg
->StackTop
) {
522 ptr
= pStubMsg
->StackTop
;
525 /* -Os mode, *pCount is already set */
529 case RPC_FC_CONSTANT_CONFORMANCE
:
530 data
= ofs
| ((DWORD
)pFormat
[1] << 16);
531 TRACE("constant conformance, val=%d\n", data
);
534 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE
:
535 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs
);
536 if (pStubMsg
->StackTop
) {
537 ptr
= pStubMsg
->StackTop
;
545 FIXME("unknown conformance type %x\n", pFormat
[0] & 0xf0);
548 switch (pFormat
[1]) {
549 case RPC_FC_DEREFERENCE
:
550 ptr
= *(LPVOID
*)((char *)ptr
+ ofs
);
552 case RPC_FC_CALLBACK
:
554 unsigned char *old_stack_top
= pStubMsg
->StackTop
;
555 pStubMsg
->StackTop
= ptr
;
557 /* ofs is index into StubDesc->apfnExprEval */
558 TRACE("callback conformance into apfnExprEval[%d]\n", ofs
);
559 pStubMsg
->StubDesc
->apfnExprEval
[ofs
](pStubMsg
);
561 pStubMsg
->StackTop
= old_stack_top
;
563 /* the callback function always stores the computed value in MaxCount */
564 *pCount
= pStubMsg
->MaxCount
;
568 ptr
= (char *)ptr
+ ofs
;
581 data
= *(USHORT
*)ptr
;
592 FIXME("unknown conformance data type %x\n", dtype
);
595 TRACE("dereferenced data type %x at %p, got %d\n", dtype
, ptr
, data
);
598 switch (pFormat
[1]) {
599 case RPC_FC_DEREFERENCE
: /* already handled */
616 FIXME("unknown conformance op %d\n", pFormat
[1]);
621 TRACE("resulting conformance is %ld\n", *pCount
);
622 if (pStubMsg
->fHasNewCorrDesc
)
628 static inline PFORMAT_STRING
SkipConformance(PMIDL_STUB_MESSAGE pStubMsg
,
629 PFORMAT_STRING pFormat
)
631 if (IsConformanceOrVariancePresent(pFormat
))
633 if (pStubMsg
->fHasNewCorrDesc
)
641 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
642 * the result overflows 32-bits */
643 static inline ULONG
safe_multiply(ULONG a
, ULONG b
)
645 ULONGLONG ret
= (ULONGLONG
)a
* b
;
646 if (ret
> 0xffffffff)
648 RpcRaiseException(RPC_S_INVALID_BOUND
);
654 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
656 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
657 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
658 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
659 pStubMsg
->Buffer
+= size
;
662 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
664 if (pStubMsg
->BufferLength
+ size
< pStubMsg
->BufferLength
) /* integer overflow of pStubMsg->BufferSize */
666 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
667 pStubMsg
->BufferLength
, size
);
668 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
670 pStubMsg
->BufferLength
+= size
;
673 /* copies data from the buffer, checking that there is enough data in the buffer
675 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, void *p
, ULONG size
)
677 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
678 (pStubMsg
->Buffer
+ size
> pStubMsg
->BufferEnd
))
680 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
681 pStubMsg
->Buffer
, pStubMsg
->BufferEnd
, size
);
682 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
684 if (p
== pStubMsg
->Buffer
)
685 ERR("pointer is the same as the buffer\n");
686 memcpy(p
, pStubMsg
->Buffer
, size
);
687 pStubMsg
->Buffer
+= size
;
690 /* copies data to the buffer, checking that there is enough space to do so */
691 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, const void *p
, ULONG size
)
693 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
694 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
696 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
697 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
,
699 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
701 memcpy(pStubMsg
->Buffer
, p
, size
);
702 pStubMsg
->Buffer
+= size
;
705 /* verify that string data sitting in the buffer is valid and safe to
707 static void validate_string_data(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG bufsize
, ULONG esize
)
711 /* verify the buffer is safe to access */
712 if ((pStubMsg
->Buffer
+ bufsize
< pStubMsg
->Buffer
) ||
713 (pStubMsg
->Buffer
+ bufsize
> pStubMsg
->BufferEnd
))
715 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize
,
716 pStubMsg
->BufferEnd
, pStubMsg
->Buffer
);
717 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
720 /* strings must always have null terminating bytes */
723 ERR("invalid string length of %d\n", bufsize
/ esize
);
724 RpcRaiseException(RPC_S_INVALID_BOUND
);
727 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
728 if (pStubMsg
->Buffer
[i
] != 0)
730 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
731 i
, pStubMsg
->Buffer
[i
]);
732 RpcRaiseException(RPC_S_INVALID_BOUND
);
736 static inline void dump_pointer_attr(unsigned char attr
)
738 if (attr
& RPC_FC_P_ALLOCALLNODES
)
739 TRACE(" RPC_FC_P_ALLOCALLNODES");
740 if (attr
& RPC_FC_P_DONTFREE
)
741 TRACE(" RPC_FC_P_DONTFREE");
742 if (attr
& RPC_FC_P_ONSTACK
)
743 TRACE(" RPC_FC_P_ONSTACK");
744 if (attr
& RPC_FC_P_SIMPLEPOINTER
)
745 TRACE(" RPC_FC_P_SIMPLEPOINTER");
746 if (attr
& RPC_FC_P_DEREF
)
747 TRACE(" RPC_FC_P_DEREF");
751 /***********************************************************************
752 * PointerMarshall [internal]
754 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
755 unsigned char *Buffer
,
756 unsigned char *Pointer
,
757 PFORMAT_STRING pFormat
)
759 unsigned type
= pFormat
[0], attr
= pFormat
[1];
763 int pointer_needs_marshaling
;
765 TRACE("(%p,%p,%p,%p)\n", pStubMsg
, Buffer
, Pointer
, pFormat
);
766 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
768 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
769 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
772 case RPC_FC_RP
: /* ref pointer (always non-null) */
775 ERR("NULL ref pointer is not allowed\n");
776 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
778 pointer_needs_marshaling
= 1;
780 case RPC_FC_UP
: /* unique pointer */
781 case RPC_FC_OP
: /* object pointer - same as unique here */
783 pointer_needs_marshaling
= 1;
785 pointer_needs_marshaling
= 0;
786 pointer_id
= Pointer
? NDR_POINTER_ID(pStubMsg
) : 0;
787 TRACE("writing 0x%08x to buffer\n", pointer_id
);
788 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
791 pointer_needs_marshaling
= !NdrFullPointerQueryPointer(
792 pStubMsg
->FullPtrXlatTables
, Pointer
, 1, &pointer_id
);
793 TRACE("writing 0x%08x to buffer\n", pointer_id
);
794 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
797 FIXME("unhandled ptr type=%02x\n", type
);
798 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
802 TRACE("calling marshaller for type 0x%x\n", (int)*desc
);
804 if (pointer_needs_marshaling
) {
805 if (attr
& RPC_FC_P_DEREF
) {
806 Pointer
= *(unsigned char**)Pointer
;
807 TRACE("deref => %p\n", Pointer
);
809 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
810 if (m
) m(pStubMsg
, Pointer
, desc
);
811 else FIXME("no marshaller for data type=%02x\n", *desc
);
814 STD_OVERFLOW_CHECK(pStubMsg
);
817 /***********************************************************************
818 * PointerUnmarshall [internal]
820 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
821 unsigned char *Buffer
,
822 unsigned char **pPointer
,
823 unsigned char *pSrcPointer
,
824 PFORMAT_STRING pFormat
,
825 unsigned char fMustAlloc
)
827 unsigned type
= pFormat
[0], attr
= pFormat
[1];
830 DWORD pointer_id
= 0;
831 int pointer_needs_unmarshaling
;
833 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg
, Buffer
, pPointer
, pSrcPointer
, pFormat
, fMustAlloc
);
834 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
836 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
837 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
840 case RPC_FC_RP
: /* ref pointer (always non-null) */
841 pointer_needs_unmarshaling
= 1;
843 case RPC_FC_UP
: /* unique pointer */
844 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
845 TRACE("pointer_id is 0x%08x\n", pointer_id
);
847 pointer_needs_unmarshaling
= 1;
850 pointer_needs_unmarshaling
= 0;
853 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
854 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
855 TRACE("pointer_id is 0x%08x\n", pointer_id
);
856 if (!fMustAlloc
&& pSrcPointer
)
858 FIXME("free object pointer %p\n", pSrcPointer
);
862 pointer_needs_unmarshaling
= 1;
864 pointer_needs_unmarshaling
= 0;
867 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
868 TRACE("pointer_id is 0x%08x\n", pointer_id
);
869 pointer_needs_unmarshaling
= !NdrFullPointerQueryRefId(
870 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, (void **)pPointer
);
873 FIXME("unhandled ptr type=%02x\n", type
);
874 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
878 if (pointer_needs_unmarshaling
) {
879 unsigned char *base_ptr_val
= *pPointer
;
880 unsigned char **current_ptr
= pPointer
;
881 if (pStubMsg
->IsClient
) {
883 /* if we aren't forcing allocation of memory then try to use the existing
884 * (source) pointer to unmarshall the data into so that [in,out]
885 * parameters behave correctly. it doesn't matter if the parameter is
886 * [out] only since in that case the pointer will be NULL. we force
887 * allocation when the source pointer is NULL here instead of in the type
888 * unmarshalling routine for the benefit of the deref code below */
891 TRACE("setting *pPointer to %p\n", pSrcPointer
);
892 *pPointer
= base_ptr_val
= pSrcPointer
;
898 /* the memory in a stub is never initialised, so we have to work out here
899 * whether we have to initialise it so we can use the optimisation of
900 * setting the pointer to the buffer, if possible, or set fMustAlloc to
902 if (attr
& RPC_FC_P_DEREF
) {
910 if (attr
& RPC_FC_P_ALLOCALLNODES
)
911 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
913 if (attr
& RPC_FC_P_DEREF
) {
915 base_ptr_val
= NdrAllocate(pStubMsg
, sizeof(void *));
916 *pPointer
= base_ptr_val
;
917 current_ptr
= (unsigned char **)base_ptr_val
;
919 current_ptr
= *(unsigned char***)current_ptr
;
920 TRACE("deref => %p\n", current_ptr
);
921 if (!fMustAlloc
&& !*current_ptr
) fMustAlloc
= TRUE
;
923 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
924 if (m
) m(pStubMsg
, current_ptr
, desc
, fMustAlloc
);
925 else FIXME("no unmarshaller for data type=%02x\n", *desc
);
927 if (type
== RPC_FC_FP
)
928 NdrFullPointerInsertRefId(pStubMsg
->FullPtrXlatTables
, pointer_id
,
932 TRACE("pointer=%p\n", *pPointer
);
935 /***********************************************************************
936 * PointerBufferSize [internal]
938 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
939 unsigned char *Pointer
,
940 PFORMAT_STRING pFormat
)
942 unsigned type
= pFormat
[0], attr
= pFormat
[1];
945 int pointer_needs_sizing
;
948 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
949 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
951 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
952 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
955 case RPC_FC_RP
: /* ref pointer (always non-null) */
958 ERR("NULL ref pointer is not allowed\n");
959 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
964 /* NULL pointer has no further representation */
969 pointer_needs_sizing
= !NdrFullPointerQueryPointer(
970 pStubMsg
->FullPtrXlatTables
, Pointer
, 0, &pointer_id
);
971 if (!pointer_needs_sizing
)
975 FIXME("unhandled ptr type=%02x\n", type
);
976 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
980 if (attr
& RPC_FC_P_DEREF
) {
981 Pointer
= *(unsigned char**)Pointer
;
982 TRACE("deref => %p\n", Pointer
);
985 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
986 if (m
) m(pStubMsg
, Pointer
, desc
);
987 else FIXME("no buffersizer for data type=%02x\n", *desc
);
990 /***********************************************************************
991 * PointerMemorySize [internal]
993 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
994 unsigned char *Buffer
,
995 PFORMAT_STRING pFormat
)
997 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1000 DWORD pointer_id
= 0;
1001 int pointer_needs_sizing
;
1003 TRACE("(%p,%p,%p)\n", pStubMsg
, Buffer
, pFormat
);
1004 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1006 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1007 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1010 case RPC_FC_RP
: /* ref pointer (always non-null) */
1011 pointer_needs_sizing
= 1;
1013 case RPC_FC_UP
: /* unique pointer */
1014 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
1015 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1016 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1018 pointer_needs_sizing
= 1;
1020 pointer_needs_sizing
= 0;
1025 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1026 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1027 pointer_needs_sizing
= !NdrFullPointerQueryRefId(
1028 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, &pointer
);
1032 FIXME("unhandled ptr type=%02x\n", type
);
1033 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1037 if (attr
& RPC_FC_P_DEREF
) {
1041 if (pointer_needs_sizing
) {
1042 m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
1043 if (m
) m(pStubMsg
, desc
);
1044 else FIXME("no memorysizer for data type=%02x\n", *desc
);
1047 return pStubMsg
->MemorySize
;
1050 /***********************************************************************
1051 * PointerFree [internal]
1053 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1054 unsigned char *Pointer
,
1055 PFORMAT_STRING pFormat
)
1057 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1058 PFORMAT_STRING desc
;
1060 unsigned char *current_pointer
= Pointer
;
1062 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1063 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1064 if (attr
& RPC_FC_P_DONTFREE
) return;
1066 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1067 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1069 if (!Pointer
) return;
1071 if (type
== RPC_FC_FP
) {
1072 int pointer_needs_freeing
= NdrFullPointerFree(
1073 pStubMsg
->FullPtrXlatTables
, Pointer
);
1074 if (!pointer_needs_freeing
)
1078 if (attr
& RPC_FC_P_DEREF
) {
1079 current_pointer
= *(unsigned char**)Pointer
;
1080 TRACE("deref => %p\n", current_pointer
);
1083 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
1084 if (m
) m(pStubMsg
, current_pointer
, desc
);
1086 /* this check stops us from trying to free buffer memory. we don't have to
1087 * worry about clients, since they won't call this function.
1088 * we don't have to check for the buffer being reallocated because
1089 * BufferStart and BufferEnd won't be reset when allocating memory for
1090 * sending the response. we don't have to check for the new buffer here as
1091 * it won't be used a type memory, only for buffer memory */
1092 if (Pointer
>= pStubMsg
->BufferStart
&& Pointer
< pStubMsg
->BufferEnd
)
1095 if (attr
& RPC_FC_P_ONSTACK
) {
1096 TRACE("not freeing stack ptr %p\n", Pointer
);
1099 TRACE("freeing %p\n", Pointer
);
1100 NdrFree(pStubMsg
, Pointer
);
1103 TRACE("not freeing %p\n", Pointer
);
1106 /***********************************************************************
1107 * EmbeddedPointerMarshall
1109 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1110 unsigned char *pMemory
,
1111 PFORMAT_STRING pFormat
)
1113 unsigned char *Mark
= pStubMsg
->BufferMark
;
1114 unsigned rep
, count
, stride
;
1116 unsigned char *saved_buffer
= NULL
;
1118 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1120 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1123 if (pStubMsg
->PointerBufferMark
)
1125 saved_buffer
= pStubMsg
->Buffer
;
1126 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1127 pStubMsg
->PointerBufferMark
= NULL
;
1130 while (pFormat
[0] != RPC_FC_END
) {
1131 switch (pFormat
[0]) {
1133 FIXME("unknown repeat type %d\n", pFormat
[0]);
1134 case RPC_FC_NO_REPEAT
:
1140 case RPC_FC_FIXED_REPEAT
:
1141 rep
= *(const WORD
*)&pFormat
[2];
1142 stride
= *(const WORD
*)&pFormat
[4];
1143 count
= *(const WORD
*)&pFormat
[8];
1146 case RPC_FC_VARIABLE_REPEAT
:
1147 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1148 stride
= *(const WORD
*)&pFormat
[2];
1149 count
= *(const WORD
*)&pFormat
[6];
1153 for (i
= 0; i
< rep
; i
++) {
1154 PFORMAT_STRING info
= pFormat
;
1155 unsigned char *membase
= pMemory
+ (i
* stride
);
1156 unsigned char *bufbase
= Mark
+ (i
* stride
);
1159 for (u
=0; u
<count
; u
++,info
+=8) {
1160 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1161 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1162 unsigned char *saved_memory
= pStubMsg
->Memory
;
1164 pStubMsg
->Memory
= pMemory
;
1165 PointerMarshall(pStubMsg
, bufptr
, *(unsigned char**)memptr
, info
+4);
1166 pStubMsg
->Memory
= saved_memory
;
1169 pFormat
+= 8 * count
;
1174 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1175 pStubMsg
->Buffer
= saved_buffer
;
1178 STD_OVERFLOW_CHECK(pStubMsg
);
1183 /***********************************************************************
1184 * EmbeddedPointerUnmarshall
1186 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1187 unsigned char *pDstBuffer
,
1188 unsigned char *pSrcMemoryPtrs
,
1189 PFORMAT_STRING pFormat
,
1190 unsigned char fMustAlloc
)
1192 unsigned char *Mark
= pStubMsg
->BufferMark
;
1193 unsigned rep
, count
, stride
;
1195 unsigned char *saved_buffer
= NULL
;
1197 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg
, pDstBuffer
, pSrcMemoryPtrs
, pFormat
, fMustAlloc
);
1199 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1202 if (pStubMsg
->PointerBufferMark
)
1204 saved_buffer
= pStubMsg
->Buffer
;
1205 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1206 pStubMsg
->PointerBufferMark
= NULL
;
1209 while (pFormat
[0] != RPC_FC_END
) {
1210 TRACE("pFormat[0] = 0x%x\n", pFormat
[0]);
1211 switch (pFormat
[0]) {
1213 FIXME("unknown repeat type %d\n", pFormat
[0]);
1214 case RPC_FC_NO_REPEAT
:
1220 case RPC_FC_FIXED_REPEAT
:
1221 rep
= *(const WORD
*)&pFormat
[2];
1222 stride
= *(const WORD
*)&pFormat
[4];
1223 count
= *(const WORD
*)&pFormat
[8];
1226 case RPC_FC_VARIABLE_REPEAT
:
1227 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1228 stride
= *(const WORD
*)&pFormat
[2];
1229 count
= *(const WORD
*)&pFormat
[6];
1233 for (i
= 0; i
< rep
; i
++) {
1234 PFORMAT_STRING info
= pFormat
;
1235 unsigned char *bufdstbase
= pDstBuffer
+ (i
* stride
);
1236 unsigned char *memsrcbase
= pSrcMemoryPtrs
+ (i
* stride
);
1237 unsigned char *bufbase
= Mark
+ (i
* stride
);
1240 for (u
=0; u
<count
; u
++,info
+=8) {
1241 unsigned char **bufdstptr
= (unsigned char **)(bufdstbase
+ *(const SHORT
*)&info
[2]);
1242 unsigned char **memsrcptr
= (unsigned char **)(memsrcbase
+ *(const SHORT
*)&info
[0]);
1243 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1244 PointerUnmarshall(pStubMsg
, bufptr
, bufdstptr
, *memsrcptr
, info
+4, fMustAlloc
);
1247 pFormat
+= 8 * count
;
1252 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1253 pStubMsg
->Buffer
= saved_buffer
;
1259 /***********************************************************************
1260 * EmbeddedPointerBufferSize
1262 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1263 unsigned char *pMemory
,
1264 PFORMAT_STRING pFormat
)
1266 unsigned rep
, count
, stride
;
1268 ULONG saved_buffer_length
= 0;
1270 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1272 if (pStubMsg
->IgnoreEmbeddedPointers
) return;
1274 if (*pFormat
!= RPC_FC_PP
) return;
1277 if (pStubMsg
->PointerLength
)
1279 saved_buffer_length
= pStubMsg
->BufferLength
;
1280 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
1281 pStubMsg
->PointerLength
= 0;
1284 while (pFormat
[0] != RPC_FC_END
) {
1285 switch (pFormat
[0]) {
1287 FIXME("unknown repeat type %d\n", pFormat
[0]);
1288 case RPC_FC_NO_REPEAT
:
1294 case RPC_FC_FIXED_REPEAT
:
1295 rep
= *(const WORD
*)&pFormat
[2];
1296 stride
= *(const WORD
*)&pFormat
[4];
1297 count
= *(const WORD
*)&pFormat
[8];
1300 case RPC_FC_VARIABLE_REPEAT
:
1301 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1302 stride
= *(const WORD
*)&pFormat
[2];
1303 count
= *(const WORD
*)&pFormat
[6];
1307 for (i
= 0; i
< rep
; i
++) {
1308 PFORMAT_STRING info
= pFormat
;
1309 unsigned char *membase
= pMemory
+ (i
* stride
);
1312 for (u
=0; u
<count
; u
++,info
+=8) {
1313 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1314 unsigned char *saved_memory
= pStubMsg
->Memory
;
1316 pStubMsg
->Memory
= pMemory
;
1317 PointerBufferSize(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1318 pStubMsg
->Memory
= saved_memory
;
1321 pFormat
+= 8 * count
;
1324 if (saved_buffer_length
)
1326 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
1327 pStubMsg
->BufferLength
= saved_buffer_length
;
1331 /***********************************************************************
1332 * EmbeddedPointerMemorySize [internal]
1334 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1335 PFORMAT_STRING pFormat
)
1337 unsigned char *Mark
= pStubMsg
->BufferMark
;
1338 unsigned rep
, count
, stride
;
1340 unsigned char *saved_buffer
= NULL
;
1342 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1344 if (pStubMsg
->IgnoreEmbeddedPointers
) return 0;
1346 if (pStubMsg
->PointerBufferMark
)
1348 saved_buffer
= pStubMsg
->Buffer
;
1349 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1350 pStubMsg
->PointerBufferMark
= NULL
;
1353 if (*pFormat
!= RPC_FC_PP
) return 0;
1356 while (pFormat
[0] != RPC_FC_END
) {
1357 switch (pFormat
[0]) {
1359 FIXME("unknown repeat type %d\n", pFormat
[0]);
1360 case RPC_FC_NO_REPEAT
:
1366 case RPC_FC_FIXED_REPEAT
:
1367 rep
= *(const WORD
*)&pFormat
[2];
1368 stride
= *(const WORD
*)&pFormat
[4];
1369 count
= *(const WORD
*)&pFormat
[8];
1372 case RPC_FC_VARIABLE_REPEAT
:
1373 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1374 stride
= *(const WORD
*)&pFormat
[2];
1375 count
= *(const WORD
*)&pFormat
[6];
1379 for (i
= 0; i
< rep
; i
++) {
1380 PFORMAT_STRING info
= pFormat
;
1381 unsigned char *bufbase
= Mark
+ (i
* stride
);
1383 for (u
=0; u
<count
; u
++,info
+=8) {
1384 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1385 PointerMemorySize(pStubMsg
, bufptr
, info
+4);
1388 pFormat
+= 8 * count
;
1393 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1394 pStubMsg
->Buffer
= saved_buffer
;
1400 /***********************************************************************
1401 * EmbeddedPointerFree [internal]
1403 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1404 unsigned char *pMemory
,
1405 PFORMAT_STRING pFormat
)
1407 unsigned rep
, count
, stride
;
1410 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1411 if (*pFormat
!= RPC_FC_PP
) return;
1414 while (pFormat
[0] != RPC_FC_END
) {
1415 switch (pFormat
[0]) {
1417 FIXME("unknown repeat type %d\n", pFormat
[0]);
1418 case RPC_FC_NO_REPEAT
:
1424 case RPC_FC_FIXED_REPEAT
:
1425 rep
= *(const WORD
*)&pFormat
[2];
1426 stride
= *(const WORD
*)&pFormat
[4];
1427 count
= *(const WORD
*)&pFormat
[8];
1430 case RPC_FC_VARIABLE_REPEAT
:
1431 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1432 stride
= *(const WORD
*)&pFormat
[2];
1433 count
= *(const WORD
*)&pFormat
[6];
1437 for (i
= 0; i
< rep
; i
++) {
1438 PFORMAT_STRING info
= pFormat
;
1439 unsigned char *membase
= pMemory
+ (i
* stride
);
1442 for (u
=0; u
<count
; u
++,info
+=8) {
1443 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1444 unsigned char *saved_memory
= pStubMsg
->Memory
;
1446 pStubMsg
->Memory
= pMemory
;
1447 PointerFree(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1448 pStubMsg
->Memory
= saved_memory
;
1451 pFormat
+= 8 * count
;
1455 /***********************************************************************
1456 * NdrPointerMarshall [RPCRT4.@]
1458 unsigned char * WINAPI
NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1459 unsigned char *pMemory
,
1460 PFORMAT_STRING pFormat
)
1462 unsigned char *Buffer
;
1464 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1466 /* Increment the buffer here instead of in PointerMarshall,
1467 * as that is used by embedded pointers which already handle the incrementing
1468 * the buffer, and shouldn't write any additional pointer data to the wire */
1469 if (*pFormat
!= RPC_FC_RP
)
1471 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
1472 Buffer
= pStubMsg
->Buffer
;
1473 safe_buffer_increment(pStubMsg
, 4);
1476 Buffer
= pStubMsg
->Buffer
;
1478 PointerMarshall(pStubMsg
, Buffer
, pMemory
, pFormat
);
1483 /***********************************************************************
1484 * NdrPointerUnmarshall [RPCRT4.@]
1486 unsigned char * WINAPI
NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1487 unsigned char **ppMemory
,
1488 PFORMAT_STRING pFormat
,
1489 unsigned char fMustAlloc
)
1491 unsigned char *Buffer
;
1493 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1495 /* Increment the buffer here instead of in PointerUnmarshall,
1496 * as that is used by embedded pointers which already handle the incrementing
1497 * the buffer, and shouldn't read any additional pointer data from the
1499 if (*pFormat
!= RPC_FC_RP
)
1501 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1502 Buffer
= pStubMsg
->Buffer
;
1503 safe_buffer_increment(pStubMsg
, 4);
1506 Buffer
= pStubMsg
->Buffer
;
1508 PointerUnmarshall(pStubMsg
, Buffer
, ppMemory
, *ppMemory
, pFormat
, fMustAlloc
);
1513 /***********************************************************************
1514 * NdrPointerBufferSize [RPCRT4.@]
1516 void WINAPI
NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1517 unsigned char *pMemory
,
1518 PFORMAT_STRING pFormat
)
1520 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1522 /* Increment the buffer length here instead of in PointerBufferSize,
1523 * as that is used by embedded pointers which already handle the buffer
1524 * length, and shouldn't write anything more to the wire */
1525 if (*pFormat
!= RPC_FC_RP
)
1527 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
1528 safe_buffer_length_increment(pStubMsg
, 4);
1531 PointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1534 /***********************************************************************
1535 * NdrPointerMemorySize [RPCRT4.@]
1537 ULONG WINAPI
NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1538 PFORMAT_STRING pFormat
)
1540 /* unsigned size = *(LPWORD)(pFormat+2); */
1541 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1542 PointerMemorySize(pStubMsg
, pStubMsg
->Buffer
, pFormat
);
1546 /***********************************************************************
1547 * NdrPointerFree [RPCRT4.@]
1549 void WINAPI
NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1550 unsigned char *pMemory
,
1551 PFORMAT_STRING pFormat
)
1553 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1554 PointerFree(pStubMsg
, pMemory
, pFormat
);
1557 /***********************************************************************
1558 * NdrSimpleTypeMarshall [RPCRT4.@]
1560 void WINAPI
NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1561 unsigned char FormatChar
)
1563 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &FormatChar
);
1566 /***********************************************************************
1567 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1569 * Unmarshall a base type.
1572 * Doesn't check that the buffer is long enough before copying, so the caller
1575 void WINAPI
NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1576 unsigned char FormatChar
)
1578 #define BASE_TYPE_UNMARSHALL(type) \
1579 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
1580 TRACE("pMemory: %p\n", pMemory); \
1581 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1582 pStubMsg->Buffer += sizeof(type);
1590 BASE_TYPE_UNMARSHALL(UCHAR
);
1591 TRACE("value: 0x%02x\n", *pMemory
);
1596 BASE_TYPE_UNMARSHALL(USHORT
);
1597 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
1601 case RPC_FC_ERROR_STATUS_T
:
1603 BASE_TYPE_UNMARSHALL(ULONG
);
1604 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
1607 BASE_TYPE_UNMARSHALL(float);
1608 TRACE("value: %f\n", *(float *)pMemory
);
1611 BASE_TYPE_UNMARSHALL(double);
1612 TRACE("value: %f\n", *(double *)pMemory
);
1615 BASE_TYPE_UNMARSHALL(ULONGLONG
);
1616 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
1619 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
1620 TRACE("pMemory: %p\n", pMemory
);
1621 /* 16-bits on the wire, but int in memory */
1622 *(UINT
*)pMemory
= *(USHORT
*)pStubMsg
->Buffer
;
1623 pStubMsg
->Buffer
+= sizeof(USHORT
);
1624 TRACE("value: 0x%08x\n", *(UINT
*)pMemory
);
1629 FIXME("Unhandled base type: 0x%02x\n", FormatChar
);
1631 #undef BASE_TYPE_UNMARSHALL
1634 /***********************************************************************
1635 * NdrSimpleStructMarshall [RPCRT4.@]
1637 unsigned char * WINAPI
NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1638 unsigned char *pMemory
,
1639 PFORMAT_STRING pFormat
)
1641 unsigned size
= *(const WORD
*)(pFormat
+2);
1642 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1644 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pFormat
[1] + 1);
1646 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1647 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
1649 if (pFormat
[0] != RPC_FC_STRUCT
)
1650 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
+4);
1655 /***********************************************************************
1656 * NdrSimpleStructUnmarshall [RPCRT4.@]
1658 unsigned char * WINAPI
NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1659 unsigned char **ppMemory
,
1660 PFORMAT_STRING pFormat
,
1661 unsigned char fMustAlloc
)
1663 unsigned size
= *(const WORD
*)(pFormat
+2);
1664 unsigned char *saved_buffer
;
1665 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1667 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1670 *ppMemory
= NdrAllocate(pStubMsg
, size
);
1673 if (!pStubMsg
->IsClient
&& !*ppMemory
)
1674 /* for servers, we just point straight into the RPC buffer */
1675 *ppMemory
= pStubMsg
->Buffer
;
1678 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1679 safe_buffer_increment(pStubMsg
, size
);
1680 if (pFormat
[0] == RPC_FC_PSTRUCT
)
1681 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
+4, fMustAlloc
);
1683 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
1684 if (*ppMemory
!= saved_buffer
)
1685 memcpy(*ppMemory
, saved_buffer
, size
);
1690 /***********************************************************************
1691 * NdrSimpleStructBufferSize [RPCRT4.@]
1693 void WINAPI
NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1694 unsigned char *pMemory
,
1695 PFORMAT_STRING pFormat
)
1697 unsigned size
= *(const WORD
*)(pFormat
+2);
1698 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1700 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
1702 safe_buffer_length_increment(pStubMsg
, size
);
1703 if (pFormat
[0] != RPC_FC_STRUCT
)
1704 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
+4);
1707 /***********************************************************************
1708 * NdrSimpleStructMemorySize [RPCRT4.@]
1710 ULONG WINAPI
NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1711 PFORMAT_STRING pFormat
)
1713 unsigned short size
= *(const WORD
*)(pFormat
+2);
1715 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1717 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1718 pStubMsg
->MemorySize
+= size
;
1719 safe_buffer_increment(pStubMsg
, size
);
1721 if (pFormat
[0] != RPC_FC_STRUCT
)
1722 EmbeddedPointerMemorySize(pStubMsg
, pFormat
+4);
1723 return pStubMsg
->MemorySize
;
1726 /***********************************************************************
1727 * NdrSimpleStructFree [RPCRT4.@]
1729 void WINAPI
NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
1730 unsigned char *pMemory
,
1731 PFORMAT_STRING pFormat
)
1733 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1734 if (pFormat
[0] != RPC_FC_STRUCT
)
1735 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
+4);
1740 static inline void array_compute_and_size_conformance(
1741 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1742 PFORMAT_STRING pFormat
)
1747 ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1748 SizeConformance(pStubMsg
);
1750 case RPC_FC_CVARRAY
:
1751 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, 0);
1752 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
1753 SizeConformance(pStubMsg
);
1755 case RPC_FC_C_CSTRING
:
1756 case RPC_FC_C_WSTRING
:
1757 if (pFormat
[0] == RPC_FC_C_CSTRING
)
1759 TRACE("string=%s\n", debugstr_a((const char *)pMemory
));
1760 pStubMsg
->ActualCount
= strlen((const char *)pMemory
)+1;
1764 TRACE("string=%s\n", debugstr_w((LPCWSTR
)pMemory
));
1765 pStubMsg
->ActualCount
= strlenW((LPCWSTR
)pMemory
)+1;
1768 if (fc
== RPC_FC_STRING_SIZED
)
1769 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
1771 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
1773 SizeConformance(pStubMsg
);
1776 ERR("unknown array format 0x%x\n", fc
);
1777 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1781 static inline void array_buffer_size(
1782 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1783 PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
1787 unsigned char alignment
;
1792 esize
= *(const WORD
*)(pFormat
+2);
1793 alignment
= pFormat
[1] + 1;
1795 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1797 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
1799 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
1800 /* conformance value plus array */
1801 safe_buffer_length_increment(pStubMsg
, size
);
1804 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1806 case RPC_FC_CVARRAY
:
1807 esize
= *(const WORD
*)(pFormat
+2);
1808 alignment
= pFormat
[1] + 1;
1810 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1811 pFormat
= SkipConformance(pStubMsg
, pFormat
);
1813 SizeVariance(pStubMsg
);
1815 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
1817 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1818 safe_buffer_length_increment(pStubMsg
, size
);
1821 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1823 case RPC_FC_C_CSTRING
:
1824 case RPC_FC_C_WSTRING
:
1825 if (fc
== RPC_FC_C_CSTRING
)
1830 SizeVariance(pStubMsg
);
1832 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1833 safe_buffer_length_increment(pStubMsg
, size
);
1836 ERR("unknown array format 0x%x\n", fc
);
1837 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1841 static inline void array_compute_and_write_conformance(
1842 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1843 PFORMAT_STRING pFormat
)
1848 ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1849 WriteConformance(pStubMsg
);
1851 case RPC_FC_CVARRAY
:
1852 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, 0);
1853 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
1854 WriteConformance(pStubMsg
);
1856 case RPC_FC_C_CSTRING
:
1857 case RPC_FC_C_WSTRING
:
1858 if (fc
== RPC_FC_C_CSTRING
)
1860 TRACE("string=%s\n", debugstr_a((const char *)pMemory
));
1861 pStubMsg
->ActualCount
= strlen((const char *)pMemory
)+1;
1865 TRACE("string=%s\n", debugstr_w((LPCWSTR
)pMemory
));
1866 pStubMsg
->ActualCount
= strlenW((LPCWSTR
)pMemory
)+1;
1868 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
1869 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
1871 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
1872 pStubMsg
->Offset
= 0;
1873 WriteConformance(pStubMsg
);
1876 ERR("unknown array format 0x%x\n", fc
);
1877 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1881 static inline void array_write_variance_and_marshall(
1882 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1883 PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
1887 unsigned char alignment
;
1892 esize
= *(const WORD
*)(pFormat
+2);
1893 alignment
= pFormat
[1] + 1;
1895 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1897 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
1899 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
1901 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1902 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
1905 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
1907 case RPC_FC_CVARRAY
:
1908 esize
= *(const WORD
*)(pFormat
+2);
1909 alignment
= pFormat
[1] + 1;
1912 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1914 pFormat
= SkipConformance(pStubMsg
, pFormat
);
1916 WriteVariance(pStubMsg
);
1918 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
1920 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1923 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1924 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, size
);
1927 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
1929 case RPC_FC_C_CSTRING
:
1930 case RPC_FC_C_WSTRING
:
1931 if (fc
== RPC_FC_C_CSTRING
)
1936 WriteVariance(pStubMsg
);
1938 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1939 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
1942 ERR("unknown array format 0x%x\n", fc
);
1943 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1947 static inline ULONG
array_read_conformance(
1948 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
1955 esize
= *(const WORD
*)(pFormat
+2);
1956 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
1957 return safe_multiply(esize
, pStubMsg
->MaxCount
);
1958 case RPC_FC_CVARRAY
:
1959 esize
= *(const WORD
*)(pFormat
+2);
1960 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
1961 return safe_multiply(esize
, pStubMsg
->MaxCount
);
1962 case RPC_FC_C_CSTRING
:
1963 case RPC_FC_C_WSTRING
:
1964 if (fc
== RPC_FC_C_CSTRING
)
1969 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
1970 ReadConformance(pStubMsg
, pFormat
+ 2);
1972 ReadConformance(pStubMsg
, NULL
);
1973 return safe_multiply(esize
, pStubMsg
->MaxCount
);
1975 ERR("unknown array format 0x%x\n", fc
);
1976 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1980 static inline ULONG
array_read_variance_and_unmarshall(
1981 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char **ppMemory
,
1982 PFORMAT_STRING pFormat
, unsigned char fMustAlloc
,
1983 unsigned char fUseBufferMemoryServer
, unsigned char fUnmarshall
)
1985 ULONG bufsize
, memsize
;
1987 unsigned char alignment
;
1988 unsigned char *saved_buffer
;
1994 esize
= *(const WORD
*)(pFormat
+2);
1995 alignment
= pFormat
[1] + 1;
1997 bufsize
= memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
1999 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2001 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2006 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2009 if (fUseBufferMemoryServer
&& !pStubMsg
->IsClient
&& !*ppMemory
)
2010 /* for servers, we just point straight into the RPC buffer */
2011 *ppMemory
= pStubMsg
->Buffer
;
2014 saved_buffer
= pStubMsg
->Buffer
;
2015 safe_buffer_increment(pStubMsg
, bufsize
);
2017 pStubMsg
->BufferMark
= saved_buffer
;
2018 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
2020 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
2021 if (*ppMemory
!= saved_buffer
)
2022 memcpy(*ppMemory
, saved_buffer
, bufsize
);
2025 case RPC_FC_CVARRAY
:
2026 esize
= *(const WORD
*)(pFormat
+2);
2027 alignment
= pFormat
[1] + 1;
2029 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2031 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2033 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2035 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2036 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2040 offset
= pStubMsg
->Offset
;
2042 if (!fMustAlloc
&& !*ppMemory
)
2045 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2046 saved_buffer
= pStubMsg
->Buffer
;
2047 safe_buffer_increment(pStubMsg
, bufsize
);
2049 pStubMsg
->BufferMark
= saved_buffer
;
2050 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
,
2053 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
2056 case RPC_FC_C_CSTRING
:
2057 case RPC_FC_C_WSTRING
:
2058 if (fc
== RPC_FC_C_CSTRING
)
2063 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
2065 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
2067 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2068 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
2069 RpcRaiseException(RPC_S_INVALID_BOUND
);
2071 if (pStubMsg
->Offset
)
2073 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2074 RpcRaiseException(RPC_S_INVALID_BOUND
);
2077 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2078 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2080 validate_string_data(pStubMsg
, bufsize
, esize
);
2085 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2088 if (fUseBufferMemoryServer
&& !pStubMsg
->IsClient
&&
2089 !*ppMemory
&& (pStubMsg
->MaxCount
== pStubMsg
->ActualCount
))
2090 /* if the data in the RPC buffer is big enough, we just point
2091 * straight into it */
2092 *ppMemory
= pStubMsg
->Buffer
;
2093 else if (!*ppMemory
)
2094 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2097 if (*ppMemory
== pStubMsg
->Buffer
)
2098 safe_buffer_increment(pStubMsg
, bufsize
);
2100 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
2102 if (*pFormat
== RPC_FC_C_CSTRING
)
2103 TRACE("string=%s\n", debugstr_a((char*)*ppMemory
));
2105 TRACE("string=%s\n", debugstr_w((LPWSTR
)*ppMemory
));
2109 ERR("unknown array format 0x%x\n", fc
);
2110 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2114 static inline void array_memory_size(
2115 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
,
2116 unsigned char fHasPointers
)
2118 ULONG bufsize
, memsize
;
2120 unsigned char alignment
;
2125 esize
= *(const WORD
*)(pFormat
+2);
2126 alignment
= pFormat
[1] + 1;
2128 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2130 bufsize
= memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2131 pStubMsg
->MemorySize
+= memsize
;
2133 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2135 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2136 safe_buffer_increment(pStubMsg
, bufsize
);
2139 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2141 case RPC_FC_CVARRAY
:
2142 esize
= *(const WORD
*)(pFormat
+2);
2143 alignment
= pFormat
[1] + 1;
2145 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2147 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2149 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2150 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2151 pStubMsg
->MemorySize
+= memsize
;
2153 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2155 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2156 safe_buffer_increment(pStubMsg
, bufsize
);
2159 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2161 case RPC_FC_C_CSTRING
:
2162 case RPC_FC_C_WSTRING
:
2163 if (fc
== RPC_FC_C_CSTRING
)
2168 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
2170 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
2172 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2173 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
2174 RpcRaiseException(RPC_S_INVALID_BOUND
);
2176 if (pStubMsg
->Offset
)
2178 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2179 RpcRaiseException(RPC_S_INVALID_BOUND
);
2182 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2183 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2185 validate_string_data(pStubMsg
, bufsize
, esize
);
2187 safe_buffer_increment(pStubMsg
, bufsize
);
2188 pStubMsg
->MemorySize
+= memsize
;
2191 ERR("unknown array format 0x%x\n", fc
);
2192 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2196 static inline void array_free(
2197 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
,
2198 unsigned char *pMemory
, PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
2203 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2205 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2207 case RPC_FC_CVARRAY
:
2208 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2209 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2211 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2213 case RPC_FC_C_CSTRING
:
2214 case RPC_FC_C_WSTRING
:
2215 /* No embedded pointers so nothing to do */
2218 ERR("unknown array format 0x%x\n", fc
);
2219 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2224 * NdrConformantString:
2226 * What MS calls a ConformantString is, in DCE terminology,
2227 * a Varying-Conformant String.
2229 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2230 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2231 * into unmarshalled string)
2232 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2234 * data: CHARTYPE[maxlen]
2236 * ], where CHARTYPE is the appropriate character type (specified externally)
2240 /***********************************************************************
2241 * NdrConformantStringMarshall [RPCRT4.@]
2243 unsigned char *WINAPI
NdrConformantStringMarshall(MIDL_STUB_MESSAGE
*pStubMsg
,
2244 unsigned char *pszMessage
, PFORMAT_STRING pFormat
)
2246 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg
, pszMessage
, pFormat
);
2248 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2249 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2250 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2253 /* allow compiler to optimise inline function by passing constant into
2254 * these functions */
2255 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2256 array_compute_and_write_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pszMessage
,
2258 array_write_variance_and_marshall(RPC_FC_C_CSTRING
, pStubMsg
, pszMessage
,
2259 pFormat
, TRUE
/* fHasPointers */);
2261 array_compute_and_write_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pszMessage
,
2263 array_write_variance_and_marshall(RPC_FC_C_WSTRING
, pStubMsg
, pszMessage
,
2264 pFormat
, TRUE
/* fHasPointers */);
2270 /***********************************************************************
2271 * NdrConformantStringBufferSize [RPCRT4.@]
2273 void WINAPI
NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2274 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
2276 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2278 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2279 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2280 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2283 /* allow compiler to optimise inline function by passing constant into
2284 * these functions */
2285 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2286 array_compute_and_size_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pMemory
,
2288 array_buffer_size(RPC_FC_C_CSTRING
, pStubMsg
, pMemory
, pFormat
,
2289 TRUE
/* fHasPointers */);
2291 array_compute_and_size_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pMemory
,
2293 array_buffer_size(RPC_FC_C_WSTRING
, pStubMsg
, pMemory
, pFormat
,
2294 TRUE
/* fHasPointers */);
2298 /************************************************************************
2299 * NdrConformantStringMemorySize [RPCRT4.@]
2301 ULONG WINAPI
NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
2302 PFORMAT_STRING pFormat
)
2304 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
2306 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2307 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2308 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2311 /* allow compiler to optimise inline function by passing constant into
2312 * these functions */
2313 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2314 array_read_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
);
2315 array_memory_size(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
,
2316 TRUE
/* fHasPointers */);
2318 array_read_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
);
2319 array_memory_size(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
,
2320 TRUE
/* fHasPointers */);
2323 return pStubMsg
->MemorySize
;
2326 /************************************************************************
2327 * NdrConformantStringUnmarshall [RPCRT4.@]
2329 unsigned char *WINAPI
NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2330 unsigned char** ppMemory
, PFORMAT_STRING pFormat
, unsigned char fMustAlloc
)
2332 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2333 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
2335 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2336 ERR("Unhandled string type: %#x\n", *pFormat
);
2337 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2340 /* allow compiler to optimise inline function by passing constant into
2341 * these functions */
2342 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2343 array_read_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
);
2344 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING
, pStubMsg
, ppMemory
,
2345 pFormat
, fMustAlloc
,
2346 TRUE
/* fUseBufferMemoryServer */,
2347 TRUE
/* fUnmarshall */);
2349 array_read_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
);
2350 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING
, pStubMsg
, ppMemory
,
2351 pFormat
, fMustAlloc
,
2352 TRUE
/* fUseBufferMemoryServer */,
2353 TRUE
/* fUnmarshall */);
2359 /***********************************************************************
2360 * NdrNonConformantStringMarshall [RPCRT4.@]
2362 unsigned char * WINAPI
NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2363 unsigned char *pMemory
,
2364 PFORMAT_STRING pFormat
)
2366 ULONG esize
, size
, maxsize
;
2368 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2370 maxsize
= *(USHORT
*)&pFormat
[2];
2372 if (*pFormat
== RPC_FC_CSTRING
)
2375 const char *str
= (const char *)pMemory
;
2376 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
2378 TRACE("string=%s\n", debugstr_an(str
, i
));
2379 pStubMsg
->ActualCount
= i
+ 1;
2382 else if (*pFormat
== RPC_FC_WSTRING
)
2385 const WCHAR
*str
= (const WCHAR
*)pMemory
;
2386 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
2388 TRACE("string=%s\n", debugstr_wn(str
, i
));
2389 pStubMsg
->ActualCount
= i
+ 1;
2394 ERR("Unhandled string type: %#x\n", *pFormat
);
2395 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2398 pStubMsg
->Offset
= 0;
2399 WriteVariance(pStubMsg
);
2401 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2402 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
2407 /***********************************************************************
2408 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2410 unsigned char * WINAPI
NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2411 unsigned char **ppMemory
,
2412 PFORMAT_STRING pFormat
,
2413 unsigned char fMustAlloc
)
2415 ULONG bufsize
, memsize
, esize
, maxsize
;
2417 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2418 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
2420 maxsize
= *(USHORT
*)&pFormat
[2];
2422 ReadVariance(pStubMsg
, NULL
, maxsize
);
2423 if (pStubMsg
->Offset
)
2425 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2426 RpcRaiseException(RPC_S_INVALID_BOUND
);
2429 if (*pFormat
== RPC_FC_CSTRING
) esize
= 1;
2430 else if (*pFormat
== RPC_FC_WSTRING
) esize
= 2;
2433 ERR("Unhandled string type: %#x\n", *pFormat
);
2434 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2437 memsize
= esize
* maxsize
;
2438 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2440 validate_string_data(pStubMsg
, bufsize
, esize
);
2442 if (fMustAlloc
|| !*ppMemory
)
2443 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2445 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
2447 if (*pFormat
== RPC_FC_CSTRING
) {
2448 TRACE("string=%s\n", debugstr_an((char*)*ppMemory
, pStubMsg
->ActualCount
));
2450 else if (*pFormat
== RPC_FC_WSTRING
) {
2451 TRACE("string=%s\n", debugstr_wn((LPWSTR
)*ppMemory
, pStubMsg
->ActualCount
));
2457 /***********************************************************************
2458 * NdrNonConformantStringBufferSize [RPCRT4.@]
2460 void WINAPI
NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2461 unsigned char *pMemory
,
2462 PFORMAT_STRING pFormat
)
2464 ULONG esize
, maxsize
;
2466 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2468 maxsize
= *(USHORT
*)&pFormat
[2];
2470 SizeVariance(pStubMsg
);
2472 if (*pFormat
== RPC_FC_CSTRING
)
2475 const char *str
= (const char *)pMemory
;
2476 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
2478 TRACE("string=%s\n", debugstr_an(str
, i
));
2479 pStubMsg
->ActualCount
= i
+ 1;
2482 else if (*pFormat
== RPC_FC_WSTRING
)
2485 const WCHAR
*str
= (const WCHAR
*)pMemory
;
2486 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
2488 TRACE("string=%s\n", debugstr_wn(str
, i
));
2489 pStubMsg
->ActualCount
= i
+ 1;
2494 ERR("Unhandled string type: %#x\n", *pFormat
);
2495 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2498 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
2501 /***********************************************************************
2502 * NdrNonConformantStringMemorySize [RPCRT4.@]
2504 ULONG WINAPI
NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2505 PFORMAT_STRING pFormat
)
2507 ULONG bufsize
, memsize
, esize
, maxsize
;
2509 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
2511 maxsize
= *(USHORT
*)&pFormat
[2];
2513 ReadVariance(pStubMsg
, NULL
, maxsize
);
2515 if (pStubMsg
->Offset
)
2517 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2518 RpcRaiseException(RPC_S_INVALID_BOUND
);
2521 if (*pFormat
== RPC_FC_CSTRING
) esize
= 1;
2522 else if (*pFormat
== RPC_FC_WSTRING
) esize
= 2;
2525 ERR("Unhandled string type: %#x\n", *pFormat
);
2526 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2529 memsize
= esize
* maxsize
;
2530 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2532 validate_string_data(pStubMsg
, bufsize
, esize
);
2534 safe_buffer_increment(pStubMsg
, bufsize
);
2535 pStubMsg
->MemorySize
+= memsize
;
2537 return pStubMsg
->MemorySize
;
2542 #include "pshpack1.h"
2546 unsigned char flags_type
; /* flags in upper nibble, type in lower nibble */
2550 #include "poppack.h"
2552 static unsigned long EmbeddedComplexSize(MIDL_STUB_MESSAGE
*pStubMsg
,
2553 PFORMAT_STRING pFormat
)
2557 case RPC_FC_PSTRUCT
:
2558 case RPC_FC_CSTRUCT
:
2559 case RPC_FC_BOGUS_STRUCT
:
2560 case RPC_FC_SMFARRAY
:
2561 case RPC_FC_SMVARRAY
:
2562 case RPC_FC_CSTRING
:
2563 return *(const WORD
*)&pFormat
[2];
2564 case RPC_FC_USER_MARSHAL
:
2565 return *(const WORD
*)&pFormat
[4];
2566 case RPC_FC_RANGE
: {
2567 switch (((const NDR_RANGE
*)pFormat
)->flags_type
& 0xf) {
2572 return sizeof(UCHAR
);
2576 return sizeof(USHORT
);
2580 return sizeof(ULONG
);
2582 return sizeof(float);
2584 return sizeof(double);
2586 return sizeof(ULONGLONG
);
2588 return sizeof(UINT
);
2590 ERR("unknown type 0x%x\n", ((const NDR_RANGE
*)pFormat
)->flags_type
& 0xf);
2591 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2594 case RPC_FC_NON_ENCAPSULATED_UNION
:
2596 if (pStubMsg
->fHasNewCorrDesc
)
2601 pFormat
+= *(const SHORT
*)pFormat
;
2602 return *(const SHORT
*)pFormat
;
2604 return sizeof(void *);
2605 case RPC_FC_WSTRING
:
2606 return *(const WORD
*)&pFormat
[2] * 2;
2608 FIXME("unhandled embedded type %02x\n", *pFormat
);
2614 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2615 PFORMAT_STRING pFormat
)
2617 NDR_MEMORYSIZE m
= NdrMemorySizer
[*pFormat
& NDR_TABLE_MASK
];
2621 FIXME("no memorysizer for data type=%02x\n", *pFormat
);
2625 return m(pStubMsg
, pFormat
);
2629 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2630 unsigned char *pMemory
,
2631 PFORMAT_STRING pFormat
,
2632 PFORMAT_STRING pPointer
)
2634 PFORMAT_STRING desc
;
2638 while (*pFormat
!= RPC_FC_END
) {
2644 TRACE("byte=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2645 safe_copy_to_buffer(pStubMsg
, pMemory
, 1);
2651 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2652 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
2656 TRACE("enum16=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2657 if (32767 < *(DWORD
*)pMemory
)
2658 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
2659 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
2665 TRACE("long=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2666 safe_copy_to_buffer(pStubMsg
, pMemory
, 4);
2670 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2671 safe_copy_to_buffer(pStubMsg
, pMemory
, 8);
2674 case RPC_FC_POINTER
:
2676 unsigned char *saved_buffer
;
2677 int pointer_buffer_mark_set
= 0;
2678 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
2679 TRACE("pStubMsg->Buffer before %p\n", pStubMsg
->Buffer
);
2680 if (*pPointer
!= RPC_FC_RP
)
2681 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
2682 saved_buffer
= pStubMsg
->Buffer
;
2683 if (pStubMsg
->PointerBufferMark
)
2685 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2686 pStubMsg
->PointerBufferMark
= NULL
;
2687 pointer_buffer_mark_set
= 1;
2689 else if (*pPointer
!= RPC_FC_RP
)
2690 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2691 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char**)pMemory
, pPointer
);
2692 if (pointer_buffer_mark_set
)
2694 STD_OVERFLOW_CHECK(pStubMsg
);
2695 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2696 pStubMsg
->Buffer
= saved_buffer
;
2697 if (*pPointer
!= RPC_FC_RP
)
2698 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2700 TRACE("pStubMsg->Buffer after %p\n", pStubMsg
->Buffer
);
2705 case RPC_FC_ALIGNM4
:
2706 ALIGN_POINTER(pMemory
, 4);
2708 case RPC_FC_ALIGNM8
:
2709 ALIGN_POINTER(pMemory
, 8);
2711 case RPC_FC_STRUCTPAD1
:
2712 case RPC_FC_STRUCTPAD2
:
2713 case RPC_FC_STRUCTPAD3
:
2714 case RPC_FC_STRUCTPAD4
:
2715 case RPC_FC_STRUCTPAD5
:
2716 case RPC_FC_STRUCTPAD6
:
2717 case RPC_FC_STRUCTPAD7
:
2718 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2720 case RPC_FC_EMBEDDED_COMPLEX
:
2721 pMemory
+= pFormat
[1];
2723 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2724 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2725 TRACE("embedded complex (size=%ld) <= %p\n", size
, pMemory
);
2726 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
2729 /* for some reason interface pointers aren't generated as
2730 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2731 * they still need the derefencing treatment that pointers are
2733 if (*desc
== RPC_FC_IP
)
2734 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2736 m(pStubMsg
, pMemory
, desc
);
2738 else FIXME("no marshaller for embedded type %02x\n", *desc
);
2745 FIXME("unhandled format 0x%02x\n", *pFormat
);
2753 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2754 unsigned char *pMemory
,
2755 PFORMAT_STRING pFormat
,
2756 PFORMAT_STRING pPointer
,
2757 unsigned char fMustAlloc
)
2759 PFORMAT_STRING desc
;
2763 while (*pFormat
!= RPC_FC_END
) {
2769 safe_copy_from_buffer(pStubMsg
, pMemory
, 1);
2770 TRACE("byte=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2776 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
2777 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2781 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
2782 *(DWORD
*)pMemory
&= 0xffff;
2783 TRACE("enum16=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
2784 if (32767 < *(DWORD
*)pMemory
)
2785 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
2791 safe_copy_from_buffer(pStubMsg
, pMemory
, 4);
2792 TRACE("long=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
2796 safe_copy_from_buffer(pStubMsg
, pMemory
, 8);
2797 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2800 case RPC_FC_POINTER
:
2802 unsigned char *saved_buffer
;
2803 int pointer_buffer_mark_set
= 0;
2804 TRACE("pointer => %p\n", pMemory
);
2805 if (*pPointer
!= RPC_FC_RP
)
2806 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2807 saved_buffer
= pStubMsg
->Buffer
;
2808 if (pStubMsg
->PointerBufferMark
)
2810 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2811 pStubMsg
->PointerBufferMark
= NULL
;
2812 pointer_buffer_mark_set
= 1;
2814 else if (*pPointer
!= RPC_FC_RP
)
2815 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2817 PointerUnmarshall(pStubMsg
, saved_buffer
, (unsigned char**)pMemory
, *(unsigned char**)pMemory
, pPointer
, fMustAlloc
);
2818 if (pointer_buffer_mark_set
)
2820 STD_OVERFLOW_CHECK(pStubMsg
);
2821 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2822 pStubMsg
->Buffer
= saved_buffer
;
2823 if (*pPointer
!= RPC_FC_RP
)
2824 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2830 case RPC_FC_ALIGNM4
:
2831 ALIGN_POINTER_CLEAR(pMemory
, 4);
2833 case RPC_FC_ALIGNM8
:
2834 ALIGN_POINTER_CLEAR(pMemory
, 8);
2836 case RPC_FC_STRUCTPAD1
:
2837 case RPC_FC_STRUCTPAD2
:
2838 case RPC_FC_STRUCTPAD3
:
2839 case RPC_FC_STRUCTPAD4
:
2840 case RPC_FC_STRUCTPAD5
:
2841 case RPC_FC_STRUCTPAD6
:
2842 case RPC_FC_STRUCTPAD7
:
2843 memset(pMemory
, 0, *pFormat
- RPC_FC_STRUCTPAD1
+ 1);
2844 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2846 case RPC_FC_EMBEDDED_COMPLEX
:
2847 pMemory
+= pFormat
[1];
2849 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2850 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2851 TRACE("embedded complex (size=%ld) => %p\n", size
, pMemory
);
2853 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
2854 * since the type is part of the memory block that is encompassed by
2855 * the whole complex type. Memory is forced to allocate when pointers
2856 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
2857 * clearing the memory we pass in to the unmarshaller */
2858 memset(pMemory
, 0, size
);
2859 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
2862 /* for some reason interface pointers aren't generated as
2863 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2864 * they still need the derefencing treatment that pointers are
2866 if (*desc
== RPC_FC_IP
)
2867 m(pStubMsg
, (unsigned char **)pMemory
, desc
, FALSE
);
2869 m(pStubMsg
, &pMemory
, desc
, FALSE
);
2871 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
2878 FIXME("unhandled format %d\n", *pFormat
);
2886 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2887 unsigned char *pMemory
,
2888 PFORMAT_STRING pFormat
,
2889 PFORMAT_STRING pPointer
)
2891 PFORMAT_STRING desc
;
2895 while (*pFormat
!= RPC_FC_END
) {
2901 safe_buffer_length_increment(pStubMsg
, 1);
2907 safe_buffer_length_increment(pStubMsg
, 2);
2911 safe_buffer_length_increment(pStubMsg
, 2);
2917 safe_buffer_length_increment(pStubMsg
, 4);
2921 safe_buffer_length_increment(pStubMsg
, 8);
2924 case RPC_FC_POINTER
:
2925 if (!pStubMsg
->IgnoreEmbeddedPointers
)
2927 int saved_buffer_length
= pStubMsg
->BufferLength
;
2928 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2929 pStubMsg
->PointerLength
= 0;
2930 if(!pStubMsg
->BufferLength
)
2931 ERR("BufferLength == 0??\n");
2932 PointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
2933 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2934 pStubMsg
->BufferLength
= saved_buffer_length
;
2936 if (*pPointer
!= RPC_FC_RP
)
2938 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
2939 safe_buffer_length_increment(pStubMsg
, 4);
2944 case RPC_FC_ALIGNM4
:
2945 ALIGN_POINTER(pMemory
, 4);
2947 case RPC_FC_ALIGNM8
:
2948 ALIGN_POINTER(pMemory
, 8);
2950 case RPC_FC_STRUCTPAD1
:
2951 case RPC_FC_STRUCTPAD2
:
2952 case RPC_FC_STRUCTPAD3
:
2953 case RPC_FC_STRUCTPAD4
:
2954 case RPC_FC_STRUCTPAD5
:
2955 case RPC_FC_STRUCTPAD6
:
2956 case RPC_FC_STRUCTPAD7
:
2957 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2959 case RPC_FC_EMBEDDED_COMPLEX
:
2960 pMemory
+= pFormat
[1];
2962 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2963 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2964 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
2967 /* for some reason interface pointers aren't generated as
2968 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2969 * they still need the derefencing treatment that pointers are
2971 if (*desc
== RPC_FC_IP
)
2972 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2974 m(pStubMsg
, pMemory
, desc
);
2976 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
2983 FIXME("unhandled format 0x%02x\n", *pFormat
);
2991 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
2992 unsigned char *pMemory
,
2993 PFORMAT_STRING pFormat
,
2994 PFORMAT_STRING pPointer
)
2996 PFORMAT_STRING desc
;
3000 while (*pFormat
!= RPC_FC_END
) {
3022 case RPC_FC_POINTER
:
3023 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
3027 case RPC_FC_ALIGNM4
:
3028 ALIGN_POINTER(pMemory
, 4);
3030 case RPC_FC_ALIGNM8
:
3031 ALIGN_POINTER(pMemory
, 8);
3033 case RPC_FC_STRUCTPAD1
:
3034 case RPC_FC_STRUCTPAD2
:
3035 case RPC_FC_STRUCTPAD3
:
3036 case RPC_FC_STRUCTPAD4
:
3037 case RPC_FC_STRUCTPAD5
:
3038 case RPC_FC_STRUCTPAD6
:
3039 case RPC_FC_STRUCTPAD7
:
3040 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3042 case RPC_FC_EMBEDDED_COMPLEX
:
3043 pMemory
+= pFormat
[1];
3045 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3046 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3047 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
3050 /* for some reason interface pointers aren't generated as
3051 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3052 * they still need the derefencing treatment that pointers are
3054 if (*desc
== RPC_FC_IP
)
3055 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
3057 m(pStubMsg
, pMemory
, desc
);
3065 FIXME("unhandled format 0x%02x\n", *pFormat
);
3073 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3074 PFORMAT_STRING pFormat
,
3075 PFORMAT_STRING pPointer
)
3077 PFORMAT_STRING desc
;
3078 unsigned long size
= 0;
3080 while (*pFormat
!= RPC_FC_END
) {
3087 safe_buffer_increment(pStubMsg
, 1);
3093 safe_buffer_increment(pStubMsg
, 2);
3097 safe_buffer_increment(pStubMsg
, 2);
3103 safe_buffer_increment(pStubMsg
, 4);
3107 safe_buffer_increment(pStubMsg
, 8);
3109 case RPC_FC_POINTER
:
3111 unsigned char *saved_buffer
;
3112 int pointer_buffer_mark_set
= 0;
3113 if (*pPointer
!= RPC_FC_RP
)
3114 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3115 saved_buffer
= pStubMsg
->Buffer
;
3116 if (pStubMsg
->PointerBufferMark
)
3118 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3119 pStubMsg
->PointerBufferMark
= NULL
;
3120 pointer_buffer_mark_set
= 1;
3122 else if (*pPointer
!= RPC_FC_RP
)
3123 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3125 if (!pStubMsg
->IgnoreEmbeddedPointers
)
3126 PointerMemorySize(pStubMsg
, saved_buffer
, pPointer
);
3127 if (pointer_buffer_mark_set
)
3129 STD_OVERFLOW_CHECK(pStubMsg
);
3130 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3131 pStubMsg
->Buffer
= saved_buffer
;
3132 if (*pPointer
!= RPC_FC_RP
)
3133 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3139 case RPC_FC_ALIGNM4
:
3140 ALIGN_LENGTH(size
, 4);
3141 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3143 case RPC_FC_ALIGNM8
:
3144 ALIGN_LENGTH(size
, 8);
3145 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3147 case RPC_FC_STRUCTPAD1
:
3148 case RPC_FC_STRUCTPAD2
:
3149 case RPC_FC_STRUCTPAD3
:
3150 case RPC_FC_STRUCTPAD4
:
3151 case RPC_FC_STRUCTPAD5
:
3152 case RPC_FC_STRUCTPAD6
:
3153 case RPC_FC_STRUCTPAD7
:
3154 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3156 case RPC_FC_EMBEDDED_COMPLEX
:
3159 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3160 size
+= EmbeddedComplexMemorySize(pStubMsg
, desc
);
3166 FIXME("unhandled format 0x%02x\n", *pFormat
);
3174 unsigned long ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg
,
3175 PFORMAT_STRING pFormat
)
3177 PFORMAT_STRING desc
;
3178 unsigned long size
= 0;
3180 while (*pFormat
!= RPC_FC_END
) {
3202 case RPC_FC_POINTER
:
3203 size
+= sizeof(void *);
3205 case RPC_FC_ALIGNM4
:
3206 ALIGN_LENGTH(size
, 4);
3208 case RPC_FC_ALIGNM8
:
3209 ALIGN_LENGTH(size
, 8);
3211 case RPC_FC_STRUCTPAD1
:
3212 case RPC_FC_STRUCTPAD2
:
3213 case RPC_FC_STRUCTPAD3
:
3214 case RPC_FC_STRUCTPAD4
:
3215 case RPC_FC_STRUCTPAD5
:
3216 case RPC_FC_STRUCTPAD6
:
3217 case RPC_FC_STRUCTPAD7
:
3218 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3220 case RPC_FC_EMBEDDED_COMPLEX
:
3223 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3224 size
+= EmbeddedComplexSize(pStubMsg
, desc
);
3230 FIXME("unhandled format 0x%02x\n", *pFormat
);
3238 /***********************************************************************
3239 * NdrComplexStructMarshall [RPCRT4.@]
3241 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3242 unsigned char *pMemory
,
3243 PFORMAT_STRING pFormat
)
3245 PFORMAT_STRING conf_array
= NULL
;
3246 PFORMAT_STRING pointer_desc
= NULL
;
3247 unsigned char *OldMemory
= pStubMsg
->Memory
;
3248 int pointer_buffer_mark_set
= 0;
3250 ULONG max_count
= 0;
3253 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3255 if (!pStubMsg
->PointerBufferMark
)
3257 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3258 /* save buffer length */
3259 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
3261 /* get the buffer pointer after complex array data, but before
3263 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- pStubMsg
->BufferStart
;
3264 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3265 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
3266 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3268 /* save it for use by embedded pointer code later */
3269 pStubMsg
->PointerBufferMark
= pStubMsg
->BufferStart
+ pStubMsg
->BufferLength
;
3270 TRACE("difference = 0x%x\n", pStubMsg
->PointerBufferMark
- pStubMsg
->Buffer
);
3271 pointer_buffer_mark_set
= 1;
3273 /* restore the original buffer length */
3274 pStubMsg
->BufferLength
= saved_buffer_length
;
3277 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pFormat
[1] + 1);
3280 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3282 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3285 pStubMsg
->Memory
= pMemory
;
3289 unsigned long struct_size
= ComplexStructSize(pStubMsg
, pFormat
);
3290 array_compute_and_write_conformance(conf_array
[0], pStubMsg
,
3291 pMemory
+ struct_size
, conf_array
);
3292 /* these could be changed in ComplexMarshall so save them for later */
3293 max_count
= pStubMsg
->MaxCount
;
3294 count
= pStubMsg
->ActualCount
;
3295 offset
= pStubMsg
->Offset
;
3298 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3302 pStubMsg
->MaxCount
= max_count
;
3303 pStubMsg
->ActualCount
= count
;
3304 pStubMsg
->Offset
= offset
;
3305 array_write_variance_and_marshall(conf_array
[0], pStubMsg
, pMemory
,
3306 conf_array
, TRUE
/* fHasPointers */);
3309 pStubMsg
->Memory
= OldMemory
;
3311 if (pointer_buffer_mark_set
)
3313 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3314 pStubMsg
->PointerBufferMark
= NULL
;
3317 STD_OVERFLOW_CHECK(pStubMsg
);
3322 /***********************************************************************
3323 * NdrComplexStructUnmarshall [RPCRT4.@]
3325 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3326 unsigned char **ppMemory
,
3327 PFORMAT_STRING pFormat
,
3328 unsigned char fMustAlloc
)
3330 unsigned size
= *(const WORD
*)(pFormat
+2);
3331 PFORMAT_STRING conf_array
= NULL
;
3332 PFORMAT_STRING pointer_desc
= NULL
;
3333 unsigned char *pMemory
;
3334 int pointer_buffer_mark_set
= 0;
3336 ULONG max_count
= 0;
3338 ULONG array_size
= 0;
3340 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3342 if (!pStubMsg
->PointerBufferMark
)
3344 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3345 /* save buffer pointer */
3346 unsigned char *saved_buffer
= pStubMsg
->Buffer
;
3348 /* get the buffer pointer after complex array data, but before
3350 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3351 NdrComplexStructMemorySize(pStubMsg
, pFormat
);
3352 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3354 /* save it for use by embedded pointer code later */
3355 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3356 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->PointerBufferMark
- saved_buffer
));
3357 pointer_buffer_mark_set
= 1;
3359 /* restore the original buffer */
3360 pStubMsg
->Buffer
= saved_buffer
;
3363 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
3366 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3368 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3373 array_size
= array_read_conformance(conf_array
[0], pStubMsg
, conf_array
);
3376 /* these could be changed in ComplexMarshall so save them for later */
3377 max_count
= pStubMsg
->MaxCount
;
3378 count
= pStubMsg
->ActualCount
;
3379 offset
= pStubMsg
->Offset
;
3382 if (fMustAlloc
|| !*ppMemory
)
3383 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3385 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
, fMustAlloc
);
3389 pStubMsg
->MaxCount
= max_count
;
3390 pStubMsg
->ActualCount
= count
;
3391 pStubMsg
->Offset
= offset
;
3393 memset(pMemory
, 0, array_size
);
3394 array_read_variance_and_unmarshall(conf_array
[0], pStubMsg
, &pMemory
,
3396 FALSE
/* fUseBufferMemoryServer */,
3397 TRUE
/* fUnmarshall */);
3400 if (pointer_buffer_mark_set
)
3402 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3403 pStubMsg
->PointerBufferMark
= NULL
;
3409 /***********************************************************************
3410 * NdrComplexStructBufferSize [RPCRT4.@]
3412 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3413 unsigned char *pMemory
,
3414 PFORMAT_STRING pFormat
)
3416 PFORMAT_STRING conf_array
= NULL
;
3417 PFORMAT_STRING pointer_desc
= NULL
;
3418 unsigned char *OldMemory
= pStubMsg
->Memory
;
3419 int pointer_length_set
= 0;
3421 ULONG max_count
= 0;
3424 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3426 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
3428 if(!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
3430 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3431 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
3433 /* get the buffer length after complex struct data, but before
3435 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3436 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
3437 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3439 /* save it for use by embedded pointer code later */
3440 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3441 pointer_length_set
= 1;
3442 TRACE("difference = 0x%lx\n", pStubMsg
->PointerLength
- saved_buffer_length
);
3444 /* restore the original buffer length */
3445 pStubMsg
->BufferLength
= saved_buffer_length
;
3449 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3451 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3454 pStubMsg
->Memory
= pMemory
;
3458 unsigned long struct_size
= ComplexStructSize(pStubMsg
, pFormat
);
3459 array_compute_and_size_conformance(conf_array
[0], pStubMsg
, pMemory
+ struct_size
,
3462 /* these could be changed in ComplexMarshall so save them for later */
3463 max_count
= pStubMsg
->MaxCount
;
3464 count
= pStubMsg
->ActualCount
;
3465 offset
= pStubMsg
->Offset
;
3468 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3472 pStubMsg
->MaxCount
= max_count
;
3473 pStubMsg
->ActualCount
= count
;
3474 pStubMsg
->Offset
= offset
;
3475 array_buffer_size(conf_array
[0], pStubMsg
, pMemory
, conf_array
,
3476 TRUE
/* fHasPointers */);
3479 pStubMsg
->Memory
= OldMemory
;
3481 if(pointer_length_set
)
3483 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3484 pStubMsg
->PointerLength
= 0;
3489 /***********************************************************************
3490 * NdrComplexStructMemorySize [RPCRT4.@]
3492 ULONG WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3493 PFORMAT_STRING pFormat
)
3495 unsigned size
= *(const WORD
*)(pFormat
+2);
3496 PFORMAT_STRING conf_array
= NULL
;
3497 PFORMAT_STRING pointer_desc
= NULL
;
3499 ULONG max_count
= 0;
3502 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3504 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
3507 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3509 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3514 array_read_conformance(conf_array
[0], pStubMsg
, conf_array
);
3516 /* these could be changed in ComplexStructMemorySize so save them for
3518 max_count
= pStubMsg
->MaxCount
;
3519 count
= pStubMsg
->ActualCount
;
3520 offset
= pStubMsg
->Offset
;
3523 ComplexStructMemorySize(pStubMsg
, pFormat
, pointer_desc
);
3527 pStubMsg
->MaxCount
= max_count
;
3528 pStubMsg
->ActualCount
= count
;
3529 pStubMsg
->Offset
= offset
;
3530 array_memory_size(conf_array
[0], pStubMsg
, conf_array
,
3531 TRUE
/* fHasPointers */);
3537 /***********************************************************************
3538 * NdrComplexStructFree [RPCRT4.@]
3540 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3541 unsigned char *pMemory
,
3542 PFORMAT_STRING pFormat
)
3544 PFORMAT_STRING conf_array
= NULL
;
3545 PFORMAT_STRING pointer_desc
= NULL
;
3546 unsigned char *OldMemory
= pStubMsg
->Memory
;
3548 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3551 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3553 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3556 pStubMsg
->Memory
= pMemory
;
3558 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3561 array_free(conf_array
[0], pStubMsg
, pMemory
, conf_array
,
3562 TRUE
/* fHasPointers */);
3564 pStubMsg
->Memory
= OldMemory
;
3567 /***********************************************************************
3568 * NdrConformantArrayMarshall [RPCRT4.@]
3570 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3571 unsigned char *pMemory
,
3572 PFORMAT_STRING pFormat
)
3574 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3575 if (pFormat
[0] != RPC_FC_CARRAY
)
3577 ERR("invalid format = 0x%x\n", pFormat
[0]);
3578 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3581 array_compute_and_write_conformance(RPC_FC_CARRAY
, pStubMsg
, pMemory
,
3583 array_write_variance_and_marshall(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3584 TRUE
/* fHasPointers */);
3589 /***********************************************************************
3590 * NdrConformantArrayUnmarshall [RPCRT4.@]
3592 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3593 unsigned char **ppMemory
,
3594 PFORMAT_STRING pFormat
,
3595 unsigned char fMustAlloc
)
3597 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3598 if (pFormat
[0] != RPC_FC_CARRAY
)
3600 ERR("invalid format = 0x%x\n", pFormat
[0]);
3601 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3604 array_read_conformance(RPC_FC_CARRAY
, pStubMsg
, pFormat
);
3605 array_read_variance_and_unmarshall(RPC_FC_CARRAY
, pStubMsg
, ppMemory
, pFormat
,
3607 TRUE
/* fUseBufferMemoryServer */,
3608 TRUE
/* fUnmarshall */);
3613 /***********************************************************************
3614 * NdrConformantArrayBufferSize [RPCRT4.@]
3616 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3617 unsigned char *pMemory
,
3618 PFORMAT_STRING pFormat
)
3620 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3621 if (pFormat
[0] != RPC_FC_CARRAY
)
3623 ERR("invalid format = 0x%x\n", pFormat
[0]);
3624 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3627 array_compute_and_size_conformance(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
);
3628 array_buffer_size(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3629 TRUE
/* fHasPointers */);
3632 /***********************************************************************
3633 * NdrConformantArrayMemorySize [RPCRT4.@]
3635 ULONG WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3636 PFORMAT_STRING pFormat
)
3638 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3639 if (pFormat
[0] != RPC_FC_CARRAY
)
3641 ERR("invalid format = 0x%x\n", pFormat
[0]);
3642 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3645 array_read_conformance(RPC_FC_CARRAY
, pStubMsg
, pFormat
);
3646 array_memory_size(RPC_FC_CARRAY
, pStubMsg
, pFormat
, TRUE
/* fHasPointers */);
3648 return pStubMsg
->MemorySize
;
3651 /***********************************************************************
3652 * NdrConformantArrayFree [RPCRT4.@]
3654 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3655 unsigned char *pMemory
,
3656 PFORMAT_STRING pFormat
)
3658 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3659 if (pFormat
[0] != RPC_FC_CARRAY
)
3661 ERR("invalid format = 0x%x\n", pFormat
[0]);
3662 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3665 array_free(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3666 TRUE
/* fHasPointers */);
3670 /***********************************************************************
3671 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3673 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
3674 unsigned char* pMemory
,
3675 PFORMAT_STRING pFormat
)
3677 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3679 if (pFormat
[0] != RPC_FC_CVARRAY
)
3681 ERR("invalid format type %x\n", pFormat
[0]);
3682 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3686 array_compute_and_write_conformance(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
3688 array_write_variance_and_marshall(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
3689 pFormat
, TRUE
/* fHasPointers */);
3695 /***********************************************************************
3696 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
3698 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
3699 unsigned char** ppMemory
,
3700 PFORMAT_STRING pFormat
,
3701 unsigned char fMustAlloc
)
3703 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3705 if (pFormat
[0] != RPC_FC_CVARRAY
)
3707 ERR("invalid format type %x\n", pFormat
[0]);
3708 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3712 array_read_conformance(RPC_FC_CVARRAY
, pStubMsg
, pFormat
);
3713 array_read_variance_and_unmarshall(RPC_FC_CVARRAY
, pStubMsg
, ppMemory
,
3714 pFormat
, fMustAlloc
,
3715 TRUE
/* fUseBufferMemoryServer */,
3716 TRUE
/* fUnmarshall */);
3722 /***********************************************************************
3723 * NdrConformantVaryingArrayFree [RPCRT4.@]
3725 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
3726 unsigned char* pMemory
,
3727 PFORMAT_STRING pFormat
)
3729 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3731 if (pFormat
[0] != RPC_FC_CVARRAY
)
3733 ERR("invalid format type %x\n", pFormat
[0]);
3734 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3738 array_free(RPC_FC_CVARRAY
, pStubMsg
, pMemory
, pFormat
,
3739 TRUE
/* fHasPointers */);
3743 /***********************************************************************
3744 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
3746 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
3747 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
3749 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3751 if (pFormat
[0] != RPC_FC_CVARRAY
)
3753 ERR("invalid format type %x\n", pFormat
[0]);
3754 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3758 array_compute_and_size_conformance(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
3760 array_buffer_size(RPC_FC_CVARRAY
, pStubMsg
, pMemory
, pFormat
,
3761 TRUE
/* fHasPointers */);
3765 /***********************************************************************
3766 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
3768 ULONG WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
3769 PFORMAT_STRING pFormat
)
3771 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
3773 if (pFormat
[0] != RPC_FC_CVARRAY
)
3775 ERR("invalid format type %x\n", pFormat
[0]);
3776 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3777 return pStubMsg
->MemorySize
;
3780 array_read_conformance(RPC_FC_CVARRAY
, pStubMsg
, pFormat
);
3781 array_memory_size(RPC_FC_CVARRAY
, pStubMsg
, pFormat
,
3782 TRUE
/* fHasPointers */);
3784 return pStubMsg
->MemorySize
;
3788 /***********************************************************************
3789 * NdrComplexArrayMarshall [RPCRT4.@]
3791 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3792 unsigned char *pMemory
,
3793 PFORMAT_STRING pFormat
)
3795 ULONG i
, count
, def
;
3796 BOOL variance_present
;
3797 unsigned char alignment
;
3798 int pointer_buffer_mark_set
= 0;
3800 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3802 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3804 ERR("invalid format type %x\n", pFormat
[0]);
3805 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3809 alignment
= pFormat
[1] + 1;
3811 if (!pStubMsg
->PointerBufferMark
)
3813 /* save buffer fields that may be changed by buffer sizer functions
3814 * and that may be needed later on */
3815 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3816 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
3817 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
3818 unsigned long saved_offset
= pStubMsg
->Offset
;
3819 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
3821 /* get the buffer pointer after complex array data, but before
3823 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- pStubMsg
->BufferStart
;
3824 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3825 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
3826 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3828 /* save it for use by embedded pointer code later */
3829 pStubMsg
->PointerBufferMark
= pStubMsg
->BufferStart
+ pStubMsg
->BufferLength
;
3830 TRACE("difference = 0x%x\n", pStubMsg
->Buffer
- pStubMsg
->BufferStart
);
3831 pointer_buffer_mark_set
= 1;
3833 /* restore fields */
3834 pStubMsg
->ActualCount
= saved_actual_count
;
3835 pStubMsg
->Offset
= saved_offset
;
3836 pStubMsg
->MaxCount
= saved_max_count
;
3837 pStubMsg
->BufferLength
= saved_buffer_length
;
3840 def
= *(const WORD
*)&pFormat
[2];
3843 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3844 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3846 variance_present
= IsConformanceOrVariancePresent(pFormat
);
3847 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3848 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3850 WriteConformance(pStubMsg
);
3851 if (variance_present
)
3852 WriteVariance(pStubMsg
);
3854 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
3856 count
= pStubMsg
->ActualCount
;
3857 for (i
= 0; i
< count
; i
++)
3858 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
3860 STD_OVERFLOW_CHECK(pStubMsg
);
3862 if (pointer_buffer_mark_set
)
3864 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3865 pStubMsg
->PointerBufferMark
= NULL
;
3871 /***********************************************************************
3872 * NdrComplexArrayUnmarshall [RPCRT4.@]
3874 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3875 unsigned char **ppMemory
,
3876 PFORMAT_STRING pFormat
,
3877 unsigned char fMustAlloc
)
3879 ULONG i
, count
, size
;
3880 unsigned char alignment
;
3881 unsigned char *pMemory
;
3882 unsigned char *saved_buffer
;
3883 int pointer_buffer_mark_set
= 0;
3884 int saved_ignore_embedded
;
3886 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3888 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3890 ERR("invalid format type %x\n", pFormat
[0]);
3891 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3895 alignment
= pFormat
[1] + 1;
3897 saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3898 /* save buffer pointer */
3899 saved_buffer
= pStubMsg
->Buffer
;
3900 /* get the buffer pointer after complex array data, but before
3902 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3903 pStubMsg
->MemorySize
= 0;
3904 NdrComplexArrayMemorySize(pStubMsg
, pFormat
);
3905 size
= pStubMsg
->MemorySize
;
3906 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3908 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->Buffer
- saved_buffer
));
3909 if (!pStubMsg
->PointerBufferMark
)
3911 /* save it for use by embedded pointer code later */
3912 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3913 pointer_buffer_mark_set
= 1;
3915 /* restore the original buffer */
3916 pStubMsg
->Buffer
= saved_buffer
;
3920 pFormat
= ReadConformance(pStubMsg
, pFormat
);
3921 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3923 if (fMustAlloc
|| !*ppMemory
)
3924 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3926 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3928 pMemory
= *ppMemory
;
3929 count
= pStubMsg
->ActualCount
;
3930 for (i
= 0; i
< count
; i
++)
3931 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
, fMustAlloc
);
3933 if (pointer_buffer_mark_set
)
3935 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3936 pStubMsg
->PointerBufferMark
= NULL
;
3942 /***********************************************************************
3943 * NdrComplexArrayBufferSize [RPCRT4.@]
3945 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3946 unsigned char *pMemory
,
3947 PFORMAT_STRING pFormat
)
3949 ULONG i
, count
, def
;
3950 unsigned char alignment
;
3951 BOOL variance_present
;
3952 int pointer_length_set
= 0;
3954 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3956 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3958 ERR("invalid format type %x\n", pFormat
[0]);
3959 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3963 alignment
= pFormat
[1] + 1;
3965 if (!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
3967 /* save buffer fields that may be changed by buffer sizer functions
3968 * and that may be needed later on */
3969 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3970 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
3971 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
3972 unsigned long saved_offset
= pStubMsg
->Offset
;
3973 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
3975 /* get the buffer pointer after complex array data, but before
3977 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3978 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
3979 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3981 /* save it for use by embedded pointer code later */
3982 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3983 pointer_length_set
= 1;
3985 /* restore fields */
3986 pStubMsg
->ActualCount
= saved_actual_count
;
3987 pStubMsg
->Offset
= saved_offset
;
3988 pStubMsg
->MaxCount
= saved_max_count
;
3989 pStubMsg
->BufferLength
= saved_buffer_length
;
3991 def
= *(const WORD
*)&pFormat
[2];
3994 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3995 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3996 SizeConformance(pStubMsg
);
3998 variance_present
= IsConformanceOrVariancePresent(pFormat
);
3999 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
4000 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
4002 if (variance_present
)
4003 SizeVariance(pStubMsg
);
4005 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
4007 count
= pStubMsg
->ActualCount
;
4008 for (i
= 0; i
< count
; i
++)
4009 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
4011 if(pointer_length_set
)
4013 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4014 pStubMsg
->PointerLength
= 0;
4018 /***********************************************************************
4019 * NdrComplexArrayMemorySize [RPCRT4.@]
4021 ULONG WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4022 PFORMAT_STRING pFormat
)
4024 ULONG i
, count
, esize
, SavedMemorySize
, MemorySize
;
4025 unsigned char alignment
;
4027 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
4029 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4031 ERR("invalid format type %x\n", pFormat
[0]);
4032 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4036 alignment
= pFormat
[1] + 1;
4040 pFormat
= ReadConformance(pStubMsg
, pFormat
);
4041 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
4043 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4045 SavedMemorySize
= pStubMsg
->MemorySize
;
4047 esize
= ComplexStructSize(pStubMsg
, pFormat
);
4049 MemorySize
= safe_multiply(pStubMsg
->MaxCount
, esize
);
4051 count
= pStubMsg
->ActualCount
;
4052 for (i
= 0; i
< count
; i
++)
4053 ComplexStructMemorySize(pStubMsg
, pFormat
, NULL
);
4055 pStubMsg
->MemorySize
= SavedMemorySize
;
4057 pStubMsg
->MemorySize
+= MemorySize
;
4061 /***********************************************************************
4062 * NdrComplexArrayFree [RPCRT4.@]
4064 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4065 unsigned char *pMemory
,
4066 PFORMAT_STRING pFormat
)
4068 ULONG i
, count
, def
;
4070 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4072 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4074 ERR("invalid format type %x\n", pFormat
[0]);
4075 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4079 def
= *(const WORD
*)&pFormat
[2];
4082 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
4083 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
4085 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
4086 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
4088 count
= pStubMsg
->ActualCount
;
4089 for (i
= 0; i
< count
; i
++)
4090 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
4093 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg
,
4094 USER_MARSHAL_CB_TYPE cbtype
, PFORMAT_STRING pFormat
,
4095 USER_MARSHAL_CB
*umcb
)
4097 umcb
->Flags
= MAKELONG(pStubMsg
->dwDestContext
,
4098 pStubMsg
->RpcMsg
->DataRepresentation
);
4099 umcb
->pStubMsg
= pStubMsg
;
4100 umcb
->pReserve
= NULL
;
4101 umcb
->Signature
= USER_MARSHAL_CB_SIGNATURE
;
4102 umcb
->CBType
= cbtype
;
4103 umcb
->pFormat
= pFormat
;
4104 umcb
->pTypeFormat
= NULL
/* FIXME */;
4107 #define USER_MARSHAL_PTR_PREFIX \
4108 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4109 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4111 /***********************************************************************
4112 * NdrUserMarshalMarshall [RPCRT4.@]
4114 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4115 unsigned char *pMemory
,
4116 PFORMAT_STRING pFormat
)
4118 unsigned flags
= pFormat
[1];
4119 unsigned index
= *(const WORD
*)&pFormat
[2];
4120 unsigned char *saved_buffer
= NULL
;
4121 USER_MARSHAL_CB umcb
;
4123 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4124 TRACE("index=%d\n", index
);
4126 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_MARSHALL
, pFormat
, &umcb
);
4128 if (flags
& USER_MARSHAL_POINTER
)
4130 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
4131 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, USER_MARSHAL_PTR_PREFIX
);
4132 pStubMsg
->Buffer
+= 4;
4133 if (pStubMsg
->PointerBufferMark
)
4135 saved_buffer
= pStubMsg
->Buffer
;
4136 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4137 pStubMsg
->PointerBufferMark
= NULL
;
4139 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 8);
4142 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4145 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
4146 &umcb
.Flags
, pStubMsg
->Buffer
, pMemory
);
4150 STD_OVERFLOW_CHECK(pStubMsg
);
4151 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4152 pStubMsg
->Buffer
= saved_buffer
;
4155 STD_OVERFLOW_CHECK(pStubMsg
);
4160 /***********************************************************************
4161 * NdrUserMarshalUnmarshall [RPCRT4.@]
4163 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4164 unsigned char **ppMemory
,
4165 PFORMAT_STRING pFormat
,
4166 unsigned char fMustAlloc
)
4168 unsigned flags
= pFormat
[1];
4169 unsigned index
= *(const WORD
*)&pFormat
[2];
4170 DWORD memsize
= *(const WORD
*)&pFormat
[4];
4171 unsigned char *saved_buffer
= NULL
;
4172 USER_MARSHAL_CB umcb
;
4174 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4175 TRACE("index=%d\n", index
);
4177 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_UNMARSHALL
, pFormat
, &umcb
);
4179 if (flags
& USER_MARSHAL_POINTER
)
4181 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4182 /* skip pointer prefix */
4183 pStubMsg
->Buffer
+= 4;
4184 if (pStubMsg
->PointerBufferMark
)
4186 saved_buffer
= pStubMsg
->Buffer
;
4187 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4188 pStubMsg
->PointerBufferMark
= NULL
;
4190 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
4193 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4195 if (fMustAlloc
|| !*ppMemory
)
4196 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
4199 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
4200 &umcb
.Flags
, pStubMsg
->Buffer
, *ppMemory
);
4204 STD_OVERFLOW_CHECK(pStubMsg
);
4205 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4206 pStubMsg
->Buffer
= saved_buffer
;
4212 /***********************************************************************
4213 * NdrUserMarshalBufferSize [RPCRT4.@]
4215 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4216 unsigned char *pMemory
,
4217 PFORMAT_STRING pFormat
)
4219 unsigned flags
= pFormat
[1];
4220 unsigned index
= *(const WORD
*)&pFormat
[2];
4221 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
4222 USER_MARSHAL_CB umcb
;
4223 unsigned long saved_buffer_length
= 0;
4225 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4226 TRACE("index=%d\n", index
);
4228 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_BUFFER_SIZE
, pFormat
, &umcb
);
4230 if (flags
& USER_MARSHAL_POINTER
)
4232 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
4233 /* skip pointer prefix */
4234 safe_buffer_length_increment(pStubMsg
, 4);
4235 if (pStubMsg
->IgnoreEmbeddedPointers
)
4237 if (pStubMsg
->PointerLength
)
4239 saved_buffer_length
= pStubMsg
->BufferLength
;
4240 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4241 pStubMsg
->PointerLength
= 0;
4243 ALIGN_LENGTH(pStubMsg
->BufferLength
, 8);
4246 ALIGN_LENGTH(pStubMsg
->BufferLength
, (flags
& 0xf) + 1);
4249 TRACE("size=%d\n", bufsize
);
4250 safe_buffer_length_increment(pStubMsg
, bufsize
);
4253 pStubMsg
->BufferLength
=
4254 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
4255 &umcb
.Flags
, pStubMsg
->BufferLength
, pMemory
);
4257 if (saved_buffer_length
)
4259 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4260 pStubMsg
->BufferLength
= saved_buffer_length
;
4265 /***********************************************************************
4266 * NdrUserMarshalMemorySize [RPCRT4.@]
4268 ULONG WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4269 PFORMAT_STRING pFormat
)
4271 unsigned flags
= pFormat
[1];
4272 unsigned index
= *(const WORD
*)&pFormat
[2];
4273 DWORD memsize
= *(const WORD
*)&pFormat
[4];
4274 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
4276 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
4277 TRACE("index=%d\n", index
);
4279 pStubMsg
->MemorySize
+= memsize
;
4281 if (flags
& USER_MARSHAL_POINTER
)
4283 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4284 /* skip pointer prefix */
4285 pStubMsg
->Buffer
+= 4;
4286 if (pStubMsg
->IgnoreEmbeddedPointers
)
4287 return pStubMsg
->MemorySize
;
4288 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
4291 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4294 FIXME("not implemented for varying buffer size\n");
4296 pStubMsg
->Buffer
+= bufsize
;
4298 return pStubMsg
->MemorySize
;
4301 /***********************************************************************
4302 * NdrUserMarshalFree [RPCRT4.@]
4304 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
4305 unsigned char *pMemory
,
4306 PFORMAT_STRING pFormat
)
4308 /* unsigned flags = pFormat[1]; */
4309 unsigned index
= *(const WORD
*)&pFormat
[2];
4310 USER_MARSHAL_CB umcb
;
4312 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4313 TRACE("index=%d\n", index
);
4315 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_FREE
, pFormat
, &umcb
);
4317 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
4318 &umcb
.Flags
, pMemory
);
4321 /***********************************************************************
4322 * NdrClearOutParameters [RPCRT4.@]
4324 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
4325 PFORMAT_STRING pFormat
,
4328 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
4331 /***********************************************************************
4332 * NdrConvert [RPCRT4.@]
4334 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
4336 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
4337 /* FIXME: since this stub doesn't do any converting, the proper behavior
4338 is to raise an exception */
4341 /***********************************************************************
4342 * NdrConvert2 [RPCRT4.@]
4344 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, LONG NumberParams
)
4346 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4347 pStubMsg
, pFormat
, NumberParams
);
4348 /* FIXME: since this stub doesn't do any converting, the proper behavior
4349 is to raise an exception */
4352 #include "pshpack1.h"
4353 typedef struct _NDR_CSTRUCT_FORMAT
4356 unsigned char alignment
;
4357 unsigned short memory_size
;
4358 short offset_to_array_description
;
4359 } NDR_CSTRUCT_FORMAT
, NDR_CVSTRUCT_FORMAT
;
4360 #include "poppack.h"
4362 /***********************************************************************
4363 * NdrConformantStructMarshall [RPCRT4.@]
4365 unsigned char * WINAPI
NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4366 unsigned char *pMemory
,
4367 PFORMAT_STRING pFormat
)
4369 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4370 PFORMAT_STRING pCArrayFormat
;
4371 ULONG esize
, bufsize
;
4373 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4375 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4376 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4378 ERR("invalid format type %x\n", pCStructFormat
->type
);
4379 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4383 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4384 pCStructFormat
->offset_to_array_description
;
4385 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4387 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4388 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4391 esize
= *(const WORD
*)(pCArrayFormat
+2);
4393 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4394 pCArrayFormat
+ 4, 0);
4396 WriteConformance(pStubMsg
);
4398 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4400 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4402 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4403 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4405 ERR("integer overflow of memory_size %u with bufsize %u\n",
4406 pCStructFormat
->memory_size
, bufsize
);
4407 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4409 /* copy constant sized part of struct */
4410 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4411 safe_copy_to_buffer(pStubMsg
, pMemory
, pCStructFormat
->memory_size
+ bufsize
);
4413 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4414 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4419 /***********************************************************************
4420 * NdrConformantStructUnmarshall [RPCRT4.@]
4422 unsigned char * WINAPI
NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4423 unsigned char **ppMemory
,
4424 PFORMAT_STRING pFormat
,
4425 unsigned char fMustAlloc
)
4427 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4428 PFORMAT_STRING pCArrayFormat
;
4429 ULONG esize
, bufsize
;
4430 unsigned char *saved_buffer
;
4432 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4434 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4435 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4437 ERR("invalid format type %x\n", pCStructFormat
->type
);
4438 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4441 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4442 pCStructFormat
->offset_to_array_description
;
4443 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4445 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4446 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4449 esize
= *(const WORD
*)(pCArrayFormat
+2);
4451 pCArrayFormat
= ReadConformance(pStubMsg
, pCArrayFormat
+ 4);
4453 ALIGN_POINTER(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4455 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4457 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4458 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4460 ERR("integer overflow of memory_size %u with bufsize %u\n",
4461 pCStructFormat
->memory_size
, bufsize
);
4462 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4467 SIZE_T size
= pCStructFormat
->memory_size
+ bufsize
;
4468 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4472 if (!pStubMsg
->IsClient
&& !*ppMemory
)
4473 /* for servers, we just point straight into the RPC buffer */
4474 *ppMemory
= pStubMsg
->Buffer
;
4477 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4478 safe_buffer_increment(pStubMsg
, pCStructFormat
->memory_size
+ bufsize
);
4479 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4480 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4482 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
4483 if (*ppMemory
!= saved_buffer
)
4484 memcpy(*ppMemory
, saved_buffer
, pCStructFormat
->memory_size
+ bufsize
);
4489 /***********************************************************************
4490 * NdrConformantStructBufferSize [RPCRT4.@]
4492 void WINAPI
NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4493 unsigned char *pMemory
,
4494 PFORMAT_STRING pFormat
)
4496 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4497 PFORMAT_STRING pCArrayFormat
;
4500 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4502 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4503 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4505 ERR("invalid format type %x\n", pCStructFormat
->type
);
4506 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4509 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4510 pCStructFormat
->offset_to_array_description
;
4511 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4513 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4514 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4517 esize
= *(const WORD
*)(pCArrayFormat
+2);
4519 pCArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
, pCArrayFormat
+4, 0);
4520 SizeConformance(pStubMsg
);
4522 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCStructFormat
->alignment
+ 1);
4524 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4526 safe_buffer_length_increment(pStubMsg
, pCStructFormat
->memory_size
);
4527 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
4529 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4530 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4533 /***********************************************************************
4534 * NdrConformantStructMemorySize [RPCRT4.@]
4536 ULONG WINAPI
NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4537 PFORMAT_STRING pFormat
)
4543 /***********************************************************************
4544 * NdrConformantStructFree [RPCRT4.@]
4546 void WINAPI
NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
4547 unsigned char *pMemory
,
4548 PFORMAT_STRING pFormat
)
4550 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4551 PFORMAT_STRING pCArrayFormat
;
4553 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4555 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4556 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4558 ERR("invalid format type %x\n", pCStructFormat
->type
);
4559 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4563 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4564 pCStructFormat
->offset_to_array_description
;
4565 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4567 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4568 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4572 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4573 pCArrayFormat
+ 4, 0);
4575 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4577 /* copy constant sized part of struct */
4578 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4580 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4581 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4584 /***********************************************************************
4585 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4587 unsigned char * WINAPI
NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4588 unsigned char *pMemory
,
4589 PFORMAT_STRING pFormat
)
4591 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4592 PFORMAT_STRING pCVArrayFormat
;
4594 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4596 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4597 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4599 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4600 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4604 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4605 pCVStructFormat
->offset_to_array_description
;
4607 array_compute_and_write_conformance(*pCVArrayFormat
, pStubMsg
,
4608 pMemory
+ pCVStructFormat
->memory_size
,
4611 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4613 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4615 /* write constant sized part */
4616 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4617 safe_copy_to_buffer(pStubMsg
, pMemory
, pCVStructFormat
->memory_size
);
4619 array_write_variance_and_marshall(*pCVArrayFormat
, pStubMsg
,
4620 pMemory
+ pCVStructFormat
->memory_size
,
4621 pCVArrayFormat
, FALSE
/* fHasPointers */);
4623 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4628 /***********************************************************************
4629 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4631 unsigned char * WINAPI
NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4632 unsigned char **ppMemory
,
4633 PFORMAT_STRING pFormat
,
4634 unsigned char fMustAlloc
)
4636 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4637 PFORMAT_STRING pCVArrayFormat
;
4638 ULONG memsize
, bufsize
;
4639 unsigned char *saved_buffer
, *saved_array_buffer
;
4641 unsigned char *array_memory
;
4643 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4645 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4646 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4648 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4649 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4653 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4654 pCVStructFormat
->offset_to_array_description
;
4656 memsize
= array_read_conformance(*pCVArrayFormat
, pStubMsg
,
4659 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4661 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4663 /* work out how much memory to allocate if we need to do so */
4664 if (!*ppMemory
|| fMustAlloc
)
4666 SIZE_T size
= pCVStructFormat
->memory_size
+ memsize
;
4667 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4670 /* mark the start of the constant data */
4671 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4672 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4674 array_memory
= *ppMemory
+ pCVStructFormat
->memory_size
;
4675 bufsize
= array_read_variance_and_unmarshall(*pCVArrayFormat
, pStubMsg
,
4676 &array_memory
, pCVArrayFormat
,
4677 FALSE
/* fMustAlloc */,
4678 FALSE
/* fUseServerBufferMemory */,
4679 FALSE
/* fUnmarshall */);
4681 /* save offset in case unmarshalling pointers changes it */
4682 offset
= pStubMsg
->Offset
;
4684 /* mark the start of the array data */
4685 saved_array_buffer
= pStubMsg
->Buffer
;
4686 safe_buffer_increment(pStubMsg
, bufsize
);
4688 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4690 /* copy the constant data */
4691 memcpy(*ppMemory
, saved_buffer
, pCVStructFormat
->memory_size
);
4692 /* copy the array data */
4693 TRACE("copying %p to %p\n", saved_array_buffer
, *ppMemory
+ pCVStructFormat
->memory_size
);
4694 memcpy(*ppMemory
+ pCVStructFormat
->memory_size
+ offset
,
4695 saved_array_buffer
, bufsize
);
4697 if (*pCVArrayFormat
== RPC_FC_C_CSTRING
)
4698 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory
+ pCVStructFormat
->memory_size
)));
4699 else if (*pCVArrayFormat
== RPC_FC_C_WSTRING
)
4700 TRACE("string=%s\n", debugstr_w((WCHAR
*)(*ppMemory
+ pCVStructFormat
->memory_size
)));
4705 /***********************************************************************
4706 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
4708 void WINAPI
NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4709 unsigned char *pMemory
,
4710 PFORMAT_STRING pFormat
)
4712 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4713 PFORMAT_STRING pCVArrayFormat
;
4715 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4717 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4718 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4720 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4721 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4725 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4726 pCVStructFormat
->offset_to_array_description
;
4727 array_compute_and_size_conformance(*pCVArrayFormat
, pStubMsg
,
4728 pMemory
+ pCVStructFormat
->memory_size
,
4731 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCVStructFormat
->alignment
+ 1);
4733 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4735 safe_buffer_length_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4737 array_buffer_size(*pCVArrayFormat
, pStubMsg
,
4738 pMemory
+ pCVStructFormat
->memory_size
, pCVArrayFormat
,
4739 FALSE
/* fHasPointers */);
4741 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4744 /***********************************************************************
4745 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4747 ULONG WINAPI
NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4748 PFORMAT_STRING pFormat
)
4750 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4751 PFORMAT_STRING pCVArrayFormat
;
4753 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4755 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4756 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4758 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4759 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4763 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4764 pCVStructFormat
->offset_to_array_description
;
4765 array_read_conformance(*pCVArrayFormat
, pStubMsg
, pCVArrayFormat
);
4767 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4769 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4771 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4772 array_memory_size(*pCVArrayFormat
, pStubMsg
, pCVArrayFormat
,
4773 FALSE
/* fHasPointers */);
4775 pStubMsg
->MemorySize
+= pCVStructFormat
->memory_size
;
4777 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4779 return pStubMsg
->MemorySize
;
4782 /***********************************************************************
4783 * NdrConformantVaryingStructFree [RPCRT4.@]
4785 void WINAPI
NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
4786 unsigned char *pMemory
,
4787 PFORMAT_STRING pFormat
)
4789 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4790 PFORMAT_STRING pCVArrayFormat
;
4792 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4794 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4795 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4797 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4798 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4802 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4803 pCVStructFormat
->offset_to_array_description
;
4804 array_free(*pCVArrayFormat
, pStubMsg
,
4805 pMemory
+ pCVStructFormat
->memory_size
, pCVArrayFormat
,
4806 FALSE
/* fHasPointers */);
4808 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4810 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4813 #include "pshpack1.h"
4817 unsigned char alignment
;
4818 unsigned short total_size
;
4819 } NDR_SMFARRAY_FORMAT
;
4824 unsigned char alignment
;
4825 unsigned long total_size
;
4826 } NDR_LGFARRAY_FORMAT
;
4827 #include "poppack.h"
4829 /***********************************************************************
4830 * NdrFixedArrayMarshall [RPCRT4.@]
4832 unsigned char * WINAPI
NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4833 unsigned char *pMemory
,
4834 PFORMAT_STRING pFormat
)
4836 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4837 unsigned long total_size
;
4839 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4841 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4842 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4844 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4845 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4849 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4851 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4853 total_size
= pSmFArrayFormat
->total_size
;
4854 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4858 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4859 total_size
= pLgFArrayFormat
->total_size
;
4860 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4863 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4864 safe_copy_to_buffer(pStubMsg
, pMemory
, total_size
);
4866 pFormat
= EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4871 /***********************************************************************
4872 * NdrFixedArrayUnmarshall [RPCRT4.@]
4874 unsigned char * WINAPI
NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4875 unsigned char **ppMemory
,
4876 PFORMAT_STRING pFormat
,
4877 unsigned char fMustAlloc
)
4879 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4880 unsigned long total_size
;
4881 unsigned char *saved_buffer
;
4883 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4885 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4886 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4888 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4889 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4893 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4895 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4897 total_size
= pSmFArrayFormat
->total_size
;
4898 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4902 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4903 total_size
= pLgFArrayFormat
->total_size
;
4904 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4908 *ppMemory
= NdrAllocate(pStubMsg
, total_size
);
4911 if (!pStubMsg
->IsClient
&& !*ppMemory
)
4912 /* for servers, we just point straight into the RPC buffer */
4913 *ppMemory
= pStubMsg
->Buffer
;
4916 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4917 safe_buffer_increment(pStubMsg
, total_size
);
4918 pFormat
= EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4920 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
4921 if (*ppMemory
!= saved_buffer
)
4922 memcpy(*ppMemory
, saved_buffer
, total_size
);
4927 /***********************************************************************
4928 * NdrFixedArrayBufferSize [RPCRT4.@]
4930 void WINAPI
NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4931 unsigned char *pMemory
,
4932 PFORMAT_STRING pFormat
)
4934 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4935 unsigned long total_size
;
4937 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4939 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4940 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4942 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4943 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4947 ALIGN_LENGTH(pStubMsg
->BufferLength
, pSmFArrayFormat
->alignment
+ 1);
4949 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4951 total_size
= pSmFArrayFormat
->total_size
;
4952 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4956 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4957 total_size
= pLgFArrayFormat
->total_size
;
4958 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4960 safe_buffer_length_increment(pStubMsg
, total_size
);
4962 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4965 /***********************************************************************
4966 * NdrFixedArrayMemorySize [RPCRT4.@]
4968 ULONG WINAPI
NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4969 PFORMAT_STRING pFormat
)
4971 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4974 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4976 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4977 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4979 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4980 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4984 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4986 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4988 total_size
= pSmFArrayFormat
->total_size
;
4989 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4993 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4994 total_size
= pLgFArrayFormat
->total_size
;
4995 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4997 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4998 safe_buffer_increment(pStubMsg
, total_size
);
4999 pStubMsg
->MemorySize
+= total_size
;
5001 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5006 /***********************************************************************
5007 * NdrFixedArrayFree [RPCRT4.@]
5009 void WINAPI
NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
5010 unsigned char *pMemory
,
5011 PFORMAT_STRING pFormat
)
5013 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5015 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5017 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5018 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5020 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5021 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5025 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5026 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5029 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5030 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5033 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5036 /***********************************************************************
5037 * NdrVaryingArrayMarshall [RPCRT4.@]
5039 unsigned char * WINAPI
NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5040 unsigned char *pMemory
,
5041 PFORMAT_STRING pFormat
)
5043 unsigned char alignment
;
5044 DWORD elements
, esize
;
5047 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5049 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5050 (pFormat
[0] != RPC_FC_LGVARRAY
))
5052 ERR("invalid format type %x\n", pFormat
[0]);
5053 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5057 alignment
= pFormat
[1] + 1;
5059 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5062 pFormat
+= sizeof(WORD
);
5063 elements
= *(const WORD
*)pFormat
;
5064 pFormat
+= sizeof(WORD
);
5069 pFormat
+= sizeof(DWORD
);
5070 elements
= *(const DWORD
*)pFormat
;
5071 pFormat
+= sizeof(DWORD
);
5074 esize
= *(const WORD
*)pFormat
;
5075 pFormat
+= sizeof(WORD
);
5077 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5078 if ((pStubMsg
->ActualCount
> elements
) ||
5079 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5081 RpcRaiseException(RPC_S_INVALID_BOUND
);
5085 WriteVariance(pStubMsg
);
5087 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
5089 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
5090 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5091 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
5093 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
5098 /***********************************************************************
5099 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5101 unsigned char * WINAPI
NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5102 unsigned char **ppMemory
,
5103 PFORMAT_STRING pFormat
,
5104 unsigned char fMustAlloc
)
5106 unsigned char alignment
;
5107 DWORD size
, elements
, esize
;
5109 unsigned char *saved_buffer
;
5112 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5114 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5115 (pFormat
[0] != RPC_FC_LGVARRAY
))
5117 ERR("invalid format type %x\n", pFormat
[0]);
5118 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5122 alignment
= pFormat
[1] + 1;
5124 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5127 size
= *(const WORD
*)pFormat
;
5128 pFormat
+= sizeof(WORD
);
5129 elements
= *(const WORD
*)pFormat
;
5130 pFormat
+= sizeof(WORD
);
5135 size
= *(const DWORD
*)pFormat
;
5136 pFormat
+= sizeof(DWORD
);
5137 elements
= *(const DWORD
*)pFormat
;
5138 pFormat
+= sizeof(DWORD
);
5141 esize
= *(const WORD
*)pFormat
;
5142 pFormat
+= sizeof(WORD
);
5144 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
5146 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
5148 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
5149 offset
= pStubMsg
->Offset
;
5151 if (!*ppMemory
|| fMustAlloc
)
5152 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5153 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5154 safe_buffer_increment(pStubMsg
, bufsize
);
5156 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
5158 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
5163 /***********************************************************************
5164 * NdrVaryingArrayBufferSize [RPCRT4.@]
5166 void WINAPI
NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5167 unsigned char *pMemory
,
5168 PFORMAT_STRING pFormat
)
5170 unsigned char alignment
;
5171 DWORD elements
, esize
;
5173 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5175 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5176 (pFormat
[0] != RPC_FC_LGVARRAY
))
5178 ERR("invalid format type %x\n", pFormat
[0]);
5179 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5183 alignment
= pFormat
[1] + 1;
5185 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5188 pFormat
+= sizeof(WORD
);
5189 elements
= *(const WORD
*)pFormat
;
5190 pFormat
+= sizeof(WORD
);
5195 pFormat
+= sizeof(DWORD
);
5196 elements
= *(const DWORD
*)pFormat
;
5197 pFormat
+= sizeof(DWORD
);
5200 esize
= *(const WORD
*)pFormat
;
5201 pFormat
+= sizeof(WORD
);
5203 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5204 if ((pStubMsg
->ActualCount
> elements
) ||
5205 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5207 RpcRaiseException(RPC_S_INVALID_BOUND
);
5211 SizeVariance(pStubMsg
);
5213 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
5215 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
5217 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5220 /***********************************************************************
5221 * NdrVaryingArrayMemorySize [RPCRT4.@]
5223 ULONG WINAPI
NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5224 PFORMAT_STRING pFormat
)
5226 unsigned char alignment
;
5227 DWORD size
, elements
, esize
;
5229 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5231 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5232 (pFormat
[0] != RPC_FC_LGVARRAY
))
5234 ERR("invalid format type %x\n", pFormat
[0]);
5235 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5239 alignment
= pFormat
[1] + 1;
5241 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5244 size
= *(const WORD
*)pFormat
;
5245 pFormat
+= sizeof(WORD
);
5246 elements
= *(const WORD
*)pFormat
;
5247 pFormat
+= sizeof(WORD
);
5252 size
= *(const DWORD
*)pFormat
;
5253 pFormat
+= sizeof(DWORD
);
5254 elements
= *(const DWORD
*)pFormat
;
5255 pFormat
+= sizeof(DWORD
);
5258 esize
= *(const WORD
*)pFormat
;
5259 pFormat
+= sizeof(WORD
);
5261 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
5263 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
5265 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
5266 pStubMsg
->MemorySize
+= size
;
5268 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5270 return pStubMsg
->MemorySize
;
5273 /***********************************************************************
5274 * NdrVaryingArrayFree [RPCRT4.@]
5276 void WINAPI
NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
5277 unsigned char *pMemory
,
5278 PFORMAT_STRING pFormat
)
5282 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5284 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5285 (pFormat
[0] != RPC_FC_LGVARRAY
))
5287 ERR("invalid format type %x\n", pFormat
[0]);
5288 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5292 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5295 pFormat
+= sizeof(WORD
);
5296 elements
= *(const WORD
*)pFormat
;
5297 pFormat
+= sizeof(WORD
);
5302 pFormat
+= sizeof(DWORD
);
5303 elements
= *(const DWORD
*)pFormat
;
5304 pFormat
+= sizeof(DWORD
);
5307 pFormat
+= sizeof(WORD
);
5309 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5310 if ((pStubMsg
->ActualCount
> elements
) ||
5311 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5313 RpcRaiseException(RPC_S_INVALID_BOUND
);
5317 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5320 static ULONG
get_discriminant(unsigned char fc
, const unsigned char *pMemory
)
5333 return *(const USHORT
*)pMemory
;
5337 return *(const ULONG
*)pMemory
;
5339 FIXME("Unhandled base type: 0x%02x\n", fc
);
5344 static PFORMAT_STRING
get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg
,
5345 unsigned long discriminant
,
5346 PFORMAT_STRING pFormat
)
5348 unsigned short num_arms
, arm
, type
;
5350 num_arms
= *(const SHORT
*)pFormat
& 0x0fff;
5352 for(arm
= 0; arm
< num_arms
; arm
++)
5354 if(discriminant
== *(const ULONG
*)pFormat
)
5362 type
= *(const unsigned short*)pFormat
;
5363 TRACE("type %04x\n", type
);
5364 if(arm
== num_arms
) /* default arm extras */
5368 ERR("no arm for 0x%lx and no default case\n", discriminant
);
5369 RpcRaiseException(RPC_S_INVALID_TAG
);
5374 TRACE("falling back to empty default case for 0x%lx\n", discriminant
);
5381 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
, ULONG discriminant
, PFORMAT_STRING pFormat
)
5383 unsigned short type
;
5387 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5391 type
= *(const unsigned short*)pFormat
;
5392 if((type
& 0xff00) == 0x8000)
5394 unsigned char basetype
= LOBYTE(type
);
5395 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &basetype
);
5399 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5400 NDR_MARSHALL m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
5403 unsigned char *saved_buffer
= NULL
;
5404 int pointer_buffer_mark_set
= 0;
5411 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
5412 saved_buffer
= pStubMsg
->Buffer
;
5413 if (pStubMsg
->PointerBufferMark
)
5415 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5416 pStubMsg
->PointerBufferMark
= NULL
;
5417 pointer_buffer_mark_set
= 1;
5420 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
5422 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char **)pMemory
, desc
);
5423 if (pointer_buffer_mark_set
)
5425 STD_OVERFLOW_CHECK(pStubMsg
);
5426 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5427 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5429 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5430 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
5431 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5433 pStubMsg
->Buffer
= saved_buffer
+ 4;
5437 m(pStubMsg
, pMemory
, desc
);
5440 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5445 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5446 unsigned char **ppMemory
,
5448 PFORMAT_STRING pFormat
,
5449 unsigned char fMustAlloc
)
5451 unsigned short type
;
5455 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5459 type
= *(const unsigned short*)pFormat
;
5460 if((type
& 0xff00) == 0x8000)
5462 unsigned char basetype
= LOBYTE(type
);
5463 return NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &basetype
, FALSE
);
5467 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5468 NDR_UNMARSHALL m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
5471 unsigned char *saved_buffer
= NULL
;
5472 int pointer_buffer_mark_set
= 0;
5479 **(void***)ppMemory
= NULL
;
5480 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5481 saved_buffer
= pStubMsg
->Buffer
;
5482 if (pStubMsg
->PointerBufferMark
)
5484 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5485 pStubMsg
->PointerBufferMark
= NULL
;
5486 pointer_buffer_mark_set
= 1;
5489 pStubMsg
->Buffer
+= 4; /* for pointer ID */
5491 if (saved_buffer
+ 4 > pStubMsg
->BufferEnd
)
5493 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5494 saved_buffer
, pStubMsg
->BufferEnd
);
5495 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5498 PointerUnmarshall(pStubMsg
, saved_buffer
, *(unsigned char ***)ppMemory
, **(unsigned char ***)ppMemory
, desc
, fMustAlloc
);
5499 if (pointer_buffer_mark_set
)
5501 STD_OVERFLOW_CHECK(pStubMsg
);
5502 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5503 pStubMsg
->Buffer
= saved_buffer
+ 4;
5507 m(pStubMsg
, ppMemory
, desc
, fMustAlloc
);
5510 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5515 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg
,
5516 unsigned char *pMemory
,
5518 PFORMAT_STRING pFormat
)
5520 unsigned short type
;
5524 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5528 type
= *(const unsigned short*)pFormat
;
5529 if((type
& 0xff00) == 0x8000)
5531 unsigned char basetype
= LOBYTE(type
);
5532 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &basetype
);
5536 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5537 NDR_BUFFERSIZE m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
5546 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
5547 safe_buffer_length_increment(pStubMsg
, 4); /* for pointer ID */
5548 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5550 int saved_buffer_length
= pStubMsg
->BufferLength
;
5551 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
5552 pStubMsg
->PointerLength
= 0;
5553 if(!pStubMsg
->BufferLength
)
5554 ERR("BufferLength == 0??\n");
5555 PointerBufferSize(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5556 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
5557 pStubMsg
->BufferLength
= saved_buffer_length
;
5561 m(pStubMsg
, pMemory
, desc
);
5564 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
5568 static ULONG
union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg
,
5570 PFORMAT_STRING pFormat
)
5572 unsigned short type
, size
;
5574 size
= *(const unsigned short*)pFormat
;
5575 pStubMsg
->Memory
+= size
;
5578 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5582 type
= *(const unsigned short*)pFormat
;
5583 if((type
& 0xff00) == 0x8000)
5585 return NdrBaseTypeMemorySize(pStubMsg
, pFormat
);
5589 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5590 NDR_MEMORYSIZE m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
5591 unsigned char *saved_buffer
;
5600 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5601 saved_buffer
= pStubMsg
->Buffer
;
5602 safe_buffer_increment(pStubMsg
, 4);
5603 ALIGN_LENGTH(pStubMsg
->MemorySize
, 4);
5604 pStubMsg
->MemorySize
+= 4;
5605 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5606 PointerMemorySize(pStubMsg
, saved_buffer
, pFormat
);
5609 return m(pStubMsg
, desc
);
5612 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5615 TRACE("size %d\n", size
);
5619 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg
,
5620 unsigned char *pMemory
,
5622 PFORMAT_STRING pFormat
)
5624 unsigned short type
;
5628 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5632 type
= *(const unsigned short*)pFormat
;
5633 if((type
& 0xff00) != 0x8000)
5635 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5636 NDR_FREE m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
5645 PointerFree(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5648 m(pStubMsg
, pMemory
, desc
);
5654 /***********************************************************************
5655 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5657 unsigned char * WINAPI
NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5658 unsigned char *pMemory
,
5659 PFORMAT_STRING pFormat
)
5661 unsigned char switch_type
;
5662 unsigned char increment
;
5665 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5668 switch_type
= *pFormat
& 0xf;
5669 increment
= (*pFormat
& 0xf0) >> 4;
5672 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, increment
);
5674 switch_value
= get_discriminant(switch_type
, pMemory
);
5675 TRACE("got switch value 0x%x\n", switch_value
);
5677 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &switch_type
);
5678 pMemory
+= increment
;
5680 return union_arm_marshall(pStubMsg
, pMemory
, switch_value
, pFormat
);
5683 /***********************************************************************
5684 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5686 unsigned char * WINAPI
NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5687 unsigned char **ppMemory
,
5688 PFORMAT_STRING pFormat
,
5689 unsigned char fMustAlloc
)
5691 unsigned char switch_type
;
5692 unsigned char increment
;
5694 unsigned short size
;
5695 unsigned char *pMemoryArm
;
5697 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5700 switch_type
= *pFormat
& 0xf;
5701 increment
= (*pFormat
& 0xf0) >> 4;
5704 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
5705 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
5706 TRACE("got switch value 0x%x\n", switch_value
);
5708 size
= *(const unsigned short*)pFormat
+ increment
;
5709 if(!*ppMemory
|| fMustAlloc
)
5710 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5712 NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &switch_type
, FALSE
);
5713 pMemoryArm
= *ppMemory
+ increment
;
5715 return union_arm_unmarshall(pStubMsg
, &pMemoryArm
, switch_value
, pFormat
, fMustAlloc
);
5718 /***********************************************************************
5719 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5721 void WINAPI
NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5722 unsigned char *pMemory
,
5723 PFORMAT_STRING pFormat
)
5725 unsigned char switch_type
;
5726 unsigned char increment
;
5729 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5732 switch_type
= *pFormat
& 0xf;
5733 increment
= (*pFormat
& 0xf0) >> 4;
5736 ALIGN_LENGTH(pStubMsg
->BufferLength
, increment
);
5737 switch_value
= get_discriminant(switch_type
, pMemory
);
5738 TRACE("got switch value 0x%x\n", switch_value
);
5740 /* Add discriminant size */
5741 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&switch_value
, &switch_type
);
5742 pMemory
+= increment
;
5744 union_arm_buffer_size(pStubMsg
, pMemory
, switch_value
, pFormat
);
5747 /***********************************************************************
5748 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5750 ULONG WINAPI
NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5751 PFORMAT_STRING pFormat
)
5753 unsigned char switch_type
;
5754 unsigned char increment
;
5757 switch_type
= *pFormat
& 0xf;
5758 increment
= (*pFormat
& 0xf0) >> 4;
5761 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
5762 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
5763 TRACE("got switch value 0x%x\n", switch_value
);
5765 pStubMsg
->Memory
+= increment
;
5767 return increment
+ union_arm_memory_size(pStubMsg
, switch_value
, pFormat
+ *(const SHORT
*)pFormat
);
5770 /***********************************************************************
5771 * NdrEncapsulatedUnionFree [RPCRT4.@]
5773 void WINAPI
NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
5774 unsigned char *pMemory
,
5775 PFORMAT_STRING pFormat
)
5777 unsigned char switch_type
;
5778 unsigned char increment
;
5781 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5784 switch_type
= *pFormat
& 0xf;
5785 increment
= (*pFormat
& 0xf0) >> 4;
5788 switch_value
= get_discriminant(switch_type
, pMemory
);
5789 TRACE("got switch value 0x%x\n", switch_value
);
5791 pMemory
+= increment
;
5793 union_arm_free(pStubMsg
, pMemory
, switch_value
, pFormat
);
5796 /***********************************************************************
5797 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5799 unsigned char * WINAPI
NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5800 unsigned char *pMemory
,
5801 PFORMAT_STRING pFormat
)
5803 unsigned char switch_type
;
5805 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5808 switch_type
= *pFormat
;
5811 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5812 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5813 /* Marshall discriminant */
5814 NdrBaseTypeMarshall(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
5816 return union_arm_marshall(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5819 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg
,
5820 PFORMAT_STRING
*ppFormat
)
5822 long discriminant
= 0;
5832 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5841 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5842 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5850 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
5851 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5856 FIXME("Unhandled base type: 0x%02x\n", **ppFormat
);
5860 if (pStubMsg
->fHasNewCorrDesc
)
5864 return discriminant
;
5867 /**********************************************************************
5868 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5870 unsigned char * WINAPI
NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5871 unsigned char **ppMemory
,
5872 PFORMAT_STRING pFormat
,
5873 unsigned char fMustAlloc
)
5876 unsigned short size
;
5878 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5881 /* Unmarshall discriminant */
5882 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
5883 TRACE("unmarshalled discriminant %lx\n", discriminant
);
5885 pFormat
+= *(const SHORT
*)pFormat
;
5887 size
= *(const unsigned short*)pFormat
;
5889 if(!*ppMemory
|| fMustAlloc
)
5890 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5892 return union_arm_unmarshall(pStubMsg
, ppMemory
, discriminant
, pFormat
, fMustAlloc
);
5895 /***********************************************************************
5896 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5898 void WINAPI
NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5899 unsigned char *pMemory
,
5900 PFORMAT_STRING pFormat
)
5902 unsigned char switch_type
;
5904 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5907 switch_type
= *pFormat
;
5910 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5911 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5912 /* Add discriminant size */
5913 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
5915 union_arm_buffer_size(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5918 /***********************************************************************
5919 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5921 ULONG WINAPI
NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5922 PFORMAT_STRING pFormat
)
5927 /* Unmarshall discriminant */
5928 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
5929 TRACE("unmarshalled discriminant 0x%x\n", discriminant
);
5931 return union_arm_memory_size(pStubMsg
, discriminant
, pFormat
+ *(const SHORT
*)pFormat
);
5934 /***********************************************************************
5935 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5937 void WINAPI
NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
5938 unsigned char *pMemory
,
5939 PFORMAT_STRING pFormat
)
5941 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5945 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5946 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5948 union_arm_free(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5951 /***********************************************************************
5952 * NdrByteCountPointerMarshall [RPCRT4.@]
5954 unsigned char * WINAPI
NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5955 unsigned char *pMemory
,
5956 PFORMAT_STRING pFormat
)
5962 /***********************************************************************
5963 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5965 unsigned char * WINAPI
NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5966 unsigned char **ppMemory
,
5967 PFORMAT_STRING pFormat
,
5968 unsigned char fMustAlloc
)
5974 /***********************************************************************
5975 * NdrByteCountPointerBufferSize [RPCRT4.@]
5977 void WINAPI
NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5978 unsigned char *pMemory
,
5979 PFORMAT_STRING pFormat
)
5984 /***********************************************************************
5985 * NdrByteCountPointerMemorySize [RPCRT4.@]
5987 ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5988 PFORMAT_STRING pFormat
)
5994 /***********************************************************************
5995 * NdrByteCountPointerFree [RPCRT4.@]
5997 void WINAPI
NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
5998 unsigned char *pMemory
,
5999 PFORMAT_STRING pFormat
)
6004 /***********************************************************************
6005 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6007 unsigned char * WINAPI
NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6008 unsigned char *pMemory
,
6009 PFORMAT_STRING pFormat
)
6015 /***********************************************************************
6016 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6018 unsigned char * WINAPI
NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6019 unsigned char **ppMemory
,
6020 PFORMAT_STRING pFormat
,
6021 unsigned char fMustAlloc
)
6027 /***********************************************************************
6028 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6030 void WINAPI
NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6031 unsigned char *pMemory
,
6032 PFORMAT_STRING pFormat
)
6037 /***********************************************************************
6038 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6040 ULONG WINAPI
NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6041 PFORMAT_STRING pFormat
)
6047 /***********************************************************************
6048 * NdrXmitOrRepAsFree [RPCRT4.@]
6050 void WINAPI
NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg
,
6051 unsigned char *pMemory
,
6052 PFORMAT_STRING pFormat
)
6057 /***********************************************************************
6058 * NdrRangeMarshall [internal]
6060 unsigned char *WINAPI
NdrRangeMarshall(
6061 PMIDL_STUB_MESSAGE pStubMsg
,
6062 unsigned char *pMemory
,
6063 PFORMAT_STRING pFormat
)
6065 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
6066 unsigned char base_type
;
6068 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6070 if (pRange
->type
!= RPC_FC_RANGE
)
6072 ERR("invalid format type %x\n", pRange
->type
);
6073 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6077 base_type
= pRange
->flags_type
& 0xf;
6079 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &base_type
);
6082 /***********************************************************************
6083 * NdrRangeUnmarshall
6085 unsigned char *WINAPI
NdrRangeUnmarshall(
6086 PMIDL_STUB_MESSAGE pStubMsg
,
6087 unsigned char **ppMemory
,
6088 PFORMAT_STRING pFormat
,
6089 unsigned char fMustAlloc
)
6091 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
6092 unsigned char base_type
;
6094 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6096 if (pRange
->type
!= RPC_FC_RANGE
)
6098 ERR("invalid format type %x\n", pRange
->type
);
6099 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6102 base_type
= pRange
->flags_type
& 0xf;
6104 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6105 base_type
, pRange
->low_value
, pRange
->high_value
);
6107 #define RANGE_UNMARSHALL(type, format_spec) \
6110 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6111 if (fMustAlloc || !*ppMemory) \
6112 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6113 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
6115 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6116 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6117 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6119 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
6120 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
6122 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6123 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
6124 (type)pRange->high_value); \
6125 RpcRaiseException(RPC_S_INVALID_BOUND); \
6128 TRACE("*ppMemory: %p\n", *ppMemory); \
6129 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
6130 pStubMsg->Buffer += sizeof(type); \
6137 RANGE_UNMARSHALL(UCHAR
, "%d");
6138 TRACE("value: 0x%02x\n", **ppMemory
);
6142 RANGE_UNMARSHALL(CHAR
, "%u");
6143 TRACE("value: 0x%02x\n", **ppMemory
);
6145 case RPC_FC_WCHAR
: /* FIXME: valid? */
6147 RANGE_UNMARSHALL(USHORT
, "%u");
6148 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6151 RANGE_UNMARSHALL(SHORT
, "%d");
6152 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6155 RANGE_UNMARSHALL(LONG
, "%d");
6156 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6159 RANGE_UNMARSHALL(ULONG
, "%u");
6160 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6164 FIXME("Unhandled enum type\n");
6166 case RPC_FC_ERROR_STATUS_T
: /* FIXME: valid? */
6171 ERR("invalid range base type: 0x%02x\n", base_type
);
6172 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6178 /***********************************************************************
6179 * NdrRangeBufferSize [internal]
6181 void WINAPI
NdrRangeBufferSize(
6182 PMIDL_STUB_MESSAGE pStubMsg
,
6183 unsigned char *pMemory
,
6184 PFORMAT_STRING pFormat
)
6186 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
6187 unsigned char base_type
;
6189 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6191 if (pRange
->type
!= RPC_FC_RANGE
)
6193 ERR("invalid format type %x\n", pRange
->type
);
6194 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6196 base_type
= pRange
->flags_type
& 0xf;
6198 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &base_type
);
6201 /***********************************************************************
6202 * NdrRangeMemorySize [internal]
6204 ULONG WINAPI
NdrRangeMemorySize(
6205 PMIDL_STUB_MESSAGE pStubMsg
,
6206 PFORMAT_STRING pFormat
)
6208 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
6209 unsigned char base_type
;
6211 if (pRange
->type
!= RPC_FC_RANGE
)
6213 ERR("invalid format type %x\n", pRange
->type
);
6214 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6217 base_type
= pRange
->flags_type
& 0xf;
6219 return NdrBaseTypeMemorySize(pStubMsg
, &base_type
);
6222 /***********************************************************************
6223 * NdrRangeFree [internal]
6225 void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6226 unsigned char *pMemory
,
6227 PFORMAT_STRING pFormat
)
6229 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6234 /***********************************************************************
6235 * NdrBaseTypeMarshall [internal]
6237 static unsigned char *WINAPI
NdrBaseTypeMarshall(
6238 PMIDL_STUB_MESSAGE pStubMsg
,
6239 unsigned char *pMemory
,
6240 PFORMAT_STRING pFormat
)
6242 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6250 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(UCHAR
));
6251 TRACE("value: 0x%02x\n", *pMemory
);
6256 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(USHORT
));
6257 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(USHORT
));
6258 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
6262 case RPC_FC_ERROR_STATUS_T
:
6264 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(ULONG
));
6265 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONG
));
6266 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
6269 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(float));
6270 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
6273 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(double));
6274 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
6277 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(ULONGLONG
));
6278 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONGLONG
));
6279 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
6282 /* only 16-bits on the wire, so do a sanity check */
6283 if (*(UINT
*)pMemory
> SHRT_MAX
)
6284 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
6285 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(USHORT
));
6286 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6287 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6288 *(USHORT
*)pStubMsg
->Buffer
= *(UINT
*)pMemory
;
6289 pStubMsg
->Buffer
+= sizeof(USHORT
);
6290 TRACE("value: 0x%04x\n", *(UINT
*)pMemory
);
6295 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6298 /* FIXME: what is the correct return value? */
6302 /***********************************************************************
6303 * NdrBaseTypeUnmarshall [internal]
6305 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(
6306 PMIDL_STUB_MESSAGE pStubMsg
,
6307 unsigned char **ppMemory
,
6308 PFORMAT_STRING pFormat
,
6309 unsigned char fMustAlloc
)
6311 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6313 #define BASE_TYPE_UNMARSHALL(type) \
6314 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6315 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6317 *ppMemory = pStubMsg->Buffer; \
6318 TRACE("*ppMemory: %p\n", *ppMemory); \
6319 safe_buffer_increment(pStubMsg, sizeof(type)); \
6324 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6325 TRACE("*ppMemory: %p\n", *ppMemory); \
6326 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6335 BASE_TYPE_UNMARSHALL(UCHAR
);
6336 TRACE("value: 0x%02x\n", **ppMemory
);
6341 BASE_TYPE_UNMARSHALL(USHORT
);
6342 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6346 case RPC_FC_ERROR_STATUS_T
:
6348 BASE_TYPE_UNMARSHALL(ULONG
);
6349 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6352 BASE_TYPE_UNMARSHALL(float);
6353 TRACE("value: %f\n", **(float **)ppMemory
);
6356 BASE_TYPE_UNMARSHALL(double);
6357 TRACE("value: %f\n", **(double **)ppMemory
);
6360 BASE_TYPE_UNMARSHALL(ULONGLONG
);
6361 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG
**)ppMemory
));
6364 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
6365 if (fMustAlloc
|| !*ppMemory
)
6366 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT
));
6367 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > pStubMsg
->BufferEnd
)
6368 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6369 TRACE("*ppMemory: %p\n", *ppMemory
);
6370 /* 16-bits on the wire, but int in memory */
6371 **(UINT
**)ppMemory
= *(USHORT
*)pStubMsg
->Buffer
;
6372 pStubMsg
->Buffer
+= sizeof(USHORT
);
6373 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
6378 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6380 #undef BASE_TYPE_UNMARSHALL
6382 /* FIXME: what is the correct return value? */
6387 /***********************************************************************
6388 * NdrBaseTypeBufferSize [internal]
6390 static void WINAPI
NdrBaseTypeBufferSize(
6391 PMIDL_STUB_MESSAGE pStubMsg
,
6392 unsigned char *pMemory
,
6393 PFORMAT_STRING pFormat
)
6395 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6403 safe_buffer_length_increment(pStubMsg
, sizeof(UCHAR
));
6409 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(USHORT
));
6410 safe_buffer_length_increment(pStubMsg
, sizeof(USHORT
));
6415 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONG
));
6416 safe_buffer_length_increment(pStubMsg
, sizeof(ULONG
));
6419 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(float));
6420 safe_buffer_length_increment(pStubMsg
, sizeof(float));
6423 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(double));
6424 safe_buffer_length_increment(pStubMsg
, sizeof(double));
6427 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONGLONG
));
6428 safe_buffer_length_increment(pStubMsg
, sizeof(ULONGLONG
));
6430 case RPC_FC_ERROR_STATUS_T
:
6431 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(error_status_t
));
6432 safe_buffer_length_increment(pStubMsg
, sizeof(error_status_t
));
6437 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6441 /***********************************************************************
6442 * NdrBaseTypeMemorySize [internal]
6444 static ULONG WINAPI
NdrBaseTypeMemorySize(
6445 PMIDL_STUB_MESSAGE pStubMsg
,
6446 PFORMAT_STRING pFormat
)
6448 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg
, *pFormat
);
6456 safe_buffer_increment(pStubMsg
, sizeof(UCHAR
));
6457 pStubMsg
->MemorySize
+= sizeof(UCHAR
);
6458 return sizeof(UCHAR
);
6462 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6463 pStubMsg
->MemorySize
+= sizeof(USHORT
);
6464 return sizeof(USHORT
);
6468 safe_buffer_increment(pStubMsg
, sizeof(ULONG
));
6469 pStubMsg
->MemorySize
+= sizeof(ULONG
);
6470 return sizeof(ULONG
);
6472 safe_buffer_increment(pStubMsg
, sizeof(float));
6473 pStubMsg
->MemorySize
+= sizeof(float);
6474 return sizeof(float);
6476 safe_buffer_increment(pStubMsg
, sizeof(double));
6477 pStubMsg
->MemorySize
+= sizeof(double);
6478 return sizeof(double);
6480 safe_buffer_increment(pStubMsg
, sizeof(ULONGLONG
));
6481 pStubMsg
->MemorySize
+= sizeof(ULONGLONG
);
6482 return sizeof(ULONGLONG
);
6483 case RPC_FC_ERROR_STATUS_T
:
6484 safe_buffer_increment(pStubMsg
, sizeof(error_status_t
));
6485 pStubMsg
->MemorySize
+= sizeof(error_status_t
);
6486 return sizeof(error_status_t
);
6488 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6489 pStubMsg
->MemorySize
+= sizeof(UINT
);
6490 return sizeof(UINT
);
6492 pStubMsg
->MemorySize
+= sizeof(void *);
6493 return sizeof(void *);
6495 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6500 /***********************************************************************
6501 * NdrBaseTypeFree [internal]
6503 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6504 unsigned char *pMemory
,
6505 PFORMAT_STRING pFormat
)
6507 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6512 /***********************************************************************
6513 * NdrContextHandleBufferSize [internal]
6515 static void WINAPI
NdrContextHandleBufferSize(
6516 PMIDL_STUB_MESSAGE pStubMsg
,
6517 unsigned char *pMemory
,
6518 PFORMAT_STRING pFormat
)
6520 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6522 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6524 ERR("invalid format type %x\n", *pFormat
);
6525 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6527 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
6528 safe_buffer_length_increment(pStubMsg
, cbNDRContext
);
6531 /***********************************************************************
6532 * NdrContextHandleMarshall [internal]
6534 static unsigned char *WINAPI
NdrContextHandleMarshall(
6535 PMIDL_STUB_MESSAGE pStubMsg
,
6536 unsigned char *pMemory
,
6537 PFORMAT_STRING pFormat
)
6539 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6541 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6543 ERR("invalid format type %x\n", *pFormat
);
6544 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6546 TRACE("flags: 0x%02x\n", pFormat
[1]);
6548 if (pFormat
[1] & 0x80)
6549 NdrClientContextMarshall(pStubMsg
, *(NDR_CCONTEXT
**)pMemory
, FALSE
);
6551 NdrClientContextMarshall(pStubMsg
, (NDR_CCONTEXT
*)pMemory
, FALSE
);
6556 /***********************************************************************
6557 * NdrContextHandleUnmarshall [internal]
6559 static unsigned char *WINAPI
NdrContextHandleUnmarshall(
6560 PMIDL_STUB_MESSAGE pStubMsg
,
6561 unsigned char **ppMemory
,
6562 PFORMAT_STRING pFormat
,
6563 unsigned char fMustAlloc
)
6565 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg
,
6566 ppMemory
, pFormat
, fMustAlloc
? "TRUE": "FALSE");
6568 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6570 ERR("invalid format type %x\n", *pFormat
);
6571 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6573 TRACE("flags: 0x%02x\n", pFormat
[1]);
6575 /* [out]-only or [ret] param */
6576 if ((pFormat
[1] & 0x60) == 0x20)
6577 **(NDR_CCONTEXT
**)ppMemory
= NULL
;
6578 NdrClientContextUnmarshall(pStubMsg
, *(NDR_CCONTEXT
**)ppMemory
, pStubMsg
->RpcMsg
->Handle
);
6583 /***********************************************************************
6584 * NdrClientContextMarshall [RPCRT4.@]
6586 void WINAPI
NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6587 NDR_CCONTEXT ContextHandle
,
6590 TRACE("(%p, %p, %d)\n", pStubMsg
, ContextHandle
, fCheck
);
6592 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
6594 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6596 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6597 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6598 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6601 /* FIXME: what does fCheck do? */
6602 NDRCContextMarshall(ContextHandle
,
6605 pStubMsg
->Buffer
+= cbNDRContext
;
6608 /***********************************************************************
6609 * NdrClientContextUnmarshall [RPCRT4.@]
6611 void WINAPI
NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6612 NDR_CCONTEXT
* pContextHandle
,
6613 RPC_BINDING_HANDLE BindHandle
)
6615 TRACE("(%p, %p, %p)\n", pStubMsg
, pContextHandle
, BindHandle
);
6617 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6619 if (pStubMsg
->Buffer
+ cbNDRContext
> pStubMsg
->BufferEnd
)
6620 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6622 NDRCContextUnmarshall(pContextHandle
,
6625 pStubMsg
->RpcMsg
->DataRepresentation
);
6627 pStubMsg
->Buffer
+= cbNDRContext
;
6630 void WINAPI
NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6631 NDR_SCONTEXT ContextHandle
,
6632 NDR_RUNDOWN RundownRoutine
)
6634 TRACE("(%p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
);
6636 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6638 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6640 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6641 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6642 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6645 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
6646 pStubMsg
->Buffer
, RundownRoutine
, NULL
,
6647 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
6648 pStubMsg
->Buffer
+= cbNDRContext
;
6651 NDR_SCONTEXT WINAPI
NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
)
6653 NDR_SCONTEXT ContextHandle
;
6655 TRACE("(%p)\n", pStubMsg
);
6657 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6659 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6661 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6662 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6663 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6666 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
6668 pStubMsg
->RpcMsg
->DataRepresentation
,
6669 NULL
, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
6670 pStubMsg
->Buffer
+= cbNDRContext
;
6672 return ContextHandle
;
6675 void WINAPI
NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg
,
6676 unsigned char* pMemory
,
6677 PFORMAT_STRING pFormat
)
6679 FIXME("(%p, %p, %p): stub\n", pStubMsg
, pMemory
, pFormat
);
6682 NDR_SCONTEXT WINAPI
NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg
,
6683 PFORMAT_STRING pFormat
)
6685 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6686 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6688 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
6690 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
6691 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
6692 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
6693 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
6694 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
6696 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
6697 if_id
= &sif
->InterfaceId
;
6700 return NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
, NULL
,
6701 pStubMsg
->RpcMsg
->DataRepresentation
, if_id
,
6705 void WINAPI
NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6706 NDR_SCONTEXT ContextHandle
,
6707 NDR_RUNDOWN RundownRoutine
,
6708 PFORMAT_STRING pFormat
)
6710 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6711 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6713 TRACE("(%p, %p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
, pFormat
);
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 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
6725 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
6726 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
6727 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
6728 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
6730 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
6731 if_id
= &sif
->InterfaceId
;
6734 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
6735 pStubMsg
->Buffer
, RundownRoutine
, if_id
, flags
);
6736 pStubMsg
->Buffer
+= cbNDRContext
;
6739 NDR_SCONTEXT WINAPI
NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6740 PFORMAT_STRING pFormat
)
6742 NDR_SCONTEXT ContextHandle
;
6743 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6744 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6746 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
6748 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6750 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6752 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6753 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6754 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6757 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
6758 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
6759 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
6760 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
6761 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
6763 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
6764 if_id
= &sif
->InterfaceId
;
6767 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
6769 pStubMsg
->RpcMsg
->DataRepresentation
,
6771 pStubMsg
->Buffer
+= cbNDRContext
;
6773 return ContextHandle
;
6776 /***********************************************************************
6777 * NdrCorrelationInitialize [RPCRT4.@]
6779 * Initializes correlation validity checking.
6782 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6783 * pMemory [I] Pointer to memory to use as a cache.
6784 * CacheSize [I] Size of the memory pointed to by pMemory.
6785 * Flags [I] Reserved. Set to zero.
6790 void WINAPI
NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg
, void *pMemory
, ULONG CacheSize
, ULONG Flags
)
6792 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg
, pMemory
, CacheSize
, Flags
);
6793 pStubMsg
->fHasNewCorrDesc
= TRUE
;
6796 /***********************************************************************
6797 * NdrCorrelationPass [RPCRT4.@]
6799 * Performs correlation validity checking.
6802 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6807 void WINAPI
NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg
)
6809 FIXME("(%p): stub\n", pStubMsg
);
6812 /***********************************************************************
6813 * NdrCorrelationFree [RPCRT4.@]
6815 * Frees any resources used while unmarshalling parameters that need
6816 * correlation validity checking.
6819 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6824 void WINAPI
NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg
)
6826 FIXME("(%p): stub\n", pStubMsg
);