4 * Copyright 2002 Greg Turner
5 * Copyright 2003-2006 CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 * - Byte count pointers
24 * - transmit_as/represent as
25 * - Multi-dimensional arrays
26 * - Conversion functions (NdrConvert)
27 * - Checks for integer addition overflow in user marshall functions
42 #include "wine/unicode.h"
43 #include "wine/rpcfc.h"
45 #include "wine/debug.h"
47 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
50 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
51 (*((UINT32 *)(pchar)) = (uint32))
53 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
54 (*((UINT32 *)(pchar)))
56 /* these would work for i386 too, but less efficient */
57 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
58 (*(pchar) = LOBYTE(LOWORD(uint32)), \
59 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
60 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
61 *((pchar)+3) = HIBYTE(HIWORD(uint32)))
63 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
65 MAKEWORD(*(pchar), *((pchar)+1)), \
66 MAKEWORD(*((pchar)+2), *((pchar)+3))))
69 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
70 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
71 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
72 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
73 *(pchar) = HIBYTE(HIWORD(uint32)))
75 #define BIG_ENDIAN_UINT32_READ(pchar) \
77 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
78 MAKEWORD(*((pchar)+1), *(pchar))))
80 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
81 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
82 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
83 # define NDR_LOCAL_UINT32_READ(pchar) \
84 BIG_ENDIAN_UINT32_READ(pchar)
86 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
87 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
88 # define NDR_LOCAL_UINT32_READ(pchar) \
89 LITTLE_ENDIAN_UINT32_READ(pchar)
92 /* _Align must be the desired alignment,
93 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
94 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
95 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
96 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
97 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
98 #define ALIGN_POINTER_CLEAR(_Ptr, _Align) \
100 memset((_Ptr), 0, ((_Align) - (ULONG_PTR)(_Ptr)) & ((_Align) - 1)); \
101 ALIGN_POINTER(_Ptr, _Align); \
104 #define STD_OVERFLOW_CHECK(_Msg) do { \
105 TRACE("buffer=%d/%d\n", (ULONG)(_Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer), _Msg->BufferLength); \
106 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
107 ERR("buffer overflow %d bytes\n", (ULONG)(_Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength))); \
110 #define NDR_POINTER_ID_BASE 0x20000
111 #define NDR_POINTER_ID(pStubMsg) (NDR_POINTER_ID_BASE + ((pStubMsg)->UniquePtrCount++) * 4)
112 #define NDR_TABLE_SIZE 128
113 #define NDR_TABLE_MASK 127
115 static unsigned char *WINAPI
NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
116 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
117 static void WINAPI
NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
118 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
119 static ULONG WINAPI
NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
121 static unsigned char *WINAPI
NdrContextHandleMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
122 static void WINAPI
NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
123 static unsigned char *WINAPI
NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
125 static unsigned char *WINAPI
NdrRangeMarshall(PMIDL_STUB_MESSAGE
,unsigned char *, PFORMAT_STRING
);
126 static void WINAPI
NdrRangeBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
127 static ULONG WINAPI
NdrRangeMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
128 static void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
130 static ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
132 const NDR_MARSHALL NdrMarshaller
[NDR_TABLE_SIZE
] = {
134 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
135 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
136 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
137 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
141 NdrPointerMarshall
, NdrPointerMarshall
,
142 NdrPointerMarshall
, NdrPointerMarshall
,
144 NdrSimpleStructMarshall
, NdrSimpleStructMarshall
,
145 NdrConformantStructMarshall
, NdrConformantStructMarshall
,
146 NdrConformantVaryingStructMarshall
,
147 NdrComplexStructMarshall
,
149 NdrConformantArrayMarshall
,
150 NdrConformantVaryingArrayMarshall
,
151 NdrFixedArrayMarshall
, NdrFixedArrayMarshall
,
152 NdrVaryingArrayMarshall
, NdrVaryingArrayMarshall
,
153 NdrComplexArrayMarshall
,
155 NdrConformantStringMarshall
, 0, 0,
156 NdrConformantStringMarshall
,
157 NdrNonConformantStringMarshall
, 0, 0, 0,
159 NdrEncapsulatedUnionMarshall
,
160 NdrNonEncapsulatedUnionMarshall
,
161 NdrByteCountPointerMarshall
,
162 NdrXmitOrRepAsMarshall
, NdrXmitOrRepAsMarshall
,
164 NdrInterfacePointerMarshall
,
166 NdrContextHandleMarshall
,
169 NdrUserMarshalMarshall
,
174 const NDR_UNMARSHALL NdrUnmarshaller
[NDR_TABLE_SIZE
] = {
176 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
177 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
178 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
179 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
181 NdrBaseTypeUnmarshall
,
183 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
184 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
186 NdrSimpleStructUnmarshall
, NdrSimpleStructUnmarshall
,
187 NdrConformantStructUnmarshall
, NdrConformantStructUnmarshall
,
188 NdrConformantVaryingStructUnmarshall
,
189 NdrComplexStructUnmarshall
,
191 NdrConformantArrayUnmarshall
,
192 NdrConformantVaryingArrayUnmarshall
,
193 NdrFixedArrayUnmarshall
, NdrFixedArrayUnmarshall
,
194 NdrVaryingArrayUnmarshall
, NdrVaryingArrayUnmarshall
,
195 NdrComplexArrayUnmarshall
,
197 NdrConformantStringUnmarshall
, 0, 0,
198 NdrConformantStringUnmarshall
,
199 NdrNonConformantStringUnmarshall
, 0, 0, 0,
201 NdrEncapsulatedUnionUnmarshall
,
202 NdrNonEncapsulatedUnionUnmarshall
,
203 NdrByteCountPointerUnmarshall
,
204 NdrXmitOrRepAsUnmarshall
, NdrXmitOrRepAsUnmarshall
,
206 NdrInterfacePointerUnmarshall
,
208 NdrContextHandleUnmarshall
,
211 NdrUserMarshalUnmarshall
,
216 const NDR_BUFFERSIZE NdrBufferSizer
[NDR_TABLE_SIZE
] = {
218 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
219 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
220 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
221 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
223 NdrBaseTypeBufferSize
,
225 NdrPointerBufferSize
, NdrPointerBufferSize
,
226 NdrPointerBufferSize
, NdrPointerBufferSize
,
228 NdrSimpleStructBufferSize
, NdrSimpleStructBufferSize
,
229 NdrConformantStructBufferSize
, NdrConformantStructBufferSize
,
230 NdrConformantVaryingStructBufferSize
,
231 NdrComplexStructBufferSize
,
233 NdrConformantArrayBufferSize
,
234 NdrConformantVaryingArrayBufferSize
,
235 NdrFixedArrayBufferSize
, NdrFixedArrayBufferSize
,
236 NdrVaryingArrayBufferSize
, NdrVaryingArrayBufferSize
,
237 NdrComplexArrayBufferSize
,
239 NdrConformantStringBufferSize
, 0, 0,
240 NdrConformantStringBufferSize
,
241 NdrNonConformantStringBufferSize
, 0, 0, 0,
243 NdrEncapsulatedUnionBufferSize
,
244 NdrNonEncapsulatedUnionBufferSize
,
245 NdrByteCountPointerBufferSize
,
246 NdrXmitOrRepAsBufferSize
, NdrXmitOrRepAsBufferSize
,
248 NdrInterfacePointerBufferSize
,
250 NdrContextHandleBufferSize
,
253 NdrUserMarshalBufferSize
,
258 const NDR_MEMORYSIZE NdrMemorySizer
[NDR_TABLE_SIZE
] = {
260 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
261 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
262 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
263 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
265 NdrBaseTypeMemorySize
,
267 NdrPointerMemorySize
, NdrPointerMemorySize
,
268 NdrPointerMemorySize
, NdrPointerMemorySize
,
270 NdrSimpleStructMemorySize
, NdrSimpleStructMemorySize
,
271 NdrConformantStructMemorySize
, NdrConformantStructMemorySize
,
272 NdrConformantVaryingStructMemorySize
,
273 NdrComplexStructMemorySize
,
275 NdrConformantArrayMemorySize
,
276 NdrConformantVaryingArrayMemorySize
,
277 NdrFixedArrayMemorySize
, NdrFixedArrayMemorySize
,
278 NdrVaryingArrayMemorySize
, NdrVaryingArrayMemorySize
,
279 NdrComplexArrayMemorySize
,
281 NdrConformantStringMemorySize
, 0, 0,
282 NdrConformantStringMemorySize
,
283 NdrNonConformantStringMemorySize
, 0, 0, 0,
285 NdrEncapsulatedUnionMemorySize
,
286 NdrNonEncapsulatedUnionMemorySize
,
287 NdrByteCountPointerMemorySize
,
288 NdrXmitOrRepAsMemorySize
, NdrXmitOrRepAsMemorySize
,
290 NdrInterfacePointerMemorySize
,
295 NdrUserMarshalMemorySize
,
300 const NDR_FREE NdrFreer
[NDR_TABLE_SIZE
] = {
302 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
303 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
304 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
305 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
309 NdrPointerFree
, NdrPointerFree
,
310 NdrPointerFree
, NdrPointerFree
,
312 NdrSimpleStructFree
, NdrSimpleStructFree
,
313 NdrConformantStructFree
, NdrConformantStructFree
,
314 NdrConformantVaryingStructFree
,
315 NdrComplexStructFree
,
317 NdrConformantArrayFree
,
318 NdrConformantVaryingArrayFree
,
319 NdrFixedArrayFree
, NdrFixedArrayFree
,
320 NdrVaryingArrayFree
, NdrVaryingArrayFree
,
326 NdrEncapsulatedUnionFree
,
327 NdrNonEncapsulatedUnionFree
,
329 NdrXmitOrRepAsFree
, NdrXmitOrRepAsFree
,
331 NdrInterfacePointerFree
,
342 typedef struct _NDR_MEMORY_LIST
347 struct _NDR_MEMORY_LIST
*next
;
350 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
352 /***********************************************************************
353 * NdrAllocate [RPCRT4.@]
355 * Allocates a block of memory using pStubMsg->pfnAllocate.
358 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
359 * len [I] Size of memory block to allocate.
362 * The memory block of size len that was allocated.
365 * The memory block is always 8-byte aligned.
366 * If the function is unable to allocate memory an ERROR_OUTOFMEMORY
367 * exception is raised.
369 void * WINAPI
NdrAllocate(MIDL_STUB_MESSAGE
*pStubMsg
, SIZE_T len
)
374 NDR_MEMORY_LIST
*mem_list
;
376 aligned_len
= ALIGNED_LENGTH(len
, 8);
377 adjusted_len
= aligned_len
+ sizeof(NDR_MEMORY_LIST
);
378 /* check for overflow */
379 if (adjusted_len
< len
)
381 ERR("overflow of adjusted_len %ld, len %ld\n", adjusted_len
, len
);
382 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
385 p
= pStubMsg
->pfnAllocate(adjusted_len
);
386 if (!p
) RpcRaiseException(ERROR_OUTOFMEMORY
);
388 mem_list
= (NDR_MEMORY_LIST
*)((char *)p
+ aligned_len
);
389 mem_list
->magic
= MEML_MAGIC
;
390 mem_list
->size
= aligned_len
;
391 mem_list
->reserved
= 0;
392 mem_list
->next
= pStubMsg
->pMemoryList
;
393 pStubMsg
->pMemoryList
= mem_list
;
399 static void NdrFree(MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *Pointer
)
401 TRACE("(%p, %p)\n", pStubMsg
, Pointer
);
403 pStubMsg
->pfnFree(Pointer
);
406 static inline BOOL
IsConformanceOrVariancePresent(PFORMAT_STRING pFormat
)
408 return (*(const ULONG
*)pFormat
!= -1);
411 static PFORMAT_STRING
ReadConformance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
)
413 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
414 if (pStubMsg
->Buffer
+ 4 > pStubMsg
->BufferEnd
)
415 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
416 pStubMsg
->MaxCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
417 pStubMsg
->Buffer
+= 4;
418 TRACE("unmarshalled conformance is %ld\n", pStubMsg
->MaxCount
);
419 if (pStubMsg
->fHasNewCorrDesc
)
425 static inline PFORMAT_STRING
ReadVariance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
, ULONG MaxValue
)
427 if (pFormat
&& !IsConformanceOrVariancePresent(pFormat
))
429 pStubMsg
->Offset
= 0;
430 pStubMsg
->ActualCount
= pStubMsg
->MaxCount
;
434 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
435 if (pStubMsg
->Buffer
+ 8 > pStubMsg
->BufferEnd
)
436 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
437 pStubMsg
->Offset
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
438 pStubMsg
->Buffer
+= 4;
439 TRACE("offset is %d\n", pStubMsg
->Offset
);
440 pStubMsg
->ActualCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
441 pStubMsg
->Buffer
+= 4;
442 TRACE("variance is %d\n", pStubMsg
->ActualCount
);
444 if ((pStubMsg
->ActualCount
> MaxValue
) ||
445 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> MaxValue
))
447 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
448 pStubMsg
->ActualCount
, pStubMsg
->Offset
, MaxValue
);
449 RpcRaiseException(RPC_S_INVALID_BOUND
);
454 if (pStubMsg
->fHasNewCorrDesc
)
460 /* writes the conformance value to the buffer */
461 static inline void WriteConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
463 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
464 if (pStubMsg
->Buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
465 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
466 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->MaxCount
);
467 pStubMsg
->Buffer
+= 4;
470 /* writes the variance values to the buffer */
471 static inline void WriteVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
473 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
474 if (pStubMsg
->Buffer
+ 8 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
475 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
476 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->Offset
);
477 pStubMsg
->Buffer
+= 4;
478 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->ActualCount
);
479 pStubMsg
->Buffer
+= 4;
482 /* requests buffer space for the conformance value */
483 static inline void SizeConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
485 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
486 if (pStubMsg
->BufferLength
+ 4 < pStubMsg
->BufferLength
)
487 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
488 pStubMsg
->BufferLength
+= 4;
491 /* requests buffer space for the variance values */
492 static inline void SizeVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
494 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
495 if (pStubMsg
->BufferLength
+ 8 < pStubMsg
->BufferLength
)
496 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
497 pStubMsg
->BufferLength
+= 8;
500 PFORMAT_STRING
ComputeConformanceOrVariance(
501 MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *pMemory
,
502 PFORMAT_STRING pFormat
, ULONG_PTR def
, ULONG_PTR
*pCount
)
504 BYTE dtype
= pFormat
[0] & 0xf;
505 short ofs
= *(const short *)&pFormat
[2];
509 if (!IsConformanceOrVariancePresent(pFormat
)) {
510 /* null descriptor */
515 switch (pFormat
[0] & 0xf0) {
516 case RPC_FC_NORMAL_CONFORMANCE
:
517 TRACE("normal conformance, ofs=%d\n", ofs
);
520 case RPC_FC_POINTER_CONFORMANCE
:
521 TRACE("pointer conformance, ofs=%d\n", ofs
);
522 ptr
= pStubMsg
->Memory
;
524 case RPC_FC_TOP_LEVEL_CONFORMANCE
:
525 TRACE("toplevel conformance, ofs=%d\n", ofs
);
526 if (pStubMsg
->StackTop
) {
527 ptr
= pStubMsg
->StackTop
;
530 /* -Os mode, *pCount is already set */
534 case RPC_FC_CONSTANT_CONFORMANCE
:
535 data
= ofs
| ((DWORD
)pFormat
[1] << 16);
536 TRACE("constant conformance, val=%d\n", data
);
539 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE
:
540 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs
);
541 if (pStubMsg
->StackTop
) {
542 ptr
= pStubMsg
->StackTop
;
550 FIXME("unknown conformance type %x\n", pFormat
[0] & 0xf0);
553 switch (pFormat
[1]) {
554 case RPC_FC_DEREFERENCE
:
555 ptr
= *(LPVOID
*)((char *)ptr
+ ofs
);
557 case RPC_FC_CALLBACK
:
559 unsigned char *old_stack_top
= pStubMsg
->StackTop
;
560 pStubMsg
->StackTop
= ptr
;
562 /* ofs is index into StubDesc->apfnExprEval */
563 TRACE("callback conformance into apfnExprEval[%d]\n", ofs
);
564 pStubMsg
->StubDesc
->apfnExprEval
[ofs
](pStubMsg
);
566 pStubMsg
->StackTop
= old_stack_top
;
568 /* the callback function always stores the computed value in MaxCount */
569 *pCount
= pStubMsg
->MaxCount
;
573 ptr
= (char *)ptr
+ ofs
;
586 data
= *(USHORT
*)ptr
;
597 FIXME("unknown conformance data type %x\n", dtype
);
600 TRACE("dereferenced data type %x at %p, got %d\n", dtype
, ptr
, data
);
603 switch (pFormat
[1]) {
604 case RPC_FC_DEREFERENCE
: /* already handled */
621 FIXME("unknown conformance op %d\n", pFormat
[1]);
626 TRACE("resulting conformance is %ld\n", *pCount
);
627 if (pStubMsg
->fHasNewCorrDesc
)
633 static inline PFORMAT_STRING
SkipConformance(PMIDL_STUB_MESSAGE pStubMsg
,
634 PFORMAT_STRING pFormat
)
636 if (IsConformanceOrVariancePresent(pFormat
))
638 if (pStubMsg
->fHasNewCorrDesc
)
646 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
647 * the result overflows 32-bits */
648 static inline ULONG
safe_multiply(ULONG a
, ULONG b
)
650 ULONGLONG ret
= (ULONGLONG
)a
* b
;
651 if (ret
> 0xffffffff)
653 RpcRaiseException(RPC_S_INVALID_BOUND
);
659 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
661 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
662 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
663 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
664 pStubMsg
->Buffer
+= size
;
667 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
669 if (pStubMsg
->BufferLength
+ size
< pStubMsg
->BufferLength
) /* integer overflow of pStubMsg->BufferSize */
671 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
672 pStubMsg
->BufferLength
, size
);
673 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
675 pStubMsg
->BufferLength
+= size
;
678 /* copies data from the buffer, checking that there is enough data in the buffer
680 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, void *p
, ULONG size
)
682 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
683 (pStubMsg
->Buffer
+ size
> pStubMsg
->BufferEnd
))
685 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
686 pStubMsg
->Buffer
, pStubMsg
->BufferEnd
, size
);
687 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
689 if (p
== pStubMsg
->Buffer
)
690 ERR("pointer is the same as the buffer\n");
691 memcpy(p
, pStubMsg
->Buffer
, size
);
692 pStubMsg
->Buffer
+= size
;
695 /* copies data to the buffer, checking that there is enough space to do so */
696 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, const void *p
, ULONG size
)
698 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
699 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
701 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
702 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
,
704 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
706 memcpy(pStubMsg
->Buffer
, p
, size
);
707 pStubMsg
->Buffer
+= size
;
710 /* verify that string data sitting in the buffer is valid and safe to
712 static void validate_string_data(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG bufsize
, ULONG esize
)
716 /* verify the buffer is safe to access */
717 if ((pStubMsg
->Buffer
+ bufsize
< pStubMsg
->Buffer
) ||
718 (pStubMsg
->Buffer
+ bufsize
> pStubMsg
->BufferEnd
))
720 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize
,
721 pStubMsg
->BufferEnd
, pStubMsg
->Buffer
);
722 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
725 /* strings must always have null terminating bytes */
728 ERR("invalid string length of %d\n", bufsize
/ esize
);
729 RpcRaiseException(RPC_S_INVALID_BOUND
);
732 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
733 if (pStubMsg
->Buffer
[i
] != 0)
735 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
736 i
, pStubMsg
->Buffer
[i
]);
737 RpcRaiseException(RPC_S_INVALID_BOUND
);
741 static inline void dump_pointer_attr(unsigned char attr
)
743 if (attr
& RPC_FC_P_ALLOCALLNODES
)
744 TRACE(" RPC_FC_P_ALLOCALLNODES");
745 if (attr
& RPC_FC_P_DONTFREE
)
746 TRACE(" RPC_FC_P_DONTFREE");
747 if (attr
& RPC_FC_P_ONSTACK
)
748 TRACE(" RPC_FC_P_ONSTACK");
749 if (attr
& RPC_FC_P_SIMPLEPOINTER
)
750 TRACE(" RPC_FC_P_SIMPLEPOINTER");
751 if (attr
& RPC_FC_P_DEREF
)
752 TRACE(" RPC_FC_P_DEREF");
756 /***********************************************************************
757 * PointerMarshall [internal]
759 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
760 unsigned char *Buffer
,
761 unsigned char *Pointer
,
762 PFORMAT_STRING pFormat
)
764 unsigned type
= pFormat
[0], attr
= pFormat
[1];
768 int pointer_needs_marshaling
;
770 TRACE("(%p,%p,%p,%p)\n", pStubMsg
, Buffer
, Pointer
, pFormat
);
771 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
773 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
774 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
777 case RPC_FC_RP
: /* ref pointer (always non-null) */
780 ERR("NULL ref pointer is not allowed\n");
781 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
783 pointer_needs_marshaling
= 1;
785 case RPC_FC_UP
: /* unique pointer */
786 case RPC_FC_OP
: /* object pointer - same as unique here */
788 pointer_needs_marshaling
= 1;
790 pointer_needs_marshaling
= 0;
791 pointer_id
= Pointer
? NDR_POINTER_ID(pStubMsg
) : 0;
792 TRACE("writing 0x%08x to buffer\n", pointer_id
);
793 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
796 pointer_needs_marshaling
= !NdrFullPointerQueryPointer(
797 pStubMsg
->FullPtrXlatTables
, Pointer
, 1, &pointer_id
);
798 TRACE("writing 0x%08x to buffer\n", pointer_id
);
799 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
802 FIXME("unhandled ptr type=%02x\n", type
);
803 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
807 TRACE("calling marshaller for type 0x%x\n", (int)*desc
);
809 if (pointer_needs_marshaling
) {
810 if (attr
& RPC_FC_P_DEREF
) {
811 Pointer
= *(unsigned char**)Pointer
;
812 TRACE("deref => %p\n", Pointer
);
814 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
815 if (m
) m(pStubMsg
, Pointer
, desc
);
816 else FIXME("no marshaller for data type=%02x\n", *desc
);
819 STD_OVERFLOW_CHECK(pStubMsg
);
822 /***********************************************************************
823 * PointerUnmarshall [internal]
825 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
826 unsigned char *Buffer
,
827 unsigned char **pPointer
,
828 unsigned char *pSrcPointer
,
829 PFORMAT_STRING pFormat
,
830 unsigned char fMustAlloc
)
832 unsigned type
= pFormat
[0], attr
= pFormat
[1];
835 DWORD pointer_id
= 0;
836 int pointer_needs_unmarshaling
;
838 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg
, Buffer
, pPointer
, pSrcPointer
, pFormat
, fMustAlloc
);
839 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
841 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
842 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
845 case RPC_FC_RP
: /* ref pointer (always non-null) */
846 pointer_needs_unmarshaling
= 1;
848 case RPC_FC_UP
: /* unique pointer */
849 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
850 TRACE("pointer_id is 0x%08x\n", pointer_id
);
852 pointer_needs_unmarshaling
= 1;
855 pointer_needs_unmarshaling
= 0;
858 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
859 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
860 TRACE("pointer_id is 0x%08x\n", pointer_id
);
861 if (!fMustAlloc
&& pSrcPointer
)
863 FIXME("free object pointer %p\n", pSrcPointer
);
867 pointer_needs_unmarshaling
= 1;
871 pointer_needs_unmarshaling
= 0;
875 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
876 TRACE("pointer_id is 0x%08x\n", pointer_id
);
877 pointer_needs_unmarshaling
= !NdrFullPointerQueryRefId(
878 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, (void **)pPointer
);
881 FIXME("unhandled ptr type=%02x\n", type
);
882 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
886 if (pointer_needs_unmarshaling
) {
887 unsigned char *base_ptr_val
= *pPointer
;
888 unsigned char **current_ptr
= pPointer
;
889 if (pStubMsg
->IsClient
) {
891 /* if we aren't forcing allocation of memory then try to use the existing
892 * (source) pointer to unmarshall the data into so that [in,out]
893 * parameters behave correctly. it doesn't matter if the parameter is
894 * [out] only since in that case the pointer will be NULL. we force
895 * allocation when the source pointer is NULL here instead of in the type
896 * unmarshalling routine for the benefit of the deref code below */
899 TRACE("setting *pPointer to %p\n", pSrcPointer
);
900 *pPointer
= base_ptr_val
= pSrcPointer
;
906 /* the memory in a stub is never initialised, so we have to work out here
907 * whether we have to initialise it so we can use the optimisation of
908 * setting the pointer to the buffer, if possible, or set fMustAlloc to
910 if (attr
& RPC_FC_P_DEREF
) {
918 if (attr
& RPC_FC_P_ALLOCALLNODES
)
919 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
921 if (attr
& RPC_FC_P_DEREF
) {
923 base_ptr_val
= NdrAllocate(pStubMsg
, sizeof(void *));
924 *pPointer
= base_ptr_val
;
925 current_ptr
= (unsigned char **)base_ptr_val
;
927 current_ptr
= *(unsigned char***)current_ptr
;
928 TRACE("deref => %p\n", current_ptr
);
929 if (!fMustAlloc
&& !*current_ptr
) fMustAlloc
= TRUE
;
931 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
932 if (m
) m(pStubMsg
, current_ptr
, desc
, fMustAlloc
);
933 else FIXME("no unmarshaller for data type=%02x\n", *desc
);
935 if (type
== RPC_FC_FP
)
936 NdrFullPointerInsertRefId(pStubMsg
->FullPtrXlatTables
, pointer_id
,
940 TRACE("pointer=%p\n", *pPointer
);
943 /***********************************************************************
944 * PointerBufferSize [internal]
946 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
947 unsigned char *Pointer
,
948 PFORMAT_STRING pFormat
)
950 unsigned type
= pFormat
[0], attr
= pFormat
[1];
953 int pointer_needs_sizing
;
956 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
957 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
959 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
960 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
963 case RPC_FC_RP
: /* ref pointer (always non-null) */
966 ERR("NULL ref pointer is not allowed\n");
967 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
972 /* NULL pointer has no further representation */
977 pointer_needs_sizing
= !NdrFullPointerQueryPointer(
978 pStubMsg
->FullPtrXlatTables
, Pointer
, 0, &pointer_id
);
979 if (!pointer_needs_sizing
)
983 FIXME("unhandled ptr type=%02x\n", type
);
984 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
988 if (attr
& RPC_FC_P_DEREF
) {
989 Pointer
= *(unsigned char**)Pointer
;
990 TRACE("deref => %p\n", Pointer
);
993 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
994 if (m
) m(pStubMsg
, Pointer
, desc
);
995 else FIXME("no buffersizer for data type=%02x\n", *desc
);
998 /***********************************************************************
999 * PointerMemorySize [internal]
1001 static ULONG
PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1002 unsigned char *Buffer
, PFORMAT_STRING pFormat
)
1004 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1005 PFORMAT_STRING desc
;
1007 DWORD pointer_id
= 0;
1008 int pointer_needs_sizing
;
1010 TRACE("(%p,%p,%p)\n", pStubMsg
, Buffer
, pFormat
);
1011 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1013 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1014 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1017 case RPC_FC_RP
: /* ref pointer (always non-null) */
1018 pointer_needs_sizing
= 1;
1020 case RPC_FC_UP
: /* unique pointer */
1021 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
1022 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1023 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1025 pointer_needs_sizing
= 1;
1027 pointer_needs_sizing
= 0;
1032 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1033 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1034 pointer_needs_sizing
= !NdrFullPointerQueryRefId(
1035 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, &pointer
);
1039 FIXME("unhandled ptr type=%02x\n", type
);
1040 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1044 if (attr
& RPC_FC_P_DEREF
) {
1045 ALIGN_LENGTH(pStubMsg
->MemorySize
, sizeof(void*));
1046 pStubMsg
->MemorySize
+= sizeof(void*);
1050 if (pointer_needs_sizing
) {
1051 m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
1052 if (m
) m(pStubMsg
, desc
);
1053 else FIXME("no memorysizer for data type=%02x\n", *desc
);
1056 return pStubMsg
->MemorySize
;
1059 /***********************************************************************
1060 * PointerFree [internal]
1062 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1063 unsigned char *Pointer
,
1064 PFORMAT_STRING pFormat
)
1066 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1067 PFORMAT_STRING desc
;
1069 unsigned char *current_pointer
= Pointer
;
1071 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1072 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1073 if (attr
& RPC_FC_P_DONTFREE
) return;
1075 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1076 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1078 if (!Pointer
) return;
1080 if (type
== RPC_FC_FP
) {
1081 int pointer_needs_freeing
= NdrFullPointerFree(
1082 pStubMsg
->FullPtrXlatTables
, Pointer
);
1083 if (!pointer_needs_freeing
)
1087 if (attr
& RPC_FC_P_DEREF
) {
1088 current_pointer
= *(unsigned char**)Pointer
;
1089 TRACE("deref => %p\n", current_pointer
);
1092 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
1093 if (m
) m(pStubMsg
, current_pointer
, desc
);
1095 /* this check stops us from trying to free buffer memory. we don't have to
1096 * worry about clients, since they won't call this function.
1097 * we don't have to check for the buffer being reallocated because
1098 * BufferStart and BufferEnd won't be reset when allocating memory for
1099 * sending the response. we don't have to check for the new buffer here as
1100 * it won't be used a type memory, only for buffer memory */
1101 if (Pointer
>= pStubMsg
->BufferStart
&& Pointer
< pStubMsg
->BufferEnd
)
1104 if (attr
& RPC_FC_P_ONSTACK
) {
1105 TRACE("not freeing stack ptr %p\n", Pointer
);
1108 TRACE("freeing %p\n", Pointer
);
1109 NdrFree(pStubMsg
, Pointer
);
1112 TRACE("not freeing %p\n", Pointer
);
1115 /***********************************************************************
1116 * EmbeddedPointerMarshall
1118 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1119 unsigned char *pMemory
,
1120 PFORMAT_STRING pFormat
)
1122 unsigned char *Mark
= pStubMsg
->BufferMark
;
1123 unsigned rep
, count
, stride
;
1125 unsigned char *saved_buffer
= NULL
;
1127 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1129 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1132 if (pStubMsg
->PointerBufferMark
)
1134 saved_buffer
= pStubMsg
->Buffer
;
1135 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1136 pStubMsg
->PointerBufferMark
= NULL
;
1139 while (pFormat
[0] != RPC_FC_END
) {
1140 switch (pFormat
[0]) {
1142 FIXME("unknown repeat type %d\n", pFormat
[0]);
1143 case RPC_FC_NO_REPEAT
:
1149 case RPC_FC_FIXED_REPEAT
:
1150 rep
= *(const WORD
*)&pFormat
[2];
1151 stride
= *(const WORD
*)&pFormat
[4];
1152 count
= *(const WORD
*)&pFormat
[8];
1155 case RPC_FC_VARIABLE_REPEAT
:
1156 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1157 stride
= *(const WORD
*)&pFormat
[2];
1158 count
= *(const WORD
*)&pFormat
[6];
1162 for (i
= 0; i
< rep
; i
++) {
1163 PFORMAT_STRING info
= pFormat
;
1164 unsigned char *membase
= pMemory
+ (i
* stride
);
1165 unsigned char *bufbase
= Mark
+ (i
* stride
);
1168 for (u
=0; u
<count
; u
++,info
+=8) {
1169 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1170 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1171 unsigned char *saved_memory
= pStubMsg
->Memory
;
1173 pStubMsg
->Memory
= pMemory
;
1174 PointerMarshall(pStubMsg
, bufptr
, *(unsigned char**)memptr
, info
+4);
1175 pStubMsg
->Memory
= saved_memory
;
1178 pFormat
+= 8 * count
;
1183 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1184 pStubMsg
->Buffer
= saved_buffer
;
1187 STD_OVERFLOW_CHECK(pStubMsg
);
1192 /***********************************************************************
1193 * EmbeddedPointerUnmarshall
1195 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1196 unsigned char *pDstBuffer
,
1197 unsigned char *pSrcMemoryPtrs
,
1198 PFORMAT_STRING pFormat
,
1199 unsigned char fMustAlloc
)
1201 unsigned char *Mark
= pStubMsg
->BufferMark
;
1202 unsigned rep
, count
, stride
;
1204 unsigned char *saved_buffer
= NULL
;
1206 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg
, pDstBuffer
, pSrcMemoryPtrs
, pFormat
, fMustAlloc
);
1208 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1211 if (pStubMsg
->PointerBufferMark
)
1213 saved_buffer
= pStubMsg
->Buffer
;
1214 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1215 pStubMsg
->PointerBufferMark
= NULL
;
1218 while (pFormat
[0] != RPC_FC_END
) {
1219 TRACE("pFormat[0] = 0x%x\n", pFormat
[0]);
1220 switch (pFormat
[0]) {
1222 FIXME("unknown repeat type %d\n", pFormat
[0]);
1223 case RPC_FC_NO_REPEAT
:
1229 case RPC_FC_FIXED_REPEAT
:
1230 rep
= *(const WORD
*)&pFormat
[2];
1231 stride
= *(const WORD
*)&pFormat
[4];
1232 count
= *(const WORD
*)&pFormat
[8];
1235 case RPC_FC_VARIABLE_REPEAT
:
1236 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1237 stride
= *(const WORD
*)&pFormat
[2];
1238 count
= *(const WORD
*)&pFormat
[6];
1242 for (i
= 0; i
< rep
; i
++) {
1243 PFORMAT_STRING info
= pFormat
;
1244 unsigned char *bufdstbase
= pDstBuffer
+ (i
* stride
);
1245 unsigned char *memsrcbase
= pSrcMemoryPtrs
+ (i
* stride
);
1246 unsigned char *bufbase
= Mark
+ (i
* stride
);
1249 for (u
=0; u
<count
; u
++,info
+=8) {
1250 unsigned char **bufdstptr
= (unsigned char **)(bufdstbase
+ *(const SHORT
*)&info
[2]);
1251 unsigned char **memsrcptr
= (unsigned char **)(memsrcbase
+ *(const SHORT
*)&info
[0]);
1252 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1253 PointerUnmarshall(pStubMsg
, bufptr
, bufdstptr
, *memsrcptr
, info
+4, fMustAlloc
);
1256 pFormat
+= 8 * count
;
1261 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1262 pStubMsg
->Buffer
= saved_buffer
;
1268 /***********************************************************************
1269 * EmbeddedPointerBufferSize
1271 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1272 unsigned char *pMemory
,
1273 PFORMAT_STRING pFormat
)
1275 unsigned rep
, count
, stride
;
1277 ULONG saved_buffer_length
= 0;
1279 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1281 if (pStubMsg
->IgnoreEmbeddedPointers
) return;
1283 if (*pFormat
!= RPC_FC_PP
) return;
1286 if (pStubMsg
->PointerLength
)
1288 saved_buffer_length
= pStubMsg
->BufferLength
;
1289 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
1290 pStubMsg
->PointerLength
= 0;
1293 while (pFormat
[0] != RPC_FC_END
) {
1294 switch (pFormat
[0]) {
1296 FIXME("unknown repeat type %d\n", pFormat
[0]);
1297 case RPC_FC_NO_REPEAT
:
1303 case RPC_FC_FIXED_REPEAT
:
1304 rep
= *(const WORD
*)&pFormat
[2];
1305 stride
= *(const WORD
*)&pFormat
[4];
1306 count
= *(const WORD
*)&pFormat
[8];
1309 case RPC_FC_VARIABLE_REPEAT
:
1310 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1311 stride
= *(const WORD
*)&pFormat
[2];
1312 count
= *(const WORD
*)&pFormat
[6];
1316 for (i
= 0; i
< rep
; i
++) {
1317 PFORMAT_STRING info
= pFormat
;
1318 unsigned char *membase
= pMemory
+ (i
* stride
);
1321 for (u
=0; u
<count
; u
++,info
+=8) {
1322 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1323 unsigned char *saved_memory
= pStubMsg
->Memory
;
1325 pStubMsg
->Memory
= pMemory
;
1326 PointerBufferSize(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1327 pStubMsg
->Memory
= saved_memory
;
1330 pFormat
+= 8 * count
;
1333 if (saved_buffer_length
)
1335 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
1336 pStubMsg
->BufferLength
= saved_buffer_length
;
1340 /***********************************************************************
1341 * EmbeddedPointerMemorySize [internal]
1343 static ULONG
EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1344 PFORMAT_STRING pFormat
)
1346 unsigned char *Mark
= pStubMsg
->BufferMark
;
1347 unsigned rep
, count
, stride
;
1349 unsigned char *saved_buffer
= NULL
;
1351 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1353 if (pStubMsg
->IgnoreEmbeddedPointers
) return 0;
1355 if (pStubMsg
->PointerBufferMark
)
1357 saved_buffer
= pStubMsg
->Buffer
;
1358 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1359 pStubMsg
->PointerBufferMark
= NULL
;
1362 if (*pFormat
!= RPC_FC_PP
) return 0;
1365 while (pFormat
[0] != RPC_FC_END
) {
1366 switch (pFormat
[0]) {
1368 FIXME("unknown repeat type %d\n", pFormat
[0]);
1369 case RPC_FC_NO_REPEAT
:
1375 case RPC_FC_FIXED_REPEAT
:
1376 rep
= *(const WORD
*)&pFormat
[2];
1377 stride
= *(const WORD
*)&pFormat
[4];
1378 count
= *(const WORD
*)&pFormat
[8];
1381 case RPC_FC_VARIABLE_REPEAT
:
1382 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1383 stride
= *(const WORD
*)&pFormat
[2];
1384 count
= *(const WORD
*)&pFormat
[6];
1388 for (i
= 0; i
< rep
; i
++) {
1389 PFORMAT_STRING info
= pFormat
;
1390 unsigned char *bufbase
= Mark
+ (i
* stride
);
1392 for (u
=0; u
<count
; u
++,info
+=8) {
1393 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1394 PointerMemorySize(pStubMsg
, bufptr
, info
+4);
1397 pFormat
+= 8 * count
;
1402 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1403 pStubMsg
->Buffer
= saved_buffer
;
1409 /***********************************************************************
1410 * EmbeddedPointerFree [internal]
1412 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1413 unsigned char *pMemory
,
1414 PFORMAT_STRING pFormat
)
1416 unsigned rep
, count
, stride
;
1419 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1420 if (*pFormat
!= RPC_FC_PP
) return;
1423 while (pFormat
[0] != RPC_FC_END
) {
1424 switch (pFormat
[0]) {
1426 FIXME("unknown repeat type %d\n", pFormat
[0]);
1427 case RPC_FC_NO_REPEAT
:
1433 case RPC_FC_FIXED_REPEAT
:
1434 rep
= *(const WORD
*)&pFormat
[2];
1435 stride
= *(const WORD
*)&pFormat
[4];
1436 count
= *(const WORD
*)&pFormat
[8];
1439 case RPC_FC_VARIABLE_REPEAT
:
1440 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1441 stride
= *(const WORD
*)&pFormat
[2];
1442 count
= *(const WORD
*)&pFormat
[6];
1446 for (i
= 0; i
< rep
; i
++) {
1447 PFORMAT_STRING info
= pFormat
;
1448 unsigned char *membase
= pMemory
+ (i
* stride
);
1451 for (u
=0; u
<count
; u
++,info
+=8) {
1452 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1453 unsigned char *saved_memory
= pStubMsg
->Memory
;
1455 pStubMsg
->Memory
= pMemory
;
1456 PointerFree(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1457 pStubMsg
->Memory
= saved_memory
;
1460 pFormat
+= 8 * count
;
1464 /***********************************************************************
1465 * NdrPointerMarshall [RPCRT4.@]
1467 unsigned char * WINAPI
NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1468 unsigned char *pMemory
,
1469 PFORMAT_STRING pFormat
)
1471 unsigned char *Buffer
;
1473 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1475 /* Increment the buffer here instead of in PointerMarshall,
1476 * as that is used by embedded pointers which already handle the incrementing
1477 * the buffer, and shouldn't write any additional pointer data to the wire */
1478 if (*pFormat
!= RPC_FC_RP
)
1480 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
1481 Buffer
= pStubMsg
->Buffer
;
1482 safe_buffer_increment(pStubMsg
, 4);
1485 Buffer
= pStubMsg
->Buffer
;
1487 PointerMarshall(pStubMsg
, Buffer
, pMemory
, pFormat
);
1492 /***********************************************************************
1493 * NdrPointerUnmarshall [RPCRT4.@]
1495 unsigned char * WINAPI
NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1496 unsigned char **ppMemory
,
1497 PFORMAT_STRING pFormat
,
1498 unsigned char fMustAlloc
)
1500 unsigned char *Buffer
;
1502 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1504 if (*pFormat
== RPC_FC_RP
)
1506 Buffer
= pStubMsg
->Buffer
;
1507 /* Do the NULL ref pointer check here because embedded pointers can be
1508 * NULL if the type the pointer is embedded in was allocated rather than
1509 * being passed in by the client */
1510 if (pStubMsg
->IsClient
&& !*ppMemory
)
1512 ERR("NULL ref pointer is not allowed\n");
1513 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
1518 /* Increment the buffer here instead of in PointerUnmarshall,
1519 * as that is used by embedded pointers which already handle the incrementing
1520 * the buffer, and shouldn't read any additional pointer data from the
1522 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1523 Buffer
= pStubMsg
->Buffer
;
1524 safe_buffer_increment(pStubMsg
, 4);
1527 PointerUnmarshall(pStubMsg
, Buffer
, ppMemory
, *ppMemory
, pFormat
, fMustAlloc
);
1532 /***********************************************************************
1533 * NdrPointerBufferSize [RPCRT4.@]
1535 void WINAPI
NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1536 unsigned char *pMemory
,
1537 PFORMAT_STRING pFormat
)
1539 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1541 /* Increment the buffer length here instead of in PointerBufferSize,
1542 * as that is used by embedded pointers which already handle the buffer
1543 * length, and shouldn't write anything more to the wire */
1544 if (*pFormat
!= RPC_FC_RP
)
1546 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
1547 safe_buffer_length_increment(pStubMsg
, 4);
1550 PointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1553 /***********************************************************************
1554 * NdrPointerMemorySize [RPCRT4.@]
1556 ULONG WINAPI
NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1557 PFORMAT_STRING pFormat
)
1559 unsigned char *Buffer
= pStubMsg
->Buffer
;
1560 if (*pFormat
!= RPC_FC_RP
)
1562 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1563 safe_buffer_increment(pStubMsg
, 4);
1565 ALIGN_LENGTH(pStubMsg
->MemorySize
, sizeof(void *));
1566 return PointerMemorySize(pStubMsg
, Buffer
, pFormat
);
1569 /***********************************************************************
1570 * NdrPointerFree [RPCRT4.@]
1572 void WINAPI
NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1573 unsigned char *pMemory
,
1574 PFORMAT_STRING pFormat
)
1576 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1577 PointerFree(pStubMsg
, pMemory
, pFormat
);
1580 /***********************************************************************
1581 * NdrSimpleTypeMarshall [RPCRT4.@]
1583 void WINAPI
NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1584 unsigned char FormatChar
)
1586 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &FormatChar
);
1589 /***********************************************************************
1590 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1592 * Unmarshall a base type.
1595 * Doesn't check that the buffer is long enough before copying, so the caller
1598 void WINAPI
NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1599 unsigned char FormatChar
)
1601 #define BASE_TYPE_UNMARSHALL(type) \
1602 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
1603 TRACE("pMemory: %p\n", pMemory); \
1604 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1605 pStubMsg->Buffer += sizeof(type);
1613 BASE_TYPE_UNMARSHALL(UCHAR
);
1614 TRACE("value: 0x%02x\n", *pMemory
);
1619 BASE_TYPE_UNMARSHALL(USHORT
);
1620 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
1624 case RPC_FC_ERROR_STATUS_T
:
1626 BASE_TYPE_UNMARSHALL(ULONG
);
1627 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
1630 BASE_TYPE_UNMARSHALL(float);
1631 TRACE("value: %f\n", *(float *)pMemory
);
1634 BASE_TYPE_UNMARSHALL(double);
1635 TRACE("value: %f\n", *(double *)pMemory
);
1638 BASE_TYPE_UNMARSHALL(ULONGLONG
);
1639 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
1642 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
1643 TRACE("pMemory: %p\n", pMemory
);
1644 /* 16-bits on the wire, but int in memory */
1645 *(UINT
*)pMemory
= *(USHORT
*)pStubMsg
->Buffer
;
1646 pStubMsg
->Buffer
+= sizeof(USHORT
);
1647 TRACE("value: 0x%08x\n", *(UINT
*)pMemory
);
1652 FIXME("Unhandled base type: 0x%02x\n", FormatChar
);
1654 #undef BASE_TYPE_UNMARSHALL
1657 /***********************************************************************
1658 * NdrSimpleStructMarshall [RPCRT4.@]
1660 unsigned char * WINAPI
NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1661 unsigned char *pMemory
,
1662 PFORMAT_STRING pFormat
)
1664 unsigned size
= *(const WORD
*)(pFormat
+2);
1665 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1667 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pFormat
[1] + 1);
1669 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1670 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
1672 if (pFormat
[0] != RPC_FC_STRUCT
)
1673 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
+4);
1678 /***********************************************************************
1679 * NdrSimpleStructUnmarshall [RPCRT4.@]
1681 unsigned char * WINAPI
NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1682 unsigned char **ppMemory
,
1683 PFORMAT_STRING pFormat
,
1684 unsigned char fMustAlloc
)
1686 unsigned size
= *(const WORD
*)(pFormat
+2);
1687 unsigned char *saved_buffer
;
1688 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1690 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1693 *ppMemory
= NdrAllocate(pStubMsg
, size
);
1696 if (!pStubMsg
->IsClient
&& !*ppMemory
)
1697 /* for servers, we just point straight into the RPC buffer */
1698 *ppMemory
= pStubMsg
->Buffer
;
1701 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1702 safe_buffer_increment(pStubMsg
, size
);
1703 if (pFormat
[0] == RPC_FC_PSTRUCT
)
1704 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
+4, fMustAlloc
);
1706 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
1707 if (*ppMemory
!= saved_buffer
)
1708 memcpy(*ppMemory
, saved_buffer
, size
);
1713 /***********************************************************************
1714 * NdrSimpleStructBufferSize [RPCRT4.@]
1716 void WINAPI
NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1717 unsigned char *pMemory
,
1718 PFORMAT_STRING pFormat
)
1720 unsigned size
= *(const WORD
*)(pFormat
+2);
1721 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1723 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
1725 safe_buffer_length_increment(pStubMsg
, size
);
1726 if (pFormat
[0] != RPC_FC_STRUCT
)
1727 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
+4);
1730 /***********************************************************************
1731 * NdrSimpleStructMemorySize [RPCRT4.@]
1733 ULONG WINAPI
NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1734 PFORMAT_STRING pFormat
)
1736 unsigned short size
= *(const WORD
*)(pFormat
+2);
1738 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1740 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1741 pStubMsg
->MemorySize
+= size
;
1742 safe_buffer_increment(pStubMsg
, size
);
1744 if (pFormat
[0] != RPC_FC_STRUCT
)
1745 EmbeddedPointerMemorySize(pStubMsg
, pFormat
+4);
1746 return pStubMsg
->MemorySize
;
1749 /***********************************************************************
1750 * NdrSimpleStructFree [RPCRT4.@]
1752 void WINAPI
NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
1753 unsigned char *pMemory
,
1754 PFORMAT_STRING pFormat
)
1756 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1757 if (pFormat
[0] != RPC_FC_STRUCT
)
1758 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
+4);
1763 static inline void array_compute_and_size_conformance(
1764 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1765 PFORMAT_STRING pFormat
)
1770 ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1771 SizeConformance(pStubMsg
);
1773 case RPC_FC_CVARRAY
:
1774 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, 0);
1775 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
1776 SizeConformance(pStubMsg
);
1778 case RPC_FC_C_CSTRING
:
1779 case RPC_FC_C_WSTRING
:
1780 if (pFormat
[0] == RPC_FC_C_CSTRING
)
1782 TRACE("string=%s\n", debugstr_a((const char *)pMemory
));
1783 pStubMsg
->ActualCount
= strlen((const char *)pMemory
)+1;
1787 TRACE("string=%s\n", debugstr_w((LPCWSTR
)pMemory
));
1788 pStubMsg
->ActualCount
= strlenW((LPCWSTR
)pMemory
)+1;
1791 if (fc
== RPC_FC_STRING_SIZED
)
1792 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
1794 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
1796 SizeConformance(pStubMsg
);
1799 ERR("unknown array format 0x%x\n", fc
);
1800 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1804 static inline void array_buffer_size(
1805 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1806 PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
1810 unsigned char alignment
;
1815 esize
= *(const WORD
*)(pFormat
+2);
1816 alignment
= pFormat
[1] + 1;
1818 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1820 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
1822 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
1823 /* conformance value plus array */
1824 safe_buffer_length_increment(pStubMsg
, size
);
1827 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1829 case RPC_FC_CVARRAY
:
1830 esize
= *(const WORD
*)(pFormat
+2);
1831 alignment
= pFormat
[1] + 1;
1833 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1834 pFormat
= SkipConformance(pStubMsg
, pFormat
);
1836 SizeVariance(pStubMsg
);
1838 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
1840 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1841 safe_buffer_length_increment(pStubMsg
, size
);
1844 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1846 case RPC_FC_C_CSTRING
:
1847 case RPC_FC_C_WSTRING
:
1848 if (fc
== RPC_FC_C_CSTRING
)
1853 SizeVariance(pStubMsg
);
1855 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1856 safe_buffer_length_increment(pStubMsg
, size
);
1859 ERR("unknown array format 0x%x\n", fc
);
1860 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1864 static inline void array_compute_and_write_conformance(
1865 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1866 PFORMAT_STRING pFormat
)
1871 ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1872 WriteConformance(pStubMsg
);
1874 case RPC_FC_CVARRAY
:
1875 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, 0);
1876 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
1877 WriteConformance(pStubMsg
);
1879 case RPC_FC_C_CSTRING
:
1880 case RPC_FC_C_WSTRING
:
1881 if (fc
== RPC_FC_C_CSTRING
)
1883 TRACE("string=%s\n", debugstr_a((const char *)pMemory
));
1884 pStubMsg
->ActualCount
= strlen((const char *)pMemory
)+1;
1888 TRACE("string=%s\n", debugstr_w((LPCWSTR
)pMemory
));
1889 pStubMsg
->ActualCount
= strlenW((LPCWSTR
)pMemory
)+1;
1891 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
1892 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
1894 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
1895 pStubMsg
->Offset
= 0;
1896 WriteConformance(pStubMsg
);
1899 ERR("unknown array format 0x%x\n", fc
);
1900 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1904 static inline void array_write_variance_and_marshall(
1905 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1906 PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
1910 unsigned char alignment
;
1915 esize
= *(const WORD
*)(pFormat
+2);
1916 alignment
= pFormat
[1] + 1;
1918 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1920 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
1922 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
1924 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1925 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
1928 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
1930 case RPC_FC_CVARRAY
:
1931 esize
= *(const WORD
*)(pFormat
+2);
1932 alignment
= pFormat
[1] + 1;
1935 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1937 pFormat
= SkipConformance(pStubMsg
, pFormat
);
1939 WriteVariance(pStubMsg
);
1941 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
1943 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1946 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1947 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, size
);
1950 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
1952 case RPC_FC_C_CSTRING
:
1953 case RPC_FC_C_WSTRING
:
1954 if (fc
== RPC_FC_C_CSTRING
)
1959 WriteVariance(pStubMsg
);
1961 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1962 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
1965 ERR("unknown array format 0x%x\n", fc
);
1966 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1970 static inline ULONG
array_read_conformance(
1971 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
1978 esize
= *(const WORD
*)(pFormat
+2);
1979 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
1980 return safe_multiply(esize
, pStubMsg
->MaxCount
);
1981 case RPC_FC_CVARRAY
:
1982 esize
= *(const WORD
*)(pFormat
+2);
1983 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
1984 return safe_multiply(esize
, pStubMsg
->MaxCount
);
1985 case RPC_FC_C_CSTRING
:
1986 case RPC_FC_C_WSTRING
:
1987 if (fc
== RPC_FC_C_CSTRING
)
1992 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
1993 ReadConformance(pStubMsg
, pFormat
+ 2);
1995 ReadConformance(pStubMsg
, NULL
);
1996 return safe_multiply(esize
, pStubMsg
->MaxCount
);
1998 ERR("unknown array format 0x%x\n", fc
);
1999 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2003 static inline ULONG
array_read_variance_and_unmarshall(
2004 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char **ppMemory
,
2005 PFORMAT_STRING pFormat
, unsigned char fMustAlloc
,
2006 unsigned char fUseBufferMemoryServer
, unsigned char fUnmarshall
)
2008 ULONG bufsize
, memsize
;
2010 unsigned char alignment
;
2011 unsigned char *saved_buffer
;
2017 esize
= *(const WORD
*)(pFormat
+2);
2018 alignment
= pFormat
[1] + 1;
2020 bufsize
= memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2022 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2024 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2029 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2032 if (fUseBufferMemoryServer
&& !pStubMsg
->IsClient
&& !*ppMemory
)
2033 /* for servers, we just point straight into the RPC buffer */
2034 *ppMemory
= pStubMsg
->Buffer
;
2037 saved_buffer
= pStubMsg
->Buffer
;
2038 safe_buffer_increment(pStubMsg
, bufsize
);
2040 pStubMsg
->BufferMark
= saved_buffer
;
2041 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
2043 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
2044 if (*ppMemory
!= saved_buffer
)
2045 memcpy(*ppMemory
, saved_buffer
, bufsize
);
2048 case RPC_FC_CVARRAY
:
2049 esize
= *(const WORD
*)(pFormat
+2);
2050 alignment
= pFormat
[1] + 1;
2052 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2054 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2056 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2058 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2059 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2063 offset
= pStubMsg
->Offset
;
2065 if (!fMustAlloc
&& !*ppMemory
)
2068 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2069 saved_buffer
= pStubMsg
->Buffer
;
2070 safe_buffer_increment(pStubMsg
, bufsize
);
2072 pStubMsg
->BufferMark
= saved_buffer
;
2073 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
,
2076 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
2079 case RPC_FC_C_CSTRING
:
2080 case RPC_FC_C_WSTRING
:
2081 if (fc
== RPC_FC_C_CSTRING
)
2086 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
2088 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
2090 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2091 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
2092 RpcRaiseException(RPC_S_INVALID_BOUND
);
2094 if (pStubMsg
->Offset
)
2096 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2097 RpcRaiseException(RPC_S_INVALID_BOUND
);
2100 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2101 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2103 validate_string_data(pStubMsg
, bufsize
, esize
);
2108 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2111 if (fUseBufferMemoryServer
&& !pStubMsg
->IsClient
&&
2112 !*ppMemory
&& (pStubMsg
->MaxCount
== pStubMsg
->ActualCount
))
2113 /* if the data in the RPC buffer is big enough, we just point
2114 * straight into it */
2115 *ppMemory
= pStubMsg
->Buffer
;
2116 else if (!*ppMemory
)
2117 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2120 if (*ppMemory
== pStubMsg
->Buffer
)
2121 safe_buffer_increment(pStubMsg
, bufsize
);
2123 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
2125 if (*pFormat
== RPC_FC_C_CSTRING
)
2126 TRACE("string=%s\n", debugstr_a((char*)*ppMemory
));
2128 TRACE("string=%s\n", debugstr_w((LPWSTR
)*ppMemory
));
2132 ERR("unknown array format 0x%x\n", fc
);
2133 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2137 static inline void array_memory_size(
2138 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
,
2139 unsigned char fHasPointers
)
2141 ULONG bufsize
, memsize
;
2143 unsigned char alignment
;
2148 esize
= *(const WORD
*)(pFormat
+2);
2149 alignment
= pFormat
[1] + 1;
2151 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2153 bufsize
= 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_CVARRAY
:
2165 esize
= *(const WORD
*)(pFormat
+2);
2166 alignment
= pFormat
[1] + 1;
2168 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2170 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2172 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2173 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2174 pStubMsg
->MemorySize
+= memsize
;
2176 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2178 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2179 safe_buffer_increment(pStubMsg
, bufsize
);
2182 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2184 case RPC_FC_C_CSTRING
:
2185 case RPC_FC_C_WSTRING
:
2186 if (fc
== RPC_FC_C_CSTRING
)
2191 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
2193 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
2195 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2196 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
2197 RpcRaiseException(RPC_S_INVALID_BOUND
);
2199 if (pStubMsg
->Offset
)
2201 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2202 RpcRaiseException(RPC_S_INVALID_BOUND
);
2205 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2206 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2208 validate_string_data(pStubMsg
, bufsize
, esize
);
2210 safe_buffer_increment(pStubMsg
, bufsize
);
2211 pStubMsg
->MemorySize
+= memsize
;
2214 ERR("unknown array format 0x%x\n", fc
);
2215 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2219 static inline void array_free(
2220 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
,
2221 unsigned char *pMemory
, PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
2226 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2228 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2230 case RPC_FC_CVARRAY
:
2231 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2232 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2234 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2236 case RPC_FC_C_CSTRING
:
2237 case RPC_FC_C_WSTRING
:
2238 /* No embedded pointers so nothing to do */
2241 ERR("unknown array format 0x%x\n", fc
);
2242 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2247 * NdrConformantString:
2249 * What MS calls a ConformantString is, in DCE terminology,
2250 * a Varying-Conformant String.
2252 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2253 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2254 * into unmarshalled string)
2255 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2257 * data: CHARTYPE[maxlen]
2259 * ], where CHARTYPE is the appropriate character type (specified externally)
2263 /***********************************************************************
2264 * NdrConformantStringMarshall [RPCRT4.@]
2266 unsigned char *WINAPI
NdrConformantStringMarshall(MIDL_STUB_MESSAGE
*pStubMsg
,
2267 unsigned char *pszMessage
, PFORMAT_STRING pFormat
)
2269 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg
, pszMessage
, pFormat
);
2271 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2272 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2273 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2276 /* allow compiler to optimise inline function by passing constant into
2277 * these functions */
2278 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2279 array_compute_and_write_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pszMessage
,
2281 array_write_variance_and_marshall(RPC_FC_C_CSTRING
, pStubMsg
, pszMessage
,
2282 pFormat
, TRUE
/* fHasPointers */);
2284 array_compute_and_write_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pszMessage
,
2286 array_write_variance_and_marshall(RPC_FC_C_WSTRING
, pStubMsg
, pszMessage
,
2287 pFormat
, TRUE
/* fHasPointers */);
2293 /***********************************************************************
2294 * NdrConformantStringBufferSize [RPCRT4.@]
2296 void WINAPI
NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2297 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
2299 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2301 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2302 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2303 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2306 /* allow compiler to optimise inline function by passing constant into
2307 * these functions */
2308 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2309 array_compute_and_size_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pMemory
,
2311 array_buffer_size(RPC_FC_C_CSTRING
, pStubMsg
, pMemory
, pFormat
,
2312 TRUE
/* fHasPointers */);
2314 array_compute_and_size_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pMemory
,
2316 array_buffer_size(RPC_FC_C_WSTRING
, pStubMsg
, pMemory
, pFormat
,
2317 TRUE
/* fHasPointers */);
2321 /************************************************************************
2322 * NdrConformantStringMemorySize [RPCRT4.@]
2324 ULONG WINAPI
NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
2325 PFORMAT_STRING pFormat
)
2327 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
2329 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2330 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2331 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2334 /* allow compiler to optimise inline function by passing constant into
2335 * these functions */
2336 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2337 array_read_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
);
2338 array_memory_size(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
,
2339 TRUE
/* fHasPointers */);
2341 array_read_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
);
2342 array_memory_size(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
,
2343 TRUE
/* fHasPointers */);
2346 return pStubMsg
->MemorySize
;
2349 /************************************************************************
2350 * NdrConformantStringUnmarshall [RPCRT4.@]
2352 unsigned char *WINAPI
NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2353 unsigned char** ppMemory
, PFORMAT_STRING pFormat
, unsigned char fMustAlloc
)
2355 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2356 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
2358 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2359 ERR("Unhandled string type: %#x\n", *pFormat
);
2360 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2363 /* allow compiler to optimise inline function by passing constant into
2364 * these functions */
2365 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2366 array_read_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
);
2367 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING
, pStubMsg
, ppMemory
,
2368 pFormat
, fMustAlloc
,
2369 TRUE
/* fUseBufferMemoryServer */,
2370 TRUE
/* fUnmarshall */);
2372 array_read_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
);
2373 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING
, pStubMsg
, ppMemory
,
2374 pFormat
, fMustAlloc
,
2375 TRUE
/* fUseBufferMemoryServer */,
2376 TRUE
/* fUnmarshall */);
2382 /***********************************************************************
2383 * NdrNonConformantStringMarshall [RPCRT4.@]
2385 unsigned char * WINAPI
NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2386 unsigned char *pMemory
,
2387 PFORMAT_STRING pFormat
)
2389 ULONG esize
, size
, maxsize
;
2391 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2393 maxsize
= *(USHORT
*)&pFormat
[2];
2395 if (*pFormat
== RPC_FC_CSTRING
)
2398 const char *str
= (const char *)pMemory
;
2399 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
2401 TRACE("string=%s\n", debugstr_an(str
, i
));
2402 pStubMsg
->ActualCount
= i
+ 1;
2405 else if (*pFormat
== RPC_FC_WSTRING
)
2408 const WCHAR
*str
= (const WCHAR
*)pMemory
;
2409 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
2411 TRACE("string=%s\n", debugstr_wn(str
, i
));
2412 pStubMsg
->ActualCount
= i
+ 1;
2417 ERR("Unhandled string type: %#x\n", *pFormat
);
2418 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2421 pStubMsg
->Offset
= 0;
2422 WriteVariance(pStubMsg
);
2424 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2425 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
2430 /***********************************************************************
2431 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2433 unsigned char * WINAPI
NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2434 unsigned char **ppMemory
,
2435 PFORMAT_STRING pFormat
,
2436 unsigned char fMustAlloc
)
2438 ULONG bufsize
, memsize
, esize
, maxsize
;
2440 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2441 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
2443 maxsize
= *(USHORT
*)&pFormat
[2];
2445 ReadVariance(pStubMsg
, NULL
, maxsize
);
2446 if (pStubMsg
->Offset
)
2448 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2449 RpcRaiseException(RPC_S_INVALID_BOUND
);
2452 if (*pFormat
== RPC_FC_CSTRING
) esize
= 1;
2453 else if (*pFormat
== RPC_FC_WSTRING
) esize
= 2;
2456 ERR("Unhandled string type: %#x\n", *pFormat
);
2457 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2460 memsize
= esize
* maxsize
;
2461 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2463 validate_string_data(pStubMsg
, bufsize
, esize
);
2465 if (!fMustAlloc
&& !*ppMemory
)
2468 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2470 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
2472 if (*pFormat
== RPC_FC_CSTRING
) {
2473 TRACE("string=%s\n", debugstr_an((char*)*ppMemory
, pStubMsg
->ActualCount
));
2475 else if (*pFormat
== RPC_FC_WSTRING
) {
2476 TRACE("string=%s\n", debugstr_wn((LPWSTR
)*ppMemory
, pStubMsg
->ActualCount
));
2482 /***********************************************************************
2483 * NdrNonConformantStringBufferSize [RPCRT4.@]
2485 void WINAPI
NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2486 unsigned char *pMemory
,
2487 PFORMAT_STRING pFormat
)
2489 ULONG esize
, maxsize
;
2491 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2493 maxsize
= *(USHORT
*)&pFormat
[2];
2495 SizeVariance(pStubMsg
);
2497 if (*pFormat
== RPC_FC_CSTRING
)
2500 const char *str
= (const char *)pMemory
;
2501 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
2503 TRACE("string=%s\n", debugstr_an(str
, i
));
2504 pStubMsg
->ActualCount
= i
+ 1;
2507 else if (*pFormat
== RPC_FC_WSTRING
)
2510 const WCHAR
*str
= (const WCHAR
*)pMemory
;
2511 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
2513 TRACE("string=%s\n", debugstr_wn(str
, i
));
2514 pStubMsg
->ActualCount
= i
+ 1;
2519 ERR("Unhandled string type: %#x\n", *pFormat
);
2520 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2523 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
2526 /***********************************************************************
2527 * NdrNonConformantStringMemorySize [RPCRT4.@]
2529 ULONG WINAPI
NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2530 PFORMAT_STRING pFormat
)
2532 ULONG bufsize
, memsize
, esize
, maxsize
;
2534 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
2536 maxsize
= *(USHORT
*)&pFormat
[2];
2538 ReadVariance(pStubMsg
, NULL
, maxsize
);
2540 if (pStubMsg
->Offset
)
2542 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2543 RpcRaiseException(RPC_S_INVALID_BOUND
);
2546 if (*pFormat
== RPC_FC_CSTRING
) esize
= 1;
2547 else if (*pFormat
== RPC_FC_WSTRING
) esize
= 2;
2550 ERR("Unhandled string type: %#x\n", *pFormat
);
2551 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2554 memsize
= esize
* maxsize
;
2555 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2557 validate_string_data(pStubMsg
, bufsize
, esize
);
2559 safe_buffer_increment(pStubMsg
, bufsize
);
2560 pStubMsg
->MemorySize
+= memsize
;
2562 return pStubMsg
->MemorySize
;
2567 #include "pshpack1.h"
2571 unsigned char flags_type
; /* flags in upper nibble, type in lower nibble */
2575 #include "poppack.h"
2577 static ULONG
EmbeddedComplexSize(MIDL_STUB_MESSAGE
*pStubMsg
,
2578 PFORMAT_STRING pFormat
)
2582 case RPC_FC_PSTRUCT
:
2583 case RPC_FC_CSTRUCT
:
2584 case RPC_FC_BOGUS_STRUCT
:
2585 case RPC_FC_SMFARRAY
:
2586 case RPC_FC_SMVARRAY
:
2587 case RPC_FC_CSTRING
:
2588 return *(const WORD
*)&pFormat
[2];
2589 case RPC_FC_USER_MARSHAL
:
2590 return *(const WORD
*)&pFormat
[4];
2591 case RPC_FC_RANGE
: {
2592 switch (((const NDR_RANGE
*)pFormat
)->flags_type
& 0xf) {
2597 return sizeof(UCHAR
);
2601 return sizeof(USHORT
);
2605 return sizeof(ULONG
);
2607 return sizeof(float);
2609 return sizeof(double);
2611 return sizeof(ULONGLONG
);
2613 return sizeof(UINT
);
2615 ERR("unknown type 0x%x\n", ((const NDR_RANGE
*)pFormat
)->flags_type
& 0xf);
2616 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2619 case RPC_FC_NON_ENCAPSULATED_UNION
:
2621 if (pStubMsg
->fHasNewCorrDesc
)
2626 pFormat
+= *(const SHORT
*)pFormat
;
2627 return *(const SHORT
*)pFormat
;
2629 return sizeof(void *);
2630 case RPC_FC_WSTRING
:
2631 return *(const WORD
*)&pFormat
[2] * 2;
2633 FIXME("unhandled embedded type %02x\n", *pFormat
);
2639 static ULONG
EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2640 PFORMAT_STRING pFormat
)
2642 NDR_MEMORYSIZE m
= NdrMemorySizer
[*pFormat
& NDR_TABLE_MASK
];
2646 FIXME("no memorysizer for data type=%02x\n", *pFormat
);
2650 return m(pStubMsg
, pFormat
);
2654 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2655 unsigned char *pMemory
,
2656 PFORMAT_STRING pFormat
,
2657 PFORMAT_STRING pPointer
)
2659 PFORMAT_STRING desc
;
2663 while (*pFormat
!= RPC_FC_END
) {
2669 TRACE("byte=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2670 safe_copy_to_buffer(pStubMsg
, pMemory
, 1);
2676 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2677 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
2681 TRACE("enum16=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2682 if (32767 < *(DWORD
*)pMemory
)
2683 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
2684 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
2690 TRACE("long=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2691 safe_copy_to_buffer(pStubMsg
, pMemory
, 4);
2695 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2696 safe_copy_to_buffer(pStubMsg
, pMemory
, 8);
2699 case RPC_FC_POINTER
:
2701 unsigned char *saved_buffer
;
2702 int pointer_buffer_mark_set
= 0;
2703 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
2704 TRACE("pStubMsg->Buffer before %p\n", pStubMsg
->Buffer
);
2705 if (*pPointer
!= RPC_FC_RP
)
2706 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
2707 saved_buffer
= pStubMsg
->Buffer
;
2708 if (pStubMsg
->PointerBufferMark
)
2710 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2711 pStubMsg
->PointerBufferMark
= NULL
;
2712 pointer_buffer_mark_set
= 1;
2714 else if (*pPointer
!= RPC_FC_RP
)
2715 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2716 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char**)pMemory
, pPointer
);
2717 if (pointer_buffer_mark_set
)
2719 STD_OVERFLOW_CHECK(pStubMsg
);
2720 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2721 pStubMsg
->Buffer
= saved_buffer
;
2722 if (*pPointer
!= RPC_FC_RP
)
2723 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2725 TRACE("pStubMsg->Buffer after %p\n", pStubMsg
->Buffer
);
2727 pMemory
+= sizeof(void *);
2730 case RPC_FC_ALIGNM2
:
2731 ALIGN_POINTER(pMemory
, 2);
2733 case RPC_FC_ALIGNM4
:
2734 ALIGN_POINTER(pMemory
, 4);
2736 case RPC_FC_ALIGNM8
:
2737 ALIGN_POINTER(pMemory
, 8);
2739 case RPC_FC_STRUCTPAD1
:
2740 case RPC_FC_STRUCTPAD2
:
2741 case RPC_FC_STRUCTPAD3
:
2742 case RPC_FC_STRUCTPAD4
:
2743 case RPC_FC_STRUCTPAD5
:
2744 case RPC_FC_STRUCTPAD6
:
2745 case RPC_FC_STRUCTPAD7
:
2746 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2748 case RPC_FC_EMBEDDED_COMPLEX
:
2749 pMemory
+= pFormat
[1];
2751 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2752 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2753 TRACE("embedded complex (size=%d) <= %p\n", size
, pMemory
);
2754 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
2757 /* for some reason interface pointers aren't generated as
2758 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2759 * they still need the derefencing treatment that pointers are
2761 if (*desc
== RPC_FC_IP
)
2762 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2764 m(pStubMsg
, pMemory
, desc
);
2766 else FIXME("no marshaller for embedded type %02x\n", *desc
);
2773 FIXME("unhandled format 0x%02x\n", *pFormat
);
2781 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2782 unsigned char *pMemory
,
2783 PFORMAT_STRING pFormat
,
2784 PFORMAT_STRING pPointer
,
2785 unsigned char fMustAlloc
)
2787 PFORMAT_STRING desc
;
2791 while (*pFormat
!= RPC_FC_END
) {
2797 safe_copy_from_buffer(pStubMsg
, pMemory
, 1);
2798 TRACE("byte=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2804 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
2805 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2809 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
2810 *(DWORD
*)pMemory
&= 0xffff;
2811 TRACE("enum16=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
2812 if (32767 < *(DWORD
*)pMemory
)
2813 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
2819 safe_copy_from_buffer(pStubMsg
, pMemory
, 4);
2820 TRACE("long=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
2824 safe_copy_from_buffer(pStubMsg
, pMemory
, 8);
2825 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2828 case RPC_FC_POINTER
:
2830 unsigned char *saved_buffer
;
2831 int pointer_buffer_mark_set
= 0;
2832 TRACE("pointer => %p\n", pMemory
);
2833 if (*pPointer
!= RPC_FC_RP
)
2834 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2835 saved_buffer
= pStubMsg
->Buffer
;
2836 if (pStubMsg
->PointerBufferMark
)
2838 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2839 pStubMsg
->PointerBufferMark
= NULL
;
2840 pointer_buffer_mark_set
= 1;
2842 else if (*pPointer
!= RPC_FC_RP
)
2843 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2845 PointerUnmarshall(pStubMsg
, saved_buffer
, (unsigned char**)pMemory
, *(unsigned char**)pMemory
, pPointer
, fMustAlloc
);
2846 if (pointer_buffer_mark_set
)
2848 STD_OVERFLOW_CHECK(pStubMsg
);
2849 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2850 pStubMsg
->Buffer
= saved_buffer
;
2851 if (*pPointer
!= RPC_FC_RP
)
2852 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2855 pMemory
+= sizeof(void *);
2858 case RPC_FC_ALIGNM2
:
2859 ALIGN_POINTER_CLEAR(pMemory
, 2);
2861 case RPC_FC_ALIGNM4
:
2862 ALIGN_POINTER_CLEAR(pMemory
, 4);
2864 case RPC_FC_ALIGNM8
:
2865 ALIGN_POINTER_CLEAR(pMemory
, 8);
2867 case RPC_FC_STRUCTPAD1
:
2868 case RPC_FC_STRUCTPAD2
:
2869 case RPC_FC_STRUCTPAD3
:
2870 case RPC_FC_STRUCTPAD4
:
2871 case RPC_FC_STRUCTPAD5
:
2872 case RPC_FC_STRUCTPAD6
:
2873 case RPC_FC_STRUCTPAD7
:
2874 memset(pMemory
, 0, *pFormat
- RPC_FC_STRUCTPAD1
+ 1);
2875 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2877 case RPC_FC_EMBEDDED_COMPLEX
:
2878 pMemory
+= pFormat
[1];
2880 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2881 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2882 TRACE("embedded complex (size=%d) => %p\n", size
, pMemory
);
2884 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
2885 * since the type is part of the memory block that is encompassed by
2886 * the whole complex type. Memory is forced to allocate when pointers
2887 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
2888 * clearing the memory we pass in to the unmarshaller */
2889 memset(pMemory
, 0, size
);
2890 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
2893 /* for some reason interface pointers aren't generated as
2894 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2895 * they still need the derefencing treatment that pointers are
2897 if (*desc
== RPC_FC_IP
)
2898 m(pStubMsg
, (unsigned char **)pMemory
, desc
, FALSE
);
2900 m(pStubMsg
, &pMemory
, desc
, FALSE
);
2902 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
2909 FIXME("unhandled format %d\n", *pFormat
);
2917 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2918 unsigned char *pMemory
,
2919 PFORMAT_STRING pFormat
,
2920 PFORMAT_STRING pPointer
)
2922 PFORMAT_STRING desc
;
2926 while (*pFormat
!= RPC_FC_END
) {
2932 safe_buffer_length_increment(pStubMsg
, 1);
2938 safe_buffer_length_increment(pStubMsg
, 2);
2942 safe_buffer_length_increment(pStubMsg
, 2);
2948 safe_buffer_length_increment(pStubMsg
, 4);
2952 safe_buffer_length_increment(pStubMsg
, 8);
2955 case RPC_FC_POINTER
:
2956 if (!pStubMsg
->IgnoreEmbeddedPointers
)
2958 int saved_buffer_length
= pStubMsg
->BufferLength
;
2959 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2960 pStubMsg
->PointerLength
= 0;
2961 if(!pStubMsg
->BufferLength
)
2962 ERR("BufferLength == 0??\n");
2963 PointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
2964 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2965 pStubMsg
->BufferLength
= saved_buffer_length
;
2967 if (*pPointer
!= RPC_FC_RP
)
2969 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
2970 safe_buffer_length_increment(pStubMsg
, 4);
2973 pMemory
+= sizeof(void*);
2975 case RPC_FC_ALIGNM2
:
2976 ALIGN_POINTER(pMemory
, 2);
2978 case RPC_FC_ALIGNM4
:
2979 ALIGN_POINTER(pMemory
, 4);
2981 case RPC_FC_ALIGNM8
:
2982 ALIGN_POINTER(pMemory
, 8);
2984 case RPC_FC_STRUCTPAD1
:
2985 case RPC_FC_STRUCTPAD2
:
2986 case RPC_FC_STRUCTPAD3
:
2987 case RPC_FC_STRUCTPAD4
:
2988 case RPC_FC_STRUCTPAD5
:
2989 case RPC_FC_STRUCTPAD6
:
2990 case RPC_FC_STRUCTPAD7
:
2991 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2993 case RPC_FC_EMBEDDED_COMPLEX
:
2994 pMemory
+= pFormat
[1];
2996 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2997 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2998 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
3001 /* for some reason interface pointers aren't generated as
3002 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3003 * they still need the derefencing treatment that pointers are
3005 if (*desc
== RPC_FC_IP
)
3006 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
3008 m(pStubMsg
, pMemory
, desc
);
3010 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
3017 FIXME("unhandled format 0x%02x\n", *pFormat
);
3025 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
3026 unsigned char *pMemory
,
3027 PFORMAT_STRING pFormat
,
3028 PFORMAT_STRING pPointer
)
3030 PFORMAT_STRING desc
;
3034 while (*pFormat
!= RPC_FC_END
) {
3056 case RPC_FC_POINTER
:
3057 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
3059 pMemory
+= sizeof(void *);
3061 case RPC_FC_ALIGNM2
:
3062 ALIGN_POINTER(pMemory
, 2);
3064 case RPC_FC_ALIGNM4
:
3065 ALIGN_POINTER(pMemory
, 4);
3067 case RPC_FC_ALIGNM8
:
3068 ALIGN_POINTER(pMemory
, 8);
3070 case RPC_FC_STRUCTPAD1
:
3071 case RPC_FC_STRUCTPAD2
:
3072 case RPC_FC_STRUCTPAD3
:
3073 case RPC_FC_STRUCTPAD4
:
3074 case RPC_FC_STRUCTPAD5
:
3075 case RPC_FC_STRUCTPAD6
:
3076 case RPC_FC_STRUCTPAD7
:
3077 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3079 case RPC_FC_EMBEDDED_COMPLEX
:
3080 pMemory
+= pFormat
[1];
3082 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3083 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3084 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
3087 /* for some reason interface pointers aren't generated as
3088 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3089 * they still need the derefencing treatment that pointers are
3091 if (*desc
== RPC_FC_IP
)
3092 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
3094 m(pStubMsg
, pMemory
, desc
);
3102 FIXME("unhandled format 0x%02x\n", *pFormat
);
3110 static ULONG
ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3111 PFORMAT_STRING pFormat
,
3112 PFORMAT_STRING pPointer
)
3114 PFORMAT_STRING desc
;
3117 while (*pFormat
!= RPC_FC_END
) {
3124 safe_buffer_increment(pStubMsg
, 1);
3130 safe_buffer_increment(pStubMsg
, 2);
3134 safe_buffer_increment(pStubMsg
, 2);
3140 safe_buffer_increment(pStubMsg
, 4);
3144 safe_buffer_increment(pStubMsg
, 8);
3146 case RPC_FC_POINTER
:
3148 unsigned char *saved_buffer
;
3149 int pointer_buffer_mark_set
= 0;
3150 if (*pPointer
!= RPC_FC_RP
)
3151 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3152 saved_buffer
= pStubMsg
->Buffer
;
3153 if (pStubMsg
->PointerBufferMark
)
3155 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3156 pStubMsg
->PointerBufferMark
= NULL
;
3157 pointer_buffer_mark_set
= 1;
3159 else if (*pPointer
!= RPC_FC_RP
)
3160 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3162 if (!pStubMsg
->IgnoreEmbeddedPointers
)
3163 PointerMemorySize(pStubMsg
, saved_buffer
, pPointer
);
3164 if (pointer_buffer_mark_set
)
3166 STD_OVERFLOW_CHECK(pStubMsg
);
3167 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3168 pStubMsg
->Buffer
= saved_buffer
;
3169 if (*pPointer
!= RPC_FC_RP
)
3170 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3173 size
+= sizeof(void *);
3176 case RPC_FC_ALIGNM2
:
3177 ALIGN_LENGTH(size
, 2);
3179 case RPC_FC_ALIGNM4
:
3180 ALIGN_LENGTH(size
, 4);
3182 case RPC_FC_ALIGNM8
:
3183 ALIGN_LENGTH(size
, 8);
3185 case RPC_FC_STRUCTPAD1
:
3186 case RPC_FC_STRUCTPAD2
:
3187 case RPC_FC_STRUCTPAD3
:
3188 case RPC_FC_STRUCTPAD4
:
3189 case RPC_FC_STRUCTPAD5
:
3190 case RPC_FC_STRUCTPAD6
:
3191 case RPC_FC_STRUCTPAD7
:
3192 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3194 case RPC_FC_EMBEDDED_COMPLEX
:
3197 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3198 size
+= EmbeddedComplexMemorySize(pStubMsg
, desc
);
3204 FIXME("unhandled format 0x%02x\n", *pFormat
);
3212 ULONG
ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
3214 PFORMAT_STRING desc
;
3217 while (*pFormat
!= RPC_FC_END
) {
3239 case RPC_FC_POINTER
:
3240 size
+= sizeof(void *);
3242 case RPC_FC_ALIGNM2
:
3243 ALIGN_LENGTH(size
, 2);
3245 case RPC_FC_ALIGNM4
:
3246 ALIGN_LENGTH(size
, 4);
3248 case RPC_FC_ALIGNM8
:
3249 ALIGN_LENGTH(size
, 8);
3251 case RPC_FC_STRUCTPAD1
:
3252 case RPC_FC_STRUCTPAD2
:
3253 case RPC_FC_STRUCTPAD3
:
3254 case RPC_FC_STRUCTPAD4
:
3255 case RPC_FC_STRUCTPAD5
:
3256 case RPC_FC_STRUCTPAD6
:
3257 case RPC_FC_STRUCTPAD7
:
3258 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3260 case RPC_FC_EMBEDDED_COMPLEX
:
3263 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3264 size
+= EmbeddedComplexSize(pStubMsg
, desc
);
3270 FIXME("unhandled format 0x%02x\n", *pFormat
);
3278 /***********************************************************************
3279 * NdrComplexStructMarshall [RPCRT4.@]
3281 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3282 unsigned char *pMemory
,
3283 PFORMAT_STRING pFormat
)
3285 PFORMAT_STRING conf_array
= NULL
;
3286 PFORMAT_STRING pointer_desc
= NULL
;
3287 unsigned char *OldMemory
= pStubMsg
->Memory
;
3288 int pointer_buffer_mark_set
= 0;
3290 ULONG max_count
= 0;
3293 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3295 if (!pStubMsg
->PointerBufferMark
)
3297 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3298 /* save buffer length */
3299 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
3301 /* get the buffer pointer after complex array data, but before
3303 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
;
3304 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3305 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
3306 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3308 /* save it for use by embedded pointer code later */
3309 pStubMsg
->PointerBufferMark
= (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
;
3310 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->PointerBufferMark
- pStubMsg
->Buffer
));
3311 pointer_buffer_mark_set
= 1;
3313 /* restore the original buffer length */
3314 pStubMsg
->BufferLength
= saved_buffer_length
;
3317 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pFormat
[1] + 1);
3320 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3322 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3325 pStubMsg
->Memory
= pMemory
;
3329 ULONG struct_size
= ComplexStructSize(pStubMsg
, pFormat
);
3330 array_compute_and_write_conformance(conf_array
[0], pStubMsg
,
3331 pMemory
+ struct_size
, conf_array
);
3332 /* these could be changed in ComplexMarshall so save them for later */
3333 max_count
= pStubMsg
->MaxCount
;
3334 count
= pStubMsg
->ActualCount
;
3335 offset
= pStubMsg
->Offset
;
3338 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3342 pStubMsg
->MaxCount
= max_count
;
3343 pStubMsg
->ActualCount
= count
;
3344 pStubMsg
->Offset
= offset
;
3345 array_write_variance_and_marshall(conf_array
[0], pStubMsg
, pMemory
,
3346 conf_array
, TRUE
/* fHasPointers */);
3349 pStubMsg
->Memory
= OldMemory
;
3351 if (pointer_buffer_mark_set
)
3353 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3354 pStubMsg
->PointerBufferMark
= NULL
;
3357 STD_OVERFLOW_CHECK(pStubMsg
);
3362 /***********************************************************************
3363 * NdrComplexStructUnmarshall [RPCRT4.@]
3365 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3366 unsigned char **ppMemory
,
3367 PFORMAT_STRING pFormat
,
3368 unsigned char fMustAlloc
)
3370 unsigned size
= *(const WORD
*)(pFormat
+2);
3371 PFORMAT_STRING conf_array
= NULL
;
3372 PFORMAT_STRING pointer_desc
= NULL
;
3373 unsigned char *pMemory
;
3374 int pointer_buffer_mark_set
= 0;
3376 ULONG max_count
= 0;
3378 ULONG array_size
= 0;
3380 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3382 if (!pStubMsg
->PointerBufferMark
)
3384 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3385 /* save buffer pointer */
3386 unsigned char *saved_buffer
= pStubMsg
->Buffer
;
3388 /* get the buffer pointer after complex array data, but before
3390 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3391 NdrComplexStructMemorySize(pStubMsg
, pFormat
);
3392 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3394 /* save it for use by embedded pointer code later */
3395 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3396 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->PointerBufferMark
- saved_buffer
));
3397 pointer_buffer_mark_set
= 1;
3399 /* restore the original buffer */
3400 pStubMsg
->Buffer
= saved_buffer
;
3403 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
3406 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3408 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3413 array_size
= array_read_conformance(conf_array
[0], pStubMsg
, conf_array
);
3416 /* these could be changed in ComplexMarshall so save them for later */
3417 max_count
= pStubMsg
->MaxCount
;
3418 count
= pStubMsg
->ActualCount
;
3419 offset
= pStubMsg
->Offset
;
3422 if (!fMustAlloc
&& !*ppMemory
)
3425 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3427 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
, fMustAlloc
);
3431 pStubMsg
->MaxCount
= max_count
;
3432 pStubMsg
->ActualCount
= count
;
3433 pStubMsg
->Offset
= offset
;
3435 memset(pMemory
, 0, array_size
);
3436 array_read_variance_and_unmarshall(conf_array
[0], pStubMsg
, &pMemory
,
3438 FALSE
/* fUseBufferMemoryServer */,
3439 TRUE
/* fUnmarshall */);
3442 if (pointer_buffer_mark_set
)
3444 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3445 pStubMsg
->PointerBufferMark
= NULL
;
3451 /***********************************************************************
3452 * NdrComplexStructBufferSize [RPCRT4.@]
3454 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3455 unsigned char *pMemory
,
3456 PFORMAT_STRING pFormat
)
3458 PFORMAT_STRING conf_array
= NULL
;
3459 PFORMAT_STRING pointer_desc
= NULL
;
3460 unsigned char *OldMemory
= pStubMsg
->Memory
;
3461 int pointer_length_set
= 0;
3463 ULONG max_count
= 0;
3466 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3468 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
3470 if(!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
3472 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3473 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
3475 /* get the buffer length after complex struct data, but before
3477 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3478 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
3479 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3481 /* save it for use by embedded pointer code later */
3482 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3483 pointer_length_set
= 1;
3484 TRACE("difference = 0x%x\n", pStubMsg
->PointerLength
- saved_buffer_length
);
3486 /* restore the original buffer length */
3487 pStubMsg
->BufferLength
= saved_buffer_length
;
3491 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3493 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3496 pStubMsg
->Memory
= pMemory
;
3500 ULONG struct_size
= ComplexStructSize(pStubMsg
, pFormat
);
3501 array_compute_and_size_conformance(conf_array
[0], pStubMsg
, pMemory
+ struct_size
,
3504 /* these could be changed in ComplexMarshall so save them for later */
3505 max_count
= pStubMsg
->MaxCount
;
3506 count
= pStubMsg
->ActualCount
;
3507 offset
= pStubMsg
->Offset
;
3510 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3514 pStubMsg
->MaxCount
= max_count
;
3515 pStubMsg
->ActualCount
= count
;
3516 pStubMsg
->Offset
= offset
;
3517 array_buffer_size(conf_array
[0], pStubMsg
, pMemory
, conf_array
,
3518 TRUE
/* fHasPointers */);
3521 pStubMsg
->Memory
= OldMemory
;
3523 if(pointer_length_set
)
3525 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3526 pStubMsg
->PointerLength
= 0;
3531 /***********************************************************************
3532 * NdrComplexStructMemorySize [RPCRT4.@]
3534 ULONG WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3535 PFORMAT_STRING pFormat
)
3537 unsigned size
= *(const WORD
*)(pFormat
+2);
3538 PFORMAT_STRING conf_array
= NULL
;
3539 PFORMAT_STRING pointer_desc
= NULL
;
3541 ULONG max_count
= 0;
3544 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3546 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
3549 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3551 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3556 array_read_conformance(conf_array
[0], pStubMsg
, conf_array
);
3558 /* these could be changed in ComplexStructMemorySize so save them for
3560 max_count
= pStubMsg
->MaxCount
;
3561 count
= pStubMsg
->ActualCount
;
3562 offset
= pStubMsg
->Offset
;
3565 ComplexStructMemorySize(pStubMsg
, pFormat
, pointer_desc
);
3569 pStubMsg
->MaxCount
= max_count
;
3570 pStubMsg
->ActualCount
= count
;
3571 pStubMsg
->Offset
= offset
;
3572 array_memory_size(conf_array
[0], pStubMsg
, conf_array
,
3573 TRUE
/* fHasPointers */);
3579 /***********************************************************************
3580 * NdrComplexStructFree [RPCRT4.@]
3582 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3583 unsigned char *pMemory
,
3584 PFORMAT_STRING pFormat
)
3586 PFORMAT_STRING conf_array
= NULL
;
3587 PFORMAT_STRING pointer_desc
= NULL
;
3588 unsigned char *OldMemory
= pStubMsg
->Memory
;
3590 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3593 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3595 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3598 pStubMsg
->Memory
= pMemory
;
3600 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3603 array_free(conf_array
[0], pStubMsg
, pMemory
, conf_array
,
3604 TRUE
/* fHasPointers */);
3606 pStubMsg
->Memory
= OldMemory
;
3609 /***********************************************************************
3610 * NdrConformantArrayMarshall [RPCRT4.@]
3612 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3613 unsigned char *pMemory
,
3614 PFORMAT_STRING pFormat
)
3616 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3617 if (pFormat
[0] != RPC_FC_CARRAY
)
3619 ERR("invalid format = 0x%x\n", pFormat
[0]);
3620 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3623 array_compute_and_write_conformance(RPC_FC_CARRAY
, pStubMsg
, pMemory
,
3625 array_write_variance_and_marshall(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3626 TRUE
/* fHasPointers */);
3631 /***********************************************************************
3632 * NdrConformantArrayUnmarshall [RPCRT4.@]
3634 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3635 unsigned char **ppMemory
,
3636 PFORMAT_STRING pFormat
,
3637 unsigned char fMustAlloc
)
3639 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3640 if (pFormat
[0] != RPC_FC_CARRAY
)
3642 ERR("invalid format = 0x%x\n", pFormat
[0]);
3643 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3646 array_read_conformance(RPC_FC_CARRAY
, pStubMsg
, pFormat
);
3647 array_read_variance_and_unmarshall(RPC_FC_CARRAY
, pStubMsg
, ppMemory
, pFormat
,
3649 TRUE
/* fUseBufferMemoryServer */,
3650 TRUE
/* fUnmarshall */);
3655 /***********************************************************************
3656 * NdrConformantArrayBufferSize [RPCRT4.@]
3658 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3659 unsigned char *pMemory
,
3660 PFORMAT_STRING pFormat
)
3662 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3663 if (pFormat
[0] != RPC_FC_CARRAY
)
3665 ERR("invalid format = 0x%x\n", pFormat
[0]);
3666 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3669 array_compute_and_size_conformance(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
);
3670 array_buffer_size(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3671 TRUE
/* fHasPointers */);
3674 /***********************************************************************
3675 * NdrConformantArrayMemorySize [RPCRT4.@]
3677 ULONG WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3678 PFORMAT_STRING pFormat
)
3680 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3681 if (pFormat
[0] != RPC_FC_CARRAY
)
3683 ERR("invalid format = 0x%x\n", pFormat
[0]);
3684 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3687 array_read_conformance(RPC_FC_CARRAY
, pStubMsg
, pFormat
);
3688 array_memory_size(RPC_FC_CARRAY
, pStubMsg
, pFormat
, TRUE
/* fHasPointers */);
3690 return pStubMsg
->MemorySize
;
3693 /***********************************************************************
3694 * NdrConformantArrayFree [RPCRT4.@]
3696 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3697 unsigned char *pMemory
,
3698 PFORMAT_STRING pFormat
)
3700 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3701 if (pFormat
[0] != RPC_FC_CARRAY
)
3703 ERR("invalid format = 0x%x\n", pFormat
[0]);
3704 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3707 array_free(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3708 TRUE
/* fHasPointers */);
3712 /***********************************************************************
3713 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3715 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
3716 unsigned char* pMemory
,
3717 PFORMAT_STRING pFormat
)
3719 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3721 if (pFormat
[0] != RPC_FC_CVARRAY
)
3723 ERR("invalid format type %x\n", pFormat
[0]);
3724 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3728 array_compute_and_write_conformance(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
3730 array_write_variance_and_marshall(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
3731 pFormat
, TRUE
/* fHasPointers */);
3737 /***********************************************************************
3738 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
3740 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
3741 unsigned char** ppMemory
,
3742 PFORMAT_STRING pFormat
,
3743 unsigned char fMustAlloc
)
3745 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3747 if (pFormat
[0] != RPC_FC_CVARRAY
)
3749 ERR("invalid format type %x\n", pFormat
[0]);
3750 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3754 array_read_conformance(RPC_FC_CVARRAY
, pStubMsg
, pFormat
);
3755 array_read_variance_and_unmarshall(RPC_FC_CVARRAY
, pStubMsg
, ppMemory
,
3756 pFormat
, fMustAlloc
,
3757 TRUE
/* fUseBufferMemoryServer */,
3758 TRUE
/* fUnmarshall */);
3764 /***********************************************************************
3765 * NdrConformantVaryingArrayFree [RPCRT4.@]
3767 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
3768 unsigned char* pMemory
,
3769 PFORMAT_STRING pFormat
)
3771 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3773 if (pFormat
[0] != RPC_FC_CVARRAY
)
3775 ERR("invalid format type %x\n", pFormat
[0]);
3776 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3780 array_free(RPC_FC_CVARRAY
, pStubMsg
, pMemory
, pFormat
,
3781 TRUE
/* fHasPointers */);
3785 /***********************************************************************
3786 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
3788 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
3789 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
3791 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3793 if (pFormat
[0] != RPC_FC_CVARRAY
)
3795 ERR("invalid format type %x\n", pFormat
[0]);
3796 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3800 array_compute_and_size_conformance(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
3802 array_buffer_size(RPC_FC_CVARRAY
, pStubMsg
, pMemory
, pFormat
,
3803 TRUE
/* fHasPointers */);
3807 /***********************************************************************
3808 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
3810 ULONG WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
3811 PFORMAT_STRING pFormat
)
3813 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
3815 if (pFormat
[0] != RPC_FC_CVARRAY
)
3817 ERR("invalid format type %x\n", pFormat
[0]);
3818 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3819 return pStubMsg
->MemorySize
;
3822 array_read_conformance(RPC_FC_CVARRAY
, pStubMsg
, pFormat
);
3823 array_memory_size(RPC_FC_CVARRAY
, pStubMsg
, pFormat
,
3824 TRUE
/* fHasPointers */);
3826 return pStubMsg
->MemorySize
;
3830 /***********************************************************************
3831 * NdrComplexArrayMarshall [RPCRT4.@]
3833 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3834 unsigned char *pMemory
,
3835 PFORMAT_STRING pFormat
)
3837 ULONG i
, count
, def
;
3838 BOOL variance_present
;
3839 unsigned char alignment
;
3840 int pointer_buffer_mark_set
= 0;
3842 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3844 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3846 ERR("invalid format type %x\n", pFormat
[0]);
3847 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3851 alignment
= pFormat
[1] + 1;
3853 if (!pStubMsg
->PointerBufferMark
)
3855 /* save buffer fields that may be changed by buffer sizer functions
3856 * and that may be needed later on */
3857 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3858 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
3859 ULONG_PTR saved_max_count
= pStubMsg
->MaxCount
;
3860 ULONG saved_offset
= pStubMsg
->Offset
;
3861 ULONG saved_actual_count
= pStubMsg
->ActualCount
;
3863 /* get the buffer pointer after complex array data, but before
3865 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
;
3866 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3867 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
3868 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3870 /* save it for use by embedded pointer code later */
3871 pStubMsg
->PointerBufferMark
= (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
;
3872 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
));
3873 pointer_buffer_mark_set
= 1;
3875 /* restore fields */
3876 pStubMsg
->ActualCount
= saved_actual_count
;
3877 pStubMsg
->Offset
= saved_offset
;
3878 pStubMsg
->MaxCount
= saved_max_count
;
3879 pStubMsg
->BufferLength
= saved_buffer_length
;
3882 def
= *(const WORD
*)&pFormat
[2];
3885 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3886 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3888 variance_present
= IsConformanceOrVariancePresent(pFormat
);
3889 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3890 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3892 WriteConformance(pStubMsg
);
3893 if (variance_present
)
3894 WriteVariance(pStubMsg
);
3896 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
3898 count
= pStubMsg
->ActualCount
;
3899 for (i
= 0; i
< count
; i
++)
3900 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
3902 STD_OVERFLOW_CHECK(pStubMsg
);
3904 if (pointer_buffer_mark_set
)
3906 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3907 pStubMsg
->PointerBufferMark
= NULL
;
3913 /***********************************************************************
3914 * NdrComplexArrayUnmarshall [RPCRT4.@]
3916 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3917 unsigned char **ppMemory
,
3918 PFORMAT_STRING pFormat
,
3919 unsigned char fMustAlloc
)
3921 ULONG i
, count
, size
;
3922 unsigned char alignment
;
3923 unsigned char *pMemory
;
3924 unsigned char *saved_buffer
;
3925 int pointer_buffer_mark_set
= 0;
3926 int saved_ignore_embedded
;
3928 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3930 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3932 ERR("invalid format type %x\n", pFormat
[0]);
3933 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3937 alignment
= pFormat
[1] + 1;
3939 saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3940 /* save buffer pointer */
3941 saved_buffer
= pStubMsg
->Buffer
;
3942 /* get the buffer pointer after complex array data, but before
3944 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3945 pStubMsg
->MemorySize
= 0;
3946 NdrComplexArrayMemorySize(pStubMsg
, pFormat
);
3947 size
= pStubMsg
->MemorySize
;
3948 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3950 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->Buffer
- saved_buffer
));
3951 if (!pStubMsg
->PointerBufferMark
)
3953 /* save it for use by embedded pointer code later */
3954 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3955 pointer_buffer_mark_set
= 1;
3957 /* restore the original buffer */
3958 pStubMsg
->Buffer
= saved_buffer
;
3962 pFormat
= ReadConformance(pStubMsg
, pFormat
);
3963 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3965 if (!fMustAlloc
&& !*ppMemory
)
3968 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3970 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3972 pMemory
= *ppMemory
;
3973 count
= pStubMsg
->ActualCount
;
3974 for (i
= 0; i
< count
; i
++)
3975 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
, fMustAlloc
);
3977 if (pointer_buffer_mark_set
)
3979 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3980 pStubMsg
->PointerBufferMark
= NULL
;
3986 /***********************************************************************
3987 * NdrComplexArrayBufferSize [RPCRT4.@]
3989 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3990 unsigned char *pMemory
,
3991 PFORMAT_STRING pFormat
)
3993 ULONG i
, count
, def
;
3994 unsigned char alignment
;
3995 BOOL variance_present
;
3996 int pointer_length_set
= 0;
3998 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4000 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4002 ERR("invalid format type %x\n", pFormat
[0]);
4003 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4007 alignment
= pFormat
[1] + 1;
4009 if (!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
4011 /* save buffer fields that may be changed by buffer sizer functions
4012 * and that may be needed later on */
4013 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
4014 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
4015 ULONG_PTR saved_max_count
= pStubMsg
->MaxCount
;
4016 ULONG saved_offset
= pStubMsg
->Offset
;
4017 ULONG saved_actual_count
= pStubMsg
->ActualCount
;
4019 /* get the buffer pointer after complex array data, but before
4021 pStubMsg
->IgnoreEmbeddedPointers
= 1;
4022 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
4023 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
4025 /* save it for use by embedded pointer code later */
4026 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4027 pointer_length_set
= 1;
4029 /* restore fields */
4030 pStubMsg
->ActualCount
= saved_actual_count
;
4031 pStubMsg
->Offset
= saved_offset
;
4032 pStubMsg
->MaxCount
= saved_max_count
;
4033 pStubMsg
->BufferLength
= saved_buffer_length
;
4035 def
= *(const WORD
*)&pFormat
[2];
4038 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
4039 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
4040 SizeConformance(pStubMsg
);
4042 variance_present
= IsConformanceOrVariancePresent(pFormat
);
4043 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
4044 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
4046 if (variance_present
)
4047 SizeVariance(pStubMsg
);
4049 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
4051 count
= pStubMsg
->ActualCount
;
4052 for (i
= 0; i
< count
; i
++)
4053 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
4055 if(pointer_length_set
)
4057 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4058 pStubMsg
->PointerLength
= 0;
4062 /***********************************************************************
4063 * NdrComplexArrayMemorySize [RPCRT4.@]
4065 ULONG WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4066 PFORMAT_STRING pFormat
)
4068 ULONG i
, count
, esize
, SavedMemorySize
, MemorySize
;
4069 unsigned char alignment
;
4071 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
4073 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4075 ERR("invalid format type %x\n", pFormat
[0]);
4076 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4080 alignment
= pFormat
[1] + 1;
4084 pFormat
= ReadConformance(pStubMsg
, pFormat
);
4085 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
4087 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4089 SavedMemorySize
= pStubMsg
->MemorySize
;
4091 esize
= ComplexStructSize(pStubMsg
, pFormat
);
4093 MemorySize
= safe_multiply(pStubMsg
->MaxCount
, esize
);
4095 count
= pStubMsg
->ActualCount
;
4096 for (i
= 0; i
< count
; i
++)
4097 ComplexStructMemorySize(pStubMsg
, pFormat
, NULL
);
4099 pStubMsg
->MemorySize
= SavedMemorySize
;
4101 pStubMsg
->MemorySize
+= MemorySize
;
4105 /***********************************************************************
4106 * NdrComplexArrayFree [RPCRT4.@]
4108 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4109 unsigned char *pMemory
,
4110 PFORMAT_STRING pFormat
)
4112 ULONG i
, count
, def
;
4114 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4116 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4118 ERR("invalid format type %x\n", pFormat
[0]);
4119 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4123 def
= *(const WORD
*)&pFormat
[2];
4126 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
4127 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
4129 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
4130 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
4132 count
= pStubMsg
->ActualCount
;
4133 for (i
= 0; i
< count
; i
++)
4134 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
4137 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg
,
4138 USER_MARSHAL_CB_TYPE cbtype
, PFORMAT_STRING pFormat
,
4139 USER_MARSHAL_CB
*umcb
)
4141 umcb
->Flags
= MAKELONG(pStubMsg
->dwDestContext
,
4142 pStubMsg
->RpcMsg
->DataRepresentation
);
4143 umcb
->pStubMsg
= pStubMsg
;
4144 umcb
->pReserve
= NULL
;
4145 umcb
->Signature
= USER_MARSHAL_CB_SIGNATURE
;
4146 umcb
->CBType
= cbtype
;
4147 umcb
->pFormat
= pFormat
;
4148 umcb
->pTypeFormat
= NULL
/* FIXME */;
4151 #define USER_MARSHAL_PTR_PREFIX \
4152 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4153 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4155 /***********************************************************************
4156 * NdrUserMarshalMarshall [RPCRT4.@]
4158 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4159 unsigned char *pMemory
,
4160 PFORMAT_STRING pFormat
)
4162 unsigned flags
= pFormat
[1];
4163 unsigned index
= *(const WORD
*)&pFormat
[2];
4164 unsigned char *saved_buffer
= NULL
;
4165 USER_MARSHAL_CB umcb
;
4167 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4168 TRACE("index=%d\n", index
);
4170 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_MARSHALL
, pFormat
, &umcb
);
4172 if (flags
& USER_MARSHAL_POINTER
)
4174 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
4175 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, USER_MARSHAL_PTR_PREFIX
);
4176 pStubMsg
->Buffer
+= 4;
4177 if (pStubMsg
->PointerBufferMark
)
4179 saved_buffer
= pStubMsg
->Buffer
;
4180 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4181 pStubMsg
->PointerBufferMark
= NULL
;
4183 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 8);
4186 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4189 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
4190 &umcb
.Flags
, pStubMsg
->Buffer
, pMemory
);
4194 STD_OVERFLOW_CHECK(pStubMsg
);
4195 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4196 pStubMsg
->Buffer
= saved_buffer
;
4199 STD_OVERFLOW_CHECK(pStubMsg
);
4204 /***********************************************************************
4205 * NdrUserMarshalUnmarshall [RPCRT4.@]
4207 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4208 unsigned char **ppMemory
,
4209 PFORMAT_STRING pFormat
,
4210 unsigned char fMustAlloc
)
4212 unsigned flags
= pFormat
[1];
4213 unsigned index
= *(const WORD
*)&pFormat
[2];
4214 DWORD memsize
= *(const WORD
*)&pFormat
[4];
4215 unsigned char *saved_buffer
= NULL
;
4216 USER_MARSHAL_CB umcb
;
4218 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4219 TRACE("index=%d\n", index
);
4221 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_UNMARSHALL
, pFormat
, &umcb
);
4223 if (flags
& USER_MARSHAL_POINTER
)
4225 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4226 /* skip pointer prefix */
4227 pStubMsg
->Buffer
+= 4;
4228 if (pStubMsg
->PointerBufferMark
)
4230 saved_buffer
= pStubMsg
->Buffer
;
4231 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4232 pStubMsg
->PointerBufferMark
= NULL
;
4234 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
4237 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4239 if (!fMustAlloc
&& !*ppMemory
)
4243 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
4244 memset(*ppMemory
, 0, memsize
);
4248 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
4249 &umcb
.Flags
, pStubMsg
->Buffer
, *ppMemory
);
4253 STD_OVERFLOW_CHECK(pStubMsg
);
4254 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4255 pStubMsg
->Buffer
= saved_buffer
;
4261 /***********************************************************************
4262 * NdrUserMarshalBufferSize [RPCRT4.@]
4264 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4265 unsigned char *pMemory
,
4266 PFORMAT_STRING pFormat
)
4268 unsigned flags
= pFormat
[1];
4269 unsigned index
= *(const WORD
*)&pFormat
[2];
4270 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
4271 USER_MARSHAL_CB umcb
;
4272 ULONG saved_buffer_length
= 0;
4274 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4275 TRACE("index=%d\n", index
);
4277 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_BUFFER_SIZE
, pFormat
, &umcb
);
4279 if (flags
& USER_MARSHAL_POINTER
)
4281 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
4282 /* skip pointer prefix */
4283 safe_buffer_length_increment(pStubMsg
, 4);
4284 if (pStubMsg
->IgnoreEmbeddedPointers
)
4286 if (pStubMsg
->PointerLength
)
4288 saved_buffer_length
= pStubMsg
->BufferLength
;
4289 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4290 pStubMsg
->PointerLength
= 0;
4292 ALIGN_LENGTH(pStubMsg
->BufferLength
, 8);
4295 ALIGN_LENGTH(pStubMsg
->BufferLength
, (flags
& 0xf) + 1);
4298 TRACE("size=%d\n", bufsize
);
4299 safe_buffer_length_increment(pStubMsg
, bufsize
);
4302 pStubMsg
->BufferLength
=
4303 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
4304 &umcb
.Flags
, pStubMsg
->BufferLength
, pMemory
);
4306 if (saved_buffer_length
)
4308 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4309 pStubMsg
->BufferLength
= saved_buffer_length
;
4314 /***********************************************************************
4315 * NdrUserMarshalMemorySize [RPCRT4.@]
4317 ULONG WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4318 PFORMAT_STRING pFormat
)
4320 unsigned flags
= pFormat
[1];
4321 unsigned index
= *(const WORD
*)&pFormat
[2];
4322 DWORD memsize
= *(const WORD
*)&pFormat
[4];
4323 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
4325 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
4326 TRACE("index=%d\n", index
);
4328 pStubMsg
->MemorySize
+= memsize
;
4330 if (flags
& USER_MARSHAL_POINTER
)
4332 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4333 /* skip pointer prefix */
4334 pStubMsg
->Buffer
+= 4;
4335 if (pStubMsg
->IgnoreEmbeddedPointers
)
4336 return pStubMsg
->MemorySize
;
4337 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
4340 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4343 FIXME("not implemented for varying buffer size\n");
4345 pStubMsg
->Buffer
+= bufsize
;
4347 return pStubMsg
->MemorySize
;
4350 /***********************************************************************
4351 * NdrUserMarshalFree [RPCRT4.@]
4353 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
4354 unsigned char *pMemory
,
4355 PFORMAT_STRING pFormat
)
4357 /* unsigned flags = pFormat[1]; */
4358 unsigned index
= *(const WORD
*)&pFormat
[2];
4359 USER_MARSHAL_CB umcb
;
4361 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4362 TRACE("index=%d\n", index
);
4364 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_FREE
, pFormat
, &umcb
);
4366 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
4367 &umcb
.Flags
, pMemory
);
4370 /***********************************************************************
4371 * NdrGetUserMarshalInfo [RPCRT4.@]
4373 RPC_STATUS RPC_ENTRY
NdrGetUserMarshalInfo(ULONG
*flags
, ULONG level
, NDR_USER_MARSHAL_INFO
*umi
)
4375 USER_MARSHAL_CB
*umcb
= CONTAINING_RECORD(flags
, USER_MARSHAL_CB
, Flags
);
4377 TRACE("(%p,%u,%p)\n", flags
, level
, umi
);
4380 return RPC_S_INVALID_ARG
;
4382 memset(&umi
->Level1
, 0, sizeof(umi
->Level1
));
4383 umi
->InformationLevel
= level
;
4385 if (umcb
->Signature
!= USER_MARSHAL_CB_SIGNATURE
)
4386 return RPC_S_INVALID_ARG
;
4388 umi
->Level1
.pfnAllocate
= umcb
->pStubMsg
->pfnAllocate
;
4389 umi
->Level1
.pfnFree
= umcb
->pStubMsg
->pfnFree
;
4390 umi
->Level1
.pRpcChannelBuffer
= umcb
->pStubMsg
->pRpcChannelBuffer
;
4392 switch (umcb
->CBType
)
4394 case USER_MARSHAL_CB_MARSHALL
:
4395 case USER_MARSHAL_CB_UNMARSHALL
:
4397 RPC_MESSAGE
*msg
= umcb
->pStubMsg
->RpcMsg
;
4398 unsigned char *buffer_start
= msg
->Buffer
;
4399 unsigned char *buffer_end
=
4400 (unsigned char *)msg
->Buffer
+ msg
->BufferLength
;
4402 if (umcb
->pStubMsg
->Buffer
< buffer_start
||
4403 umcb
->pStubMsg
->Buffer
> buffer_end
)
4404 return ERROR_INVALID_USER_BUFFER
;
4406 umi
->Level1
.Buffer
= umcb
->pStubMsg
->Buffer
;
4407 umi
->Level1
.BufferSize
= buffer_end
- umcb
->pStubMsg
->Buffer
;
4410 case USER_MARSHAL_CB_BUFFER_SIZE
:
4411 case USER_MARSHAL_CB_FREE
:
4414 WARN("unrecognised CBType %d\n", umcb
->CBType
);
4420 /***********************************************************************
4421 * NdrClearOutParameters [RPCRT4.@]
4423 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
4424 PFORMAT_STRING pFormat
,
4427 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
4430 /***********************************************************************
4431 * NdrConvert [RPCRT4.@]
4433 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
4435 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
4436 /* FIXME: since this stub doesn't do any converting, the proper behavior
4437 is to raise an exception */
4440 /***********************************************************************
4441 * NdrConvert2 [RPCRT4.@]
4443 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, LONG NumberParams
)
4445 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4446 pStubMsg
, pFormat
, NumberParams
);
4447 /* FIXME: since this stub doesn't do any converting, the proper behavior
4448 is to raise an exception */
4451 #include "pshpack1.h"
4452 typedef struct _NDR_CSTRUCT_FORMAT
4455 unsigned char alignment
;
4456 unsigned short memory_size
;
4457 short offset_to_array_description
;
4458 } NDR_CSTRUCT_FORMAT
, NDR_CVSTRUCT_FORMAT
;
4459 #include "poppack.h"
4461 /***********************************************************************
4462 * NdrConformantStructMarshall [RPCRT4.@]
4464 unsigned char * WINAPI
NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4465 unsigned char *pMemory
,
4466 PFORMAT_STRING pFormat
)
4468 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4469 PFORMAT_STRING pCArrayFormat
;
4470 ULONG esize
, bufsize
;
4472 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4474 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4475 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4477 ERR("invalid format type %x\n", pCStructFormat
->type
);
4478 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4482 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4483 pCStructFormat
->offset_to_array_description
;
4484 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4486 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4487 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4490 esize
= *(const WORD
*)(pCArrayFormat
+2);
4492 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4493 pCArrayFormat
+ 4, 0);
4495 WriteConformance(pStubMsg
);
4497 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4499 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4501 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4502 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4504 ERR("integer overflow of memory_size %u with bufsize %u\n",
4505 pCStructFormat
->memory_size
, bufsize
);
4506 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4508 /* copy constant sized part of struct */
4509 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4510 safe_copy_to_buffer(pStubMsg
, pMemory
, pCStructFormat
->memory_size
+ bufsize
);
4512 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4513 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4518 /***********************************************************************
4519 * NdrConformantStructUnmarshall [RPCRT4.@]
4521 unsigned char * WINAPI
NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4522 unsigned char **ppMemory
,
4523 PFORMAT_STRING pFormat
,
4524 unsigned char fMustAlloc
)
4526 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4527 PFORMAT_STRING pCArrayFormat
;
4528 ULONG esize
, bufsize
;
4529 unsigned char *saved_buffer
;
4531 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4533 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4534 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4536 ERR("invalid format type %x\n", pCStructFormat
->type
);
4537 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4540 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4541 pCStructFormat
->offset_to_array_description
;
4542 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4544 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4545 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4548 esize
= *(const WORD
*)(pCArrayFormat
+2);
4550 pCArrayFormat
= ReadConformance(pStubMsg
, pCArrayFormat
+ 4);
4552 ALIGN_POINTER(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4554 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4556 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4557 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4559 ERR("integer overflow of memory_size %u with bufsize %u\n",
4560 pCStructFormat
->memory_size
, bufsize
);
4561 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4566 SIZE_T size
= pCStructFormat
->memory_size
+ bufsize
;
4567 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4571 if (!pStubMsg
->IsClient
&& !*ppMemory
)
4572 /* for servers, we just point straight into the RPC buffer */
4573 *ppMemory
= pStubMsg
->Buffer
;
4576 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4577 safe_buffer_increment(pStubMsg
, pCStructFormat
->memory_size
+ bufsize
);
4578 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4579 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4581 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
4582 if (*ppMemory
!= saved_buffer
)
4583 memcpy(*ppMemory
, saved_buffer
, pCStructFormat
->memory_size
+ bufsize
);
4588 /***********************************************************************
4589 * NdrConformantStructBufferSize [RPCRT4.@]
4591 void WINAPI
NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4592 unsigned char *pMemory
,
4593 PFORMAT_STRING pFormat
)
4595 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4596 PFORMAT_STRING pCArrayFormat
;
4599 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4601 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4602 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4604 ERR("invalid format type %x\n", pCStructFormat
->type
);
4605 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4608 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4609 pCStructFormat
->offset_to_array_description
;
4610 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4612 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4613 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4616 esize
= *(const WORD
*)(pCArrayFormat
+2);
4618 pCArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
, pCArrayFormat
+4, 0);
4619 SizeConformance(pStubMsg
);
4621 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCStructFormat
->alignment
+ 1);
4623 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4625 safe_buffer_length_increment(pStubMsg
, pCStructFormat
->memory_size
);
4626 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
4628 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4629 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4632 /***********************************************************************
4633 * NdrConformantStructMemorySize [RPCRT4.@]
4635 ULONG WINAPI
NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4636 PFORMAT_STRING pFormat
)
4642 /***********************************************************************
4643 * NdrConformantStructFree [RPCRT4.@]
4645 void WINAPI
NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
4646 unsigned char *pMemory
,
4647 PFORMAT_STRING pFormat
)
4649 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4650 PFORMAT_STRING pCArrayFormat
;
4652 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4654 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4655 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4657 ERR("invalid format type %x\n", pCStructFormat
->type
);
4658 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4662 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4663 pCStructFormat
->offset_to_array_description
;
4664 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4666 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4667 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4671 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4672 pCArrayFormat
+ 4, 0);
4674 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4676 /* copy constant sized part of struct */
4677 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4679 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4680 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4683 /***********************************************************************
4684 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4686 unsigned char * WINAPI
NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4687 unsigned char *pMemory
,
4688 PFORMAT_STRING pFormat
)
4690 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4691 PFORMAT_STRING pCVArrayFormat
;
4693 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4695 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4696 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4698 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4699 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4703 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4704 pCVStructFormat
->offset_to_array_description
;
4706 array_compute_and_write_conformance(*pCVArrayFormat
, pStubMsg
,
4707 pMemory
+ pCVStructFormat
->memory_size
,
4710 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4712 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4714 /* write constant sized part */
4715 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4716 safe_copy_to_buffer(pStubMsg
, pMemory
, pCVStructFormat
->memory_size
);
4718 array_write_variance_and_marshall(*pCVArrayFormat
, pStubMsg
,
4719 pMemory
+ pCVStructFormat
->memory_size
,
4720 pCVArrayFormat
, FALSE
/* fHasPointers */);
4722 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4727 /***********************************************************************
4728 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4730 unsigned char * WINAPI
NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4731 unsigned char **ppMemory
,
4732 PFORMAT_STRING pFormat
,
4733 unsigned char fMustAlloc
)
4735 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4736 PFORMAT_STRING pCVArrayFormat
;
4737 ULONG memsize
, bufsize
;
4738 unsigned char *saved_buffer
, *saved_array_buffer
;
4740 unsigned char *array_memory
;
4742 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4744 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4745 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4747 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4748 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4752 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4753 pCVStructFormat
->offset_to_array_description
;
4755 memsize
= array_read_conformance(*pCVArrayFormat
, pStubMsg
,
4758 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4760 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4762 /* work out how much memory to allocate if we need to do so */
4763 if (!fMustAlloc
&& !*ppMemory
)
4767 SIZE_T size
= pCVStructFormat
->memory_size
+ memsize
;
4768 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4771 /* mark the start of the constant data */
4772 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4773 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4775 array_memory
= *ppMemory
+ pCVStructFormat
->memory_size
;
4776 bufsize
= array_read_variance_and_unmarshall(*pCVArrayFormat
, pStubMsg
,
4777 &array_memory
, pCVArrayFormat
,
4778 FALSE
/* fMustAlloc */,
4779 FALSE
/* fUseServerBufferMemory */,
4780 FALSE
/* fUnmarshall */);
4782 /* save offset in case unmarshalling pointers changes it */
4783 offset
= pStubMsg
->Offset
;
4785 /* mark the start of the array data */
4786 saved_array_buffer
= pStubMsg
->Buffer
;
4787 safe_buffer_increment(pStubMsg
, bufsize
);
4789 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4791 /* copy the constant data */
4792 memcpy(*ppMemory
, saved_buffer
, pCVStructFormat
->memory_size
);
4793 /* copy the array data */
4794 TRACE("copying %p to %p\n", saved_array_buffer
, *ppMemory
+ pCVStructFormat
->memory_size
);
4795 memcpy(*ppMemory
+ pCVStructFormat
->memory_size
+ offset
,
4796 saved_array_buffer
, bufsize
);
4798 if (*pCVArrayFormat
== RPC_FC_C_CSTRING
)
4799 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory
+ pCVStructFormat
->memory_size
)));
4800 else if (*pCVArrayFormat
== RPC_FC_C_WSTRING
)
4801 TRACE("string=%s\n", debugstr_w((WCHAR
*)(*ppMemory
+ pCVStructFormat
->memory_size
)));
4806 /***********************************************************************
4807 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
4809 void WINAPI
NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4810 unsigned char *pMemory
,
4811 PFORMAT_STRING pFormat
)
4813 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4814 PFORMAT_STRING pCVArrayFormat
;
4816 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4818 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4819 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4821 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4822 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4826 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4827 pCVStructFormat
->offset_to_array_description
;
4828 array_compute_and_size_conformance(*pCVArrayFormat
, pStubMsg
,
4829 pMemory
+ pCVStructFormat
->memory_size
,
4832 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCVStructFormat
->alignment
+ 1);
4834 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4836 safe_buffer_length_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4838 array_buffer_size(*pCVArrayFormat
, pStubMsg
,
4839 pMemory
+ pCVStructFormat
->memory_size
, pCVArrayFormat
,
4840 FALSE
/* fHasPointers */);
4842 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4845 /***********************************************************************
4846 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4848 ULONG WINAPI
NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4849 PFORMAT_STRING pFormat
)
4851 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4852 PFORMAT_STRING pCVArrayFormat
;
4854 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4856 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4857 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4859 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4860 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4864 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4865 pCVStructFormat
->offset_to_array_description
;
4866 array_read_conformance(*pCVArrayFormat
, pStubMsg
, pCVArrayFormat
);
4868 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4870 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4872 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4873 array_memory_size(*pCVArrayFormat
, pStubMsg
, pCVArrayFormat
,
4874 FALSE
/* fHasPointers */);
4876 pStubMsg
->MemorySize
+= pCVStructFormat
->memory_size
;
4878 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4880 return pStubMsg
->MemorySize
;
4883 /***********************************************************************
4884 * NdrConformantVaryingStructFree [RPCRT4.@]
4886 void WINAPI
NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
4887 unsigned char *pMemory
,
4888 PFORMAT_STRING pFormat
)
4890 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4891 PFORMAT_STRING pCVArrayFormat
;
4893 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4895 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4896 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4898 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4899 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4903 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4904 pCVStructFormat
->offset_to_array_description
;
4905 array_free(*pCVArrayFormat
, pStubMsg
,
4906 pMemory
+ pCVStructFormat
->memory_size
, pCVArrayFormat
,
4907 FALSE
/* fHasPointers */);
4909 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4911 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4914 #include "pshpack1.h"
4918 unsigned char alignment
;
4919 unsigned short total_size
;
4920 } NDR_SMFARRAY_FORMAT
;
4925 unsigned char alignment
;
4927 } NDR_LGFARRAY_FORMAT
;
4928 #include "poppack.h"
4930 /***********************************************************************
4931 * NdrFixedArrayMarshall [RPCRT4.@]
4933 unsigned char * WINAPI
NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4934 unsigned char *pMemory
,
4935 PFORMAT_STRING pFormat
)
4937 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
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_POINTER_CLEAR(pStubMsg
->Buffer
, 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);
4964 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4965 safe_copy_to_buffer(pStubMsg
, pMemory
, total_size
);
4967 pFormat
= EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4972 /***********************************************************************
4973 * NdrFixedArrayUnmarshall [RPCRT4.@]
4975 unsigned char * WINAPI
NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4976 unsigned char **ppMemory
,
4977 PFORMAT_STRING pFormat
,
4978 unsigned char fMustAlloc
)
4980 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4982 unsigned char *saved_buffer
;
4984 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4986 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4987 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4989 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4990 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4994 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4996 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4998 total_size
= pSmFArrayFormat
->total_size
;
4999 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5003 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5004 total_size
= pLgFArrayFormat
->total_size
;
5005 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5009 *ppMemory
= NdrAllocate(pStubMsg
, total_size
);
5012 if (!pStubMsg
->IsClient
&& !*ppMemory
)
5013 /* for servers, we just point straight into the RPC buffer */
5014 *ppMemory
= pStubMsg
->Buffer
;
5017 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5018 safe_buffer_increment(pStubMsg
, total_size
);
5019 pFormat
= EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
5021 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
5022 if (*ppMemory
!= saved_buffer
)
5023 memcpy(*ppMemory
, saved_buffer
, total_size
);
5028 /***********************************************************************
5029 * NdrFixedArrayBufferSize [RPCRT4.@]
5031 void WINAPI
NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5032 unsigned char *pMemory
,
5033 PFORMAT_STRING pFormat
)
5035 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5038 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5040 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5041 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5043 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5044 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5048 ALIGN_LENGTH(pStubMsg
->BufferLength
, pSmFArrayFormat
->alignment
+ 1);
5050 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5052 total_size
= pSmFArrayFormat
->total_size
;
5053 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5057 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5058 total_size
= pLgFArrayFormat
->total_size
;
5059 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5061 safe_buffer_length_increment(pStubMsg
, total_size
);
5063 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5066 /***********************************************************************
5067 * NdrFixedArrayMemorySize [RPCRT4.@]
5069 ULONG WINAPI
NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5070 PFORMAT_STRING pFormat
)
5072 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5075 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5077 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5078 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5080 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5081 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5085 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
5087 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5089 total_size
= pSmFArrayFormat
->total_size
;
5090 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5094 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5095 total_size
= pLgFArrayFormat
->total_size
;
5096 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5098 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5099 safe_buffer_increment(pStubMsg
, total_size
);
5100 pStubMsg
->MemorySize
+= total_size
;
5102 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5107 /***********************************************************************
5108 * NdrFixedArrayFree [RPCRT4.@]
5110 void WINAPI
NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
5111 unsigned char *pMemory
,
5112 PFORMAT_STRING pFormat
)
5114 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5116 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5118 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5119 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5121 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5122 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5126 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5127 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5130 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5131 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5134 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5137 /***********************************************************************
5138 * NdrVaryingArrayMarshall [RPCRT4.@]
5140 unsigned char * WINAPI
NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5141 unsigned char *pMemory
,
5142 PFORMAT_STRING pFormat
)
5144 unsigned char alignment
;
5145 DWORD elements
, esize
;
5148 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5150 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5151 (pFormat
[0] != RPC_FC_LGVARRAY
))
5153 ERR("invalid format type %x\n", pFormat
[0]);
5154 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5158 alignment
= pFormat
[1] + 1;
5160 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5163 pFormat
+= sizeof(WORD
);
5164 elements
= *(const WORD
*)pFormat
;
5165 pFormat
+= sizeof(WORD
);
5170 pFormat
+= sizeof(DWORD
);
5171 elements
= *(const DWORD
*)pFormat
;
5172 pFormat
+= sizeof(DWORD
);
5175 esize
= *(const WORD
*)pFormat
;
5176 pFormat
+= sizeof(WORD
);
5178 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5179 if ((pStubMsg
->ActualCount
> elements
) ||
5180 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5182 RpcRaiseException(RPC_S_INVALID_BOUND
);
5186 WriteVariance(pStubMsg
);
5188 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
5190 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
5191 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5192 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
5194 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
5199 /***********************************************************************
5200 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5202 unsigned char * WINAPI
NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5203 unsigned char **ppMemory
,
5204 PFORMAT_STRING pFormat
,
5205 unsigned char fMustAlloc
)
5207 unsigned char alignment
;
5208 DWORD size
, elements
, esize
;
5210 unsigned char *saved_buffer
;
5213 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5215 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5216 (pFormat
[0] != RPC_FC_LGVARRAY
))
5218 ERR("invalid format type %x\n", pFormat
[0]);
5219 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5223 alignment
= pFormat
[1] + 1;
5225 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5228 size
= *(const WORD
*)pFormat
;
5229 pFormat
+= sizeof(WORD
);
5230 elements
= *(const WORD
*)pFormat
;
5231 pFormat
+= sizeof(WORD
);
5236 size
= *(const DWORD
*)pFormat
;
5237 pFormat
+= sizeof(DWORD
);
5238 elements
= *(const DWORD
*)pFormat
;
5239 pFormat
+= sizeof(DWORD
);
5242 esize
= *(const WORD
*)pFormat
;
5243 pFormat
+= sizeof(WORD
);
5245 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
5247 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
5249 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
5250 offset
= pStubMsg
->Offset
;
5252 if (!fMustAlloc
&& !*ppMemory
)
5255 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5256 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5257 safe_buffer_increment(pStubMsg
, bufsize
);
5259 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
5261 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
5266 /***********************************************************************
5267 * NdrVaryingArrayBufferSize [RPCRT4.@]
5269 void WINAPI
NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5270 unsigned char *pMemory
,
5271 PFORMAT_STRING pFormat
)
5273 unsigned char alignment
;
5274 DWORD elements
, esize
;
5276 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5278 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5279 (pFormat
[0] != RPC_FC_LGVARRAY
))
5281 ERR("invalid format type %x\n", pFormat
[0]);
5282 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5286 alignment
= pFormat
[1] + 1;
5288 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5291 pFormat
+= sizeof(WORD
);
5292 elements
= *(const WORD
*)pFormat
;
5293 pFormat
+= sizeof(WORD
);
5298 pFormat
+= sizeof(DWORD
);
5299 elements
= *(const DWORD
*)pFormat
;
5300 pFormat
+= sizeof(DWORD
);
5303 esize
= *(const WORD
*)pFormat
;
5304 pFormat
+= sizeof(WORD
);
5306 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5307 if ((pStubMsg
->ActualCount
> elements
) ||
5308 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5310 RpcRaiseException(RPC_S_INVALID_BOUND
);
5314 SizeVariance(pStubMsg
);
5316 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
5318 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
5320 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5323 /***********************************************************************
5324 * NdrVaryingArrayMemorySize [RPCRT4.@]
5326 ULONG WINAPI
NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5327 PFORMAT_STRING pFormat
)
5329 unsigned char alignment
;
5330 DWORD size
, elements
, esize
;
5332 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5334 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5335 (pFormat
[0] != RPC_FC_LGVARRAY
))
5337 ERR("invalid format type %x\n", pFormat
[0]);
5338 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5342 alignment
= pFormat
[1] + 1;
5344 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5347 size
= *(const WORD
*)pFormat
;
5348 pFormat
+= sizeof(WORD
);
5349 elements
= *(const WORD
*)pFormat
;
5350 pFormat
+= sizeof(WORD
);
5355 size
= *(const DWORD
*)pFormat
;
5356 pFormat
+= sizeof(DWORD
);
5357 elements
= *(const DWORD
*)pFormat
;
5358 pFormat
+= sizeof(DWORD
);
5361 esize
= *(const WORD
*)pFormat
;
5362 pFormat
+= sizeof(WORD
);
5364 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
5366 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
5368 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
5369 pStubMsg
->MemorySize
+= size
;
5371 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5373 return pStubMsg
->MemorySize
;
5376 /***********************************************************************
5377 * NdrVaryingArrayFree [RPCRT4.@]
5379 void WINAPI
NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
5380 unsigned char *pMemory
,
5381 PFORMAT_STRING pFormat
)
5385 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5387 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5388 (pFormat
[0] != RPC_FC_LGVARRAY
))
5390 ERR("invalid format type %x\n", pFormat
[0]);
5391 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5395 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5398 pFormat
+= sizeof(WORD
);
5399 elements
= *(const WORD
*)pFormat
;
5400 pFormat
+= sizeof(WORD
);
5405 pFormat
+= sizeof(DWORD
);
5406 elements
= *(const DWORD
*)pFormat
;
5407 pFormat
+= sizeof(DWORD
);
5410 pFormat
+= sizeof(WORD
);
5412 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5413 if ((pStubMsg
->ActualCount
> elements
) ||
5414 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5416 RpcRaiseException(RPC_S_INVALID_BOUND
);
5420 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5423 static ULONG
get_discriminant(unsigned char fc
, const unsigned char *pMemory
)
5436 return *(const USHORT
*)pMemory
;
5440 return *(const ULONG
*)pMemory
;
5442 FIXME("Unhandled base type: 0x%02x\n", fc
);
5447 static PFORMAT_STRING
get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg
,
5449 PFORMAT_STRING pFormat
)
5451 unsigned short num_arms
, arm
, type
;
5453 num_arms
= *(const SHORT
*)pFormat
& 0x0fff;
5455 for(arm
= 0; arm
< num_arms
; arm
++)
5457 if(discriminant
== *(const ULONG
*)pFormat
)
5465 type
= *(const unsigned short*)pFormat
;
5466 TRACE("type %04x\n", type
);
5467 if(arm
== num_arms
) /* default arm extras */
5471 ERR("no arm for 0x%x and no default case\n", discriminant
);
5472 RpcRaiseException(RPC_S_INVALID_TAG
);
5477 TRACE("falling back to empty default case for 0x%x\n", discriminant
);
5484 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
, ULONG discriminant
, PFORMAT_STRING pFormat
)
5486 unsigned short type
;
5490 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5494 type
= *(const unsigned short*)pFormat
;
5495 if((type
& 0xff00) == 0x8000)
5497 unsigned char basetype
= LOBYTE(type
);
5498 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &basetype
);
5502 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5503 NDR_MARSHALL m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
5506 unsigned char *saved_buffer
= NULL
;
5507 int pointer_buffer_mark_set
= 0;
5514 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
5515 saved_buffer
= pStubMsg
->Buffer
;
5516 if (pStubMsg
->PointerBufferMark
)
5518 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5519 pStubMsg
->PointerBufferMark
= NULL
;
5520 pointer_buffer_mark_set
= 1;
5523 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
5525 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char **)pMemory
, desc
);
5526 if (pointer_buffer_mark_set
)
5528 STD_OVERFLOW_CHECK(pStubMsg
);
5529 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5530 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5532 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5533 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
5534 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5536 pStubMsg
->Buffer
= saved_buffer
+ 4;
5540 m(pStubMsg
, pMemory
, desc
);
5543 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5548 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5549 unsigned char **ppMemory
,
5551 PFORMAT_STRING pFormat
,
5552 unsigned char fMustAlloc
)
5554 unsigned short type
;
5558 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5562 type
= *(const unsigned short*)pFormat
;
5563 if((type
& 0xff00) == 0x8000)
5565 unsigned char basetype
= LOBYTE(type
);
5566 return NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &basetype
, FALSE
);
5570 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5571 NDR_UNMARSHALL m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
5574 unsigned char *saved_buffer
= NULL
;
5575 int pointer_buffer_mark_set
= 0;
5582 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5583 saved_buffer
= pStubMsg
->Buffer
;
5584 if (pStubMsg
->PointerBufferMark
)
5586 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5587 pStubMsg
->PointerBufferMark
= NULL
;
5588 pointer_buffer_mark_set
= 1;
5591 pStubMsg
->Buffer
+= 4; /* for pointer ID */
5593 if (saved_buffer
+ 4 > pStubMsg
->BufferEnd
)
5595 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5596 saved_buffer
, pStubMsg
->BufferEnd
);
5597 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5600 PointerUnmarshall(pStubMsg
, saved_buffer
, *(unsigned char ***)ppMemory
, **(unsigned char ***)ppMemory
, desc
, fMustAlloc
);
5601 if (pointer_buffer_mark_set
)
5603 STD_OVERFLOW_CHECK(pStubMsg
);
5604 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5605 pStubMsg
->Buffer
= saved_buffer
+ 4;
5609 m(pStubMsg
, ppMemory
, desc
, fMustAlloc
);
5612 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5617 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg
,
5618 unsigned char *pMemory
,
5620 PFORMAT_STRING pFormat
)
5622 unsigned short type
;
5626 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5630 type
= *(const unsigned short*)pFormat
;
5631 if((type
& 0xff00) == 0x8000)
5633 unsigned char basetype
= LOBYTE(type
);
5634 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &basetype
);
5638 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5639 NDR_BUFFERSIZE m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
5648 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
5649 safe_buffer_length_increment(pStubMsg
, 4); /* for pointer ID */
5650 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5652 int saved_buffer_length
= pStubMsg
->BufferLength
;
5653 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
5654 pStubMsg
->PointerLength
= 0;
5655 if(!pStubMsg
->BufferLength
)
5656 ERR("BufferLength == 0??\n");
5657 PointerBufferSize(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5658 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
5659 pStubMsg
->BufferLength
= saved_buffer_length
;
5663 m(pStubMsg
, pMemory
, desc
);
5666 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
5670 static ULONG
union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg
,
5672 PFORMAT_STRING pFormat
)
5674 unsigned short type
, size
;
5676 size
= *(const unsigned short*)pFormat
;
5677 pStubMsg
->Memory
+= size
;
5680 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5684 type
= *(const unsigned short*)pFormat
;
5685 if((type
& 0xff00) == 0x8000)
5687 return NdrBaseTypeMemorySize(pStubMsg
, pFormat
);
5691 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5692 NDR_MEMORYSIZE m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
5693 unsigned char *saved_buffer
;
5702 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5703 saved_buffer
= pStubMsg
->Buffer
;
5704 safe_buffer_increment(pStubMsg
, 4);
5705 ALIGN_LENGTH(pStubMsg
->MemorySize
, sizeof(void *));
5706 pStubMsg
->MemorySize
+= sizeof(void *);
5707 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5708 PointerMemorySize(pStubMsg
, saved_buffer
, pFormat
);
5711 return m(pStubMsg
, desc
);
5714 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5717 TRACE("size %d\n", size
);
5721 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg
,
5722 unsigned char *pMemory
,
5724 PFORMAT_STRING pFormat
)
5726 unsigned short type
;
5730 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5734 type
= *(const unsigned short*)pFormat
;
5735 if((type
& 0xff00) != 0x8000)
5737 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5738 NDR_FREE m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
5747 PointerFree(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5750 m(pStubMsg
, pMemory
, desc
);
5756 /***********************************************************************
5757 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5759 unsigned char * WINAPI
NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5760 unsigned char *pMemory
,
5761 PFORMAT_STRING pFormat
)
5763 unsigned char switch_type
;
5764 unsigned char increment
;
5767 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5770 switch_type
= *pFormat
& 0xf;
5771 increment
= (*pFormat
& 0xf0) >> 4;
5774 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, increment
);
5776 switch_value
= get_discriminant(switch_type
, pMemory
);
5777 TRACE("got switch value 0x%x\n", switch_value
);
5779 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &switch_type
);
5780 pMemory
+= increment
;
5782 return union_arm_marshall(pStubMsg
, pMemory
, switch_value
, pFormat
);
5785 /***********************************************************************
5786 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5788 unsigned char * WINAPI
NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5789 unsigned char **ppMemory
,
5790 PFORMAT_STRING pFormat
,
5791 unsigned char fMustAlloc
)
5793 unsigned char switch_type
;
5794 unsigned char increment
;
5796 unsigned short size
;
5797 unsigned char *pMemoryArm
;
5799 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5802 switch_type
= *pFormat
& 0xf;
5803 increment
= (*pFormat
& 0xf0) >> 4;
5806 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
5807 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
5808 TRACE("got switch value 0x%x\n", switch_value
);
5810 size
= *(const unsigned short*)pFormat
+ increment
;
5811 if (!fMustAlloc
&& !*ppMemory
)
5814 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5816 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
5817 * since the arm is part of the memory block that is encompassed by
5818 * the whole union. Memory is forced to allocate when pointers
5819 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
5820 * clearing the memory we pass in to the unmarshaller */
5822 memset(*ppMemory
, 0, size
);
5824 NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &switch_type
, FALSE
);
5825 pMemoryArm
= *ppMemory
+ increment
;
5827 return union_arm_unmarshall(pStubMsg
, &pMemoryArm
, switch_value
, pFormat
, FALSE
);
5830 /***********************************************************************
5831 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5833 void WINAPI
NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5834 unsigned char *pMemory
,
5835 PFORMAT_STRING pFormat
)
5837 unsigned char switch_type
;
5838 unsigned char increment
;
5841 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5844 switch_type
= *pFormat
& 0xf;
5845 increment
= (*pFormat
& 0xf0) >> 4;
5848 ALIGN_LENGTH(pStubMsg
->BufferLength
, increment
);
5849 switch_value
= get_discriminant(switch_type
, pMemory
);
5850 TRACE("got switch value 0x%x\n", switch_value
);
5852 /* Add discriminant size */
5853 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&switch_value
, &switch_type
);
5854 pMemory
+= increment
;
5856 union_arm_buffer_size(pStubMsg
, pMemory
, switch_value
, pFormat
);
5859 /***********************************************************************
5860 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5862 ULONG WINAPI
NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5863 PFORMAT_STRING pFormat
)
5865 unsigned char switch_type
;
5866 unsigned char increment
;
5869 switch_type
= *pFormat
& 0xf;
5870 increment
= (*pFormat
& 0xf0) >> 4;
5873 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
5874 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
5875 TRACE("got switch value 0x%x\n", switch_value
);
5877 pStubMsg
->Memory
+= increment
;
5879 return increment
+ union_arm_memory_size(pStubMsg
, switch_value
, pFormat
+ *(const SHORT
*)pFormat
);
5882 /***********************************************************************
5883 * NdrEncapsulatedUnionFree [RPCRT4.@]
5885 void WINAPI
NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
5886 unsigned char *pMemory
,
5887 PFORMAT_STRING pFormat
)
5889 unsigned char switch_type
;
5890 unsigned char increment
;
5893 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5896 switch_type
= *pFormat
& 0xf;
5897 increment
= (*pFormat
& 0xf0) >> 4;
5900 switch_value
= get_discriminant(switch_type
, pMemory
);
5901 TRACE("got switch value 0x%x\n", switch_value
);
5903 pMemory
+= increment
;
5905 union_arm_free(pStubMsg
, pMemory
, switch_value
, pFormat
);
5908 /***********************************************************************
5909 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5911 unsigned char * WINAPI
NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5912 unsigned char *pMemory
,
5913 PFORMAT_STRING pFormat
)
5915 unsigned char switch_type
;
5917 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5920 switch_type
= *pFormat
;
5923 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5924 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5925 /* Marshall discriminant */
5926 NdrBaseTypeMarshall(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
5928 return union_arm_marshall(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5931 static LONG
unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg
,
5932 PFORMAT_STRING
*ppFormat
)
5934 LONG discriminant
= 0;
5944 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5953 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5954 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5962 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
5963 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5968 FIXME("Unhandled base type: 0x%02x\n", **ppFormat
);
5972 if (pStubMsg
->fHasNewCorrDesc
)
5976 return discriminant
;
5979 /**********************************************************************
5980 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5982 unsigned char * WINAPI
NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5983 unsigned char **ppMemory
,
5984 PFORMAT_STRING pFormat
,
5985 unsigned char fMustAlloc
)
5988 unsigned short size
;
5990 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5993 /* Unmarshall discriminant */
5994 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
5995 TRACE("unmarshalled discriminant %x\n", discriminant
);
5997 pFormat
+= *(const SHORT
*)pFormat
;
5999 size
= *(const unsigned short*)pFormat
;
6001 if (!fMustAlloc
&& !*ppMemory
)
6004 *ppMemory
= NdrAllocate(pStubMsg
, size
);
6006 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6007 * since the arm is part of the memory block that is encompassed by
6008 * the whole union. Memory is forced to allocate when pointers
6009 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6010 * clearing the memory we pass in to the unmarshaller */
6012 memset(*ppMemory
, 0, size
);
6014 return union_arm_unmarshall(pStubMsg
, ppMemory
, discriminant
, pFormat
, FALSE
);
6017 /***********************************************************************
6018 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
6020 void WINAPI
NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6021 unsigned char *pMemory
,
6022 PFORMAT_STRING pFormat
)
6024 unsigned char switch_type
;
6026 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6029 switch_type
= *pFormat
;
6032 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6033 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6034 /* Add discriminant size */
6035 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
6037 union_arm_buffer_size(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6040 /***********************************************************************
6041 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
6043 ULONG WINAPI
NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6044 PFORMAT_STRING pFormat
)
6049 /* Unmarshall discriminant */
6050 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
6051 TRACE("unmarshalled discriminant 0x%x\n", discriminant
);
6053 return union_arm_memory_size(pStubMsg
, discriminant
, pFormat
+ *(const SHORT
*)pFormat
);
6056 /***********************************************************************
6057 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6059 void WINAPI
NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
6060 unsigned char *pMemory
,
6061 PFORMAT_STRING pFormat
)
6063 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6067 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6068 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6070 union_arm_free(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6073 /***********************************************************************
6074 * NdrByteCountPointerMarshall [RPCRT4.@]
6076 unsigned char * WINAPI
NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6077 unsigned char *pMemory
,
6078 PFORMAT_STRING pFormat
)
6084 /***********************************************************************
6085 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6087 unsigned char * WINAPI
NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6088 unsigned char **ppMemory
,
6089 PFORMAT_STRING pFormat
,
6090 unsigned char fMustAlloc
)
6096 /***********************************************************************
6097 * NdrByteCountPointerBufferSize [RPCRT4.@]
6099 void WINAPI
NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6100 unsigned char *pMemory
,
6101 PFORMAT_STRING pFormat
)
6106 /***********************************************************************
6107 * NdrByteCountPointerMemorySize [internal]
6109 static ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6110 PFORMAT_STRING pFormat
)
6116 /***********************************************************************
6117 * NdrByteCountPointerFree [RPCRT4.@]
6119 void WINAPI
NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
6120 unsigned char *pMemory
,
6121 PFORMAT_STRING pFormat
)
6126 /***********************************************************************
6127 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6129 unsigned char * WINAPI
NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6130 unsigned char *pMemory
,
6131 PFORMAT_STRING pFormat
)
6137 /***********************************************************************
6138 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6140 unsigned char * WINAPI
NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6141 unsigned char **ppMemory
,
6142 PFORMAT_STRING pFormat
,
6143 unsigned char fMustAlloc
)
6149 /***********************************************************************
6150 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6152 void WINAPI
NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6153 unsigned char *pMemory
,
6154 PFORMAT_STRING pFormat
)
6159 /***********************************************************************
6160 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6162 ULONG WINAPI
NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6163 PFORMAT_STRING pFormat
)
6169 /***********************************************************************
6170 * NdrXmitOrRepAsFree [RPCRT4.@]
6172 void WINAPI
NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg
,
6173 unsigned char *pMemory
,
6174 PFORMAT_STRING pFormat
)
6179 /***********************************************************************
6180 * NdrRangeMarshall [internal]
6182 static unsigned char *WINAPI
NdrRangeMarshall(
6183 PMIDL_STUB_MESSAGE pStubMsg
,
6184 unsigned char *pMemory
,
6185 PFORMAT_STRING pFormat
)
6187 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
6188 unsigned char base_type
;
6190 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6192 if (pRange
->type
!= RPC_FC_RANGE
)
6194 ERR("invalid format type %x\n", pRange
->type
);
6195 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6199 base_type
= pRange
->flags_type
& 0xf;
6201 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &base_type
);
6204 /***********************************************************************
6205 * NdrRangeUnmarshall [RPCRT4.@]
6207 unsigned char *WINAPI
NdrRangeUnmarshall(
6208 PMIDL_STUB_MESSAGE pStubMsg
,
6209 unsigned char **ppMemory
,
6210 PFORMAT_STRING pFormat
,
6211 unsigned char fMustAlloc
)
6213 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
6214 unsigned char base_type
;
6216 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6218 if (pRange
->type
!= RPC_FC_RANGE
)
6220 ERR("invalid format type %x\n", pRange
->type
);
6221 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6224 base_type
= pRange
->flags_type
& 0xf;
6226 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6227 base_type
, pRange
->low_value
, pRange
->high_value
);
6229 #define RANGE_UNMARSHALL(mem_type, wire_type, format_spec) \
6232 ALIGN_POINTER(pStubMsg->Buffer, sizeof(wire_type)); \
6233 if (!fMustAlloc && !*ppMemory) \
6234 fMustAlloc = TRUE; \
6236 *ppMemory = NdrAllocate(pStubMsg, sizeof(mem_type)); \
6237 if (pStubMsg->Buffer + sizeof(wire_type) > pStubMsg->BufferEnd) \
6239 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6240 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6241 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6243 if ((*(wire_type *)pStubMsg->Buffer < (mem_type)pRange->low_value) || \
6244 (*(wire_type *)pStubMsg->Buffer > (mem_type)pRange->high_value)) \
6246 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6247 *(wire_type *)pStubMsg->Buffer, (mem_type)pRange->low_value, \
6248 (mem_type)pRange->high_value); \
6249 RpcRaiseException(RPC_S_INVALID_BOUND); \
6252 TRACE("*ppMemory: %p\n", *ppMemory); \
6253 **(mem_type **)ppMemory = *(wire_type *)pStubMsg->Buffer; \
6254 pStubMsg->Buffer += sizeof(wire_type); \
6261 RANGE_UNMARSHALL(UCHAR
, UCHAR
, "%d");
6262 TRACE("value: 0x%02x\n", **ppMemory
);
6266 RANGE_UNMARSHALL(CHAR
, CHAR
, "%u");
6267 TRACE("value: 0x%02x\n", **ppMemory
);
6269 case RPC_FC_WCHAR
: /* FIXME: valid? */
6271 RANGE_UNMARSHALL(USHORT
, USHORT
, "%u");
6272 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6275 RANGE_UNMARSHALL(SHORT
, SHORT
, "%d");
6276 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6280 RANGE_UNMARSHALL(LONG
, LONG
, "%d");
6281 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6284 RANGE_UNMARSHALL(ULONG
, ULONG
, "%u");
6285 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6288 RANGE_UNMARSHALL(UINT
, USHORT
, "%u");
6289 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
6295 ERR("invalid range base type: 0x%02x\n", base_type
);
6296 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6302 /***********************************************************************
6303 * NdrRangeBufferSize [internal]
6305 static void WINAPI
NdrRangeBufferSize(
6306 PMIDL_STUB_MESSAGE pStubMsg
,
6307 unsigned char *pMemory
,
6308 PFORMAT_STRING pFormat
)
6310 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
6311 unsigned char base_type
;
6313 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6315 if (pRange
->type
!= RPC_FC_RANGE
)
6317 ERR("invalid format type %x\n", pRange
->type
);
6318 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6320 base_type
= pRange
->flags_type
& 0xf;
6322 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &base_type
);
6325 /***********************************************************************
6326 * NdrRangeMemorySize [internal]
6328 static ULONG WINAPI
NdrRangeMemorySize(
6329 PMIDL_STUB_MESSAGE pStubMsg
,
6330 PFORMAT_STRING pFormat
)
6332 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
6333 unsigned char base_type
;
6335 if (pRange
->type
!= RPC_FC_RANGE
)
6337 ERR("invalid format type %x\n", pRange
->type
);
6338 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6341 base_type
= pRange
->flags_type
& 0xf;
6343 return NdrBaseTypeMemorySize(pStubMsg
, &base_type
);
6346 /***********************************************************************
6347 * NdrRangeFree [internal]
6349 static void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6350 unsigned char *pMemory
,
6351 PFORMAT_STRING pFormat
)
6353 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6358 /***********************************************************************
6359 * NdrBaseTypeMarshall [internal]
6361 static unsigned char *WINAPI
NdrBaseTypeMarshall(
6362 PMIDL_STUB_MESSAGE pStubMsg
,
6363 unsigned char *pMemory
,
6364 PFORMAT_STRING pFormat
)
6366 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6374 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(UCHAR
));
6375 TRACE("value: 0x%02x\n", *pMemory
);
6380 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(USHORT
));
6381 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(USHORT
));
6382 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
6386 case RPC_FC_ERROR_STATUS_T
:
6388 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(ULONG
));
6389 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONG
));
6390 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
6393 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(float));
6394 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
6397 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(double));
6398 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
6401 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(ULONGLONG
));
6402 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONGLONG
));
6403 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
6406 /* only 16-bits on the wire, so do a sanity check */
6407 if (*(UINT
*)pMemory
> SHRT_MAX
)
6408 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
6409 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(USHORT
));
6410 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6411 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6412 *(USHORT
*)pStubMsg
->Buffer
= *(UINT
*)pMemory
;
6413 pStubMsg
->Buffer
+= sizeof(USHORT
);
6414 TRACE("value: 0x%04x\n", *(UINT
*)pMemory
);
6419 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6422 /* FIXME: what is the correct return value? */
6426 /***********************************************************************
6427 * NdrBaseTypeUnmarshall [internal]
6429 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(
6430 PMIDL_STUB_MESSAGE pStubMsg
,
6431 unsigned char **ppMemory
,
6432 PFORMAT_STRING pFormat
,
6433 unsigned char fMustAlloc
)
6435 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6437 #define BASE_TYPE_UNMARSHALL(type) \
6438 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6439 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6441 *ppMemory = pStubMsg->Buffer; \
6442 TRACE("*ppMemory: %p\n", *ppMemory); \
6443 safe_buffer_increment(pStubMsg, sizeof(type)); \
6448 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6449 TRACE("*ppMemory: %p\n", *ppMemory); \
6450 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6459 BASE_TYPE_UNMARSHALL(UCHAR
);
6460 TRACE("value: 0x%02x\n", **ppMemory
);
6465 BASE_TYPE_UNMARSHALL(USHORT
);
6466 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6470 case RPC_FC_ERROR_STATUS_T
:
6472 BASE_TYPE_UNMARSHALL(ULONG
);
6473 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6476 BASE_TYPE_UNMARSHALL(float);
6477 TRACE("value: %f\n", **(float **)ppMemory
);
6480 BASE_TYPE_UNMARSHALL(double);
6481 TRACE("value: %f\n", **(double **)ppMemory
);
6484 BASE_TYPE_UNMARSHALL(ULONGLONG
);
6485 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG
**)ppMemory
));
6488 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
6489 if (!fMustAlloc
&& !*ppMemory
)
6492 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT
));
6493 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > pStubMsg
->BufferEnd
)
6494 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6495 TRACE("*ppMemory: %p\n", *ppMemory
);
6496 /* 16-bits on the wire, but int in memory */
6497 **(UINT
**)ppMemory
= *(USHORT
*)pStubMsg
->Buffer
;
6498 pStubMsg
->Buffer
+= sizeof(USHORT
);
6499 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
6504 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6506 #undef BASE_TYPE_UNMARSHALL
6508 /* FIXME: what is the correct return value? */
6513 /***********************************************************************
6514 * NdrBaseTypeBufferSize [internal]
6516 static void WINAPI
NdrBaseTypeBufferSize(
6517 PMIDL_STUB_MESSAGE pStubMsg
,
6518 unsigned char *pMemory
,
6519 PFORMAT_STRING pFormat
)
6521 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6529 safe_buffer_length_increment(pStubMsg
, sizeof(UCHAR
));
6535 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(USHORT
));
6536 safe_buffer_length_increment(pStubMsg
, sizeof(USHORT
));
6541 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONG
));
6542 safe_buffer_length_increment(pStubMsg
, sizeof(ULONG
));
6545 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(float));
6546 safe_buffer_length_increment(pStubMsg
, sizeof(float));
6549 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(double));
6550 safe_buffer_length_increment(pStubMsg
, sizeof(double));
6553 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONGLONG
));
6554 safe_buffer_length_increment(pStubMsg
, sizeof(ULONGLONG
));
6556 case RPC_FC_ERROR_STATUS_T
:
6557 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(error_status_t
));
6558 safe_buffer_length_increment(pStubMsg
, sizeof(error_status_t
));
6563 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6567 /***********************************************************************
6568 * NdrBaseTypeMemorySize [internal]
6570 static ULONG WINAPI
NdrBaseTypeMemorySize(
6571 PMIDL_STUB_MESSAGE pStubMsg
,
6572 PFORMAT_STRING pFormat
)
6574 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg
, *pFormat
);
6582 safe_buffer_increment(pStubMsg
, sizeof(UCHAR
));
6583 pStubMsg
->MemorySize
+= sizeof(UCHAR
);
6584 return sizeof(UCHAR
);
6588 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
6589 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6590 ALIGN_LENGTH(pStubMsg
->MemorySize
, sizeof(USHORT
));
6591 pStubMsg
->MemorySize
+= sizeof(USHORT
);
6592 return sizeof(USHORT
);
6596 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
6597 safe_buffer_increment(pStubMsg
, sizeof(ULONG
));
6598 ALIGN_LENGTH(pStubMsg
->MemorySize
, sizeof(ULONG
));
6599 pStubMsg
->MemorySize
+= sizeof(ULONG
);
6600 return sizeof(ULONG
);
6602 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(float));
6603 safe_buffer_increment(pStubMsg
, sizeof(float));
6604 ALIGN_LENGTH(pStubMsg
->MemorySize
, sizeof(float));
6605 pStubMsg
->MemorySize
+= sizeof(float);
6606 return sizeof(float);
6608 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(double));
6609 safe_buffer_increment(pStubMsg
, sizeof(double));
6610 ALIGN_LENGTH(pStubMsg
->MemorySize
, sizeof(double));
6611 pStubMsg
->MemorySize
+= sizeof(double);
6612 return sizeof(double);
6614 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONGLONG
));
6615 safe_buffer_increment(pStubMsg
, sizeof(ULONGLONG
));
6616 ALIGN_LENGTH(pStubMsg
->MemorySize
, sizeof(ULONGLONG
));
6617 pStubMsg
->MemorySize
+= sizeof(ULONGLONG
);
6618 return sizeof(ULONGLONG
);
6619 case RPC_FC_ERROR_STATUS_T
:
6620 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(error_status_t
));
6621 safe_buffer_increment(pStubMsg
, sizeof(error_status_t
));
6622 ALIGN_LENGTH(pStubMsg
->MemorySize
, sizeof(error_status_t
));
6623 pStubMsg
->MemorySize
+= sizeof(error_status_t
);
6624 return sizeof(error_status_t
);
6626 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
6627 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6628 ALIGN_LENGTH(pStubMsg
->MemorySize
, sizeof(UINT
));
6629 pStubMsg
->MemorySize
+= sizeof(UINT
);
6630 return sizeof(UINT
);
6632 ALIGN_LENGTH(pStubMsg
->MemorySize
, sizeof(void *));
6633 pStubMsg
->MemorySize
+= sizeof(void *);
6634 return sizeof(void *);
6636 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6641 /***********************************************************************
6642 * NdrBaseTypeFree [internal]
6644 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6645 unsigned char *pMemory
,
6646 PFORMAT_STRING pFormat
)
6648 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6653 /***********************************************************************
6654 * NdrContextHandleBufferSize [internal]
6656 static void WINAPI
NdrContextHandleBufferSize(
6657 PMIDL_STUB_MESSAGE pStubMsg
,
6658 unsigned char *pMemory
,
6659 PFORMAT_STRING pFormat
)
6661 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6663 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6665 ERR("invalid format type %x\n", *pFormat
);
6666 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6668 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
6669 safe_buffer_length_increment(pStubMsg
, cbNDRContext
);
6672 /***********************************************************************
6673 * NdrContextHandleMarshall [internal]
6675 static unsigned char *WINAPI
NdrContextHandleMarshall(
6676 PMIDL_STUB_MESSAGE pStubMsg
,
6677 unsigned char *pMemory
,
6678 PFORMAT_STRING pFormat
)
6680 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6682 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6684 ERR("invalid format type %x\n", *pFormat
);
6685 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6687 TRACE("flags: 0x%02x\n", pFormat
[1]);
6689 if (pFormat
[1] & 0x80)
6690 NdrClientContextMarshall(pStubMsg
, *(NDR_CCONTEXT
**)pMemory
, FALSE
);
6692 NdrClientContextMarshall(pStubMsg
, pMemory
, FALSE
);
6697 /***********************************************************************
6698 * NdrContextHandleUnmarshall [internal]
6700 static unsigned char *WINAPI
NdrContextHandleUnmarshall(
6701 PMIDL_STUB_MESSAGE pStubMsg
,
6702 unsigned char **ppMemory
,
6703 PFORMAT_STRING pFormat
,
6704 unsigned char fMustAlloc
)
6706 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg
,
6707 ppMemory
, pFormat
, fMustAlloc
? "TRUE": "FALSE");
6709 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6711 ERR("invalid format type %x\n", *pFormat
);
6712 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6714 TRACE("flags: 0x%02x\n", pFormat
[1]);
6716 /* [out]-only or [ret] param */
6717 if ((pFormat
[1] & 0x60) == 0x20)
6718 **(NDR_CCONTEXT
**)ppMemory
= NULL
;
6719 NdrClientContextUnmarshall(pStubMsg
, *(NDR_CCONTEXT
**)ppMemory
, pStubMsg
->RpcMsg
->Handle
);
6724 /***********************************************************************
6725 * NdrClientContextMarshall [RPCRT4.@]
6727 void WINAPI
NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6728 NDR_CCONTEXT ContextHandle
,
6731 TRACE("(%p, %p, %d)\n", pStubMsg
, ContextHandle
, fCheck
);
6733 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
6735 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6737 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6738 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6739 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6742 /* FIXME: what does fCheck do? */
6743 NDRCContextMarshall(ContextHandle
,
6746 pStubMsg
->Buffer
+= cbNDRContext
;
6749 /***********************************************************************
6750 * NdrClientContextUnmarshall [RPCRT4.@]
6752 void WINAPI
NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6753 NDR_CCONTEXT
* pContextHandle
,
6754 RPC_BINDING_HANDLE BindHandle
)
6756 TRACE("(%p, %p, %p)\n", pStubMsg
, pContextHandle
, BindHandle
);
6758 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6760 if (pStubMsg
->Buffer
+ cbNDRContext
> pStubMsg
->BufferEnd
)
6761 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6763 NDRCContextUnmarshall(pContextHandle
,
6766 pStubMsg
->RpcMsg
->DataRepresentation
);
6768 pStubMsg
->Buffer
+= cbNDRContext
;
6771 void WINAPI
NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6772 NDR_SCONTEXT ContextHandle
,
6773 NDR_RUNDOWN RundownRoutine
)
6775 TRACE("(%p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
);
6777 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6779 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6781 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6782 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6783 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6786 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
6787 pStubMsg
->Buffer
, RundownRoutine
, NULL
,
6788 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
6789 pStubMsg
->Buffer
+= cbNDRContext
;
6792 NDR_SCONTEXT WINAPI
NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
)
6794 NDR_SCONTEXT ContextHandle
;
6796 TRACE("(%p)\n", pStubMsg
);
6798 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6800 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6802 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6803 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6804 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6807 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
6809 pStubMsg
->RpcMsg
->DataRepresentation
,
6810 NULL
, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
6811 pStubMsg
->Buffer
+= cbNDRContext
;
6813 return ContextHandle
;
6816 void WINAPI
NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg
,
6817 unsigned char* pMemory
,
6818 PFORMAT_STRING pFormat
)
6820 FIXME("(%p, %p, %p): stub\n", pStubMsg
, pMemory
, pFormat
);
6823 NDR_SCONTEXT WINAPI
NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg
,
6824 PFORMAT_STRING pFormat
)
6826 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6827 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6829 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
6831 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
6832 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
6833 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
6834 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
6835 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
6837 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
6838 if_id
= &sif
->InterfaceId
;
6841 return NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
, NULL
,
6842 pStubMsg
->RpcMsg
->DataRepresentation
, if_id
,
6846 void WINAPI
NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6847 NDR_SCONTEXT ContextHandle
,
6848 NDR_RUNDOWN RundownRoutine
,
6849 PFORMAT_STRING pFormat
)
6851 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6852 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6854 TRACE("(%p, %p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
, pFormat
);
6856 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6858 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6860 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6861 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6862 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6865 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
6866 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
6867 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
6868 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
6869 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
6871 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
6872 if_id
= &sif
->InterfaceId
;
6875 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
6876 pStubMsg
->Buffer
, RundownRoutine
, if_id
, flags
);
6877 pStubMsg
->Buffer
+= cbNDRContext
;
6880 NDR_SCONTEXT WINAPI
NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6881 PFORMAT_STRING pFormat
)
6883 NDR_SCONTEXT ContextHandle
;
6884 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6885 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6887 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
6889 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6891 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6893 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6894 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6895 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6898 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
6899 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
6900 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
6901 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
6902 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
6904 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
6905 if_id
= &sif
->InterfaceId
;
6908 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
6910 pStubMsg
->RpcMsg
->DataRepresentation
,
6912 pStubMsg
->Buffer
+= cbNDRContext
;
6914 return ContextHandle
;
6917 /***********************************************************************
6918 * NdrCorrelationInitialize [RPCRT4.@]
6920 * Initializes correlation validity checking.
6923 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6924 * pMemory [I] Pointer to memory to use as a cache.
6925 * CacheSize [I] Size of the memory pointed to by pMemory.
6926 * Flags [I] Reserved. Set to zero.
6931 void WINAPI
NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg
, void *pMemory
, ULONG CacheSize
, ULONG Flags
)
6933 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg
, pMemory
, CacheSize
, Flags
);
6934 pStubMsg
->fHasNewCorrDesc
= TRUE
;
6937 /***********************************************************************
6938 * NdrCorrelationPass [RPCRT4.@]
6940 * Performs correlation validity checking.
6943 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6948 void WINAPI
NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg
)
6950 FIXME("(%p): stub\n", pStubMsg
);
6953 /***********************************************************************
6954 * NdrCorrelationFree [RPCRT4.@]
6956 * Frees any resources used while unmarshalling parameters that need
6957 * correlation validity checking.
6960 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6965 void WINAPI
NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg
)
6967 FIXME("(%p): stub\n", pStubMsg
);