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;
866 pointer_needs_unmarshaling
= 0;
870 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
871 TRACE("pointer_id is 0x%08x\n", pointer_id
);
872 pointer_needs_unmarshaling
= !NdrFullPointerQueryRefId(
873 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, (void **)pPointer
);
876 FIXME("unhandled ptr type=%02x\n", type
);
877 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
881 if (pointer_needs_unmarshaling
) {
882 unsigned char *base_ptr_val
= *pPointer
;
883 unsigned char **current_ptr
= pPointer
;
884 if (pStubMsg
->IsClient
) {
886 /* if we aren't forcing allocation of memory then try to use the existing
887 * (source) pointer to unmarshall the data into so that [in,out]
888 * parameters behave correctly. it doesn't matter if the parameter is
889 * [out] only since in that case the pointer will be NULL. we force
890 * allocation when the source pointer is NULL here instead of in the type
891 * unmarshalling routine for the benefit of the deref code below */
894 TRACE("setting *pPointer to %p\n", pSrcPointer
);
895 *pPointer
= base_ptr_val
= pSrcPointer
;
901 /* the memory in a stub is never initialised, so we have to work out here
902 * whether we have to initialise it so we can use the optimisation of
903 * setting the pointer to the buffer, if possible, or set fMustAlloc to
905 if (attr
& RPC_FC_P_DEREF
) {
913 if (attr
& RPC_FC_P_ALLOCALLNODES
)
914 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
916 if (attr
& RPC_FC_P_DEREF
) {
918 base_ptr_val
= NdrAllocate(pStubMsg
, sizeof(void *));
919 *pPointer
= base_ptr_val
;
920 current_ptr
= (unsigned char **)base_ptr_val
;
922 current_ptr
= *(unsigned char***)current_ptr
;
923 TRACE("deref => %p\n", current_ptr
);
924 if (!fMustAlloc
&& !*current_ptr
) fMustAlloc
= TRUE
;
926 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
927 if (m
) m(pStubMsg
, current_ptr
, desc
, fMustAlloc
);
928 else FIXME("no unmarshaller for data type=%02x\n", *desc
);
930 if (type
== RPC_FC_FP
)
931 NdrFullPointerInsertRefId(pStubMsg
->FullPtrXlatTables
, pointer_id
,
935 TRACE("pointer=%p\n", *pPointer
);
938 /***********************************************************************
939 * PointerBufferSize [internal]
941 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
942 unsigned char *Pointer
,
943 PFORMAT_STRING pFormat
)
945 unsigned type
= pFormat
[0], attr
= pFormat
[1];
948 int pointer_needs_sizing
;
951 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
952 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
954 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
955 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
958 case RPC_FC_RP
: /* ref pointer (always non-null) */
961 ERR("NULL ref pointer is not allowed\n");
962 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
967 /* NULL pointer has no further representation */
972 pointer_needs_sizing
= !NdrFullPointerQueryPointer(
973 pStubMsg
->FullPtrXlatTables
, Pointer
, 0, &pointer_id
);
974 if (!pointer_needs_sizing
)
978 FIXME("unhandled ptr type=%02x\n", type
);
979 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
983 if (attr
& RPC_FC_P_DEREF
) {
984 Pointer
= *(unsigned char**)Pointer
;
985 TRACE("deref => %p\n", Pointer
);
988 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
989 if (m
) m(pStubMsg
, Pointer
, desc
);
990 else FIXME("no buffersizer for data type=%02x\n", *desc
);
993 /***********************************************************************
994 * PointerMemorySize [internal]
996 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
997 unsigned char *Buffer
,
998 PFORMAT_STRING pFormat
)
1000 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1001 PFORMAT_STRING desc
;
1003 DWORD pointer_id
= 0;
1004 int pointer_needs_sizing
;
1006 TRACE("(%p,%p,%p)\n", pStubMsg
, Buffer
, pFormat
);
1007 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1009 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1010 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1013 case RPC_FC_RP
: /* ref pointer (always non-null) */
1014 pointer_needs_sizing
= 1;
1016 case RPC_FC_UP
: /* unique pointer */
1017 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
1018 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1019 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1021 pointer_needs_sizing
= 1;
1023 pointer_needs_sizing
= 0;
1028 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1029 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1030 pointer_needs_sizing
= !NdrFullPointerQueryRefId(
1031 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, &pointer
);
1035 FIXME("unhandled ptr type=%02x\n", type
);
1036 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1040 if (attr
& RPC_FC_P_DEREF
) {
1044 if (pointer_needs_sizing
) {
1045 m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
1046 if (m
) m(pStubMsg
, desc
);
1047 else FIXME("no memorysizer for data type=%02x\n", *desc
);
1050 return pStubMsg
->MemorySize
;
1053 /***********************************************************************
1054 * PointerFree [internal]
1056 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1057 unsigned char *Pointer
,
1058 PFORMAT_STRING pFormat
)
1060 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1061 PFORMAT_STRING desc
;
1063 unsigned char *current_pointer
= Pointer
;
1065 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1066 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1067 if (attr
& RPC_FC_P_DONTFREE
) return;
1069 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1070 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1072 if (!Pointer
) return;
1074 if (type
== RPC_FC_FP
) {
1075 int pointer_needs_freeing
= NdrFullPointerFree(
1076 pStubMsg
->FullPtrXlatTables
, Pointer
);
1077 if (!pointer_needs_freeing
)
1081 if (attr
& RPC_FC_P_DEREF
) {
1082 current_pointer
= *(unsigned char**)Pointer
;
1083 TRACE("deref => %p\n", current_pointer
);
1086 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
1087 if (m
) m(pStubMsg
, current_pointer
, desc
);
1089 /* this check stops us from trying to free buffer memory. we don't have to
1090 * worry about clients, since they won't call this function.
1091 * we don't have to check for the buffer being reallocated because
1092 * BufferStart and BufferEnd won't be reset when allocating memory for
1093 * sending the response. we don't have to check for the new buffer here as
1094 * it won't be used a type memory, only for buffer memory */
1095 if (Pointer
>= pStubMsg
->BufferStart
&& Pointer
< pStubMsg
->BufferEnd
)
1098 if (attr
& RPC_FC_P_ONSTACK
) {
1099 TRACE("not freeing stack ptr %p\n", Pointer
);
1102 TRACE("freeing %p\n", Pointer
);
1103 NdrFree(pStubMsg
, Pointer
);
1106 TRACE("not freeing %p\n", Pointer
);
1109 /***********************************************************************
1110 * EmbeddedPointerMarshall
1112 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1113 unsigned char *pMemory
,
1114 PFORMAT_STRING pFormat
)
1116 unsigned char *Mark
= pStubMsg
->BufferMark
;
1117 unsigned rep
, count
, stride
;
1119 unsigned char *saved_buffer
= NULL
;
1121 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1123 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1126 if (pStubMsg
->PointerBufferMark
)
1128 saved_buffer
= pStubMsg
->Buffer
;
1129 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1130 pStubMsg
->PointerBufferMark
= NULL
;
1133 while (pFormat
[0] != RPC_FC_END
) {
1134 switch (pFormat
[0]) {
1136 FIXME("unknown repeat type %d\n", pFormat
[0]);
1137 case RPC_FC_NO_REPEAT
:
1143 case RPC_FC_FIXED_REPEAT
:
1144 rep
= *(const WORD
*)&pFormat
[2];
1145 stride
= *(const WORD
*)&pFormat
[4];
1146 count
= *(const WORD
*)&pFormat
[8];
1149 case RPC_FC_VARIABLE_REPEAT
:
1150 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1151 stride
= *(const WORD
*)&pFormat
[2];
1152 count
= *(const WORD
*)&pFormat
[6];
1156 for (i
= 0; i
< rep
; i
++) {
1157 PFORMAT_STRING info
= pFormat
;
1158 unsigned char *membase
= pMemory
+ (i
* stride
);
1159 unsigned char *bufbase
= Mark
+ (i
* stride
);
1162 for (u
=0; u
<count
; u
++,info
+=8) {
1163 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1164 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1165 unsigned char *saved_memory
= pStubMsg
->Memory
;
1167 pStubMsg
->Memory
= pMemory
;
1168 PointerMarshall(pStubMsg
, bufptr
, *(unsigned char**)memptr
, info
+4);
1169 pStubMsg
->Memory
= saved_memory
;
1172 pFormat
+= 8 * count
;
1177 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1178 pStubMsg
->Buffer
= saved_buffer
;
1181 STD_OVERFLOW_CHECK(pStubMsg
);
1186 /***********************************************************************
1187 * EmbeddedPointerUnmarshall
1189 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1190 unsigned char *pDstBuffer
,
1191 unsigned char *pSrcMemoryPtrs
,
1192 PFORMAT_STRING pFormat
,
1193 unsigned char fMustAlloc
)
1195 unsigned char *Mark
= pStubMsg
->BufferMark
;
1196 unsigned rep
, count
, stride
;
1198 unsigned char *saved_buffer
= NULL
;
1200 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg
, pDstBuffer
, pSrcMemoryPtrs
, pFormat
, fMustAlloc
);
1202 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1205 if (pStubMsg
->PointerBufferMark
)
1207 saved_buffer
= pStubMsg
->Buffer
;
1208 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1209 pStubMsg
->PointerBufferMark
= NULL
;
1212 while (pFormat
[0] != RPC_FC_END
) {
1213 TRACE("pFormat[0] = 0x%x\n", pFormat
[0]);
1214 switch (pFormat
[0]) {
1216 FIXME("unknown repeat type %d\n", pFormat
[0]);
1217 case RPC_FC_NO_REPEAT
:
1223 case RPC_FC_FIXED_REPEAT
:
1224 rep
= *(const WORD
*)&pFormat
[2];
1225 stride
= *(const WORD
*)&pFormat
[4];
1226 count
= *(const WORD
*)&pFormat
[8];
1229 case RPC_FC_VARIABLE_REPEAT
:
1230 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1231 stride
= *(const WORD
*)&pFormat
[2];
1232 count
= *(const WORD
*)&pFormat
[6];
1236 for (i
= 0; i
< rep
; i
++) {
1237 PFORMAT_STRING info
= pFormat
;
1238 unsigned char *bufdstbase
= pDstBuffer
+ (i
* stride
);
1239 unsigned char *memsrcbase
= pSrcMemoryPtrs
+ (i
* stride
);
1240 unsigned char *bufbase
= Mark
+ (i
* stride
);
1243 for (u
=0; u
<count
; u
++,info
+=8) {
1244 unsigned char **bufdstptr
= (unsigned char **)(bufdstbase
+ *(const SHORT
*)&info
[2]);
1245 unsigned char **memsrcptr
= (unsigned char **)(memsrcbase
+ *(const SHORT
*)&info
[0]);
1246 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1247 PointerUnmarshall(pStubMsg
, bufptr
, bufdstptr
, *memsrcptr
, info
+4, fMustAlloc
);
1250 pFormat
+= 8 * count
;
1255 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1256 pStubMsg
->Buffer
= saved_buffer
;
1262 /***********************************************************************
1263 * EmbeddedPointerBufferSize
1265 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1266 unsigned char *pMemory
,
1267 PFORMAT_STRING pFormat
)
1269 unsigned rep
, count
, stride
;
1271 ULONG saved_buffer_length
= 0;
1273 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1275 if (pStubMsg
->IgnoreEmbeddedPointers
) return;
1277 if (*pFormat
!= RPC_FC_PP
) return;
1280 if (pStubMsg
->PointerLength
)
1282 saved_buffer_length
= pStubMsg
->BufferLength
;
1283 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
1284 pStubMsg
->PointerLength
= 0;
1287 while (pFormat
[0] != RPC_FC_END
) {
1288 switch (pFormat
[0]) {
1290 FIXME("unknown repeat type %d\n", pFormat
[0]);
1291 case RPC_FC_NO_REPEAT
:
1297 case RPC_FC_FIXED_REPEAT
:
1298 rep
= *(const WORD
*)&pFormat
[2];
1299 stride
= *(const WORD
*)&pFormat
[4];
1300 count
= *(const WORD
*)&pFormat
[8];
1303 case RPC_FC_VARIABLE_REPEAT
:
1304 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1305 stride
= *(const WORD
*)&pFormat
[2];
1306 count
= *(const WORD
*)&pFormat
[6];
1310 for (i
= 0; i
< rep
; i
++) {
1311 PFORMAT_STRING info
= pFormat
;
1312 unsigned char *membase
= pMemory
+ (i
* stride
);
1315 for (u
=0; u
<count
; u
++,info
+=8) {
1316 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1317 unsigned char *saved_memory
= pStubMsg
->Memory
;
1319 pStubMsg
->Memory
= pMemory
;
1320 PointerBufferSize(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1321 pStubMsg
->Memory
= saved_memory
;
1324 pFormat
+= 8 * count
;
1327 if (saved_buffer_length
)
1329 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
1330 pStubMsg
->BufferLength
= saved_buffer_length
;
1334 /***********************************************************************
1335 * EmbeddedPointerMemorySize [internal]
1337 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1338 PFORMAT_STRING pFormat
)
1340 unsigned char *Mark
= pStubMsg
->BufferMark
;
1341 unsigned rep
, count
, stride
;
1343 unsigned char *saved_buffer
= NULL
;
1345 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1347 if (pStubMsg
->IgnoreEmbeddedPointers
) return 0;
1349 if (pStubMsg
->PointerBufferMark
)
1351 saved_buffer
= pStubMsg
->Buffer
;
1352 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1353 pStubMsg
->PointerBufferMark
= NULL
;
1356 if (*pFormat
!= RPC_FC_PP
) return 0;
1359 while (pFormat
[0] != RPC_FC_END
) {
1360 switch (pFormat
[0]) {
1362 FIXME("unknown repeat type %d\n", pFormat
[0]);
1363 case RPC_FC_NO_REPEAT
:
1369 case RPC_FC_FIXED_REPEAT
:
1370 rep
= *(const WORD
*)&pFormat
[2];
1371 stride
= *(const WORD
*)&pFormat
[4];
1372 count
= *(const WORD
*)&pFormat
[8];
1375 case RPC_FC_VARIABLE_REPEAT
:
1376 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1377 stride
= *(const WORD
*)&pFormat
[2];
1378 count
= *(const WORD
*)&pFormat
[6];
1382 for (i
= 0; i
< rep
; i
++) {
1383 PFORMAT_STRING info
= pFormat
;
1384 unsigned char *bufbase
= Mark
+ (i
* stride
);
1386 for (u
=0; u
<count
; u
++,info
+=8) {
1387 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1388 PointerMemorySize(pStubMsg
, bufptr
, info
+4);
1391 pFormat
+= 8 * count
;
1396 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1397 pStubMsg
->Buffer
= saved_buffer
;
1403 /***********************************************************************
1404 * EmbeddedPointerFree [internal]
1406 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1407 unsigned char *pMemory
,
1408 PFORMAT_STRING pFormat
)
1410 unsigned rep
, count
, stride
;
1413 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1414 if (*pFormat
!= RPC_FC_PP
) return;
1417 while (pFormat
[0] != RPC_FC_END
) {
1418 switch (pFormat
[0]) {
1420 FIXME("unknown repeat type %d\n", pFormat
[0]);
1421 case RPC_FC_NO_REPEAT
:
1427 case RPC_FC_FIXED_REPEAT
:
1428 rep
= *(const WORD
*)&pFormat
[2];
1429 stride
= *(const WORD
*)&pFormat
[4];
1430 count
= *(const WORD
*)&pFormat
[8];
1433 case RPC_FC_VARIABLE_REPEAT
:
1434 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1435 stride
= *(const WORD
*)&pFormat
[2];
1436 count
= *(const WORD
*)&pFormat
[6];
1440 for (i
= 0; i
< rep
; i
++) {
1441 PFORMAT_STRING info
= pFormat
;
1442 unsigned char *membase
= pMemory
+ (i
* stride
);
1445 for (u
=0; u
<count
; u
++,info
+=8) {
1446 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1447 unsigned char *saved_memory
= pStubMsg
->Memory
;
1449 pStubMsg
->Memory
= pMemory
;
1450 PointerFree(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1451 pStubMsg
->Memory
= saved_memory
;
1454 pFormat
+= 8 * count
;
1458 /***********************************************************************
1459 * NdrPointerMarshall [RPCRT4.@]
1461 unsigned char * WINAPI
NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1462 unsigned char *pMemory
,
1463 PFORMAT_STRING pFormat
)
1465 unsigned char *Buffer
;
1467 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1469 /* Increment the buffer here instead of in PointerMarshall,
1470 * as that is used by embedded pointers which already handle the incrementing
1471 * the buffer, and shouldn't write any additional pointer data to the wire */
1472 if (*pFormat
!= RPC_FC_RP
)
1474 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
1475 Buffer
= pStubMsg
->Buffer
;
1476 safe_buffer_increment(pStubMsg
, 4);
1479 Buffer
= pStubMsg
->Buffer
;
1481 PointerMarshall(pStubMsg
, Buffer
, pMemory
, pFormat
);
1486 /***********************************************************************
1487 * NdrPointerUnmarshall [RPCRT4.@]
1489 unsigned char * WINAPI
NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1490 unsigned char **ppMemory
,
1491 PFORMAT_STRING pFormat
,
1492 unsigned char fMustAlloc
)
1494 unsigned char *Buffer
;
1496 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1498 /* Increment the buffer here instead of in PointerUnmarshall,
1499 * as that is used by embedded pointers which already handle the incrementing
1500 * the buffer, and shouldn't read any additional pointer data from the
1502 if (*pFormat
!= RPC_FC_RP
)
1504 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1505 Buffer
= pStubMsg
->Buffer
;
1506 safe_buffer_increment(pStubMsg
, 4);
1509 Buffer
= pStubMsg
->Buffer
;
1511 PointerUnmarshall(pStubMsg
, Buffer
, ppMemory
, *ppMemory
, pFormat
, fMustAlloc
);
1516 /***********************************************************************
1517 * NdrPointerBufferSize [RPCRT4.@]
1519 void WINAPI
NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1520 unsigned char *pMemory
,
1521 PFORMAT_STRING pFormat
)
1523 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1525 /* Increment the buffer length here instead of in PointerBufferSize,
1526 * as that is used by embedded pointers which already handle the buffer
1527 * length, and shouldn't write anything more to the wire */
1528 if (*pFormat
!= RPC_FC_RP
)
1530 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
1531 safe_buffer_length_increment(pStubMsg
, 4);
1534 PointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1537 /***********************************************************************
1538 * NdrPointerMemorySize [RPCRT4.@]
1540 ULONG WINAPI
NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1541 PFORMAT_STRING pFormat
)
1543 /* unsigned size = *(LPWORD)(pFormat+2); */
1544 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1545 PointerMemorySize(pStubMsg
, pStubMsg
->Buffer
, pFormat
);
1549 /***********************************************************************
1550 * NdrPointerFree [RPCRT4.@]
1552 void WINAPI
NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1553 unsigned char *pMemory
,
1554 PFORMAT_STRING pFormat
)
1556 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1557 PointerFree(pStubMsg
, pMemory
, pFormat
);
1560 /***********************************************************************
1561 * NdrSimpleTypeMarshall [RPCRT4.@]
1563 void WINAPI
NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1564 unsigned char FormatChar
)
1566 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &FormatChar
);
1569 /***********************************************************************
1570 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1572 * Unmarshall a base type.
1575 * Doesn't check that the buffer is long enough before copying, so the caller
1578 void WINAPI
NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1579 unsigned char FormatChar
)
1581 #define BASE_TYPE_UNMARSHALL(type) \
1582 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
1583 TRACE("pMemory: %p\n", pMemory); \
1584 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1585 pStubMsg->Buffer += sizeof(type);
1593 BASE_TYPE_UNMARSHALL(UCHAR
);
1594 TRACE("value: 0x%02x\n", *pMemory
);
1599 BASE_TYPE_UNMARSHALL(USHORT
);
1600 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
1604 case RPC_FC_ERROR_STATUS_T
:
1606 BASE_TYPE_UNMARSHALL(ULONG
);
1607 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
1610 BASE_TYPE_UNMARSHALL(float);
1611 TRACE("value: %f\n", *(float *)pMemory
);
1614 BASE_TYPE_UNMARSHALL(double);
1615 TRACE("value: %f\n", *(double *)pMemory
);
1618 BASE_TYPE_UNMARSHALL(ULONGLONG
);
1619 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
1622 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
1623 TRACE("pMemory: %p\n", pMemory
);
1624 /* 16-bits on the wire, but int in memory */
1625 *(UINT
*)pMemory
= *(USHORT
*)pStubMsg
->Buffer
;
1626 pStubMsg
->Buffer
+= sizeof(USHORT
);
1627 TRACE("value: 0x%08x\n", *(UINT
*)pMemory
);
1632 FIXME("Unhandled base type: 0x%02x\n", FormatChar
);
1634 #undef BASE_TYPE_UNMARSHALL
1637 /***********************************************************************
1638 * NdrSimpleStructMarshall [RPCRT4.@]
1640 unsigned char * WINAPI
NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1641 unsigned char *pMemory
,
1642 PFORMAT_STRING pFormat
)
1644 unsigned size
= *(const WORD
*)(pFormat
+2);
1645 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1647 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pFormat
[1] + 1);
1649 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1650 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
1652 if (pFormat
[0] != RPC_FC_STRUCT
)
1653 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
+4);
1658 /***********************************************************************
1659 * NdrSimpleStructUnmarshall [RPCRT4.@]
1661 unsigned char * WINAPI
NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1662 unsigned char **ppMemory
,
1663 PFORMAT_STRING pFormat
,
1664 unsigned char fMustAlloc
)
1666 unsigned size
= *(const WORD
*)(pFormat
+2);
1667 unsigned char *saved_buffer
;
1668 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1670 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1673 *ppMemory
= NdrAllocate(pStubMsg
, size
);
1676 if (!pStubMsg
->IsClient
&& !*ppMemory
)
1677 /* for servers, we just point straight into the RPC buffer */
1678 *ppMemory
= pStubMsg
->Buffer
;
1681 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1682 safe_buffer_increment(pStubMsg
, size
);
1683 if (pFormat
[0] == RPC_FC_PSTRUCT
)
1684 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
+4, fMustAlloc
);
1686 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
1687 if (*ppMemory
!= saved_buffer
)
1688 memcpy(*ppMemory
, saved_buffer
, size
);
1693 /***********************************************************************
1694 * NdrSimpleStructBufferSize [RPCRT4.@]
1696 void WINAPI
NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1697 unsigned char *pMemory
,
1698 PFORMAT_STRING pFormat
)
1700 unsigned size
= *(const WORD
*)(pFormat
+2);
1701 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1703 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
1705 safe_buffer_length_increment(pStubMsg
, size
);
1706 if (pFormat
[0] != RPC_FC_STRUCT
)
1707 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
+4);
1710 /***********************************************************************
1711 * NdrSimpleStructMemorySize [RPCRT4.@]
1713 ULONG WINAPI
NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1714 PFORMAT_STRING pFormat
)
1716 unsigned short size
= *(const WORD
*)(pFormat
+2);
1718 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1720 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1721 pStubMsg
->MemorySize
+= size
;
1722 safe_buffer_increment(pStubMsg
, size
);
1724 if (pFormat
[0] != RPC_FC_STRUCT
)
1725 EmbeddedPointerMemorySize(pStubMsg
, pFormat
+4);
1726 return pStubMsg
->MemorySize
;
1729 /***********************************************************************
1730 * NdrSimpleStructFree [RPCRT4.@]
1732 void WINAPI
NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
1733 unsigned char *pMemory
,
1734 PFORMAT_STRING pFormat
)
1736 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1737 if (pFormat
[0] != RPC_FC_STRUCT
)
1738 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
+4);
1743 static inline void array_compute_and_size_conformance(
1744 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1745 PFORMAT_STRING pFormat
)
1750 ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1751 SizeConformance(pStubMsg
);
1753 case RPC_FC_CVARRAY
:
1754 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, 0);
1755 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
1756 SizeConformance(pStubMsg
);
1758 case RPC_FC_C_CSTRING
:
1759 case RPC_FC_C_WSTRING
:
1760 if (pFormat
[0] == RPC_FC_C_CSTRING
)
1762 TRACE("string=%s\n", debugstr_a((const char *)pMemory
));
1763 pStubMsg
->ActualCount
= strlen((const char *)pMemory
)+1;
1767 TRACE("string=%s\n", debugstr_w((LPCWSTR
)pMemory
));
1768 pStubMsg
->ActualCount
= strlenW((LPCWSTR
)pMemory
)+1;
1771 if (fc
== RPC_FC_STRING_SIZED
)
1772 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
1774 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
1776 SizeConformance(pStubMsg
);
1779 ERR("unknown array format 0x%x\n", fc
);
1780 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1784 static inline void array_buffer_size(
1785 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1786 PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
1790 unsigned char alignment
;
1795 esize
= *(const WORD
*)(pFormat
+2);
1796 alignment
= pFormat
[1] + 1;
1798 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1800 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
1802 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
1803 /* conformance value plus array */
1804 safe_buffer_length_increment(pStubMsg
, size
);
1807 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1809 case RPC_FC_CVARRAY
:
1810 esize
= *(const WORD
*)(pFormat
+2);
1811 alignment
= pFormat
[1] + 1;
1813 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1814 pFormat
= SkipConformance(pStubMsg
, pFormat
);
1816 SizeVariance(pStubMsg
);
1818 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
1820 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1821 safe_buffer_length_increment(pStubMsg
, size
);
1824 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1826 case RPC_FC_C_CSTRING
:
1827 case RPC_FC_C_WSTRING
:
1828 if (fc
== RPC_FC_C_CSTRING
)
1833 SizeVariance(pStubMsg
);
1835 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1836 safe_buffer_length_increment(pStubMsg
, size
);
1839 ERR("unknown array format 0x%x\n", fc
);
1840 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1844 static inline void array_compute_and_write_conformance(
1845 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1846 PFORMAT_STRING pFormat
)
1851 ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1852 WriteConformance(pStubMsg
);
1854 case RPC_FC_CVARRAY
:
1855 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, 0);
1856 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
1857 WriteConformance(pStubMsg
);
1859 case RPC_FC_C_CSTRING
:
1860 case RPC_FC_C_WSTRING
:
1861 if (fc
== RPC_FC_C_CSTRING
)
1863 TRACE("string=%s\n", debugstr_a((const char *)pMemory
));
1864 pStubMsg
->ActualCount
= strlen((const char *)pMemory
)+1;
1868 TRACE("string=%s\n", debugstr_w((LPCWSTR
)pMemory
));
1869 pStubMsg
->ActualCount
= strlenW((LPCWSTR
)pMemory
)+1;
1871 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
1872 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
1874 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
1875 pStubMsg
->Offset
= 0;
1876 WriteConformance(pStubMsg
);
1879 ERR("unknown array format 0x%x\n", fc
);
1880 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1884 static inline void array_write_variance_and_marshall(
1885 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1886 PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
1890 unsigned char alignment
;
1895 esize
= *(const WORD
*)(pFormat
+2);
1896 alignment
= pFormat
[1] + 1;
1898 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1900 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
1902 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
1904 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1905 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
1908 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
1910 case RPC_FC_CVARRAY
:
1911 esize
= *(const WORD
*)(pFormat
+2);
1912 alignment
= pFormat
[1] + 1;
1915 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1917 pFormat
= SkipConformance(pStubMsg
, pFormat
);
1919 WriteVariance(pStubMsg
);
1921 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
1923 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1926 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1927 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, size
);
1930 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
1932 case RPC_FC_C_CSTRING
:
1933 case RPC_FC_C_WSTRING
:
1934 if (fc
== RPC_FC_C_CSTRING
)
1939 WriteVariance(pStubMsg
);
1941 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1942 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
1945 ERR("unknown array format 0x%x\n", fc
);
1946 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1950 static inline ULONG
array_read_conformance(
1951 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
1958 esize
= *(const WORD
*)(pFormat
+2);
1959 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
1960 return safe_multiply(esize
, pStubMsg
->MaxCount
);
1961 case RPC_FC_CVARRAY
:
1962 esize
= *(const WORD
*)(pFormat
+2);
1963 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
1964 return safe_multiply(esize
, pStubMsg
->MaxCount
);
1965 case RPC_FC_C_CSTRING
:
1966 case RPC_FC_C_WSTRING
:
1967 if (fc
== RPC_FC_C_CSTRING
)
1972 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
1973 ReadConformance(pStubMsg
, pFormat
+ 2);
1975 ReadConformance(pStubMsg
, NULL
);
1976 return safe_multiply(esize
, pStubMsg
->MaxCount
);
1978 ERR("unknown array format 0x%x\n", fc
);
1979 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1983 static inline ULONG
array_read_variance_and_unmarshall(
1984 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char **ppMemory
,
1985 PFORMAT_STRING pFormat
, unsigned char fMustAlloc
,
1986 unsigned char fUseBufferMemoryServer
, unsigned char fUnmarshall
)
1988 ULONG bufsize
, memsize
;
1990 unsigned char alignment
;
1991 unsigned char *saved_buffer
;
1997 esize
= *(const WORD
*)(pFormat
+2);
1998 alignment
= pFormat
[1] + 1;
2000 bufsize
= memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2002 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2004 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2009 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2012 if (fUseBufferMemoryServer
&& !pStubMsg
->IsClient
&& !*ppMemory
)
2013 /* for servers, we just point straight into the RPC buffer */
2014 *ppMemory
= pStubMsg
->Buffer
;
2017 saved_buffer
= pStubMsg
->Buffer
;
2018 safe_buffer_increment(pStubMsg
, bufsize
);
2020 pStubMsg
->BufferMark
= saved_buffer
;
2021 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
2023 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
2024 if (*ppMemory
!= saved_buffer
)
2025 memcpy(*ppMemory
, saved_buffer
, bufsize
);
2028 case RPC_FC_CVARRAY
:
2029 esize
= *(const WORD
*)(pFormat
+2);
2030 alignment
= pFormat
[1] + 1;
2032 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2034 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2036 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2038 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2039 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2043 offset
= pStubMsg
->Offset
;
2045 if (!fMustAlloc
&& !*ppMemory
)
2048 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2049 saved_buffer
= pStubMsg
->Buffer
;
2050 safe_buffer_increment(pStubMsg
, bufsize
);
2052 pStubMsg
->BufferMark
= saved_buffer
;
2053 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
,
2056 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
2059 case RPC_FC_C_CSTRING
:
2060 case RPC_FC_C_WSTRING
:
2061 if (fc
== RPC_FC_C_CSTRING
)
2066 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
2068 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
2070 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2071 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
2072 RpcRaiseException(RPC_S_INVALID_BOUND
);
2074 if (pStubMsg
->Offset
)
2076 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2077 RpcRaiseException(RPC_S_INVALID_BOUND
);
2080 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2081 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2083 validate_string_data(pStubMsg
, bufsize
, esize
);
2088 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2091 if (fUseBufferMemoryServer
&& !pStubMsg
->IsClient
&&
2092 !*ppMemory
&& (pStubMsg
->MaxCount
== pStubMsg
->ActualCount
))
2093 /* if the data in the RPC buffer is big enough, we just point
2094 * straight into it */
2095 *ppMemory
= pStubMsg
->Buffer
;
2096 else if (!*ppMemory
)
2097 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2100 if (*ppMemory
== pStubMsg
->Buffer
)
2101 safe_buffer_increment(pStubMsg
, bufsize
);
2103 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
2105 if (*pFormat
== RPC_FC_C_CSTRING
)
2106 TRACE("string=%s\n", debugstr_a((char*)*ppMemory
));
2108 TRACE("string=%s\n", debugstr_w((LPWSTR
)*ppMemory
));
2112 ERR("unknown array format 0x%x\n", fc
);
2113 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2117 static inline void array_memory_size(
2118 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
,
2119 unsigned char fHasPointers
)
2121 ULONG bufsize
, memsize
;
2123 unsigned char alignment
;
2128 esize
= *(const WORD
*)(pFormat
+2);
2129 alignment
= pFormat
[1] + 1;
2131 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2133 bufsize
= memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2134 pStubMsg
->MemorySize
+= memsize
;
2136 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2138 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2139 safe_buffer_increment(pStubMsg
, bufsize
);
2142 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2144 case RPC_FC_CVARRAY
:
2145 esize
= *(const WORD
*)(pFormat
+2);
2146 alignment
= pFormat
[1] + 1;
2148 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2150 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2152 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2153 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2154 pStubMsg
->MemorySize
+= memsize
;
2156 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2158 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2159 safe_buffer_increment(pStubMsg
, bufsize
);
2162 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2164 case RPC_FC_C_CSTRING
:
2165 case RPC_FC_C_WSTRING
:
2166 if (fc
== RPC_FC_C_CSTRING
)
2171 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
2173 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
2175 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2176 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
2177 RpcRaiseException(RPC_S_INVALID_BOUND
);
2179 if (pStubMsg
->Offset
)
2181 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2182 RpcRaiseException(RPC_S_INVALID_BOUND
);
2185 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2186 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2188 validate_string_data(pStubMsg
, bufsize
, esize
);
2190 safe_buffer_increment(pStubMsg
, bufsize
);
2191 pStubMsg
->MemorySize
+= memsize
;
2194 ERR("unknown array format 0x%x\n", fc
);
2195 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2199 static inline void array_free(
2200 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
,
2201 unsigned char *pMemory
, PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
2206 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2208 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2210 case RPC_FC_CVARRAY
:
2211 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2212 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2214 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2216 case RPC_FC_C_CSTRING
:
2217 case RPC_FC_C_WSTRING
:
2218 /* No embedded pointers so nothing to do */
2221 ERR("unknown array format 0x%x\n", fc
);
2222 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2227 * NdrConformantString:
2229 * What MS calls a ConformantString is, in DCE terminology,
2230 * a Varying-Conformant String.
2232 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2233 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2234 * into unmarshalled string)
2235 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2237 * data: CHARTYPE[maxlen]
2239 * ], where CHARTYPE is the appropriate character type (specified externally)
2243 /***********************************************************************
2244 * NdrConformantStringMarshall [RPCRT4.@]
2246 unsigned char *WINAPI
NdrConformantStringMarshall(MIDL_STUB_MESSAGE
*pStubMsg
,
2247 unsigned char *pszMessage
, PFORMAT_STRING pFormat
)
2249 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg
, pszMessage
, pFormat
);
2251 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2252 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2253 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2256 /* allow compiler to optimise inline function by passing constant into
2257 * these functions */
2258 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2259 array_compute_and_write_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pszMessage
,
2261 array_write_variance_and_marshall(RPC_FC_C_CSTRING
, pStubMsg
, pszMessage
,
2262 pFormat
, TRUE
/* fHasPointers */);
2264 array_compute_and_write_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pszMessage
,
2266 array_write_variance_and_marshall(RPC_FC_C_WSTRING
, pStubMsg
, pszMessage
,
2267 pFormat
, TRUE
/* fHasPointers */);
2273 /***********************************************************************
2274 * NdrConformantStringBufferSize [RPCRT4.@]
2276 void WINAPI
NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2277 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
2279 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2281 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2282 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2283 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2286 /* allow compiler to optimise inline function by passing constant into
2287 * these functions */
2288 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2289 array_compute_and_size_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pMemory
,
2291 array_buffer_size(RPC_FC_C_CSTRING
, pStubMsg
, pMemory
, pFormat
,
2292 TRUE
/* fHasPointers */);
2294 array_compute_and_size_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pMemory
,
2296 array_buffer_size(RPC_FC_C_WSTRING
, pStubMsg
, pMemory
, pFormat
,
2297 TRUE
/* fHasPointers */);
2301 /************************************************************************
2302 * NdrConformantStringMemorySize [RPCRT4.@]
2304 ULONG WINAPI
NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
2305 PFORMAT_STRING pFormat
)
2307 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
2309 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2310 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2311 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2314 /* allow compiler to optimise inline function by passing constant into
2315 * these functions */
2316 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2317 array_read_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
);
2318 array_memory_size(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
,
2319 TRUE
/* fHasPointers */);
2321 array_read_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
);
2322 array_memory_size(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
,
2323 TRUE
/* fHasPointers */);
2326 return pStubMsg
->MemorySize
;
2329 /************************************************************************
2330 * NdrConformantStringUnmarshall [RPCRT4.@]
2332 unsigned char *WINAPI
NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2333 unsigned char** ppMemory
, PFORMAT_STRING pFormat
, unsigned char fMustAlloc
)
2335 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2336 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
2338 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2339 ERR("Unhandled string type: %#x\n", *pFormat
);
2340 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2343 /* allow compiler to optimise inline function by passing constant into
2344 * these functions */
2345 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2346 array_read_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
);
2347 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING
, pStubMsg
, ppMemory
,
2348 pFormat
, fMustAlloc
,
2349 TRUE
/* fUseBufferMemoryServer */,
2350 TRUE
/* fUnmarshall */);
2352 array_read_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
);
2353 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING
, pStubMsg
, ppMemory
,
2354 pFormat
, fMustAlloc
,
2355 TRUE
/* fUseBufferMemoryServer */,
2356 TRUE
/* fUnmarshall */);
2362 /***********************************************************************
2363 * NdrNonConformantStringMarshall [RPCRT4.@]
2365 unsigned char * WINAPI
NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2366 unsigned char *pMemory
,
2367 PFORMAT_STRING pFormat
)
2369 ULONG esize
, size
, maxsize
;
2371 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2373 maxsize
= *(USHORT
*)&pFormat
[2];
2375 if (*pFormat
== RPC_FC_CSTRING
)
2378 const char *str
= (const char *)pMemory
;
2379 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
2381 TRACE("string=%s\n", debugstr_an(str
, i
));
2382 pStubMsg
->ActualCount
= i
+ 1;
2385 else if (*pFormat
== RPC_FC_WSTRING
)
2388 const WCHAR
*str
= (const WCHAR
*)pMemory
;
2389 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
2391 TRACE("string=%s\n", debugstr_wn(str
, i
));
2392 pStubMsg
->ActualCount
= i
+ 1;
2397 ERR("Unhandled string type: %#x\n", *pFormat
);
2398 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2401 pStubMsg
->Offset
= 0;
2402 WriteVariance(pStubMsg
);
2404 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2405 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
2410 /***********************************************************************
2411 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2413 unsigned char * WINAPI
NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2414 unsigned char **ppMemory
,
2415 PFORMAT_STRING pFormat
,
2416 unsigned char fMustAlloc
)
2418 ULONG bufsize
, memsize
, esize
, maxsize
;
2420 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2421 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
2423 maxsize
= *(USHORT
*)&pFormat
[2];
2425 ReadVariance(pStubMsg
, NULL
, maxsize
);
2426 if (pStubMsg
->Offset
)
2428 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2429 RpcRaiseException(RPC_S_INVALID_BOUND
);
2432 if (*pFormat
== RPC_FC_CSTRING
) esize
= 1;
2433 else if (*pFormat
== RPC_FC_WSTRING
) esize
= 2;
2436 ERR("Unhandled string type: %#x\n", *pFormat
);
2437 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2440 memsize
= esize
* maxsize
;
2441 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2443 validate_string_data(pStubMsg
, bufsize
, esize
);
2445 if (fMustAlloc
|| !*ppMemory
)
2446 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2448 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
2450 if (*pFormat
== RPC_FC_CSTRING
) {
2451 TRACE("string=%s\n", debugstr_an((char*)*ppMemory
, pStubMsg
->ActualCount
));
2453 else if (*pFormat
== RPC_FC_WSTRING
) {
2454 TRACE("string=%s\n", debugstr_wn((LPWSTR
)*ppMemory
, pStubMsg
->ActualCount
));
2460 /***********************************************************************
2461 * NdrNonConformantStringBufferSize [RPCRT4.@]
2463 void WINAPI
NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2464 unsigned char *pMemory
,
2465 PFORMAT_STRING pFormat
)
2467 ULONG esize
, maxsize
;
2469 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2471 maxsize
= *(USHORT
*)&pFormat
[2];
2473 SizeVariance(pStubMsg
);
2475 if (*pFormat
== RPC_FC_CSTRING
)
2478 const char *str
= (const char *)pMemory
;
2479 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
2481 TRACE("string=%s\n", debugstr_an(str
, i
));
2482 pStubMsg
->ActualCount
= i
+ 1;
2485 else if (*pFormat
== RPC_FC_WSTRING
)
2488 const WCHAR
*str
= (const WCHAR
*)pMemory
;
2489 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
2491 TRACE("string=%s\n", debugstr_wn(str
, i
));
2492 pStubMsg
->ActualCount
= i
+ 1;
2497 ERR("Unhandled string type: %#x\n", *pFormat
);
2498 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2501 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
2504 /***********************************************************************
2505 * NdrNonConformantStringMemorySize [RPCRT4.@]
2507 ULONG WINAPI
NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2508 PFORMAT_STRING pFormat
)
2510 ULONG bufsize
, memsize
, esize
, maxsize
;
2512 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
2514 maxsize
= *(USHORT
*)&pFormat
[2];
2516 ReadVariance(pStubMsg
, NULL
, maxsize
);
2518 if (pStubMsg
->Offset
)
2520 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2521 RpcRaiseException(RPC_S_INVALID_BOUND
);
2524 if (*pFormat
== RPC_FC_CSTRING
) esize
= 1;
2525 else if (*pFormat
== RPC_FC_WSTRING
) esize
= 2;
2528 ERR("Unhandled string type: %#x\n", *pFormat
);
2529 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2532 memsize
= esize
* maxsize
;
2533 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2535 validate_string_data(pStubMsg
, bufsize
, esize
);
2537 safe_buffer_increment(pStubMsg
, bufsize
);
2538 pStubMsg
->MemorySize
+= memsize
;
2540 return pStubMsg
->MemorySize
;
2545 #include "pshpack1.h"
2549 unsigned char flags_type
; /* flags in upper nibble, type in lower nibble */
2553 #include "poppack.h"
2555 static unsigned long EmbeddedComplexSize(MIDL_STUB_MESSAGE
*pStubMsg
,
2556 PFORMAT_STRING pFormat
)
2560 case RPC_FC_PSTRUCT
:
2561 case RPC_FC_CSTRUCT
:
2562 case RPC_FC_BOGUS_STRUCT
:
2563 case RPC_FC_SMFARRAY
:
2564 case RPC_FC_SMVARRAY
:
2565 case RPC_FC_CSTRING
:
2566 return *(const WORD
*)&pFormat
[2];
2567 case RPC_FC_USER_MARSHAL
:
2568 return *(const WORD
*)&pFormat
[4];
2569 case RPC_FC_RANGE
: {
2570 switch (((const NDR_RANGE
*)pFormat
)->flags_type
& 0xf) {
2575 return sizeof(UCHAR
);
2579 return sizeof(USHORT
);
2583 return sizeof(ULONG
);
2585 return sizeof(float);
2587 return sizeof(double);
2589 return sizeof(ULONGLONG
);
2591 return sizeof(UINT
);
2593 ERR("unknown type 0x%x\n", ((const NDR_RANGE
*)pFormat
)->flags_type
& 0xf);
2594 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2597 case RPC_FC_NON_ENCAPSULATED_UNION
:
2599 if (pStubMsg
->fHasNewCorrDesc
)
2604 pFormat
+= *(const SHORT
*)pFormat
;
2605 return *(const SHORT
*)pFormat
;
2607 return sizeof(void *);
2608 case RPC_FC_WSTRING
:
2609 return *(const WORD
*)&pFormat
[2] * 2;
2611 FIXME("unhandled embedded type %02x\n", *pFormat
);
2617 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2618 PFORMAT_STRING pFormat
)
2620 NDR_MEMORYSIZE m
= NdrMemorySizer
[*pFormat
& NDR_TABLE_MASK
];
2624 FIXME("no memorysizer for data type=%02x\n", *pFormat
);
2628 return m(pStubMsg
, pFormat
);
2632 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2633 unsigned char *pMemory
,
2634 PFORMAT_STRING pFormat
,
2635 PFORMAT_STRING pPointer
)
2637 PFORMAT_STRING desc
;
2641 while (*pFormat
!= RPC_FC_END
) {
2647 TRACE("byte=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2648 safe_copy_to_buffer(pStubMsg
, pMemory
, 1);
2654 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2655 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
2659 TRACE("enum16=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2660 if (32767 < *(DWORD
*)pMemory
)
2661 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
2662 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
2668 TRACE("long=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2669 safe_copy_to_buffer(pStubMsg
, pMemory
, 4);
2673 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2674 safe_copy_to_buffer(pStubMsg
, pMemory
, 8);
2677 case RPC_FC_POINTER
:
2679 unsigned char *saved_buffer
;
2680 int pointer_buffer_mark_set
= 0;
2681 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
2682 TRACE("pStubMsg->Buffer before %p\n", pStubMsg
->Buffer
);
2683 if (*pPointer
!= RPC_FC_RP
)
2684 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
2685 saved_buffer
= pStubMsg
->Buffer
;
2686 if (pStubMsg
->PointerBufferMark
)
2688 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2689 pStubMsg
->PointerBufferMark
= NULL
;
2690 pointer_buffer_mark_set
= 1;
2692 else if (*pPointer
!= RPC_FC_RP
)
2693 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2694 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char**)pMemory
, pPointer
);
2695 if (pointer_buffer_mark_set
)
2697 STD_OVERFLOW_CHECK(pStubMsg
);
2698 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2699 pStubMsg
->Buffer
= saved_buffer
;
2700 if (*pPointer
!= RPC_FC_RP
)
2701 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2703 TRACE("pStubMsg->Buffer after %p\n", pStubMsg
->Buffer
);
2708 case RPC_FC_ALIGNM4
:
2709 ALIGN_POINTER(pMemory
, 4);
2711 case RPC_FC_ALIGNM8
:
2712 ALIGN_POINTER(pMemory
, 8);
2714 case RPC_FC_STRUCTPAD1
:
2715 case RPC_FC_STRUCTPAD2
:
2716 case RPC_FC_STRUCTPAD3
:
2717 case RPC_FC_STRUCTPAD4
:
2718 case RPC_FC_STRUCTPAD5
:
2719 case RPC_FC_STRUCTPAD6
:
2720 case RPC_FC_STRUCTPAD7
:
2721 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2723 case RPC_FC_EMBEDDED_COMPLEX
:
2724 pMemory
+= pFormat
[1];
2726 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2727 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2728 TRACE("embedded complex (size=%ld) <= %p\n", size
, pMemory
);
2729 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
2732 /* for some reason interface pointers aren't generated as
2733 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2734 * they still need the derefencing treatment that pointers are
2736 if (*desc
== RPC_FC_IP
)
2737 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2739 m(pStubMsg
, pMemory
, desc
);
2741 else FIXME("no marshaller for embedded type %02x\n", *desc
);
2748 FIXME("unhandled format 0x%02x\n", *pFormat
);
2756 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2757 unsigned char *pMemory
,
2758 PFORMAT_STRING pFormat
,
2759 PFORMAT_STRING pPointer
,
2760 unsigned char fMustAlloc
)
2762 PFORMAT_STRING desc
;
2766 while (*pFormat
!= RPC_FC_END
) {
2772 safe_copy_from_buffer(pStubMsg
, pMemory
, 1);
2773 TRACE("byte=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2779 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
2780 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2784 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
2785 *(DWORD
*)pMemory
&= 0xffff;
2786 TRACE("enum16=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
2787 if (32767 < *(DWORD
*)pMemory
)
2788 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
2794 safe_copy_from_buffer(pStubMsg
, pMemory
, 4);
2795 TRACE("long=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
2799 safe_copy_from_buffer(pStubMsg
, pMemory
, 8);
2800 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2803 case RPC_FC_POINTER
:
2805 unsigned char *saved_buffer
;
2806 int pointer_buffer_mark_set
= 0;
2807 TRACE("pointer => %p\n", pMemory
);
2808 if (*pPointer
!= RPC_FC_RP
)
2809 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2810 saved_buffer
= pStubMsg
->Buffer
;
2811 if (pStubMsg
->PointerBufferMark
)
2813 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2814 pStubMsg
->PointerBufferMark
= NULL
;
2815 pointer_buffer_mark_set
= 1;
2817 else if (*pPointer
!= RPC_FC_RP
)
2818 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2820 PointerUnmarshall(pStubMsg
, saved_buffer
, (unsigned char**)pMemory
, *(unsigned char**)pMemory
, pPointer
, fMustAlloc
);
2821 if (pointer_buffer_mark_set
)
2823 STD_OVERFLOW_CHECK(pStubMsg
);
2824 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2825 pStubMsg
->Buffer
= saved_buffer
;
2826 if (*pPointer
!= RPC_FC_RP
)
2827 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2833 case RPC_FC_ALIGNM4
:
2834 ALIGN_POINTER_CLEAR(pMemory
, 4);
2836 case RPC_FC_ALIGNM8
:
2837 ALIGN_POINTER_CLEAR(pMemory
, 8);
2839 case RPC_FC_STRUCTPAD1
:
2840 case RPC_FC_STRUCTPAD2
:
2841 case RPC_FC_STRUCTPAD3
:
2842 case RPC_FC_STRUCTPAD4
:
2843 case RPC_FC_STRUCTPAD5
:
2844 case RPC_FC_STRUCTPAD6
:
2845 case RPC_FC_STRUCTPAD7
:
2846 memset(pMemory
, 0, *pFormat
- RPC_FC_STRUCTPAD1
+ 1);
2847 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2849 case RPC_FC_EMBEDDED_COMPLEX
:
2850 pMemory
+= pFormat
[1];
2852 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2853 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2854 TRACE("embedded complex (size=%ld) => %p\n", size
, pMemory
);
2856 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
2857 * since the type is part of the memory block that is encompassed by
2858 * the whole complex type. Memory is forced to allocate when pointers
2859 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
2860 * clearing the memory we pass in to the unmarshaller */
2861 memset(pMemory
, 0, size
);
2862 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
2865 /* for some reason interface pointers aren't generated as
2866 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2867 * they still need the derefencing treatment that pointers are
2869 if (*desc
== RPC_FC_IP
)
2870 m(pStubMsg
, (unsigned char **)pMemory
, desc
, FALSE
);
2872 m(pStubMsg
, &pMemory
, desc
, FALSE
);
2874 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
2881 FIXME("unhandled format %d\n", *pFormat
);
2889 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2890 unsigned char *pMemory
,
2891 PFORMAT_STRING pFormat
,
2892 PFORMAT_STRING pPointer
)
2894 PFORMAT_STRING desc
;
2898 while (*pFormat
!= RPC_FC_END
) {
2904 safe_buffer_length_increment(pStubMsg
, 1);
2910 safe_buffer_length_increment(pStubMsg
, 2);
2914 safe_buffer_length_increment(pStubMsg
, 2);
2920 safe_buffer_length_increment(pStubMsg
, 4);
2924 safe_buffer_length_increment(pStubMsg
, 8);
2927 case RPC_FC_POINTER
:
2928 if (!pStubMsg
->IgnoreEmbeddedPointers
)
2930 int saved_buffer_length
= pStubMsg
->BufferLength
;
2931 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2932 pStubMsg
->PointerLength
= 0;
2933 if(!pStubMsg
->BufferLength
)
2934 ERR("BufferLength == 0??\n");
2935 PointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
2936 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2937 pStubMsg
->BufferLength
= saved_buffer_length
;
2939 if (*pPointer
!= RPC_FC_RP
)
2941 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
2942 safe_buffer_length_increment(pStubMsg
, 4);
2947 case RPC_FC_ALIGNM4
:
2948 ALIGN_POINTER(pMemory
, 4);
2950 case RPC_FC_ALIGNM8
:
2951 ALIGN_POINTER(pMemory
, 8);
2953 case RPC_FC_STRUCTPAD1
:
2954 case RPC_FC_STRUCTPAD2
:
2955 case RPC_FC_STRUCTPAD3
:
2956 case RPC_FC_STRUCTPAD4
:
2957 case RPC_FC_STRUCTPAD5
:
2958 case RPC_FC_STRUCTPAD6
:
2959 case RPC_FC_STRUCTPAD7
:
2960 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2962 case RPC_FC_EMBEDDED_COMPLEX
:
2963 pMemory
+= pFormat
[1];
2965 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2966 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2967 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
2970 /* for some reason interface pointers aren't generated as
2971 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2972 * they still need the derefencing treatment that pointers are
2974 if (*desc
== RPC_FC_IP
)
2975 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2977 m(pStubMsg
, pMemory
, desc
);
2979 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
2986 FIXME("unhandled format 0x%02x\n", *pFormat
);
2994 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
2995 unsigned char *pMemory
,
2996 PFORMAT_STRING pFormat
,
2997 PFORMAT_STRING pPointer
)
2999 PFORMAT_STRING desc
;
3003 while (*pFormat
!= RPC_FC_END
) {
3025 case RPC_FC_POINTER
:
3026 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
3030 case RPC_FC_ALIGNM4
:
3031 ALIGN_POINTER(pMemory
, 4);
3033 case RPC_FC_ALIGNM8
:
3034 ALIGN_POINTER(pMemory
, 8);
3036 case RPC_FC_STRUCTPAD1
:
3037 case RPC_FC_STRUCTPAD2
:
3038 case RPC_FC_STRUCTPAD3
:
3039 case RPC_FC_STRUCTPAD4
:
3040 case RPC_FC_STRUCTPAD5
:
3041 case RPC_FC_STRUCTPAD6
:
3042 case RPC_FC_STRUCTPAD7
:
3043 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3045 case RPC_FC_EMBEDDED_COMPLEX
:
3046 pMemory
+= pFormat
[1];
3048 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3049 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3050 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
3053 /* for some reason interface pointers aren't generated as
3054 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3055 * they still need the derefencing treatment that pointers are
3057 if (*desc
== RPC_FC_IP
)
3058 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
3060 m(pStubMsg
, pMemory
, desc
);
3068 FIXME("unhandled format 0x%02x\n", *pFormat
);
3076 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3077 PFORMAT_STRING pFormat
,
3078 PFORMAT_STRING pPointer
)
3080 PFORMAT_STRING desc
;
3081 unsigned long size
= 0;
3083 while (*pFormat
!= RPC_FC_END
) {
3090 safe_buffer_increment(pStubMsg
, 1);
3096 safe_buffer_increment(pStubMsg
, 2);
3100 safe_buffer_increment(pStubMsg
, 2);
3106 safe_buffer_increment(pStubMsg
, 4);
3110 safe_buffer_increment(pStubMsg
, 8);
3112 case RPC_FC_POINTER
:
3114 unsigned char *saved_buffer
;
3115 int pointer_buffer_mark_set
= 0;
3116 if (*pPointer
!= RPC_FC_RP
)
3117 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3118 saved_buffer
= pStubMsg
->Buffer
;
3119 if (pStubMsg
->PointerBufferMark
)
3121 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3122 pStubMsg
->PointerBufferMark
= NULL
;
3123 pointer_buffer_mark_set
= 1;
3125 else if (*pPointer
!= RPC_FC_RP
)
3126 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3128 if (!pStubMsg
->IgnoreEmbeddedPointers
)
3129 PointerMemorySize(pStubMsg
, saved_buffer
, pPointer
);
3130 if (pointer_buffer_mark_set
)
3132 STD_OVERFLOW_CHECK(pStubMsg
);
3133 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3134 pStubMsg
->Buffer
= saved_buffer
;
3135 if (*pPointer
!= RPC_FC_RP
)
3136 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3142 case RPC_FC_ALIGNM4
:
3143 ALIGN_LENGTH(size
, 4);
3144 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3146 case RPC_FC_ALIGNM8
:
3147 ALIGN_LENGTH(size
, 8);
3148 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3150 case RPC_FC_STRUCTPAD1
:
3151 case RPC_FC_STRUCTPAD2
:
3152 case RPC_FC_STRUCTPAD3
:
3153 case RPC_FC_STRUCTPAD4
:
3154 case RPC_FC_STRUCTPAD5
:
3155 case RPC_FC_STRUCTPAD6
:
3156 case RPC_FC_STRUCTPAD7
:
3157 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3159 case RPC_FC_EMBEDDED_COMPLEX
:
3162 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3163 size
+= EmbeddedComplexMemorySize(pStubMsg
, desc
);
3169 FIXME("unhandled format 0x%02x\n", *pFormat
);
3177 unsigned long ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg
,
3178 PFORMAT_STRING pFormat
)
3180 PFORMAT_STRING desc
;
3181 unsigned long size
= 0;
3183 while (*pFormat
!= RPC_FC_END
) {
3205 case RPC_FC_POINTER
:
3206 size
+= sizeof(void *);
3208 case RPC_FC_ALIGNM4
:
3209 ALIGN_LENGTH(size
, 4);
3211 case RPC_FC_ALIGNM8
:
3212 ALIGN_LENGTH(size
, 8);
3214 case RPC_FC_STRUCTPAD1
:
3215 case RPC_FC_STRUCTPAD2
:
3216 case RPC_FC_STRUCTPAD3
:
3217 case RPC_FC_STRUCTPAD4
:
3218 case RPC_FC_STRUCTPAD5
:
3219 case RPC_FC_STRUCTPAD6
:
3220 case RPC_FC_STRUCTPAD7
:
3221 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3223 case RPC_FC_EMBEDDED_COMPLEX
:
3226 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3227 size
+= EmbeddedComplexSize(pStubMsg
, desc
);
3233 FIXME("unhandled format 0x%02x\n", *pFormat
);
3241 /***********************************************************************
3242 * NdrComplexStructMarshall [RPCRT4.@]
3244 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3245 unsigned char *pMemory
,
3246 PFORMAT_STRING pFormat
)
3248 PFORMAT_STRING conf_array
= NULL
;
3249 PFORMAT_STRING pointer_desc
= NULL
;
3250 unsigned char *OldMemory
= pStubMsg
->Memory
;
3251 int pointer_buffer_mark_set
= 0;
3253 ULONG max_count
= 0;
3256 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3258 if (!pStubMsg
->PointerBufferMark
)
3260 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3261 /* save buffer length */
3262 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
3264 /* get the buffer pointer after complex array data, but before
3266 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- pStubMsg
->BufferStart
;
3267 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3268 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
3269 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3271 /* save it for use by embedded pointer code later */
3272 pStubMsg
->PointerBufferMark
= pStubMsg
->BufferStart
+ pStubMsg
->BufferLength
;
3273 TRACE("difference = 0x%x\n", pStubMsg
->PointerBufferMark
- pStubMsg
->Buffer
);
3274 pointer_buffer_mark_set
= 1;
3276 /* restore the original buffer length */
3277 pStubMsg
->BufferLength
= saved_buffer_length
;
3280 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pFormat
[1] + 1);
3283 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3285 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3288 pStubMsg
->Memory
= pMemory
;
3292 unsigned long struct_size
= ComplexStructSize(pStubMsg
, pFormat
);
3293 array_compute_and_write_conformance(conf_array
[0], pStubMsg
,
3294 pMemory
+ struct_size
, conf_array
);
3295 /* these could be changed in ComplexMarshall so save them for later */
3296 max_count
= pStubMsg
->MaxCount
;
3297 count
= pStubMsg
->ActualCount
;
3298 offset
= pStubMsg
->Offset
;
3301 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3305 pStubMsg
->MaxCount
= max_count
;
3306 pStubMsg
->ActualCount
= count
;
3307 pStubMsg
->Offset
= offset
;
3308 array_write_variance_and_marshall(conf_array
[0], pStubMsg
, pMemory
,
3309 conf_array
, TRUE
/* fHasPointers */);
3312 pStubMsg
->Memory
= OldMemory
;
3314 if (pointer_buffer_mark_set
)
3316 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3317 pStubMsg
->PointerBufferMark
= NULL
;
3320 STD_OVERFLOW_CHECK(pStubMsg
);
3325 /***********************************************************************
3326 * NdrComplexStructUnmarshall [RPCRT4.@]
3328 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3329 unsigned char **ppMemory
,
3330 PFORMAT_STRING pFormat
,
3331 unsigned char fMustAlloc
)
3333 unsigned size
= *(const WORD
*)(pFormat
+2);
3334 PFORMAT_STRING conf_array
= NULL
;
3335 PFORMAT_STRING pointer_desc
= NULL
;
3336 unsigned char *pMemory
;
3337 int pointer_buffer_mark_set
= 0;
3339 ULONG max_count
= 0;
3341 ULONG array_size
= 0;
3343 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3345 if (!pStubMsg
->PointerBufferMark
)
3347 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3348 /* save buffer pointer */
3349 unsigned char *saved_buffer
= pStubMsg
->Buffer
;
3351 /* get the buffer pointer after complex array data, but before
3353 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3354 NdrComplexStructMemorySize(pStubMsg
, pFormat
);
3355 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3357 /* save it for use by embedded pointer code later */
3358 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3359 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->PointerBufferMark
- saved_buffer
));
3360 pointer_buffer_mark_set
= 1;
3362 /* restore the original buffer */
3363 pStubMsg
->Buffer
= saved_buffer
;
3366 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
3369 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3371 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3376 array_size
= array_read_conformance(conf_array
[0], pStubMsg
, conf_array
);
3379 /* these could be changed in ComplexMarshall so save them for later */
3380 max_count
= pStubMsg
->MaxCount
;
3381 count
= pStubMsg
->ActualCount
;
3382 offset
= pStubMsg
->Offset
;
3385 if (fMustAlloc
|| !*ppMemory
)
3386 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3388 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
, fMustAlloc
);
3392 pStubMsg
->MaxCount
= max_count
;
3393 pStubMsg
->ActualCount
= count
;
3394 pStubMsg
->Offset
= offset
;
3396 memset(pMemory
, 0, array_size
);
3397 array_read_variance_and_unmarshall(conf_array
[0], pStubMsg
, &pMemory
,
3399 FALSE
/* fUseBufferMemoryServer */,
3400 TRUE
/* fUnmarshall */);
3403 if (pointer_buffer_mark_set
)
3405 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3406 pStubMsg
->PointerBufferMark
= NULL
;
3412 /***********************************************************************
3413 * NdrComplexStructBufferSize [RPCRT4.@]
3415 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3416 unsigned char *pMemory
,
3417 PFORMAT_STRING pFormat
)
3419 PFORMAT_STRING conf_array
= NULL
;
3420 PFORMAT_STRING pointer_desc
= NULL
;
3421 unsigned char *OldMemory
= pStubMsg
->Memory
;
3422 int pointer_length_set
= 0;
3424 ULONG max_count
= 0;
3427 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3429 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
3431 if(!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
3433 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3434 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
3436 /* get the buffer length after complex struct data, but before
3438 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3439 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
3440 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3442 /* save it for use by embedded pointer code later */
3443 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3444 pointer_length_set
= 1;
3445 TRACE("difference = 0x%lx\n", pStubMsg
->PointerLength
- saved_buffer_length
);
3447 /* restore the original buffer length */
3448 pStubMsg
->BufferLength
= saved_buffer_length
;
3452 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3454 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3457 pStubMsg
->Memory
= pMemory
;
3461 unsigned long struct_size
= ComplexStructSize(pStubMsg
, pFormat
);
3462 array_compute_and_size_conformance(conf_array
[0], pStubMsg
, pMemory
+ struct_size
,
3465 /* these could be changed in ComplexMarshall so save them for later */
3466 max_count
= pStubMsg
->MaxCount
;
3467 count
= pStubMsg
->ActualCount
;
3468 offset
= pStubMsg
->Offset
;
3471 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3475 pStubMsg
->MaxCount
= max_count
;
3476 pStubMsg
->ActualCount
= count
;
3477 pStubMsg
->Offset
= offset
;
3478 array_buffer_size(conf_array
[0], pStubMsg
, pMemory
, conf_array
,
3479 TRUE
/* fHasPointers */);
3482 pStubMsg
->Memory
= OldMemory
;
3484 if(pointer_length_set
)
3486 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3487 pStubMsg
->PointerLength
= 0;
3492 /***********************************************************************
3493 * NdrComplexStructMemorySize [RPCRT4.@]
3495 ULONG WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3496 PFORMAT_STRING pFormat
)
3498 unsigned size
= *(const WORD
*)(pFormat
+2);
3499 PFORMAT_STRING conf_array
= NULL
;
3500 PFORMAT_STRING pointer_desc
= NULL
;
3502 ULONG max_count
= 0;
3505 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3507 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
3510 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3512 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3517 array_read_conformance(conf_array
[0], pStubMsg
, conf_array
);
3519 /* these could be changed in ComplexStructMemorySize so save them for
3521 max_count
= pStubMsg
->MaxCount
;
3522 count
= pStubMsg
->ActualCount
;
3523 offset
= pStubMsg
->Offset
;
3526 ComplexStructMemorySize(pStubMsg
, pFormat
, pointer_desc
);
3530 pStubMsg
->MaxCount
= max_count
;
3531 pStubMsg
->ActualCount
= count
;
3532 pStubMsg
->Offset
= offset
;
3533 array_memory_size(conf_array
[0], pStubMsg
, conf_array
,
3534 TRUE
/* fHasPointers */);
3540 /***********************************************************************
3541 * NdrComplexStructFree [RPCRT4.@]
3543 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3544 unsigned char *pMemory
,
3545 PFORMAT_STRING pFormat
)
3547 PFORMAT_STRING conf_array
= NULL
;
3548 PFORMAT_STRING pointer_desc
= NULL
;
3549 unsigned char *OldMemory
= pStubMsg
->Memory
;
3551 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3554 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3556 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3559 pStubMsg
->Memory
= pMemory
;
3561 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3564 array_free(conf_array
[0], pStubMsg
, pMemory
, conf_array
,
3565 TRUE
/* fHasPointers */);
3567 pStubMsg
->Memory
= OldMemory
;
3570 /***********************************************************************
3571 * NdrConformantArrayMarshall [RPCRT4.@]
3573 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3574 unsigned char *pMemory
,
3575 PFORMAT_STRING pFormat
)
3577 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3578 if (pFormat
[0] != RPC_FC_CARRAY
)
3580 ERR("invalid format = 0x%x\n", pFormat
[0]);
3581 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3584 array_compute_and_write_conformance(RPC_FC_CARRAY
, pStubMsg
, pMemory
,
3586 array_write_variance_and_marshall(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3587 TRUE
/* fHasPointers */);
3592 /***********************************************************************
3593 * NdrConformantArrayUnmarshall [RPCRT4.@]
3595 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3596 unsigned char **ppMemory
,
3597 PFORMAT_STRING pFormat
,
3598 unsigned char fMustAlloc
)
3600 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3601 if (pFormat
[0] != RPC_FC_CARRAY
)
3603 ERR("invalid format = 0x%x\n", pFormat
[0]);
3604 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3607 array_read_conformance(RPC_FC_CARRAY
, pStubMsg
, pFormat
);
3608 array_read_variance_and_unmarshall(RPC_FC_CARRAY
, pStubMsg
, ppMemory
, pFormat
,
3610 TRUE
/* fUseBufferMemoryServer */,
3611 TRUE
/* fUnmarshall */);
3616 /***********************************************************************
3617 * NdrConformantArrayBufferSize [RPCRT4.@]
3619 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3620 unsigned char *pMemory
,
3621 PFORMAT_STRING pFormat
)
3623 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3624 if (pFormat
[0] != RPC_FC_CARRAY
)
3626 ERR("invalid format = 0x%x\n", pFormat
[0]);
3627 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3630 array_compute_and_size_conformance(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
);
3631 array_buffer_size(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3632 TRUE
/* fHasPointers */);
3635 /***********************************************************************
3636 * NdrConformantArrayMemorySize [RPCRT4.@]
3638 ULONG WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3639 PFORMAT_STRING pFormat
)
3641 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3642 if (pFormat
[0] != RPC_FC_CARRAY
)
3644 ERR("invalid format = 0x%x\n", pFormat
[0]);
3645 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3648 array_read_conformance(RPC_FC_CARRAY
, pStubMsg
, pFormat
);
3649 array_memory_size(RPC_FC_CARRAY
, pStubMsg
, pFormat
, TRUE
/* fHasPointers */);
3651 return pStubMsg
->MemorySize
;
3654 /***********************************************************************
3655 * NdrConformantArrayFree [RPCRT4.@]
3657 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3658 unsigned char *pMemory
,
3659 PFORMAT_STRING pFormat
)
3661 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3662 if (pFormat
[0] != RPC_FC_CARRAY
)
3664 ERR("invalid format = 0x%x\n", pFormat
[0]);
3665 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3668 array_free(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3669 TRUE
/* fHasPointers */);
3673 /***********************************************************************
3674 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3676 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
3677 unsigned char* pMemory
,
3678 PFORMAT_STRING pFormat
)
3680 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3682 if (pFormat
[0] != RPC_FC_CVARRAY
)
3684 ERR("invalid format type %x\n", pFormat
[0]);
3685 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3689 array_compute_and_write_conformance(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
3691 array_write_variance_and_marshall(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
3692 pFormat
, TRUE
/* fHasPointers */);
3698 /***********************************************************************
3699 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
3701 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
3702 unsigned char** ppMemory
,
3703 PFORMAT_STRING pFormat
,
3704 unsigned char fMustAlloc
)
3706 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3708 if (pFormat
[0] != RPC_FC_CVARRAY
)
3710 ERR("invalid format type %x\n", pFormat
[0]);
3711 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3715 array_read_conformance(RPC_FC_CVARRAY
, pStubMsg
, pFormat
);
3716 array_read_variance_and_unmarshall(RPC_FC_CVARRAY
, pStubMsg
, ppMemory
,
3717 pFormat
, fMustAlloc
,
3718 TRUE
/* fUseBufferMemoryServer */,
3719 TRUE
/* fUnmarshall */);
3725 /***********************************************************************
3726 * NdrConformantVaryingArrayFree [RPCRT4.@]
3728 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
3729 unsigned char* pMemory
,
3730 PFORMAT_STRING pFormat
)
3732 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3734 if (pFormat
[0] != RPC_FC_CVARRAY
)
3736 ERR("invalid format type %x\n", pFormat
[0]);
3737 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3741 array_free(RPC_FC_CVARRAY
, pStubMsg
, pMemory
, pFormat
,
3742 TRUE
/* fHasPointers */);
3746 /***********************************************************************
3747 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
3749 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
3750 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
3752 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3754 if (pFormat
[0] != RPC_FC_CVARRAY
)
3756 ERR("invalid format type %x\n", pFormat
[0]);
3757 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3761 array_compute_and_size_conformance(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
3763 array_buffer_size(RPC_FC_CVARRAY
, pStubMsg
, pMemory
, pFormat
,
3764 TRUE
/* fHasPointers */);
3768 /***********************************************************************
3769 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
3771 ULONG WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
3772 PFORMAT_STRING pFormat
)
3774 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
3776 if (pFormat
[0] != RPC_FC_CVARRAY
)
3778 ERR("invalid format type %x\n", pFormat
[0]);
3779 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3780 return pStubMsg
->MemorySize
;
3783 array_read_conformance(RPC_FC_CVARRAY
, pStubMsg
, pFormat
);
3784 array_memory_size(RPC_FC_CVARRAY
, pStubMsg
, pFormat
,
3785 TRUE
/* fHasPointers */);
3787 return pStubMsg
->MemorySize
;
3791 /***********************************************************************
3792 * NdrComplexArrayMarshall [RPCRT4.@]
3794 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3795 unsigned char *pMemory
,
3796 PFORMAT_STRING pFormat
)
3798 ULONG i
, count
, def
;
3799 BOOL variance_present
;
3800 unsigned char alignment
;
3801 int pointer_buffer_mark_set
= 0;
3803 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3805 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3807 ERR("invalid format type %x\n", pFormat
[0]);
3808 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3812 alignment
= pFormat
[1] + 1;
3814 if (!pStubMsg
->PointerBufferMark
)
3816 /* save buffer fields that may be changed by buffer sizer functions
3817 * and that may be needed later on */
3818 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3819 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
3820 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
3821 unsigned long saved_offset
= pStubMsg
->Offset
;
3822 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
3824 /* get the buffer pointer after complex array data, but before
3826 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- pStubMsg
->BufferStart
;
3827 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3828 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
3829 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3831 /* save it for use by embedded pointer code later */
3832 pStubMsg
->PointerBufferMark
= pStubMsg
->BufferStart
+ pStubMsg
->BufferLength
;
3833 TRACE("difference = 0x%x\n", pStubMsg
->Buffer
- pStubMsg
->BufferStart
);
3834 pointer_buffer_mark_set
= 1;
3836 /* restore fields */
3837 pStubMsg
->ActualCount
= saved_actual_count
;
3838 pStubMsg
->Offset
= saved_offset
;
3839 pStubMsg
->MaxCount
= saved_max_count
;
3840 pStubMsg
->BufferLength
= saved_buffer_length
;
3843 def
= *(const WORD
*)&pFormat
[2];
3846 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3847 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3849 variance_present
= IsConformanceOrVariancePresent(pFormat
);
3850 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3851 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3853 WriteConformance(pStubMsg
);
3854 if (variance_present
)
3855 WriteVariance(pStubMsg
);
3857 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
3859 count
= pStubMsg
->ActualCount
;
3860 for (i
= 0; i
< count
; i
++)
3861 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
3863 STD_OVERFLOW_CHECK(pStubMsg
);
3865 if (pointer_buffer_mark_set
)
3867 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3868 pStubMsg
->PointerBufferMark
= NULL
;
3874 /***********************************************************************
3875 * NdrComplexArrayUnmarshall [RPCRT4.@]
3877 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3878 unsigned char **ppMemory
,
3879 PFORMAT_STRING pFormat
,
3880 unsigned char fMustAlloc
)
3882 ULONG i
, count
, size
;
3883 unsigned char alignment
;
3884 unsigned char *pMemory
;
3885 unsigned char *saved_buffer
;
3886 int pointer_buffer_mark_set
= 0;
3887 int saved_ignore_embedded
;
3889 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3891 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3893 ERR("invalid format type %x\n", pFormat
[0]);
3894 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3898 alignment
= pFormat
[1] + 1;
3900 saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3901 /* save buffer pointer */
3902 saved_buffer
= pStubMsg
->Buffer
;
3903 /* get the buffer pointer after complex array data, but before
3905 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3906 pStubMsg
->MemorySize
= 0;
3907 NdrComplexArrayMemorySize(pStubMsg
, pFormat
);
3908 size
= pStubMsg
->MemorySize
;
3909 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3911 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->Buffer
- saved_buffer
));
3912 if (!pStubMsg
->PointerBufferMark
)
3914 /* save it for use by embedded pointer code later */
3915 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3916 pointer_buffer_mark_set
= 1;
3918 /* restore the original buffer */
3919 pStubMsg
->Buffer
= saved_buffer
;
3923 pFormat
= ReadConformance(pStubMsg
, pFormat
);
3924 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3926 if (fMustAlloc
|| !*ppMemory
)
3927 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3929 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3931 pMemory
= *ppMemory
;
3932 count
= pStubMsg
->ActualCount
;
3933 for (i
= 0; i
< count
; i
++)
3934 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
, fMustAlloc
);
3936 if (pointer_buffer_mark_set
)
3938 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3939 pStubMsg
->PointerBufferMark
= NULL
;
3945 /***********************************************************************
3946 * NdrComplexArrayBufferSize [RPCRT4.@]
3948 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3949 unsigned char *pMemory
,
3950 PFORMAT_STRING pFormat
)
3952 ULONG i
, count
, def
;
3953 unsigned char alignment
;
3954 BOOL variance_present
;
3955 int pointer_length_set
= 0;
3957 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3959 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3961 ERR("invalid format type %x\n", pFormat
[0]);
3962 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3966 alignment
= pFormat
[1] + 1;
3968 if (!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
3970 /* save buffer fields that may be changed by buffer sizer functions
3971 * and that may be needed later on */
3972 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3973 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
3974 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
3975 unsigned long saved_offset
= pStubMsg
->Offset
;
3976 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
3978 /* get the buffer pointer after complex array data, but before
3980 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3981 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
3982 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3984 /* save it for use by embedded pointer code later */
3985 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3986 pointer_length_set
= 1;
3988 /* restore fields */
3989 pStubMsg
->ActualCount
= saved_actual_count
;
3990 pStubMsg
->Offset
= saved_offset
;
3991 pStubMsg
->MaxCount
= saved_max_count
;
3992 pStubMsg
->BufferLength
= saved_buffer_length
;
3994 def
= *(const WORD
*)&pFormat
[2];
3997 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3998 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3999 SizeConformance(pStubMsg
);
4001 variance_present
= IsConformanceOrVariancePresent(pFormat
);
4002 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
4003 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
4005 if (variance_present
)
4006 SizeVariance(pStubMsg
);
4008 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
4010 count
= pStubMsg
->ActualCount
;
4011 for (i
= 0; i
< count
; i
++)
4012 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
4014 if(pointer_length_set
)
4016 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4017 pStubMsg
->PointerLength
= 0;
4021 /***********************************************************************
4022 * NdrComplexArrayMemorySize [RPCRT4.@]
4024 ULONG WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4025 PFORMAT_STRING pFormat
)
4027 ULONG i
, count
, esize
, SavedMemorySize
, MemorySize
;
4028 unsigned char alignment
;
4030 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
4032 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4034 ERR("invalid format type %x\n", pFormat
[0]);
4035 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4039 alignment
= pFormat
[1] + 1;
4043 pFormat
= ReadConformance(pStubMsg
, pFormat
);
4044 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
4046 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4048 SavedMemorySize
= pStubMsg
->MemorySize
;
4050 esize
= ComplexStructSize(pStubMsg
, pFormat
);
4052 MemorySize
= safe_multiply(pStubMsg
->MaxCount
, esize
);
4054 count
= pStubMsg
->ActualCount
;
4055 for (i
= 0; i
< count
; i
++)
4056 ComplexStructMemorySize(pStubMsg
, pFormat
, NULL
);
4058 pStubMsg
->MemorySize
= SavedMemorySize
;
4060 pStubMsg
->MemorySize
+= MemorySize
;
4064 /***********************************************************************
4065 * NdrComplexArrayFree [RPCRT4.@]
4067 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4068 unsigned char *pMemory
,
4069 PFORMAT_STRING pFormat
)
4071 ULONG i
, count
, def
;
4073 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4075 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4077 ERR("invalid format type %x\n", pFormat
[0]);
4078 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4082 def
= *(const WORD
*)&pFormat
[2];
4085 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
4086 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
4088 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
4089 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
4091 count
= pStubMsg
->ActualCount
;
4092 for (i
= 0; i
< count
; i
++)
4093 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
4096 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg
,
4097 USER_MARSHAL_CB_TYPE cbtype
, PFORMAT_STRING pFormat
,
4098 USER_MARSHAL_CB
*umcb
)
4100 umcb
->Flags
= MAKELONG(pStubMsg
->dwDestContext
,
4101 pStubMsg
->RpcMsg
->DataRepresentation
);
4102 umcb
->pStubMsg
= pStubMsg
;
4103 umcb
->pReserve
= NULL
;
4104 umcb
->Signature
= USER_MARSHAL_CB_SIGNATURE
;
4105 umcb
->CBType
= cbtype
;
4106 umcb
->pFormat
= pFormat
;
4107 umcb
->pTypeFormat
= NULL
/* FIXME */;
4110 #define USER_MARSHAL_PTR_PREFIX \
4111 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4112 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4114 /***********************************************************************
4115 * NdrUserMarshalMarshall [RPCRT4.@]
4117 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4118 unsigned char *pMemory
,
4119 PFORMAT_STRING pFormat
)
4121 unsigned flags
= pFormat
[1];
4122 unsigned index
= *(const WORD
*)&pFormat
[2];
4123 unsigned char *saved_buffer
= NULL
;
4124 USER_MARSHAL_CB umcb
;
4126 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4127 TRACE("index=%d\n", index
);
4129 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_MARSHALL
, pFormat
, &umcb
);
4131 if (flags
& USER_MARSHAL_POINTER
)
4133 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
4134 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, USER_MARSHAL_PTR_PREFIX
);
4135 pStubMsg
->Buffer
+= 4;
4136 if (pStubMsg
->PointerBufferMark
)
4138 saved_buffer
= pStubMsg
->Buffer
;
4139 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4140 pStubMsg
->PointerBufferMark
= NULL
;
4142 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 8);
4145 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4148 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
4149 &umcb
.Flags
, pStubMsg
->Buffer
, pMemory
);
4153 STD_OVERFLOW_CHECK(pStubMsg
);
4154 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4155 pStubMsg
->Buffer
= saved_buffer
;
4158 STD_OVERFLOW_CHECK(pStubMsg
);
4163 /***********************************************************************
4164 * NdrUserMarshalUnmarshall [RPCRT4.@]
4166 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4167 unsigned char **ppMemory
,
4168 PFORMAT_STRING pFormat
,
4169 unsigned char fMustAlloc
)
4171 unsigned flags
= pFormat
[1];
4172 unsigned index
= *(const WORD
*)&pFormat
[2];
4173 DWORD memsize
= *(const WORD
*)&pFormat
[4];
4174 unsigned char *saved_buffer
= NULL
;
4175 USER_MARSHAL_CB umcb
;
4177 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4178 TRACE("index=%d\n", index
);
4180 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_UNMARSHALL
, pFormat
, &umcb
);
4182 if (flags
& USER_MARSHAL_POINTER
)
4184 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4185 /* skip pointer prefix */
4186 pStubMsg
->Buffer
+= 4;
4187 if (pStubMsg
->PointerBufferMark
)
4189 saved_buffer
= pStubMsg
->Buffer
;
4190 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4191 pStubMsg
->PointerBufferMark
= NULL
;
4193 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
4196 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4198 if (fMustAlloc
|| !*ppMemory
)
4199 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
4202 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
4203 &umcb
.Flags
, pStubMsg
->Buffer
, *ppMemory
);
4207 STD_OVERFLOW_CHECK(pStubMsg
);
4208 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4209 pStubMsg
->Buffer
= saved_buffer
;
4215 /***********************************************************************
4216 * NdrUserMarshalBufferSize [RPCRT4.@]
4218 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4219 unsigned char *pMemory
,
4220 PFORMAT_STRING pFormat
)
4222 unsigned flags
= pFormat
[1];
4223 unsigned index
= *(const WORD
*)&pFormat
[2];
4224 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
4225 USER_MARSHAL_CB umcb
;
4226 unsigned long saved_buffer_length
= 0;
4228 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4229 TRACE("index=%d\n", index
);
4231 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_BUFFER_SIZE
, pFormat
, &umcb
);
4233 if (flags
& USER_MARSHAL_POINTER
)
4235 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
4236 /* skip pointer prefix */
4237 safe_buffer_length_increment(pStubMsg
, 4);
4238 if (pStubMsg
->IgnoreEmbeddedPointers
)
4240 if (pStubMsg
->PointerLength
)
4242 saved_buffer_length
= pStubMsg
->BufferLength
;
4243 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4244 pStubMsg
->PointerLength
= 0;
4246 ALIGN_LENGTH(pStubMsg
->BufferLength
, 8);
4249 ALIGN_LENGTH(pStubMsg
->BufferLength
, (flags
& 0xf) + 1);
4252 TRACE("size=%d\n", bufsize
);
4253 safe_buffer_length_increment(pStubMsg
, bufsize
);
4256 pStubMsg
->BufferLength
=
4257 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
4258 &umcb
.Flags
, pStubMsg
->BufferLength
, pMemory
);
4260 if (saved_buffer_length
)
4262 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4263 pStubMsg
->BufferLength
= saved_buffer_length
;
4268 /***********************************************************************
4269 * NdrUserMarshalMemorySize [RPCRT4.@]
4271 ULONG WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4272 PFORMAT_STRING pFormat
)
4274 unsigned flags
= pFormat
[1];
4275 unsigned index
= *(const WORD
*)&pFormat
[2];
4276 DWORD memsize
= *(const WORD
*)&pFormat
[4];
4277 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
4279 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
4280 TRACE("index=%d\n", index
);
4282 pStubMsg
->MemorySize
+= memsize
;
4284 if (flags
& USER_MARSHAL_POINTER
)
4286 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4287 /* skip pointer prefix */
4288 pStubMsg
->Buffer
+= 4;
4289 if (pStubMsg
->IgnoreEmbeddedPointers
)
4290 return pStubMsg
->MemorySize
;
4291 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
4294 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4297 FIXME("not implemented for varying buffer size\n");
4299 pStubMsg
->Buffer
+= bufsize
;
4301 return pStubMsg
->MemorySize
;
4304 /***********************************************************************
4305 * NdrUserMarshalFree [RPCRT4.@]
4307 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
4308 unsigned char *pMemory
,
4309 PFORMAT_STRING pFormat
)
4311 /* unsigned flags = pFormat[1]; */
4312 unsigned index
= *(const WORD
*)&pFormat
[2];
4313 USER_MARSHAL_CB umcb
;
4315 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4316 TRACE("index=%d\n", index
);
4318 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_FREE
, pFormat
, &umcb
);
4320 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
4321 &umcb
.Flags
, pMemory
);
4324 /***********************************************************************
4325 * NdrClearOutParameters [RPCRT4.@]
4327 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
4328 PFORMAT_STRING pFormat
,
4331 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
4334 /***********************************************************************
4335 * NdrConvert [RPCRT4.@]
4337 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
4339 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
4340 /* FIXME: since this stub doesn't do any converting, the proper behavior
4341 is to raise an exception */
4344 /***********************************************************************
4345 * NdrConvert2 [RPCRT4.@]
4347 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, LONG NumberParams
)
4349 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4350 pStubMsg
, pFormat
, NumberParams
);
4351 /* FIXME: since this stub doesn't do any converting, the proper behavior
4352 is to raise an exception */
4355 #include "pshpack1.h"
4356 typedef struct _NDR_CSTRUCT_FORMAT
4359 unsigned char alignment
;
4360 unsigned short memory_size
;
4361 short offset_to_array_description
;
4362 } NDR_CSTRUCT_FORMAT
, NDR_CVSTRUCT_FORMAT
;
4363 #include "poppack.h"
4365 /***********************************************************************
4366 * NdrConformantStructMarshall [RPCRT4.@]
4368 unsigned char * WINAPI
NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4369 unsigned char *pMemory
,
4370 PFORMAT_STRING pFormat
)
4372 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4373 PFORMAT_STRING pCArrayFormat
;
4374 ULONG esize
, bufsize
;
4376 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4378 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4379 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4381 ERR("invalid format type %x\n", pCStructFormat
->type
);
4382 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4386 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4387 pCStructFormat
->offset_to_array_description
;
4388 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4390 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4391 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4394 esize
= *(const WORD
*)(pCArrayFormat
+2);
4396 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4397 pCArrayFormat
+ 4, 0);
4399 WriteConformance(pStubMsg
);
4401 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4403 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4405 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4406 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4408 ERR("integer overflow of memory_size %u with bufsize %u\n",
4409 pCStructFormat
->memory_size
, bufsize
);
4410 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4412 /* copy constant sized part of struct */
4413 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4414 safe_copy_to_buffer(pStubMsg
, pMemory
, pCStructFormat
->memory_size
+ bufsize
);
4416 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4417 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4422 /***********************************************************************
4423 * NdrConformantStructUnmarshall [RPCRT4.@]
4425 unsigned char * WINAPI
NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4426 unsigned char **ppMemory
,
4427 PFORMAT_STRING pFormat
,
4428 unsigned char fMustAlloc
)
4430 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4431 PFORMAT_STRING pCArrayFormat
;
4432 ULONG esize
, bufsize
;
4433 unsigned char *saved_buffer
;
4435 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4437 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4438 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4440 ERR("invalid format type %x\n", pCStructFormat
->type
);
4441 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4444 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4445 pCStructFormat
->offset_to_array_description
;
4446 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4448 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4449 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4452 esize
= *(const WORD
*)(pCArrayFormat
+2);
4454 pCArrayFormat
= ReadConformance(pStubMsg
, pCArrayFormat
+ 4);
4456 ALIGN_POINTER(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4458 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4460 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4461 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4463 ERR("integer overflow of memory_size %u with bufsize %u\n",
4464 pCStructFormat
->memory_size
, bufsize
);
4465 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4470 SIZE_T size
= pCStructFormat
->memory_size
+ bufsize
;
4471 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4475 if (!pStubMsg
->IsClient
&& !*ppMemory
)
4476 /* for servers, we just point straight into the RPC buffer */
4477 *ppMemory
= pStubMsg
->Buffer
;
4480 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4481 safe_buffer_increment(pStubMsg
, pCStructFormat
->memory_size
+ bufsize
);
4482 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4483 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4485 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
4486 if (*ppMemory
!= saved_buffer
)
4487 memcpy(*ppMemory
, saved_buffer
, pCStructFormat
->memory_size
+ bufsize
);
4492 /***********************************************************************
4493 * NdrConformantStructBufferSize [RPCRT4.@]
4495 void WINAPI
NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4496 unsigned char *pMemory
,
4497 PFORMAT_STRING pFormat
)
4499 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4500 PFORMAT_STRING pCArrayFormat
;
4503 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4505 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4506 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4508 ERR("invalid format type %x\n", pCStructFormat
->type
);
4509 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4512 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4513 pCStructFormat
->offset_to_array_description
;
4514 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4516 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4517 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4520 esize
= *(const WORD
*)(pCArrayFormat
+2);
4522 pCArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
, pCArrayFormat
+4, 0);
4523 SizeConformance(pStubMsg
);
4525 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCStructFormat
->alignment
+ 1);
4527 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4529 safe_buffer_length_increment(pStubMsg
, pCStructFormat
->memory_size
);
4530 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
4532 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4533 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4536 /***********************************************************************
4537 * NdrConformantStructMemorySize [RPCRT4.@]
4539 ULONG WINAPI
NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4540 PFORMAT_STRING pFormat
)
4546 /***********************************************************************
4547 * NdrConformantStructFree [RPCRT4.@]
4549 void WINAPI
NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
4550 unsigned char *pMemory
,
4551 PFORMAT_STRING pFormat
)
4553 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4554 PFORMAT_STRING pCArrayFormat
;
4556 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4558 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4559 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4561 ERR("invalid format type %x\n", pCStructFormat
->type
);
4562 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4566 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4567 pCStructFormat
->offset_to_array_description
;
4568 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4570 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4571 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4575 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4576 pCArrayFormat
+ 4, 0);
4578 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4580 /* copy constant sized part of struct */
4581 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4583 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4584 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4587 /***********************************************************************
4588 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4590 unsigned char * WINAPI
NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4591 unsigned char *pMemory
,
4592 PFORMAT_STRING pFormat
)
4594 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4595 PFORMAT_STRING pCVArrayFormat
;
4597 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4599 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4600 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4602 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4603 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4607 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4608 pCVStructFormat
->offset_to_array_description
;
4610 array_compute_and_write_conformance(*pCVArrayFormat
, pStubMsg
,
4611 pMemory
+ pCVStructFormat
->memory_size
,
4614 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4616 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4618 /* write constant sized part */
4619 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4620 safe_copy_to_buffer(pStubMsg
, pMemory
, pCVStructFormat
->memory_size
);
4622 array_write_variance_and_marshall(*pCVArrayFormat
, pStubMsg
,
4623 pMemory
+ pCVStructFormat
->memory_size
,
4624 pCVArrayFormat
, FALSE
/* fHasPointers */);
4626 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4631 /***********************************************************************
4632 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4634 unsigned char * WINAPI
NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4635 unsigned char **ppMemory
,
4636 PFORMAT_STRING pFormat
,
4637 unsigned char fMustAlloc
)
4639 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4640 PFORMAT_STRING pCVArrayFormat
;
4641 ULONG memsize
, bufsize
;
4642 unsigned char *saved_buffer
, *saved_array_buffer
;
4644 unsigned char *array_memory
;
4646 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4648 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4649 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4651 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4652 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4656 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4657 pCVStructFormat
->offset_to_array_description
;
4659 memsize
= array_read_conformance(*pCVArrayFormat
, pStubMsg
,
4662 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4664 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4666 /* work out how much memory to allocate if we need to do so */
4667 if (!*ppMemory
|| fMustAlloc
)
4669 SIZE_T size
= pCVStructFormat
->memory_size
+ memsize
;
4670 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4673 /* mark the start of the constant data */
4674 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4675 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4677 array_memory
= *ppMemory
+ pCVStructFormat
->memory_size
;
4678 bufsize
= array_read_variance_and_unmarshall(*pCVArrayFormat
, pStubMsg
,
4679 &array_memory
, pCVArrayFormat
,
4680 FALSE
/* fMustAlloc */,
4681 FALSE
/* fUseServerBufferMemory */,
4682 FALSE
/* fUnmarshall */);
4684 /* save offset in case unmarshalling pointers changes it */
4685 offset
= pStubMsg
->Offset
;
4687 /* mark the start of the array data */
4688 saved_array_buffer
= pStubMsg
->Buffer
;
4689 safe_buffer_increment(pStubMsg
, bufsize
);
4691 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4693 /* copy the constant data */
4694 memcpy(*ppMemory
, saved_buffer
, pCVStructFormat
->memory_size
);
4695 /* copy the array data */
4696 TRACE("copying %p to %p\n", saved_array_buffer
, *ppMemory
+ pCVStructFormat
->memory_size
);
4697 memcpy(*ppMemory
+ pCVStructFormat
->memory_size
+ offset
,
4698 saved_array_buffer
, bufsize
);
4700 if (*pCVArrayFormat
== RPC_FC_C_CSTRING
)
4701 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory
+ pCVStructFormat
->memory_size
)));
4702 else if (*pCVArrayFormat
== RPC_FC_C_WSTRING
)
4703 TRACE("string=%s\n", debugstr_w((WCHAR
*)(*ppMemory
+ pCVStructFormat
->memory_size
)));
4708 /***********************************************************************
4709 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
4711 void WINAPI
NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4712 unsigned char *pMemory
,
4713 PFORMAT_STRING pFormat
)
4715 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4716 PFORMAT_STRING pCVArrayFormat
;
4718 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4720 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4721 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4723 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4724 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4728 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4729 pCVStructFormat
->offset_to_array_description
;
4730 array_compute_and_size_conformance(*pCVArrayFormat
, pStubMsg
,
4731 pMemory
+ pCVStructFormat
->memory_size
,
4734 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCVStructFormat
->alignment
+ 1);
4736 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4738 safe_buffer_length_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4740 array_buffer_size(*pCVArrayFormat
, pStubMsg
,
4741 pMemory
+ pCVStructFormat
->memory_size
, pCVArrayFormat
,
4742 FALSE
/* fHasPointers */);
4744 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4747 /***********************************************************************
4748 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4750 ULONG WINAPI
NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4751 PFORMAT_STRING pFormat
)
4753 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4754 PFORMAT_STRING pCVArrayFormat
;
4756 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4758 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4759 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4761 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4762 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4766 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4767 pCVStructFormat
->offset_to_array_description
;
4768 array_read_conformance(*pCVArrayFormat
, pStubMsg
, pCVArrayFormat
);
4770 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4772 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4774 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4775 array_memory_size(*pCVArrayFormat
, pStubMsg
, pCVArrayFormat
,
4776 FALSE
/* fHasPointers */);
4778 pStubMsg
->MemorySize
+= pCVStructFormat
->memory_size
;
4780 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4782 return pStubMsg
->MemorySize
;
4785 /***********************************************************************
4786 * NdrConformantVaryingStructFree [RPCRT4.@]
4788 void WINAPI
NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
4789 unsigned char *pMemory
,
4790 PFORMAT_STRING pFormat
)
4792 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4793 PFORMAT_STRING pCVArrayFormat
;
4795 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4797 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4798 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4800 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4801 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4805 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4806 pCVStructFormat
->offset_to_array_description
;
4807 array_free(*pCVArrayFormat
, pStubMsg
,
4808 pMemory
+ pCVStructFormat
->memory_size
, pCVArrayFormat
,
4809 FALSE
/* fHasPointers */);
4811 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4813 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4816 #include "pshpack1.h"
4820 unsigned char alignment
;
4821 unsigned short total_size
;
4822 } NDR_SMFARRAY_FORMAT
;
4827 unsigned char alignment
;
4828 unsigned long total_size
;
4829 } NDR_LGFARRAY_FORMAT
;
4830 #include "poppack.h"
4832 /***********************************************************************
4833 * NdrFixedArrayMarshall [RPCRT4.@]
4835 unsigned char * WINAPI
NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4836 unsigned char *pMemory
,
4837 PFORMAT_STRING pFormat
)
4839 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4840 unsigned long total_size
;
4842 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4844 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4845 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4847 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4848 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4852 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4854 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4856 total_size
= pSmFArrayFormat
->total_size
;
4857 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4861 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4862 total_size
= pLgFArrayFormat
->total_size
;
4863 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4866 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4867 safe_copy_to_buffer(pStubMsg
, pMemory
, total_size
);
4869 pFormat
= EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4874 /***********************************************************************
4875 * NdrFixedArrayUnmarshall [RPCRT4.@]
4877 unsigned char * WINAPI
NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4878 unsigned char **ppMemory
,
4879 PFORMAT_STRING pFormat
,
4880 unsigned char fMustAlloc
)
4882 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4883 unsigned long total_size
;
4884 unsigned char *saved_buffer
;
4886 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4888 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4889 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4891 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4892 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4896 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4898 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4900 total_size
= pSmFArrayFormat
->total_size
;
4901 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4905 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4906 total_size
= pLgFArrayFormat
->total_size
;
4907 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4911 *ppMemory
= NdrAllocate(pStubMsg
, total_size
);
4914 if (!pStubMsg
->IsClient
&& !*ppMemory
)
4915 /* for servers, we just point straight into the RPC buffer */
4916 *ppMemory
= pStubMsg
->Buffer
;
4919 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4920 safe_buffer_increment(pStubMsg
, total_size
);
4921 pFormat
= EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4923 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
4924 if (*ppMemory
!= saved_buffer
)
4925 memcpy(*ppMemory
, saved_buffer
, total_size
);
4930 /***********************************************************************
4931 * NdrFixedArrayBufferSize [RPCRT4.@]
4933 void WINAPI
NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4934 unsigned char *pMemory
,
4935 PFORMAT_STRING pFormat
)
4937 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4938 unsigned long total_size
;
4940 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4942 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4943 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4945 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4946 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4950 ALIGN_LENGTH(pStubMsg
->BufferLength
, pSmFArrayFormat
->alignment
+ 1);
4952 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4954 total_size
= pSmFArrayFormat
->total_size
;
4955 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4959 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4960 total_size
= pLgFArrayFormat
->total_size
;
4961 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4963 safe_buffer_length_increment(pStubMsg
, total_size
);
4965 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4968 /***********************************************************************
4969 * NdrFixedArrayMemorySize [RPCRT4.@]
4971 ULONG WINAPI
NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4972 PFORMAT_STRING pFormat
)
4974 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4977 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4979 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4980 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4982 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4983 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4987 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4989 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4991 total_size
= pSmFArrayFormat
->total_size
;
4992 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4996 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4997 total_size
= pLgFArrayFormat
->total_size
;
4998 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5000 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5001 safe_buffer_increment(pStubMsg
, total_size
);
5002 pStubMsg
->MemorySize
+= total_size
;
5004 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5009 /***********************************************************************
5010 * NdrFixedArrayFree [RPCRT4.@]
5012 void WINAPI
NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
5013 unsigned char *pMemory
,
5014 PFORMAT_STRING pFormat
)
5016 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5018 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5020 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5021 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5023 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5024 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5028 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5029 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5032 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5033 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5036 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5039 /***********************************************************************
5040 * NdrVaryingArrayMarshall [RPCRT4.@]
5042 unsigned char * WINAPI
NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5043 unsigned char *pMemory
,
5044 PFORMAT_STRING pFormat
)
5046 unsigned char alignment
;
5047 DWORD elements
, esize
;
5050 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5052 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5053 (pFormat
[0] != RPC_FC_LGVARRAY
))
5055 ERR("invalid format type %x\n", pFormat
[0]);
5056 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5060 alignment
= pFormat
[1] + 1;
5062 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5065 pFormat
+= sizeof(WORD
);
5066 elements
= *(const WORD
*)pFormat
;
5067 pFormat
+= sizeof(WORD
);
5072 pFormat
+= sizeof(DWORD
);
5073 elements
= *(const DWORD
*)pFormat
;
5074 pFormat
+= sizeof(DWORD
);
5077 esize
= *(const WORD
*)pFormat
;
5078 pFormat
+= sizeof(WORD
);
5080 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5081 if ((pStubMsg
->ActualCount
> elements
) ||
5082 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5084 RpcRaiseException(RPC_S_INVALID_BOUND
);
5088 WriteVariance(pStubMsg
);
5090 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
5092 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
5093 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5094 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
5096 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
5101 /***********************************************************************
5102 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5104 unsigned char * WINAPI
NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5105 unsigned char **ppMemory
,
5106 PFORMAT_STRING pFormat
,
5107 unsigned char fMustAlloc
)
5109 unsigned char alignment
;
5110 DWORD size
, elements
, esize
;
5112 unsigned char *saved_buffer
;
5115 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5117 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5118 (pFormat
[0] != RPC_FC_LGVARRAY
))
5120 ERR("invalid format type %x\n", pFormat
[0]);
5121 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5125 alignment
= pFormat
[1] + 1;
5127 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5130 size
= *(const WORD
*)pFormat
;
5131 pFormat
+= sizeof(WORD
);
5132 elements
= *(const WORD
*)pFormat
;
5133 pFormat
+= sizeof(WORD
);
5138 size
= *(const DWORD
*)pFormat
;
5139 pFormat
+= sizeof(DWORD
);
5140 elements
= *(const DWORD
*)pFormat
;
5141 pFormat
+= sizeof(DWORD
);
5144 esize
= *(const WORD
*)pFormat
;
5145 pFormat
+= sizeof(WORD
);
5147 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
5149 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
5151 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
5152 offset
= pStubMsg
->Offset
;
5154 if (!*ppMemory
|| fMustAlloc
)
5155 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5156 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5157 safe_buffer_increment(pStubMsg
, bufsize
);
5159 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
5161 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
5166 /***********************************************************************
5167 * NdrVaryingArrayBufferSize [RPCRT4.@]
5169 void WINAPI
NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5170 unsigned char *pMemory
,
5171 PFORMAT_STRING pFormat
)
5173 unsigned char alignment
;
5174 DWORD elements
, esize
;
5176 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5178 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5179 (pFormat
[0] != RPC_FC_LGVARRAY
))
5181 ERR("invalid format type %x\n", pFormat
[0]);
5182 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5186 alignment
= pFormat
[1] + 1;
5188 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5191 pFormat
+= sizeof(WORD
);
5192 elements
= *(const WORD
*)pFormat
;
5193 pFormat
+= sizeof(WORD
);
5198 pFormat
+= sizeof(DWORD
);
5199 elements
= *(const DWORD
*)pFormat
;
5200 pFormat
+= sizeof(DWORD
);
5203 esize
= *(const WORD
*)pFormat
;
5204 pFormat
+= sizeof(WORD
);
5206 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5207 if ((pStubMsg
->ActualCount
> elements
) ||
5208 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5210 RpcRaiseException(RPC_S_INVALID_BOUND
);
5214 SizeVariance(pStubMsg
);
5216 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
5218 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
5220 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5223 /***********************************************************************
5224 * NdrVaryingArrayMemorySize [RPCRT4.@]
5226 ULONG WINAPI
NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5227 PFORMAT_STRING pFormat
)
5229 unsigned char alignment
;
5230 DWORD size
, elements
, esize
;
5232 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5234 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5235 (pFormat
[0] != RPC_FC_LGVARRAY
))
5237 ERR("invalid format type %x\n", pFormat
[0]);
5238 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5242 alignment
= pFormat
[1] + 1;
5244 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5247 size
= *(const WORD
*)pFormat
;
5248 pFormat
+= sizeof(WORD
);
5249 elements
= *(const WORD
*)pFormat
;
5250 pFormat
+= sizeof(WORD
);
5255 size
= *(const DWORD
*)pFormat
;
5256 pFormat
+= sizeof(DWORD
);
5257 elements
= *(const DWORD
*)pFormat
;
5258 pFormat
+= sizeof(DWORD
);
5261 esize
= *(const WORD
*)pFormat
;
5262 pFormat
+= sizeof(WORD
);
5264 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
5266 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
5268 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
5269 pStubMsg
->MemorySize
+= size
;
5271 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5273 return pStubMsg
->MemorySize
;
5276 /***********************************************************************
5277 * NdrVaryingArrayFree [RPCRT4.@]
5279 void WINAPI
NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
5280 unsigned char *pMemory
,
5281 PFORMAT_STRING pFormat
)
5285 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5287 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5288 (pFormat
[0] != RPC_FC_LGVARRAY
))
5290 ERR("invalid format type %x\n", pFormat
[0]);
5291 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5295 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5298 pFormat
+= sizeof(WORD
);
5299 elements
= *(const WORD
*)pFormat
;
5300 pFormat
+= sizeof(WORD
);
5305 pFormat
+= sizeof(DWORD
);
5306 elements
= *(const DWORD
*)pFormat
;
5307 pFormat
+= sizeof(DWORD
);
5310 pFormat
+= sizeof(WORD
);
5312 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5313 if ((pStubMsg
->ActualCount
> elements
) ||
5314 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5316 RpcRaiseException(RPC_S_INVALID_BOUND
);
5320 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5323 static ULONG
get_discriminant(unsigned char fc
, const unsigned char *pMemory
)
5336 return *(const USHORT
*)pMemory
;
5340 return *(const ULONG
*)pMemory
;
5342 FIXME("Unhandled base type: 0x%02x\n", fc
);
5347 static PFORMAT_STRING
get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg
,
5348 unsigned long discriminant
,
5349 PFORMAT_STRING pFormat
)
5351 unsigned short num_arms
, arm
, type
;
5353 num_arms
= *(const SHORT
*)pFormat
& 0x0fff;
5355 for(arm
= 0; arm
< num_arms
; arm
++)
5357 if(discriminant
== *(const ULONG
*)pFormat
)
5365 type
= *(const unsigned short*)pFormat
;
5366 TRACE("type %04x\n", type
);
5367 if(arm
== num_arms
) /* default arm extras */
5371 ERR("no arm for 0x%lx and no default case\n", discriminant
);
5372 RpcRaiseException(RPC_S_INVALID_TAG
);
5377 TRACE("falling back to empty default case for 0x%lx\n", discriminant
);
5384 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
, ULONG discriminant
, PFORMAT_STRING pFormat
)
5386 unsigned short type
;
5390 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5394 type
= *(const unsigned short*)pFormat
;
5395 if((type
& 0xff00) == 0x8000)
5397 unsigned char basetype
= LOBYTE(type
);
5398 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &basetype
);
5402 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5403 NDR_MARSHALL m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
5406 unsigned char *saved_buffer
= NULL
;
5407 int pointer_buffer_mark_set
= 0;
5414 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
5415 saved_buffer
= pStubMsg
->Buffer
;
5416 if (pStubMsg
->PointerBufferMark
)
5418 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5419 pStubMsg
->PointerBufferMark
= NULL
;
5420 pointer_buffer_mark_set
= 1;
5423 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
5425 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char **)pMemory
, desc
);
5426 if (pointer_buffer_mark_set
)
5428 STD_OVERFLOW_CHECK(pStubMsg
);
5429 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5430 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5432 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5433 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
5434 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5436 pStubMsg
->Buffer
= saved_buffer
+ 4;
5440 m(pStubMsg
, pMemory
, desc
);
5443 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5448 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5449 unsigned char **ppMemory
,
5451 PFORMAT_STRING pFormat
,
5452 unsigned char fMustAlloc
)
5454 unsigned short type
;
5458 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5462 type
= *(const unsigned short*)pFormat
;
5463 if((type
& 0xff00) == 0x8000)
5465 unsigned char basetype
= LOBYTE(type
);
5466 return NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &basetype
, FALSE
);
5470 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5471 NDR_UNMARSHALL m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
5474 unsigned char *saved_buffer
= NULL
;
5475 int pointer_buffer_mark_set
= 0;
5482 **(void***)ppMemory
= NULL
;
5483 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5484 saved_buffer
= pStubMsg
->Buffer
;
5485 if (pStubMsg
->PointerBufferMark
)
5487 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5488 pStubMsg
->PointerBufferMark
= NULL
;
5489 pointer_buffer_mark_set
= 1;
5492 pStubMsg
->Buffer
+= 4; /* for pointer ID */
5494 if (saved_buffer
+ 4 > pStubMsg
->BufferEnd
)
5496 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5497 saved_buffer
, pStubMsg
->BufferEnd
);
5498 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5501 PointerUnmarshall(pStubMsg
, saved_buffer
, *(unsigned char ***)ppMemory
, **(unsigned char ***)ppMemory
, desc
, fMustAlloc
);
5502 if (pointer_buffer_mark_set
)
5504 STD_OVERFLOW_CHECK(pStubMsg
);
5505 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5506 pStubMsg
->Buffer
= saved_buffer
+ 4;
5510 m(pStubMsg
, ppMemory
, desc
, fMustAlloc
);
5513 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5518 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg
,
5519 unsigned char *pMemory
,
5521 PFORMAT_STRING pFormat
)
5523 unsigned short type
;
5527 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5531 type
= *(const unsigned short*)pFormat
;
5532 if((type
& 0xff00) == 0x8000)
5534 unsigned char basetype
= LOBYTE(type
);
5535 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &basetype
);
5539 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5540 NDR_BUFFERSIZE m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
5549 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
5550 safe_buffer_length_increment(pStubMsg
, 4); /* for pointer ID */
5551 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5553 int saved_buffer_length
= pStubMsg
->BufferLength
;
5554 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
5555 pStubMsg
->PointerLength
= 0;
5556 if(!pStubMsg
->BufferLength
)
5557 ERR("BufferLength == 0??\n");
5558 PointerBufferSize(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5559 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
5560 pStubMsg
->BufferLength
= saved_buffer_length
;
5564 m(pStubMsg
, pMemory
, desc
);
5567 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
5571 static ULONG
union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg
,
5573 PFORMAT_STRING pFormat
)
5575 unsigned short type
, size
;
5577 size
= *(const unsigned short*)pFormat
;
5578 pStubMsg
->Memory
+= size
;
5581 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5585 type
= *(const unsigned short*)pFormat
;
5586 if((type
& 0xff00) == 0x8000)
5588 return NdrBaseTypeMemorySize(pStubMsg
, pFormat
);
5592 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5593 NDR_MEMORYSIZE m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
5594 unsigned char *saved_buffer
;
5603 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5604 saved_buffer
= pStubMsg
->Buffer
;
5605 safe_buffer_increment(pStubMsg
, 4);
5606 ALIGN_LENGTH(pStubMsg
->MemorySize
, 4);
5607 pStubMsg
->MemorySize
+= 4;
5608 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5609 PointerMemorySize(pStubMsg
, saved_buffer
, pFormat
);
5612 return m(pStubMsg
, desc
);
5615 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5618 TRACE("size %d\n", size
);
5622 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg
,
5623 unsigned char *pMemory
,
5625 PFORMAT_STRING pFormat
)
5627 unsigned short type
;
5631 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5635 type
= *(const unsigned short*)pFormat
;
5636 if((type
& 0xff00) != 0x8000)
5638 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5639 NDR_FREE m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
5648 PointerFree(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5651 m(pStubMsg
, pMemory
, desc
);
5657 /***********************************************************************
5658 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5660 unsigned char * WINAPI
NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5661 unsigned char *pMemory
,
5662 PFORMAT_STRING pFormat
)
5664 unsigned char switch_type
;
5665 unsigned char increment
;
5668 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5671 switch_type
= *pFormat
& 0xf;
5672 increment
= (*pFormat
& 0xf0) >> 4;
5675 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, increment
);
5677 switch_value
= get_discriminant(switch_type
, pMemory
);
5678 TRACE("got switch value 0x%x\n", switch_value
);
5680 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &switch_type
);
5681 pMemory
+= increment
;
5683 return union_arm_marshall(pStubMsg
, pMemory
, switch_value
, pFormat
);
5686 /***********************************************************************
5687 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5689 unsigned char * WINAPI
NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5690 unsigned char **ppMemory
,
5691 PFORMAT_STRING pFormat
,
5692 unsigned char fMustAlloc
)
5694 unsigned char switch_type
;
5695 unsigned char increment
;
5697 unsigned short size
;
5698 unsigned char *pMemoryArm
;
5700 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5703 switch_type
= *pFormat
& 0xf;
5704 increment
= (*pFormat
& 0xf0) >> 4;
5707 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
5708 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
5709 TRACE("got switch value 0x%x\n", switch_value
);
5711 size
= *(const unsigned short*)pFormat
+ increment
;
5712 if(!*ppMemory
|| fMustAlloc
)
5713 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5715 NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &switch_type
, FALSE
);
5716 pMemoryArm
= *ppMemory
+ increment
;
5718 return union_arm_unmarshall(pStubMsg
, &pMemoryArm
, switch_value
, pFormat
, fMustAlloc
);
5721 /***********************************************************************
5722 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5724 void WINAPI
NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5725 unsigned char *pMemory
,
5726 PFORMAT_STRING pFormat
)
5728 unsigned char switch_type
;
5729 unsigned char increment
;
5732 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5735 switch_type
= *pFormat
& 0xf;
5736 increment
= (*pFormat
& 0xf0) >> 4;
5739 ALIGN_LENGTH(pStubMsg
->BufferLength
, increment
);
5740 switch_value
= get_discriminant(switch_type
, pMemory
);
5741 TRACE("got switch value 0x%x\n", switch_value
);
5743 /* Add discriminant size */
5744 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&switch_value
, &switch_type
);
5745 pMemory
+= increment
;
5747 union_arm_buffer_size(pStubMsg
, pMemory
, switch_value
, pFormat
);
5750 /***********************************************************************
5751 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5753 ULONG WINAPI
NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5754 PFORMAT_STRING pFormat
)
5756 unsigned char switch_type
;
5757 unsigned char increment
;
5760 switch_type
= *pFormat
& 0xf;
5761 increment
= (*pFormat
& 0xf0) >> 4;
5764 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
5765 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
5766 TRACE("got switch value 0x%x\n", switch_value
);
5768 pStubMsg
->Memory
+= increment
;
5770 return increment
+ union_arm_memory_size(pStubMsg
, switch_value
, pFormat
+ *(const SHORT
*)pFormat
);
5773 /***********************************************************************
5774 * NdrEncapsulatedUnionFree [RPCRT4.@]
5776 void WINAPI
NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
5777 unsigned char *pMemory
,
5778 PFORMAT_STRING pFormat
)
5780 unsigned char switch_type
;
5781 unsigned char increment
;
5784 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5787 switch_type
= *pFormat
& 0xf;
5788 increment
= (*pFormat
& 0xf0) >> 4;
5791 switch_value
= get_discriminant(switch_type
, pMemory
);
5792 TRACE("got switch value 0x%x\n", switch_value
);
5794 pMemory
+= increment
;
5796 union_arm_free(pStubMsg
, pMemory
, switch_value
, pFormat
);
5799 /***********************************************************************
5800 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5802 unsigned char * WINAPI
NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5803 unsigned char *pMemory
,
5804 PFORMAT_STRING pFormat
)
5806 unsigned char switch_type
;
5808 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5811 switch_type
= *pFormat
;
5814 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5815 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5816 /* Marshall discriminant */
5817 NdrBaseTypeMarshall(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
5819 return union_arm_marshall(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5822 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg
,
5823 PFORMAT_STRING
*ppFormat
)
5825 long discriminant
= 0;
5835 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5844 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5845 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5853 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
5854 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5859 FIXME("Unhandled base type: 0x%02x\n", **ppFormat
);
5863 if (pStubMsg
->fHasNewCorrDesc
)
5867 return discriminant
;
5870 /**********************************************************************
5871 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5873 unsigned char * WINAPI
NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5874 unsigned char **ppMemory
,
5875 PFORMAT_STRING pFormat
,
5876 unsigned char fMustAlloc
)
5879 unsigned short size
;
5881 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5884 /* Unmarshall discriminant */
5885 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
5886 TRACE("unmarshalled discriminant %lx\n", discriminant
);
5888 pFormat
+= *(const SHORT
*)pFormat
;
5890 size
= *(const unsigned short*)pFormat
;
5892 if(!*ppMemory
|| fMustAlloc
)
5893 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5895 return union_arm_unmarshall(pStubMsg
, ppMemory
, discriminant
, pFormat
, fMustAlloc
);
5898 /***********************************************************************
5899 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5901 void WINAPI
NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5902 unsigned char *pMemory
,
5903 PFORMAT_STRING pFormat
)
5905 unsigned char switch_type
;
5907 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5910 switch_type
= *pFormat
;
5913 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5914 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5915 /* Add discriminant size */
5916 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
5918 union_arm_buffer_size(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5921 /***********************************************************************
5922 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5924 ULONG WINAPI
NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5925 PFORMAT_STRING pFormat
)
5930 /* Unmarshall discriminant */
5931 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
5932 TRACE("unmarshalled discriminant 0x%x\n", discriminant
);
5934 return union_arm_memory_size(pStubMsg
, discriminant
, pFormat
+ *(const SHORT
*)pFormat
);
5937 /***********************************************************************
5938 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5940 void WINAPI
NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
5941 unsigned char *pMemory
,
5942 PFORMAT_STRING pFormat
)
5944 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5948 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5949 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5951 union_arm_free(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5954 /***********************************************************************
5955 * NdrByteCountPointerMarshall [RPCRT4.@]
5957 unsigned char * WINAPI
NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5958 unsigned char *pMemory
,
5959 PFORMAT_STRING pFormat
)
5965 /***********************************************************************
5966 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5968 unsigned char * WINAPI
NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5969 unsigned char **ppMemory
,
5970 PFORMAT_STRING pFormat
,
5971 unsigned char fMustAlloc
)
5977 /***********************************************************************
5978 * NdrByteCountPointerBufferSize [RPCRT4.@]
5980 void WINAPI
NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5981 unsigned char *pMemory
,
5982 PFORMAT_STRING pFormat
)
5987 /***********************************************************************
5988 * NdrByteCountPointerMemorySize [RPCRT4.@]
5990 ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5991 PFORMAT_STRING pFormat
)
5997 /***********************************************************************
5998 * NdrByteCountPointerFree [RPCRT4.@]
6000 void WINAPI
NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
6001 unsigned char *pMemory
,
6002 PFORMAT_STRING pFormat
)
6007 /***********************************************************************
6008 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6010 unsigned char * WINAPI
NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6011 unsigned char *pMemory
,
6012 PFORMAT_STRING pFormat
)
6018 /***********************************************************************
6019 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6021 unsigned char * WINAPI
NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6022 unsigned char **ppMemory
,
6023 PFORMAT_STRING pFormat
,
6024 unsigned char fMustAlloc
)
6030 /***********************************************************************
6031 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6033 void WINAPI
NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6034 unsigned char *pMemory
,
6035 PFORMAT_STRING pFormat
)
6040 /***********************************************************************
6041 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6043 ULONG WINAPI
NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6044 PFORMAT_STRING pFormat
)
6050 /***********************************************************************
6051 * NdrXmitOrRepAsFree [RPCRT4.@]
6053 void WINAPI
NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg
,
6054 unsigned char *pMemory
,
6055 PFORMAT_STRING pFormat
)
6060 /***********************************************************************
6061 * NdrRangeMarshall [internal]
6063 unsigned char *WINAPI
NdrRangeMarshall(
6064 PMIDL_STUB_MESSAGE pStubMsg
,
6065 unsigned char *pMemory
,
6066 PFORMAT_STRING pFormat
)
6068 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
6069 unsigned char base_type
;
6071 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6073 if (pRange
->type
!= RPC_FC_RANGE
)
6075 ERR("invalid format type %x\n", pRange
->type
);
6076 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6080 base_type
= pRange
->flags_type
& 0xf;
6082 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &base_type
);
6085 /***********************************************************************
6086 * NdrRangeUnmarshall
6088 unsigned char *WINAPI
NdrRangeUnmarshall(
6089 PMIDL_STUB_MESSAGE pStubMsg
,
6090 unsigned char **ppMemory
,
6091 PFORMAT_STRING pFormat
,
6092 unsigned char fMustAlloc
)
6094 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
6095 unsigned char base_type
;
6097 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6099 if (pRange
->type
!= RPC_FC_RANGE
)
6101 ERR("invalid format type %x\n", pRange
->type
);
6102 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6105 base_type
= pRange
->flags_type
& 0xf;
6107 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6108 base_type
, pRange
->low_value
, pRange
->high_value
);
6110 #define RANGE_UNMARSHALL(type, format_spec) \
6113 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6114 if (fMustAlloc || !*ppMemory) \
6115 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6116 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
6118 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6119 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6120 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6122 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
6123 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
6125 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6126 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
6127 (type)pRange->high_value); \
6128 RpcRaiseException(RPC_S_INVALID_BOUND); \
6131 TRACE("*ppMemory: %p\n", *ppMemory); \
6132 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
6133 pStubMsg->Buffer += sizeof(type); \
6140 RANGE_UNMARSHALL(UCHAR
, "%d");
6141 TRACE("value: 0x%02x\n", **ppMemory
);
6145 RANGE_UNMARSHALL(CHAR
, "%u");
6146 TRACE("value: 0x%02x\n", **ppMemory
);
6148 case RPC_FC_WCHAR
: /* FIXME: valid? */
6150 RANGE_UNMARSHALL(USHORT
, "%u");
6151 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6154 RANGE_UNMARSHALL(SHORT
, "%d");
6155 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6158 RANGE_UNMARSHALL(LONG
, "%d");
6159 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6162 RANGE_UNMARSHALL(ULONG
, "%u");
6163 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6167 FIXME("Unhandled enum type\n");
6169 case RPC_FC_ERROR_STATUS_T
: /* FIXME: valid? */
6174 ERR("invalid range base type: 0x%02x\n", base_type
);
6175 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6181 /***********************************************************************
6182 * NdrRangeBufferSize [internal]
6184 void WINAPI
NdrRangeBufferSize(
6185 PMIDL_STUB_MESSAGE pStubMsg
,
6186 unsigned char *pMemory
,
6187 PFORMAT_STRING pFormat
)
6189 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
6190 unsigned char base_type
;
6192 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6194 if (pRange
->type
!= RPC_FC_RANGE
)
6196 ERR("invalid format type %x\n", pRange
->type
);
6197 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6199 base_type
= pRange
->flags_type
& 0xf;
6201 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &base_type
);
6204 /***********************************************************************
6205 * NdrRangeMemorySize [internal]
6207 ULONG WINAPI
NdrRangeMemorySize(
6208 PMIDL_STUB_MESSAGE pStubMsg
,
6209 PFORMAT_STRING pFormat
)
6211 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
6212 unsigned char base_type
;
6214 if (pRange
->type
!= RPC_FC_RANGE
)
6216 ERR("invalid format type %x\n", pRange
->type
);
6217 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6220 base_type
= pRange
->flags_type
& 0xf;
6222 return NdrBaseTypeMemorySize(pStubMsg
, &base_type
);
6225 /***********************************************************************
6226 * NdrRangeFree [internal]
6228 void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6229 unsigned char *pMemory
,
6230 PFORMAT_STRING pFormat
)
6232 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6237 /***********************************************************************
6238 * NdrBaseTypeMarshall [internal]
6240 static unsigned char *WINAPI
NdrBaseTypeMarshall(
6241 PMIDL_STUB_MESSAGE pStubMsg
,
6242 unsigned char *pMemory
,
6243 PFORMAT_STRING pFormat
)
6245 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6253 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(UCHAR
));
6254 TRACE("value: 0x%02x\n", *pMemory
);
6259 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(USHORT
));
6260 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(USHORT
));
6261 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
6265 case RPC_FC_ERROR_STATUS_T
:
6267 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(ULONG
));
6268 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONG
));
6269 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
6272 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(float));
6273 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
6276 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(double));
6277 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
6280 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(ULONGLONG
));
6281 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONGLONG
));
6282 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
6285 /* only 16-bits on the wire, so do a sanity check */
6286 if (*(UINT
*)pMemory
> SHRT_MAX
)
6287 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
6288 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(USHORT
));
6289 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6290 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6291 *(USHORT
*)pStubMsg
->Buffer
= *(UINT
*)pMemory
;
6292 pStubMsg
->Buffer
+= sizeof(USHORT
);
6293 TRACE("value: 0x%04x\n", *(UINT
*)pMemory
);
6298 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6301 /* FIXME: what is the correct return value? */
6305 /***********************************************************************
6306 * NdrBaseTypeUnmarshall [internal]
6308 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(
6309 PMIDL_STUB_MESSAGE pStubMsg
,
6310 unsigned char **ppMemory
,
6311 PFORMAT_STRING pFormat
,
6312 unsigned char fMustAlloc
)
6314 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6316 #define BASE_TYPE_UNMARSHALL(type) \
6317 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6318 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6320 *ppMemory = pStubMsg->Buffer; \
6321 TRACE("*ppMemory: %p\n", *ppMemory); \
6322 safe_buffer_increment(pStubMsg, sizeof(type)); \
6327 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6328 TRACE("*ppMemory: %p\n", *ppMemory); \
6329 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6338 BASE_TYPE_UNMARSHALL(UCHAR
);
6339 TRACE("value: 0x%02x\n", **ppMemory
);
6344 BASE_TYPE_UNMARSHALL(USHORT
);
6345 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6349 case RPC_FC_ERROR_STATUS_T
:
6351 BASE_TYPE_UNMARSHALL(ULONG
);
6352 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6355 BASE_TYPE_UNMARSHALL(float);
6356 TRACE("value: %f\n", **(float **)ppMemory
);
6359 BASE_TYPE_UNMARSHALL(double);
6360 TRACE("value: %f\n", **(double **)ppMemory
);
6363 BASE_TYPE_UNMARSHALL(ULONGLONG
);
6364 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG
**)ppMemory
));
6367 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
6368 if (fMustAlloc
|| !*ppMemory
)
6369 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT
));
6370 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > pStubMsg
->BufferEnd
)
6371 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6372 TRACE("*ppMemory: %p\n", *ppMemory
);
6373 /* 16-bits on the wire, but int in memory */
6374 **(UINT
**)ppMemory
= *(USHORT
*)pStubMsg
->Buffer
;
6375 pStubMsg
->Buffer
+= sizeof(USHORT
);
6376 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
6381 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6383 #undef BASE_TYPE_UNMARSHALL
6385 /* FIXME: what is the correct return value? */
6390 /***********************************************************************
6391 * NdrBaseTypeBufferSize [internal]
6393 static void WINAPI
NdrBaseTypeBufferSize(
6394 PMIDL_STUB_MESSAGE pStubMsg
,
6395 unsigned char *pMemory
,
6396 PFORMAT_STRING pFormat
)
6398 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6406 safe_buffer_length_increment(pStubMsg
, sizeof(UCHAR
));
6412 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(USHORT
));
6413 safe_buffer_length_increment(pStubMsg
, sizeof(USHORT
));
6418 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONG
));
6419 safe_buffer_length_increment(pStubMsg
, sizeof(ULONG
));
6422 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(float));
6423 safe_buffer_length_increment(pStubMsg
, sizeof(float));
6426 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(double));
6427 safe_buffer_length_increment(pStubMsg
, sizeof(double));
6430 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONGLONG
));
6431 safe_buffer_length_increment(pStubMsg
, sizeof(ULONGLONG
));
6433 case RPC_FC_ERROR_STATUS_T
:
6434 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(error_status_t
));
6435 safe_buffer_length_increment(pStubMsg
, sizeof(error_status_t
));
6440 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6444 /***********************************************************************
6445 * NdrBaseTypeMemorySize [internal]
6447 static ULONG WINAPI
NdrBaseTypeMemorySize(
6448 PMIDL_STUB_MESSAGE pStubMsg
,
6449 PFORMAT_STRING pFormat
)
6451 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg
, *pFormat
);
6459 safe_buffer_increment(pStubMsg
, sizeof(UCHAR
));
6460 pStubMsg
->MemorySize
+= sizeof(UCHAR
);
6461 return sizeof(UCHAR
);
6465 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6466 pStubMsg
->MemorySize
+= sizeof(USHORT
);
6467 return sizeof(USHORT
);
6471 safe_buffer_increment(pStubMsg
, sizeof(ULONG
));
6472 pStubMsg
->MemorySize
+= sizeof(ULONG
);
6473 return sizeof(ULONG
);
6475 safe_buffer_increment(pStubMsg
, sizeof(float));
6476 pStubMsg
->MemorySize
+= sizeof(float);
6477 return sizeof(float);
6479 safe_buffer_increment(pStubMsg
, sizeof(double));
6480 pStubMsg
->MemorySize
+= sizeof(double);
6481 return sizeof(double);
6483 safe_buffer_increment(pStubMsg
, sizeof(ULONGLONG
));
6484 pStubMsg
->MemorySize
+= sizeof(ULONGLONG
);
6485 return sizeof(ULONGLONG
);
6486 case RPC_FC_ERROR_STATUS_T
:
6487 safe_buffer_increment(pStubMsg
, sizeof(error_status_t
));
6488 pStubMsg
->MemorySize
+= sizeof(error_status_t
);
6489 return sizeof(error_status_t
);
6491 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6492 pStubMsg
->MemorySize
+= sizeof(UINT
);
6493 return sizeof(UINT
);
6495 pStubMsg
->MemorySize
+= sizeof(void *);
6496 return sizeof(void *);
6498 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6503 /***********************************************************************
6504 * NdrBaseTypeFree [internal]
6506 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6507 unsigned char *pMemory
,
6508 PFORMAT_STRING pFormat
)
6510 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6515 /***********************************************************************
6516 * NdrContextHandleBufferSize [internal]
6518 static void WINAPI
NdrContextHandleBufferSize(
6519 PMIDL_STUB_MESSAGE pStubMsg
,
6520 unsigned char *pMemory
,
6521 PFORMAT_STRING pFormat
)
6523 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6525 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6527 ERR("invalid format type %x\n", *pFormat
);
6528 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6530 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
6531 safe_buffer_length_increment(pStubMsg
, cbNDRContext
);
6534 /***********************************************************************
6535 * NdrContextHandleMarshall [internal]
6537 static unsigned char *WINAPI
NdrContextHandleMarshall(
6538 PMIDL_STUB_MESSAGE pStubMsg
,
6539 unsigned char *pMemory
,
6540 PFORMAT_STRING pFormat
)
6542 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6544 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6546 ERR("invalid format type %x\n", *pFormat
);
6547 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6549 TRACE("flags: 0x%02x\n", pFormat
[1]);
6551 if (pFormat
[1] & 0x80)
6552 NdrClientContextMarshall(pStubMsg
, *(NDR_CCONTEXT
**)pMemory
, FALSE
);
6554 NdrClientContextMarshall(pStubMsg
, (NDR_CCONTEXT
*)pMemory
, FALSE
);
6559 /***********************************************************************
6560 * NdrContextHandleUnmarshall [internal]
6562 static unsigned char *WINAPI
NdrContextHandleUnmarshall(
6563 PMIDL_STUB_MESSAGE pStubMsg
,
6564 unsigned char **ppMemory
,
6565 PFORMAT_STRING pFormat
,
6566 unsigned char fMustAlloc
)
6568 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg
,
6569 ppMemory
, pFormat
, fMustAlloc
? "TRUE": "FALSE");
6571 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6573 ERR("invalid format type %x\n", *pFormat
);
6574 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6576 TRACE("flags: 0x%02x\n", pFormat
[1]);
6578 /* [out]-only or [ret] param */
6579 if ((pFormat
[1] & 0x60) == 0x20)
6580 **(NDR_CCONTEXT
**)ppMemory
= NULL
;
6581 NdrClientContextUnmarshall(pStubMsg
, *(NDR_CCONTEXT
**)ppMemory
, pStubMsg
->RpcMsg
->Handle
);
6586 /***********************************************************************
6587 * NdrClientContextMarshall [RPCRT4.@]
6589 void WINAPI
NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6590 NDR_CCONTEXT ContextHandle
,
6593 TRACE("(%p, %p, %d)\n", pStubMsg
, ContextHandle
, fCheck
);
6595 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
6597 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6599 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6600 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6601 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6604 /* FIXME: what does fCheck do? */
6605 NDRCContextMarshall(ContextHandle
,
6608 pStubMsg
->Buffer
+= cbNDRContext
;
6611 /***********************************************************************
6612 * NdrClientContextUnmarshall [RPCRT4.@]
6614 void WINAPI
NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6615 NDR_CCONTEXT
* pContextHandle
,
6616 RPC_BINDING_HANDLE BindHandle
)
6618 TRACE("(%p, %p, %p)\n", pStubMsg
, pContextHandle
, BindHandle
);
6620 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6622 if (pStubMsg
->Buffer
+ cbNDRContext
> pStubMsg
->BufferEnd
)
6623 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6625 NDRCContextUnmarshall(pContextHandle
,
6628 pStubMsg
->RpcMsg
->DataRepresentation
);
6630 pStubMsg
->Buffer
+= cbNDRContext
;
6633 void WINAPI
NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6634 NDR_SCONTEXT ContextHandle
,
6635 NDR_RUNDOWN RundownRoutine
)
6637 TRACE("(%p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
);
6639 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6641 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6643 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6644 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6645 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6648 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
6649 pStubMsg
->Buffer
, RundownRoutine
, NULL
,
6650 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
6651 pStubMsg
->Buffer
+= cbNDRContext
;
6654 NDR_SCONTEXT WINAPI
NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
)
6656 NDR_SCONTEXT ContextHandle
;
6658 TRACE("(%p)\n", pStubMsg
);
6660 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6662 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6664 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6665 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6666 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6669 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
6671 pStubMsg
->RpcMsg
->DataRepresentation
,
6672 NULL
, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
6673 pStubMsg
->Buffer
+= cbNDRContext
;
6675 return ContextHandle
;
6678 void WINAPI
NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg
,
6679 unsigned char* pMemory
,
6680 PFORMAT_STRING pFormat
)
6682 FIXME("(%p, %p, %p): stub\n", pStubMsg
, pMemory
, pFormat
);
6685 NDR_SCONTEXT WINAPI
NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg
,
6686 PFORMAT_STRING pFormat
)
6688 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6689 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6691 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
6693 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
6694 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
6695 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
6696 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
6697 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
6699 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
6700 if_id
= &sif
->InterfaceId
;
6703 return NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
, NULL
,
6704 pStubMsg
->RpcMsg
->DataRepresentation
, if_id
,
6708 void WINAPI
NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6709 NDR_SCONTEXT ContextHandle
,
6710 NDR_RUNDOWN RundownRoutine
,
6711 PFORMAT_STRING pFormat
)
6713 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6714 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6716 TRACE("(%p, %p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
, pFormat
);
6718 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6720 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6722 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6723 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6724 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6727 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
6728 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
6729 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
6730 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
6731 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
6733 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
6734 if_id
= &sif
->InterfaceId
;
6737 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
6738 pStubMsg
->Buffer
, RundownRoutine
, if_id
, flags
);
6739 pStubMsg
->Buffer
+= cbNDRContext
;
6742 NDR_SCONTEXT WINAPI
NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6743 PFORMAT_STRING pFormat
)
6745 NDR_SCONTEXT ContextHandle
;
6746 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6747 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6749 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
6751 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6753 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6755 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6756 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6757 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6760 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
6761 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
6762 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
6763 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
6764 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
6766 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
6767 if_id
= &sif
->InterfaceId
;
6770 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
6772 pStubMsg
->RpcMsg
->DataRepresentation
,
6774 pStubMsg
->Buffer
+= cbNDRContext
;
6776 return ContextHandle
;
6779 /***********************************************************************
6780 * NdrCorrelationInitialize [RPCRT4.@]
6782 * Initializes correlation validity checking.
6785 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6786 * pMemory [I] Pointer to memory to use as a cache.
6787 * CacheSize [I] Size of the memory pointed to by pMemory.
6788 * Flags [I] Reserved. Set to zero.
6793 void WINAPI
NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg
, void *pMemory
, ULONG CacheSize
, ULONG Flags
)
6795 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg
, pMemory
, CacheSize
, Flags
);
6796 pStubMsg
->fHasNewCorrDesc
= TRUE
;
6799 /***********************************************************************
6800 * NdrCorrelationPass [RPCRT4.@]
6802 * Performs correlation validity checking.
6805 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6810 void WINAPI
NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg
)
6812 FIXME("(%p): stub\n", pStubMsg
);
6815 /***********************************************************************
6816 * NdrCorrelationFree [RPCRT4.@]
6818 * Frees any resources used while unmarshalling parameters that need
6819 * correlation validity checking.
6822 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6827 void WINAPI
NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg
)
6829 FIXME("(%p): stub\n", pStubMsg
);