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
43 #include "wine/unicode.h"
44 #include "wine/rpcfc.h"
46 #include "wine/debug.h"
48 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
51 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
52 (*((UINT32 *)(pchar)) = (uint32))
54 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
55 (*((UINT32 *)(pchar)))
57 /* these would work for i386 too, but less efficient */
58 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
59 (*(pchar) = LOBYTE(LOWORD(uint32)), \
60 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
61 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
62 *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
63 (uint32)) /* allow as r-value */
65 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
67 MAKEWORD(*(pchar), *((pchar)+1)), \
68 MAKEWORD(*((pchar)+2), *((pchar)+3))))
71 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
72 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
73 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
74 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
75 *(pchar) = HIBYTE(HIWORD(uint32)), \
76 (uint32)) /* allow as r-value */
78 #define BIG_ENDIAN_UINT32_READ(pchar) \
80 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
81 MAKEWORD(*((pchar)+1), *(pchar))))
83 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
84 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
85 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
86 # define NDR_LOCAL_UINT32_READ(pchar) \
87 BIG_ENDIAN_UINT32_READ(pchar)
89 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
90 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
91 # define NDR_LOCAL_UINT32_READ(pchar) \
92 LITTLE_ENDIAN_UINT32_READ(pchar)
95 /* _Align must be the desired alignment,
96 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
97 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
98 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
99 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
100 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
101 #define ALIGN_POINTER_CLEAR(_Ptr, _Align) \
103 memset((_Ptr), 0, ((_Align) - (ULONG_PTR)(_Ptr)) & ((_Align) - 1)); \
104 ALIGN_POINTER(_Ptr, _Align); \
107 #define STD_OVERFLOW_CHECK(_Msg) do { \
108 TRACE("buffer=%d/%d\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
109 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
110 ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
113 #define NDR_POINTER_ID_BASE 0x20000
114 #define NDR_POINTER_ID(pStubMsg) (NDR_POINTER_ID_BASE + ((pStubMsg)->UniquePtrCount++) * 4)
115 #define NDR_TABLE_SIZE 128
116 #define NDR_TABLE_MASK 127
118 static unsigned char *WINAPI
NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
119 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
120 static void WINAPI
NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
121 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
122 static ULONG WINAPI
NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
124 static unsigned char *WINAPI
NdrContextHandleMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
125 static void WINAPI
NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
126 static unsigned char *WINAPI
NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
128 const NDR_MARSHALL NdrMarshaller
[NDR_TABLE_SIZE
] = {
130 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
131 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
132 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
133 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
137 NdrPointerMarshall
, NdrPointerMarshall
,
138 NdrPointerMarshall
, NdrPointerMarshall
,
140 NdrSimpleStructMarshall
, NdrSimpleStructMarshall
,
141 NdrConformantStructMarshall
, NdrConformantStructMarshall
,
142 NdrConformantVaryingStructMarshall
,
143 NdrComplexStructMarshall
,
145 NdrConformantArrayMarshall
,
146 NdrConformantVaryingArrayMarshall
,
147 NdrFixedArrayMarshall
, NdrFixedArrayMarshall
,
148 NdrVaryingArrayMarshall
, NdrVaryingArrayMarshall
,
149 NdrComplexArrayMarshall
,
151 NdrConformantStringMarshall
, 0, 0,
152 NdrConformantStringMarshall
,
153 NdrNonConformantStringMarshall
, 0, 0, 0,
155 NdrEncapsulatedUnionMarshall
,
156 NdrNonEncapsulatedUnionMarshall
,
157 NdrByteCountPointerMarshall
,
158 NdrXmitOrRepAsMarshall
, NdrXmitOrRepAsMarshall
,
160 NdrInterfacePointerMarshall
,
162 NdrContextHandleMarshall
,
165 NdrUserMarshalMarshall
,
170 const NDR_UNMARSHALL NdrUnmarshaller
[NDR_TABLE_SIZE
] = {
172 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
173 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
174 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
175 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
177 NdrBaseTypeUnmarshall
,
179 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
180 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
182 NdrSimpleStructUnmarshall
, NdrSimpleStructUnmarshall
,
183 NdrConformantStructUnmarshall
, NdrConformantStructUnmarshall
,
184 NdrConformantVaryingStructUnmarshall
,
185 NdrComplexStructUnmarshall
,
187 NdrConformantArrayUnmarshall
,
188 NdrConformantVaryingArrayUnmarshall
,
189 NdrFixedArrayUnmarshall
, NdrFixedArrayUnmarshall
,
190 NdrVaryingArrayUnmarshall
, NdrVaryingArrayUnmarshall
,
191 NdrComplexArrayUnmarshall
,
193 NdrConformantStringUnmarshall
, 0, 0,
194 NdrConformantStringUnmarshall
,
195 NdrNonConformantStringUnmarshall
, 0, 0, 0,
197 NdrEncapsulatedUnionUnmarshall
,
198 NdrNonEncapsulatedUnionUnmarshall
,
199 NdrByteCountPointerUnmarshall
,
200 NdrXmitOrRepAsUnmarshall
, NdrXmitOrRepAsUnmarshall
,
202 NdrInterfacePointerUnmarshall
,
204 NdrContextHandleUnmarshall
,
207 NdrUserMarshalUnmarshall
,
212 const NDR_BUFFERSIZE NdrBufferSizer
[NDR_TABLE_SIZE
] = {
214 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
215 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
216 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
217 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
219 NdrBaseTypeBufferSize
,
221 NdrPointerBufferSize
, NdrPointerBufferSize
,
222 NdrPointerBufferSize
, NdrPointerBufferSize
,
224 NdrSimpleStructBufferSize
, NdrSimpleStructBufferSize
,
225 NdrConformantStructBufferSize
, NdrConformantStructBufferSize
,
226 NdrConformantVaryingStructBufferSize
,
227 NdrComplexStructBufferSize
,
229 NdrConformantArrayBufferSize
,
230 NdrConformantVaryingArrayBufferSize
,
231 NdrFixedArrayBufferSize
, NdrFixedArrayBufferSize
,
232 NdrVaryingArrayBufferSize
, NdrVaryingArrayBufferSize
,
233 NdrComplexArrayBufferSize
,
235 NdrConformantStringBufferSize
, 0, 0,
236 NdrConformantStringBufferSize
,
237 NdrNonConformantStringBufferSize
, 0, 0, 0,
239 NdrEncapsulatedUnionBufferSize
,
240 NdrNonEncapsulatedUnionBufferSize
,
241 NdrByteCountPointerBufferSize
,
242 NdrXmitOrRepAsBufferSize
, NdrXmitOrRepAsBufferSize
,
244 NdrInterfacePointerBufferSize
,
246 NdrContextHandleBufferSize
,
249 NdrUserMarshalBufferSize
,
254 const NDR_MEMORYSIZE NdrMemorySizer
[NDR_TABLE_SIZE
] = {
256 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
257 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
258 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
259 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
261 NdrBaseTypeMemorySize
,
263 NdrPointerMemorySize
, NdrPointerMemorySize
,
264 NdrPointerMemorySize
, NdrPointerMemorySize
,
266 NdrSimpleStructMemorySize
, NdrSimpleStructMemorySize
,
267 NdrConformantStructMemorySize
, NdrConformantStructMemorySize
,
268 NdrConformantVaryingStructMemorySize
,
269 NdrComplexStructMemorySize
,
271 NdrConformantArrayMemorySize
,
272 NdrConformantVaryingArrayMemorySize
,
273 NdrFixedArrayMemorySize
, NdrFixedArrayMemorySize
,
274 NdrVaryingArrayMemorySize
, NdrVaryingArrayMemorySize
,
275 NdrComplexArrayMemorySize
,
277 NdrConformantStringMemorySize
, 0, 0,
278 NdrConformantStringMemorySize
,
279 NdrNonConformantStringMemorySize
, 0, 0, 0,
281 NdrEncapsulatedUnionMemorySize
,
282 NdrNonEncapsulatedUnionMemorySize
,
283 NdrByteCountPointerMemorySize
,
284 NdrXmitOrRepAsMemorySize
, NdrXmitOrRepAsMemorySize
,
286 NdrInterfacePointerMemorySize
,
291 NdrUserMarshalMemorySize
,
296 const NDR_FREE NdrFreer
[NDR_TABLE_SIZE
] = {
298 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
299 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
300 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
301 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
305 NdrPointerFree
, NdrPointerFree
,
306 NdrPointerFree
, NdrPointerFree
,
308 NdrSimpleStructFree
, NdrSimpleStructFree
,
309 NdrConformantStructFree
, NdrConformantStructFree
,
310 NdrConformantVaryingStructFree
,
311 NdrComplexStructFree
,
313 NdrConformantArrayFree
,
314 NdrConformantVaryingArrayFree
,
315 NdrFixedArrayFree
, NdrFixedArrayFree
,
316 NdrVaryingArrayFree
, NdrVaryingArrayFree
,
322 NdrEncapsulatedUnionFree
,
323 NdrNonEncapsulatedUnionFree
,
325 NdrXmitOrRepAsFree
, NdrXmitOrRepAsFree
,
327 NdrInterfacePointerFree
,
338 typedef struct _NDR_MEMORY_LIST
343 struct _NDR_MEMORY_LIST
*next
;
346 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
348 /***********************************************************************
349 * NdrAllocate [RPCRT4.@]
351 * Allocates a block of memory using pStubMsg->pfnAllocate.
354 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
355 * len [I] Size of memory block to allocate.
358 * The memory block of size len that was allocated.
361 * The memory block is always 8-byte aligned.
362 * If the function is unable to allocate memory an ERROR_OUTOFMEMORY
363 * exception is raised.
365 void * WINAPI
NdrAllocate(MIDL_STUB_MESSAGE
*pStubMsg
, size_t len
)
370 NDR_MEMORY_LIST
*mem_list
;
372 aligned_len
= ALIGNED_LENGTH(len
, 8);
373 adjusted_len
= aligned_len
+ sizeof(NDR_MEMORY_LIST
);
374 /* check for overflow */
375 if (adjusted_len
< len
)
377 ERR("overflow of adjusted_len %d, len %d\n", adjusted_len
, len
);
378 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
381 p
= pStubMsg
->pfnAllocate(adjusted_len
);
382 if (!p
) RpcRaiseException(ERROR_OUTOFMEMORY
);
384 mem_list
= (NDR_MEMORY_LIST
*)((char *)p
+ aligned_len
);
385 mem_list
->magic
= MEML_MAGIC
;
386 mem_list
->size
= aligned_len
;
387 mem_list
->reserved
= 0;
388 mem_list
->next
= pStubMsg
->pMemoryList
;
389 pStubMsg
->pMemoryList
= mem_list
;
395 static void WINAPI
NdrFree(MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *Pointer
)
397 TRACE("(%p, %p)\n", pStubMsg
, Pointer
);
399 pStubMsg
->pfnFree(Pointer
);
402 static inline BOOL
IsConformanceOrVariancePresent(PFORMAT_STRING pFormat
)
404 return (*(const ULONG
*)pFormat
!= -1);
407 static PFORMAT_STRING
ReadConformance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
)
409 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
410 if (pStubMsg
->Buffer
+ 4 > pStubMsg
->BufferEnd
)
411 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
412 pStubMsg
->MaxCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
413 pStubMsg
->Buffer
+= 4;
414 TRACE("unmarshalled conformance is %ld\n", pStubMsg
->MaxCount
);
415 if (pStubMsg
->fHasNewCorrDesc
)
421 static inline PFORMAT_STRING
ReadVariance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
, ULONG MaxValue
)
423 if (pFormat
&& !IsConformanceOrVariancePresent(pFormat
))
425 pStubMsg
->Offset
= 0;
426 pStubMsg
->ActualCount
= pStubMsg
->MaxCount
;
430 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
431 if (pStubMsg
->Buffer
+ 8 > pStubMsg
->BufferEnd
)
432 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
433 pStubMsg
->Offset
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
434 pStubMsg
->Buffer
+= 4;
435 TRACE("offset is %d\n", pStubMsg
->Offset
);
436 pStubMsg
->ActualCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
437 pStubMsg
->Buffer
+= 4;
438 TRACE("variance is %d\n", pStubMsg
->ActualCount
);
440 if ((pStubMsg
->ActualCount
> MaxValue
) ||
441 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> MaxValue
))
443 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
444 pStubMsg
->ActualCount
, pStubMsg
->Offset
, MaxValue
);
445 RpcRaiseException(RPC_S_INVALID_BOUND
);
450 if (pStubMsg
->fHasNewCorrDesc
)
456 /* writes the conformance value to the buffer */
457 static inline void WriteConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
459 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
460 if (pStubMsg
->Buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
461 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
462 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->MaxCount
);
463 pStubMsg
->Buffer
+= 4;
466 /* writes the variance values to the buffer */
467 static inline void WriteVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
469 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
470 if (pStubMsg
->Buffer
+ 8 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
471 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
472 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->Offset
);
473 pStubMsg
->Buffer
+= 4;
474 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->ActualCount
);
475 pStubMsg
->Buffer
+= 4;
478 /* requests buffer space for the conformance value */
479 static inline void SizeConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
481 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
482 if (pStubMsg
->BufferLength
+ 4 < pStubMsg
->BufferLength
)
483 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
484 pStubMsg
->BufferLength
+= 4;
487 /* requests buffer space for the variance values */
488 static inline void SizeVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
490 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
491 if (pStubMsg
->BufferLength
+ 8 < pStubMsg
->BufferLength
)
492 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
493 pStubMsg
->BufferLength
+= 8;
496 PFORMAT_STRING
ComputeConformanceOrVariance(
497 MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *pMemory
,
498 PFORMAT_STRING pFormat
, ULONG_PTR def
, ULONG_PTR
*pCount
)
500 BYTE dtype
= pFormat
[0] & 0xf;
501 short ofs
= *(const short *)&pFormat
[2];
505 if (!IsConformanceOrVariancePresent(pFormat
)) {
506 /* null descriptor */
511 switch (pFormat
[0] & 0xf0) {
512 case RPC_FC_NORMAL_CONFORMANCE
:
513 TRACE("normal conformance, ofs=%d\n", ofs
);
516 case RPC_FC_POINTER_CONFORMANCE
:
517 TRACE("pointer conformance, ofs=%d\n", ofs
);
518 ptr
= pStubMsg
->Memory
;
520 case RPC_FC_TOP_LEVEL_CONFORMANCE
:
521 TRACE("toplevel conformance, ofs=%d\n", ofs
);
522 if (pStubMsg
->StackTop
) {
523 ptr
= pStubMsg
->StackTop
;
526 /* -Os mode, *pCount is already set */
530 case RPC_FC_CONSTANT_CONFORMANCE
:
531 data
= ofs
| ((DWORD
)pFormat
[1] << 16);
532 TRACE("constant conformance, val=%d\n", data
);
535 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE
:
536 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs
);
537 if (pStubMsg
->StackTop
) {
538 ptr
= pStubMsg
->StackTop
;
546 FIXME("unknown conformance type %x\n", pFormat
[0] & 0xf0);
549 switch (pFormat
[1]) {
550 case RPC_FC_DEREFERENCE
:
551 ptr
= *(LPVOID
*)((char *)ptr
+ ofs
);
553 case RPC_FC_CALLBACK
:
555 unsigned char *old_stack_top
= pStubMsg
->StackTop
;
556 pStubMsg
->StackTop
= ptr
;
558 /* ofs is index into StubDesc->apfnExprEval */
559 TRACE("callback conformance into apfnExprEval[%d]\n", ofs
);
560 pStubMsg
->StubDesc
->apfnExprEval
[ofs
](pStubMsg
);
562 pStubMsg
->StackTop
= old_stack_top
;
564 /* the callback function always stores the computed value in MaxCount */
565 *pCount
= pStubMsg
->MaxCount
;
569 ptr
= (char *)ptr
+ ofs
;
582 data
= *(USHORT
*)ptr
;
593 FIXME("unknown conformance data type %x\n", dtype
);
596 TRACE("dereferenced data type %x at %p, got %d\n", dtype
, ptr
, data
);
599 switch (pFormat
[1]) {
600 case RPC_FC_DEREFERENCE
: /* already handled */
617 FIXME("unknown conformance op %d\n", pFormat
[1]);
622 TRACE("resulting conformance is %ld\n", *pCount
);
623 if (pStubMsg
->fHasNewCorrDesc
)
629 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
630 * the result overflows 32-bits */
631 static inline ULONG
safe_multiply(ULONG a
, ULONG b
)
633 ULONGLONG ret
= (ULONGLONG
)a
* b
;
634 if (ret
> 0xffffffff)
636 RpcRaiseException(RPC_S_INVALID_BOUND
);
642 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
644 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
645 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
646 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
647 pStubMsg
->Buffer
+= size
;
650 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
652 if (pStubMsg
->BufferLength
+ size
< pStubMsg
->BufferLength
) /* integer overflow of pStubMsg->BufferSize */
654 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
655 pStubMsg
->BufferLength
, size
);
656 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
658 pStubMsg
->BufferLength
+= size
;
661 /* copies data from the buffer, checking that there is enough data in the buffer
663 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, void *p
, ULONG size
)
665 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
666 (pStubMsg
->Buffer
+ size
> pStubMsg
->BufferEnd
))
668 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
669 pStubMsg
->Buffer
, pStubMsg
->BufferEnd
, size
);
670 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
672 if (p
== pStubMsg
->Buffer
)
673 ERR("pointer is the same as the buffer\n");
674 memcpy(p
, pStubMsg
->Buffer
, size
);
675 pStubMsg
->Buffer
+= size
;
678 /* copies data to the buffer, checking that there is enough space to do so */
679 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, const void *p
, ULONG size
)
681 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
682 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
684 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
685 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
,
687 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
689 memcpy(pStubMsg
->Buffer
, p
, size
);
690 pStubMsg
->Buffer
+= size
;
693 /* verify that string data sitting in the buffer is valid and safe to
695 static void validate_string_data(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG bufsize
, ULONG esize
)
699 /* verify the buffer is safe to access */
700 if ((pStubMsg
->Buffer
+ bufsize
< pStubMsg
->Buffer
) ||
701 (pStubMsg
->Buffer
+ bufsize
> pStubMsg
->BufferEnd
))
703 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize
,
704 pStubMsg
->BufferEnd
, pStubMsg
->Buffer
);
705 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
708 /* strings must always have null terminating bytes */
711 ERR("invalid string length of %d\n", bufsize
/ esize
);
712 RpcRaiseException(RPC_S_INVALID_BOUND
);
715 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
716 if (pStubMsg
->Buffer
[i
] != 0)
718 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
719 i
, pStubMsg
->Buffer
[i
]);
720 RpcRaiseException(RPC_S_INVALID_BOUND
);
725 * NdrConformantString:
727 * What MS calls a ConformantString is, in DCE terminology,
728 * a Varying-Conformant String.
730 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
731 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
732 * into unmarshalled string)
733 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
735 * data: CHARTYPE[maxlen]
737 * ], where CHARTYPE is the appropriate character type (specified externally)
741 /***********************************************************************
742 * NdrConformantStringMarshall [RPCRT4.@]
744 unsigned char *WINAPI
NdrConformantStringMarshall(MIDL_STUB_MESSAGE
*pStubMsg
,
745 unsigned char *pszMessage
, PFORMAT_STRING pFormat
)
749 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg
, pszMessage
, pFormat
);
751 if (*pFormat
== RPC_FC_C_CSTRING
) {
752 TRACE("string=%s\n", debugstr_a((char*)pszMessage
));
753 pStubMsg
->ActualCount
= strlen((char*)pszMessage
)+1;
756 else if (*pFormat
== RPC_FC_C_WSTRING
) {
757 TRACE("string=%s\n", debugstr_w((LPWSTR
)pszMessage
));
758 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pszMessage
)+1;
762 ERR("Unhandled string type: %#x\n", *pFormat
);
763 /* FIXME: raise an exception. */
767 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
768 pFormat
= ComputeConformance(pStubMsg
, pszMessage
, pFormat
+ 2, 0);
770 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
771 pStubMsg
->Offset
= 0;
772 WriteConformance(pStubMsg
);
773 WriteVariance(pStubMsg
);
775 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
776 safe_copy_to_buffer(pStubMsg
, pszMessage
, size
); /* the string itself */
779 return NULL
; /* is this always right? */
782 /***********************************************************************
783 * NdrConformantStringBufferSize [RPCRT4.@]
785 void WINAPI
NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
786 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
790 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
792 SizeConformance(pStubMsg
);
793 SizeVariance(pStubMsg
);
795 if (*pFormat
== RPC_FC_C_CSTRING
) {
796 TRACE("string=%s\n", debugstr_a((char*)pMemory
));
797 pStubMsg
->ActualCount
= strlen((char*)pMemory
)+1;
800 else if (*pFormat
== RPC_FC_C_WSTRING
) {
801 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
));
802 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
)+1;
806 ERR("Unhandled string type: %#x\n", *pFormat
);
807 /* FIXME: raise an exception */
811 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
812 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
814 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
816 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
819 /************************************************************************
820 * NdrConformantStringMemorySize [RPCRT4.@]
822 ULONG WINAPI
NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
823 PFORMAT_STRING pFormat
)
825 ULONG bufsize
, memsize
, esize
;
827 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
829 ReadConformance(pStubMsg
, NULL
);
830 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
832 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
834 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
835 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
836 RpcRaiseException(RPC_S_INVALID_BOUND
);
838 if (pStubMsg
->Offset
)
840 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
841 RpcRaiseException(RPC_S_INVALID_BOUND
);
844 if (*pFormat
== RPC_FC_C_CSTRING
) esize
= 1;
845 else if (*pFormat
== RPC_FC_C_WSTRING
) esize
= 2;
847 ERR("Unhandled string type: %#x\n", *pFormat
);
848 /* FIXME: raise an exception */
852 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
853 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
855 validate_string_data(pStubMsg
, bufsize
, esize
);
857 safe_buffer_increment(pStubMsg
, bufsize
);
858 pStubMsg
->MemorySize
+= memsize
;
860 return pStubMsg
->MemorySize
;
863 /************************************************************************
864 * NdrConformantStringUnmarshall [RPCRT4.@]
866 unsigned char *WINAPI
NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
867 unsigned char** ppMemory
, PFORMAT_STRING pFormat
, unsigned char fMustAlloc
)
869 ULONG bufsize
, memsize
, esize
;
871 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
872 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
874 assert(pFormat
&& ppMemory
&& pStubMsg
);
876 ReadConformance(pStubMsg
, NULL
);
877 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
879 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
881 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
882 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
883 RpcRaiseException(RPC_S_INVALID_BOUND
);
886 if (pStubMsg
->Offset
)
888 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
889 RpcRaiseException(RPC_S_INVALID_BOUND
);
893 if (*pFormat
== RPC_FC_C_CSTRING
) esize
= 1;
894 else if (*pFormat
== RPC_FC_C_WSTRING
) esize
= 2;
896 ERR("Unhandled string type: %#x\n", *pFormat
);
897 /* FIXME: raise an exception */
901 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
902 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
904 validate_string_data(pStubMsg
, bufsize
, esize
);
907 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
910 if (!pStubMsg
->IsClient
&& !*ppMemory
&& (pStubMsg
->MaxCount
== pStubMsg
->ActualCount
))
911 /* if the data in the RPC buffer is big enough, we just point straight
913 *ppMemory
= pStubMsg
->Buffer
;
915 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
918 if (*ppMemory
== pStubMsg
->Buffer
)
919 safe_buffer_increment(pStubMsg
, bufsize
);
921 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
923 if (*pFormat
== RPC_FC_C_CSTRING
) {
924 TRACE("string=%s\n", debugstr_a((char*)*ppMemory
));
926 else if (*pFormat
== RPC_FC_C_WSTRING
) {
927 TRACE("string=%s\n", debugstr_w((LPWSTR
)*ppMemory
));
930 return NULL
; /* FIXME: is this always right? */
933 /***********************************************************************
934 * NdrNonConformantStringMarshall [RPCRT4.@]
936 unsigned char * WINAPI
NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
937 unsigned char *pMemory
,
938 PFORMAT_STRING pFormat
)
940 ULONG esize
, size
, maxsize
;
942 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
944 maxsize
= *(USHORT
*)&pFormat
[2];
946 if (*pFormat
== RPC_FC_CSTRING
)
949 const char *str
= (const char *)pMemory
;
950 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
952 TRACE("string=%s\n", debugstr_an(str
, i
));
953 pStubMsg
->ActualCount
= i
+ 1;
956 else if (*pFormat
== RPC_FC_WSTRING
)
959 const WCHAR
*str
= (const WCHAR
*)pMemory
;
960 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
962 TRACE("string=%s\n", debugstr_wn(str
, i
));
963 pStubMsg
->ActualCount
= i
+ 1;
968 ERR("Unhandled string type: %#x\n", *pFormat
);
969 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
972 pStubMsg
->Offset
= 0;
973 WriteVariance(pStubMsg
);
975 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
976 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
981 /***********************************************************************
982 * NdrNonConformantStringUnmarshall [RPCRT4.@]
984 unsigned char * WINAPI
NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
985 unsigned char **ppMemory
,
986 PFORMAT_STRING pFormat
,
987 unsigned char fMustAlloc
)
989 ULONG bufsize
, memsize
, esize
, maxsize
;
991 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
992 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
994 maxsize
= *(USHORT
*)&pFormat
[2];
996 ReadVariance(pStubMsg
, NULL
, maxsize
);
997 if (pStubMsg
->Offset
)
999 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
1000 RpcRaiseException(RPC_S_INVALID_BOUND
);
1003 if (*pFormat
== RPC_FC_CSTRING
) esize
= 1;
1004 else if (*pFormat
== RPC_FC_WSTRING
) esize
= 2;
1007 ERR("Unhandled string type: %#x\n", *pFormat
);
1008 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1011 memsize
= esize
* maxsize
;
1012 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1014 validate_string_data(pStubMsg
, bufsize
, esize
);
1016 if (fMustAlloc
|| !*ppMemory
)
1017 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
1019 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
1021 if (*pFormat
== RPC_FC_CSTRING
) {
1022 TRACE("string=%s\n", debugstr_an((char*)*ppMemory
, pStubMsg
->ActualCount
));
1024 else if (*pFormat
== RPC_FC_WSTRING
) {
1025 TRACE("string=%s\n", debugstr_wn((LPWSTR
)*ppMemory
, pStubMsg
->ActualCount
));
1031 /***********************************************************************
1032 * NdrNonConformantStringBufferSize [RPCRT4.@]
1034 void WINAPI
NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1035 unsigned char *pMemory
,
1036 PFORMAT_STRING pFormat
)
1038 ULONG esize
, maxsize
;
1040 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
1042 maxsize
= *(USHORT
*)&pFormat
[2];
1044 SizeVariance(pStubMsg
);
1046 if (*pFormat
== RPC_FC_CSTRING
)
1049 const char *str
= (const char *)pMemory
;
1050 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
1052 TRACE("string=%s\n", debugstr_an(str
, i
));
1053 pStubMsg
->ActualCount
= i
+ 1;
1056 else if (*pFormat
== RPC_FC_WSTRING
)
1059 const WCHAR
*str
= (const WCHAR
*)pMemory
;
1060 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
1062 TRACE("string=%s\n", debugstr_wn(str
, i
));
1063 pStubMsg
->ActualCount
= i
+ 1;
1068 ERR("Unhandled string type: %#x\n", *pFormat
);
1069 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1072 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
1075 /***********************************************************************
1076 * NdrNonConformantStringMemorySize [RPCRT4.@]
1078 ULONG WINAPI
NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1079 PFORMAT_STRING pFormat
)
1081 ULONG bufsize
, memsize
, esize
, maxsize
;
1083 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
1085 maxsize
= *(USHORT
*)&pFormat
[2];
1087 ReadVariance(pStubMsg
, NULL
, maxsize
);
1089 if (pStubMsg
->Offset
)
1091 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
1092 RpcRaiseException(RPC_S_INVALID_BOUND
);
1095 if (*pFormat
== RPC_FC_CSTRING
) esize
= 1;
1096 else if (*pFormat
== RPC_FC_WSTRING
) esize
= 2;
1099 ERR("Unhandled string type: %#x\n", *pFormat
);
1100 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1103 memsize
= esize
* maxsize
;
1104 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1106 validate_string_data(pStubMsg
, bufsize
, esize
);
1108 safe_buffer_increment(pStubMsg
, bufsize
);
1109 pStubMsg
->MemorySize
+= memsize
;
1111 return pStubMsg
->MemorySize
;
1114 static inline void dump_pointer_attr(unsigned char attr
)
1116 if (attr
& RPC_FC_P_ALLOCALLNODES
)
1117 TRACE(" RPC_FC_P_ALLOCALLNODES");
1118 if (attr
& RPC_FC_P_DONTFREE
)
1119 TRACE(" RPC_FC_P_DONTFREE");
1120 if (attr
& RPC_FC_P_ONSTACK
)
1121 TRACE(" RPC_FC_P_ONSTACK");
1122 if (attr
& RPC_FC_P_SIMPLEPOINTER
)
1123 TRACE(" RPC_FC_P_SIMPLEPOINTER");
1124 if (attr
& RPC_FC_P_DEREF
)
1125 TRACE(" RPC_FC_P_DEREF");
1129 /***********************************************************************
1130 * PointerMarshall [internal]
1132 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1133 unsigned char *Buffer
,
1134 unsigned char *Pointer
,
1135 PFORMAT_STRING pFormat
)
1137 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1138 PFORMAT_STRING desc
;
1141 int pointer_needs_marshaling
;
1143 TRACE("(%p,%p,%p,%p)\n", pStubMsg
, Buffer
, Pointer
, pFormat
);
1144 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1146 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1147 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1150 case RPC_FC_RP
: /* ref pointer (always non-null) */
1153 ERR("NULL ref pointer is not allowed\n");
1154 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
1156 pointer_needs_marshaling
= 1;
1158 case RPC_FC_UP
: /* unique pointer */
1159 case RPC_FC_OP
: /* object pointer - same as unique here */
1161 pointer_needs_marshaling
= 1;
1163 pointer_needs_marshaling
= 0;
1164 pointer_id
= Pointer
? NDR_POINTER_ID(pStubMsg
) : 0;
1165 TRACE("writing 0x%08x to buffer\n", pointer_id
);
1166 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
1169 pointer_needs_marshaling
= !NdrFullPointerQueryPointer(
1170 pStubMsg
->FullPtrXlatTables
, Pointer
, 1, &pointer_id
);
1171 TRACE("writing 0x%08x to buffer\n", pointer_id
);
1172 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
1175 FIXME("unhandled ptr type=%02x\n", type
);
1176 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1180 TRACE("calling marshaller for type 0x%x\n", (int)*desc
);
1182 if (pointer_needs_marshaling
) {
1183 if (attr
& RPC_FC_P_DEREF
) {
1184 Pointer
= *(unsigned char**)Pointer
;
1185 TRACE("deref => %p\n", Pointer
);
1187 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
1188 if (m
) m(pStubMsg
, Pointer
, desc
);
1189 else FIXME("no marshaller for data type=%02x\n", *desc
);
1192 STD_OVERFLOW_CHECK(pStubMsg
);
1195 /***********************************************************************
1196 * PointerUnmarshall [internal]
1198 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1199 unsigned char *Buffer
,
1200 unsigned char **pPointer
,
1201 unsigned char *pSrcPointer
,
1202 PFORMAT_STRING pFormat
,
1203 unsigned char fMustAlloc
)
1205 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1206 PFORMAT_STRING desc
;
1208 DWORD pointer_id
= 0;
1209 int pointer_needs_unmarshaling
;
1211 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg
, Buffer
, pPointer
, pSrcPointer
, pFormat
, fMustAlloc
);
1212 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1214 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1215 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1218 case RPC_FC_RP
: /* ref pointer (always non-null) */
1219 pointer_needs_unmarshaling
= 1;
1221 case RPC_FC_UP
: /* unique pointer */
1222 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1223 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1225 pointer_needs_unmarshaling
= 1;
1228 pointer_needs_unmarshaling
= 0;
1231 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
1232 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1233 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1234 if (!fMustAlloc
&& pSrcPointer
)
1236 FIXME("free object pointer %p\n", pSrcPointer
);
1240 pointer_needs_unmarshaling
= 1;
1242 pointer_needs_unmarshaling
= 0;
1245 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1246 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1247 pointer_needs_unmarshaling
= !NdrFullPointerQueryRefId(
1248 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, (void **)pPointer
);
1251 FIXME("unhandled ptr type=%02x\n", type
);
1252 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1256 if (pointer_needs_unmarshaling
) {
1257 unsigned char *base_ptr_val
= *pPointer
;
1258 unsigned char **current_ptr
= pPointer
;
1259 if (pStubMsg
->IsClient
) {
1261 /* if we aren't forcing allocation of memory then try to use the existing
1262 * (source) pointer to unmarshall the data into so that [in,out]
1263 * parameters behave correctly. it doesn't matter if the parameter is
1264 * [out] only since in that case the pointer will be NULL. we force
1265 * allocation when the source pointer is NULL here instead of in the type
1266 * unmarshalling routine for the benefit of the deref code below */
1269 TRACE("setting *pPointer to %p\n", pSrcPointer
);
1270 *pPointer
= base_ptr_val
= pSrcPointer
;
1276 /* the memory in a stub is never initialised, so we have to work out here
1277 * whether we have to initialise it so we can use the optimisation of
1278 * setting the pointer to the buffer, if possible, or set fMustAlloc to
1280 if (attr
& RPC_FC_P_DEREF
) {
1283 base_ptr_val
= NULL
;
1284 *current_ptr
= NULL
;
1288 if (attr
& RPC_FC_P_ALLOCALLNODES
)
1289 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
1291 if (attr
& RPC_FC_P_DEREF
) {
1293 base_ptr_val
= NdrAllocate(pStubMsg
, sizeof(void *));
1294 *pPointer
= base_ptr_val
;
1295 current_ptr
= (unsigned char **)base_ptr_val
;
1297 current_ptr
= *(unsigned char***)current_ptr
;
1298 TRACE("deref => %p\n", current_ptr
);
1299 if (!fMustAlloc
&& !*current_ptr
) fMustAlloc
= TRUE
;
1301 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
1302 if (m
) m(pStubMsg
, current_ptr
, desc
, fMustAlloc
);
1303 else FIXME("no unmarshaller for data type=%02x\n", *desc
);
1305 if (type
== RPC_FC_FP
)
1306 NdrFullPointerInsertRefId(pStubMsg
->FullPtrXlatTables
, pointer_id
,
1310 TRACE("pointer=%p\n", *pPointer
);
1313 /***********************************************************************
1314 * PointerBufferSize [internal]
1316 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1317 unsigned char *Pointer
,
1318 PFORMAT_STRING pFormat
)
1320 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1321 PFORMAT_STRING desc
;
1323 int pointer_needs_sizing
;
1326 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1327 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1329 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1330 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1333 case RPC_FC_RP
: /* ref pointer (always non-null) */
1336 ERR("NULL ref pointer is not allowed\n");
1337 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
1342 /* NULL pointer has no further representation */
1347 pointer_needs_sizing
= !NdrFullPointerQueryPointer(
1348 pStubMsg
->FullPtrXlatTables
, Pointer
, 0, &pointer_id
);
1349 if (!pointer_needs_sizing
)
1353 FIXME("unhandled ptr type=%02x\n", type
);
1354 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1358 if (attr
& RPC_FC_P_DEREF
) {
1359 Pointer
= *(unsigned char**)Pointer
;
1360 TRACE("deref => %p\n", Pointer
);
1363 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
1364 if (m
) m(pStubMsg
, Pointer
, desc
);
1365 else FIXME("no buffersizer for data type=%02x\n", *desc
);
1368 /***********************************************************************
1369 * PointerMemorySize [internal]
1371 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1372 unsigned char *Buffer
,
1373 PFORMAT_STRING pFormat
)
1375 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1376 PFORMAT_STRING desc
;
1378 DWORD pointer_id
= 0;
1379 int pointer_needs_sizing
;
1381 TRACE("(%p,%p,%p)\n", pStubMsg
, Buffer
, pFormat
);
1382 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1384 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1385 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1388 case RPC_FC_RP
: /* ref pointer (always non-null) */
1389 pointer_needs_sizing
= 1;
1391 case RPC_FC_UP
: /* unique pointer */
1392 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
1393 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1394 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1396 pointer_needs_sizing
= 1;
1398 pointer_needs_sizing
= 0;
1403 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1404 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1405 pointer_needs_sizing
= !NdrFullPointerQueryRefId(
1406 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, &pointer
);
1410 FIXME("unhandled ptr type=%02x\n", type
);
1411 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1415 if (attr
& RPC_FC_P_DEREF
) {
1419 if (pointer_needs_sizing
) {
1420 m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
1421 if (m
) m(pStubMsg
, desc
);
1422 else FIXME("no memorysizer for data type=%02x\n", *desc
);
1425 return pStubMsg
->MemorySize
;
1428 /***********************************************************************
1429 * PointerFree [internal]
1431 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1432 unsigned char *Pointer
,
1433 PFORMAT_STRING pFormat
)
1435 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1436 PFORMAT_STRING desc
;
1438 unsigned char *current_pointer
= Pointer
;
1440 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1441 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1442 if (attr
& RPC_FC_P_DONTFREE
) return;
1444 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1445 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1447 if (!Pointer
) return;
1449 if (type
== RPC_FC_FP
) {
1450 int pointer_needs_freeing
= NdrFullPointerFree(
1451 pStubMsg
->FullPtrXlatTables
, Pointer
);
1452 if (!pointer_needs_freeing
)
1456 if (attr
& RPC_FC_P_DEREF
) {
1457 current_pointer
= *(unsigned char**)Pointer
;
1458 TRACE("deref => %p\n", current_pointer
);
1461 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
1462 if (m
) m(pStubMsg
, current_pointer
, desc
);
1464 /* this check stops us from trying to free buffer memory. we don't have to
1465 * worry about clients, since they won't call this function.
1466 * we don't have to check for the buffer being reallocated because
1467 * BufferStart and BufferEnd won't be reset when allocating memory for
1468 * sending the response. we don't have to check for the new buffer here as
1469 * it won't be used a type memory, only for buffer memory */
1470 if (Pointer
>= pStubMsg
->BufferStart
&& Pointer
< pStubMsg
->BufferEnd
)
1473 if (attr
& RPC_FC_P_ONSTACK
) {
1474 TRACE("not freeing stack ptr %p\n", Pointer
);
1477 TRACE("freeing %p\n", Pointer
);
1478 NdrFree(pStubMsg
, Pointer
);
1481 TRACE("not freeing %p\n", Pointer
);
1484 /***********************************************************************
1485 * EmbeddedPointerMarshall
1487 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1488 unsigned char *pMemory
,
1489 PFORMAT_STRING pFormat
)
1491 unsigned char *Mark
= pStubMsg
->BufferMark
;
1492 unsigned rep
, count
, stride
;
1494 unsigned char *saved_buffer
= NULL
;
1496 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1498 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1501 if (pStubMsg
->PointerBufferMark
)
1503 saved_buffer
= pStubMsg
->Buffer
;
1504 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1505 pStubMsg
->PointerBufferMark
= NULL
;
1508 while (pFormat
[0] != RPC_FC_END
) {
1509 switch (pFormat
[0]) {
1511 FIXME("unknown repeat type %d\n", pFormat
[0]);
1512 case RPC_FC_NO_REPEAT
:
1518 case RPC_FC_FIXED_REPEAT
:
1519 rep
= *(const WORD
*)&pFormat
[2];
1520 stride
= *(const WORD
*)&pFormat
[4];
1521 count
= *(const WORD
*)&pFormat
[8];
1524 case RPC_FC_VARIABLE_REPEAT
:
1525 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1526 stride
= *(const WORD
*)&pFormat
[2];
1527 count
= *(const WORD
*)&pFormat
[6];
1531 for (i
= 0; i
< rep
; i
++) {
1532 PFORMAT_STRING info
= pFormat
;
1533 unsigned char *membase
= pMemory
+ (i
* stride
);
1534 unsigned char *bufbase
= Mark
+ (i
* stride
);
1537 for (u
=0; u
<count
; u
++,info
+=8) {
1538 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1539 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1540 unsigned char *saved_memory
= pStubMsg
->Memory
;
1542 pStubMsg
->Memory
= pMemory
;
1543 PointerMarshall(pStubMsg
, bufptr
, *(unsigned char**)memptr
, info
+4);
1544 pStubMsg
->Memory
= saved_memory
;
1547 pFormat
+= 8 * count
;
1552 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1553 pStubMsg
->Buffer
= saved_buffer
;
1556 STD_OVERFLOW_CHECK(pStubMsg
);
1561 /***********************************************************************
1562 * EmbeddedPointerUnmarshall
1564 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1565 unsigned char *pDstBuffer
,
1566 unsigned char *pSrcMemoryPtrs
,
1567 PFORMAT_STRING pFormat
,
1568 unsigned char fMustAlloc
)
1570 unsigned char *Mark
= pStubMsg
->BufferMark
;
1571 unsigned rep
, count
, stride
;
1573 unsigned char *saved_buffer
= NULL
;
1575 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg
, pDstBuffer
, pSrcMemoryPtrs
, pFormat
, fMustAlloc
);
1577 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1580 if (pStubMsg
->PointerBufferMark
)
1582 saved_buffer
= pStubMsg
->Buffer
;
1583 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1584 pStubMsg
->PointerBufferMark
= NULL
;
1587 while (pFormat
[0] != RPC_FC_END
) {
1588 TRACE("pFormat[0] = 0x%x\n", pFormat
[0]);
1589 switch (pFormat
[0]) {
1591 FIXME("unknown repeat type %d\n", pFormat
[0]);
1592 case RPC_FC_NO_REPEAT
:
1598 case RPC_FC_FIXED_REPEAT
:
1599 rep
= *(const WORD
*)&pFormat
[2];
1600 stride
= *(const WORD
*)&pFormat
[4];
1601 count
= *(const WORD
*)&pFormat
[8];
1604 case RPC_FC_VARIABLE_REPEAT
:
1605 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1606 stride
= *(const WORD
*)&pFormat
[2];
1607 count
= *(const WORD
*)&pFormat
[6];
1611 for (i
= 0; i
< rep
; i
++) {
1612 PFORMAT_STRING info
= pFormat
;
1613 unsigned char *bufdstbase
= pDstBuffer
+ (i
* stride
);
1614 unsigned char *memsrcbase
= pSrcMemoryPtrs
+ (i
* stride
);
1615 unsigned char *bufbase
= Mark
+ (i
* stride
);
1618 for (u
=0; u
<count
; u
++,info
+=8) {
1619 unsigned char **bufdstptr
= (unsigned char **)(bufdstbase
+ *(const SHORT
*)&info
[2]);
1620 unsigned char **memsrcptr
= (unsigned char **)(memsrcbase
+ *(const SHORT
*)&info
[0]);
1621 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1622 PointerUnmarshall(pStubMsg
, bufptr
, bufdstptr
, *memsrcptr
, info
+4, fMustAlloc
);
1625 pFormat
+= 8 * count
;
1630 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1631 pStubMsg
->Buffer
= saved_buffer
;
1637 /***********************************************************************
1638 * EmbeddedPointerBufferSize
1640 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1641 unsigned char *pMemory
,
1642 PFORMAT_STRING pFormat
)
1644 unsigned rep
, count
, stride
;
1646 ULONG saved_buffer_length
= 0;
1648 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1650 if (pStubMsg
->IgnoreEmbeddedPointers
) return;
1652 if (*pFormat
!= RPC_FC_PP
) return;
1655 if (pStubMsg
->PointerLength
)
1657 saved_buffer_length
= pStubMsg
->BufferLength
;
1658 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
1659 pStubMsg
->PointerLength
= 0;
1662 while (pFormat
[0] != RPC_FC_END
) {
1663 switch (pFormat
[0]) {
1665 FIXME("unknown repeat type %d\n", pFormat
[0]);
1666 case RPC_FC_NO_REPEAT
:
1672 case RPC_FC_FIXED_REPEAT
:
1673 rep
= *(const WORD
*)&pFormat
[2];
1674 stride
= *(const WORD
*)&pFormat
[4];
1675 count
= *(const WORD
*)&pFormat
[8];
1678 case RPC_FC_VARIABLE_REPEAT
:
1679 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1680 stride
= *(const WORD
*)&pFormat
[2];
1681 count
= *(const WORD
*)&pFormat
[6];
1685 for (i
= 0; i
< rep
; i
++) {
1686 PFORMAT_STRING info
= pFormat
;
1687 unsigned char *membase
= pMemory
+ (i
* stride
);
1690 for (u
=0; u
<count
; u
++,info
+=8) {
1691 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1692 unsigned char *saved_memory
= pStubMsg
->Memory
;
1694 pStubMsg
->Memory
= pMemory
;
1695 PointerBufferSize(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1696 pStubMsg
->Memory
= saved_memory
;
1699 pFormat
+= 8 * count
;
1702 if (saved_buffer_length
)
1704 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
1705 pStubMsg
->BufferLength
= saved_buffer_length
;
1709 /***********************************************************************
1710 * EmbeddedPointerMemorySize [internal]
1712 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1713 PFORMAT_STRING pFormat
)
1715 unsigned char *Mark
= pStubMsg
->BufferMark
;
1716 unsigned rep
, count
, stride
;
1718 unsigned char *saved_buffer
= NULL
;
1720 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1722 if (pStubMsg
->IgnoreEmbeddedPointers
) return 0;
1724 if (pStubMsg
->PointerBufferMark
)
1726 saved_buffer
= pStubMsg
->Buffer
;
1727 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1728 pStubMsg
->PointerBufferMark
= NULL
;
1731 if (*pFormat
!= RPC_FC_PP
) return 0;
1734 while (pFormat
[0] != RPC_FC_END
) {
1735 switch (pFormat
[0]) {
1737 FIXME("unknown repeat type %d\n", pFormat
[0]);
1738 case RPC_FC_NO_REPEAT
:
1744 case RPC_FC_FIXED_REPEAT
:
1745 rep
= *(const WORD
*)&pFormat
[2];
1746 stride
= *(const WORD
*)&pFormat
[4];
1747 count
= *(const WORD
*)&pFormat
[8];
1750 case RPC_FC_VARIABLE_REPEAT
:
1751 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1752 stride
= *(const WORD
*)&pFormat
[2];
1753 count
= *(const WORD
*)&pFormat
[6];
1757 for (i
= 0; i
< rep
; i
++) {
1758 PFORMAT_STRING info
= pFormat
;
1759 unsigned char *bufbase
= Mark
+ (i
* stride
);
1761 for (u
=0; u
<count
; u
++,info
+=8) {
1762 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1763 PointerMemorySize(pStubMsg
, bufptr
, info
+4);
1766 pFormat
+= 8 * count
;
1771 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1772 pStubMsg
->Buffer
= saved_buffer
;
1778 /***********************************************************************
1779 * EmbeddedPointerFree [internal]
1781 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1782 unsigned char *pMemory
,
1783 PFORMAT_STRING pFormat
)
1785 unsigned rep
, count
, stride
;
1788 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1789 if (*pFormat
!= RPC_FC_PP
) return;
1792 while (pFormat
[0] != RPC_FC_END
) {
1793 switch (pFormat
[0]) {
1795 FIXME("unknown repeat type %d\n", pFormat
[0]);
1796 case RPC_FC_NO_REPEAT
:
1802 case RPC_FC_FIXED_REPEAT
:
1803 rep
= *(const WORD
*)&pFormat
[2];
1804 stride
= *(const WORD
*)&pFormat
[4];
1805 count
= *(const WORD
*)&pFormat
[8];
1808 case RPC_FC_VARIABLE_REPEAT
:
1809 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1810 stride
= *(const WORD
*)&pFormat
[2];
1811 count
= *(const WORD
*)&pFormat
[6];
1815 for (i
= 0; i
< rep
; i
++) {
1816 PFORMAT_STRING info
= pFormat
;
1817 unsigned char *membase
= pMemory
+ (i
* stride
);
1820 for (u
=0; u
<count
; u
++,info
+=8) {
1821 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1822 unsigned char *saved_memory
= pStubMsg
->Memory
;
1824 pStubMsg
->Memory
= pMemory
;
1825 PointerFree(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1826 pStubMsg
->Memory
= saved_memory
;
1829 pFormat
+= 8 * count
;
1833 /***********************************************************************
1834 * NdrPointerMarshall [RPCRT4.@]
1836 unsigned char * WINAPI
NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1837 unsigned char *pMemory
,
1838 PFORMAT_STRING pFormat
)
1840 unsigned char *Buffer
;
1842 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1844 /* Increment the buffer here instead of in PointerMarshall,
1845 * as that is used by embedded pointers which already handle the incrementing
1846 * the buffer, and shouldn't write any additional pointer data to the wire */
1847 if (*pFormat
!= RPC_FC_RP
)
1849 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
1850 Buffer
= pStubMsg
->Buffer
;
1851 safe_buffer_increment(pStubMsg
, 4);
1854 Buffer
= pStubMsg
->Buffer
;
1856 PointerMarshall(pStubMsg
, Buffer
, pMemory
, pFormat
);
1861 /***********************************************************************
1862 * NdrPointerUnmarshall [RPCRT4.@]
1864 unsigned char * WINAPI
NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1865 unsigned char **ppMemory
,
1866 PFORMAT_STRING pFormat
,
1867 unsigned char fMustAlloc
)
1869 unsigned char *Buffer
;
1871 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1873 /* Increment the buffer here instead of in PointerUnmarshall,
1874 * as that is used by embedded pointers which already handle the incrementing
1875 * the buffer, and shouldn't read any additional pointer data from the
1877 if (*pFormat
!= RPC_FC_RP
)
1879 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1880 Buffer
= pStubMsg
->Buffer
;
1881 safe_buffer_increment(pStubMsg
, 4);
1884 Buffer
= pStubMsg
->Buffer
;
1886 PointerUnmarshall(pStubMsg
, Buffer
, ppMemory
, *ppMemory
, pFormat
, fMustAlloc
);
1891 /***********************************************************************
1892 * NdrPointerBufferSize [RPCRT4.@]
1894 void WINAPI
NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1895 unsigned char *pMemory
,
1896 PFORMAT_STRING pFormat
)
1898 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1900 /* Increment the buffer length here instead of in PointerBufferSize,
1901 * as that is used by embedded pointers which already handle the buffer
1902 * length, and shouldn't write anything more to the wire */
1903 if (*pFormat
!= RPC_FC_RP
)
1905 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
1906 safe_buffer_length_increment(pStubMsg
, 4);
1909 PointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1912 /***********************************************************************
1913 * NdrPointerMemorySize [RPCRT4.@]
1915 ULONG WINAPI
NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1916 PFORMAT_STRING pFormat
)
1918 /* unsigned size = *(LPWORD)(pFormat+2); */
1919 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1920 PointerMemorySize(pStubMsg
, pStubMsg
->Buffer
, pFormat
);
1924 /***********************************************************************
1925 * NdrPointerFree [RPCRT4.@]
1927 void WINAPI
NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1928 unsigned char *pMemory
,
1929 PFORMAT_STRING pFormat
)
1931 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1932 PointerFree(pStubMsg
, pMemory
, pFormat
);
1935 /***********************************************************************
1936 * NdrSimpleTypeMarshall [RPCRT4.@]
1938 void WINAPI
NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1939 unsigned char FormatChar
)
1941 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &FormatChar
);
1944 /***********************************************************************
1945 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1947 * Unmarshall a base type.
1950 * Doesn't check that the buffer is long enough before copying, so the caller
1953 void WINAPI
NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1954 unsigned char FormatChar
)
1956 #define BASE_TYPE_UNMARSHALL(type) \
1957 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
1958 TRACE("pMemory: %p\n", pMemory); \
1959 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1960 pStubMsg->Buffer += sizeof(type);
1968 BASE_TYPE_UNMARSHALL(UCHAR
);
1969 TRACE("value: 0x%02x\n", *pMemory
);
1974 BASE_TYPE_UNMARSHALL(USHORT
);
1975 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
1979 case RPC_FC_ERROR_STATUS_T
:
1981 BASE_TYPE_UNMARSHALL(ULONG
);
1982 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
1985 BASE_TYPE_UNMARSHALL(float);
1986 TRACE("value: %f\n", *(float *)pMemory
);
1989 BASE_TYPE_UNMARSHALL(double);
1990 TRACE("value: %f\n", *(double *)pMemory
);
1993 BASE_TYPE_UNMARSHALL(ULONGLONG
);
1994 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
1997 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
1998 TRACE("pMemory: %p\n", pMemory
);
1999 /* 16-bits on the wire, but int in memory */
2000 *(UINT
*)pMemory
= *(USHORT
*)pStubMsg
->Buffer
;
2001 pStubMsg
->Buffer
+= sizeof(USHORT
);
2002 TRACE("value: 0x%08x\n", *(UINT
*)pMemory
);
2007 FIXME("Unhandled base type: 0x%02x\n", FormatChar
);
2009 #undef BASE_TYPE_UNMARSHALL
2012 /***********************************************************************
2013 * NdrSimpleStructMarshall [RPCRT4.@]
2015 unsigned char * WINAPI
NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2016 unsigned char *pMemory
,
2017 PFORMAT_STRING pFormat
)
2019 unsigned size
= *(const WORD
*)(pFormat
+2);
2020 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2022 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pFormat
[1] + 1);
2024 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2025 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
2027 if (pFormat
[0] != RPC_FC_STRUCT
)
2028 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
+4);
2033 /***********************************************************************
2034 * NdrSimpleStructUnmarshall [RPCRT4.@]
2036 unsigned char * WINAPI
NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2037 unsigned char **ppMemory
,
2038 PFORMAT_STRING pFormat
,
2039 unsigned char fMustAlloc
)
2041 unsigned size
= *(const WORD
*)(pFormat
+2);
2042 unsigned char *saved_buffer
;
2043 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2045 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2048 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2051 if (!pStubMsg
->IsClient
&& !*ppMemory
)
2052 /* for servers, we just point straight into the RPC buffer */
2053 *ppMemory
= pStubMsg
->Buffer
;
2056 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2057 safe_buffer_increment(pStubMsg
, size
);
2058 if (pFormat
[0] == RPC_FC_PSTRUCT
)
2059 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
+4, fMustAlloc
);
2061 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
2062 if (*ppMemory
!= saved_buffer
)
2063 memcpy(*ppMemory
, saved_buffer
, size
);
2068 /***********************************************************************
2069 * NdrSimpleStructBufferSize [RPCRT4.@]
2071 void WINAPI
NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2072 unsigned char *pMemory
,
2073 PFORMAT_STRING pFormat
)
2075 unsigned size
= *(const WORD
*)(pFormat
+2);
2076 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2078 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
2080 safe_buffer_length_increment(pStubMsg
, size
);
2081 if (pFormat
[0] != RPC_FC_STRUCT
)
2082 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
+4);
2085 /***********************************************************************
2086 * NdrSimpleStructMemorySize [RPCRT4.@]
2088 ULONG WINAPI
NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2089 PFORMAT_STRING pFormat
)
2091 unsigned short size
= *(const WORD
*)(pFormat
+2);
2093 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2095 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2096 pStubMsg
->MemorySize
+= size
;
2097 safe_buffer_increment(pStubMsg
, size
);
2099 if (pFormat
[0] != RPC_FC_STRUCT
)
2100 EmbeddedPointerMemorySize(pStubMsg
, pFormat
+4);
2101 return pStubMsg
->MemorySize
;
2104 /***********************************************************************
2105 * NdrSimpleStructFree [RPCRT4.@]
2107 void WINAPI
NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
2108 unsigned char *pMemory
,
2109 PFORMAT_STRING pFormat
)
2111 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2112 if (pFormat
[0] != RPC_FC_STRUCT
)
2113 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
+4);
2117 #include "pshpack1.h"
2121 unsigned char flags_type
; /* flags in upper nibble, type in lower nibble */
2125 #include "poppack.h"
2127 static unsigned long EmbeddedComplexSize(MIDL_STUB_MESSAGE
*pStubMsg
,
2128 PFORMAT_STRING pFormat
)
2132 case RPC_FC_PSTRUCT
:
2133 case RPC_FC_CSTRUCT
:
2134 case RPC_FC_BOGUS_STRUCT
:
2135 case RPC_FC_SMFARRAY
:
2136 case RPC_FC_SMVARRAY
:
2137 case RPC_FC_CSTRING
:
2138 return *(const WORD
*)&pFormat
[2];
2139 case RPC_FC_USER_MARSHAL
:
2140 return *(const WORD
*)&pFormat
[4];
2141 case RPC_FC_RANGE
: {
2142 switch (((const NDR_RANGE
*)pFormat
)->flags_type
& 0xf) {
2147 return sizeof(UCHAR
);
2151 return sizeof(USHORT
);
2155 return sizeof(ULONG
);
2157 return sizeof(float);
2159 return sizeof(double);
2161 return sizeof(ULONGLONG
);
2162 case RPC_FC_ERROR_STATUS_T
:
2163 return sizeof(error_status_t
);
2165 return sizeof(UINT
);
2167 ERR("unknown type 0x%x\n", ((const NDR_RANGE
*)pFormat
)->flags_type
& 0xf);
2168 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2171 case RPC_FC_NON_ENCAPSULATED_UNION
:
2173 if (pStubMsg
->fHasNewCorrDesc
)
2178 pFormat
+= *(const SHORT
*)pFormat
;
2179 return *(const SHORT
*)pFormat
;
2181 return sizeof(void *);
2182 case RPC_FC_WSTRING
:
2183 return *(const WORD
*)&pFormat
[2] * 2;
2185 FIXME("unhandled embedded type %02x\n", *pFormat
);
2191 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2192 PFORMAT_STRING pFormat
)
2194 NDR_MEMORYSIZE m
= NdrMemorySizer
[*pFormat
& NDR_TABLE_MASK
];
2198 FIXME("no memorysizer for data type=%02x\n", *pFormat
);
2202 return m(pStubMsg
, pFormat
);
2206 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2207 unsigned char *pMemory
,
2208 PFORMAT_STRING pFormat
,
2209 PFORMAT_STRING pPointer
)
2211 PFORMAT_STRING desc
;
2215 while (*pFormat
!= RPC_FC_END
) {
2221 TRACE("byte=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2222 safe_copy_to_buffer(pStubMsg
, pMemory
, 1);
2228 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2229 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
2233 TRACE("enum16=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2234 if (32767 < *(DWORD
*)pMemory
)
2235 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
2236 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
2242 TRACE("long=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2243 safe_copy_to_buffer(pStubMsg
, pMemory
, 4);
2247 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2248 safe_copy_to_buffer(pStubMsg
, pMemory
, 8);
2251 case RPC_FC_POINTER
:
2253 unsigned char *saved_buffer
;
2254 int pointer_buffer_mark_set
= 0;
2255 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
2256 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
2257 saved_buffer
= pStubMsg
->Buffer
;
2258 if (pStubMsg
->PointerBufferMark
)
2260 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2261 pStubMsg
->PointerBufferMark
= NULL
;
2262 pointer_buffer_mark_set
= 1;
2265 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2266 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char**)pMemory
, pPointer
);
2267 if (pointer_buffer_mark_set
)
2269 STD_OVERFLOW_CHECK(pStubMsg
);
2270 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2271 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
2273 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2274 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
2275 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2277 pStubMsg
->Buffer
= saved_buffer
+ 4;
2283 case RPC_FC_ALIGNM4
:
2284 ALIGN_POINTER(pMemory
, 4);
2286 case RPC_FC_ALIGNM8
:
2287 ALIGN_POINTER(pMemory
, 8);
2289 case RPC_FC_STRUCTPAD1
:
2290 case RPC_FC_STRUCTPAD2
:
2291 case RPC_FC_STRUCTPAD3
:
2292 case RPC_FC_STRUCTPAD4
:
2293 case RPC_FC_STRUCTPAD5
:
2294 case RPC_FC_STRUCTPAD6
:
2295 case RPC_FC_STRUCTPAD7
:
2296 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2298 case RPC_FC_EMBEDDED_COMPLEX
:
2299 pMemory
+= pFormat
[1];
2301 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2302 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2303 TRACE("embedded complex (size=%ld) <= %p\n", size
, pMemory
);
2304 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
2307 /* for some reason interface pointers aren't generated as
2308 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2309 * they still need the derefencing treatment that pointers are
2311 if (*desc
== RPC_FC_IP
)
2312 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2314 m(pStubMsg
, pMemory
, desc
);
2316 else FIXME("no marshaller for embedded type %02x\n", *desc
);
2323 FIXME("unhandled format 0x%02x\n", *pFormat
);
2331 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2332 unsigned char *pMemory
,
2333 PFORMAT_STRING pFormat
,
2334 PFORMAT_STRING pPointer
,
2335 unsigned char fMustAlloc
)
2337 PFORMAT_STRING desc
;
2341 while (*pFormat
!= RPC_FC_END
) {
2347 safe_copy_from_buffer(pStubMsg
, pMemory
, 1);
2348 TRACE("byte=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2354 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
2355 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2359 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
2360 *(DWORD
*)pMemory
&= 0xffff;
2361 TRACE("enum16=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
2362 if (32767 < *(DWORD
*)pMemory
)
2363 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
2369 safe_copy_from_buffer(pStubMsg
, pMemory
, 4);
2370 TRACE("long=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
2374 safe_copy_from_buffer(pStubMsg
, pMemory
, 8);
2375 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2378 case RPC_FC_POINTER
:
2380 unsigned char *saved_buffer
;
2381 int pointer_buffer_mark_set
= 0;
2382 TRACE("pointer => %p\n", pMemory
);
2383 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2384 saved_buffer
= pStubMsg
->Buffer
;
2385 if (pStubMsg
->PointerBufferMark
)
2387 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2388 pStubMsg
->PointerBufferMark
= NULL
;
2389 pointer_buffer_mark_set
= 1;
2392 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2394 PointerUnmarshall(pStubMsg
, saved_buffer
, (unsigned char**)pMemory
, *(unsigned char**)pMemory
, pPointer
, fMustAlloc
);
2395 if (pointer_buffer_mark_set
)
2397 STD_OVERFLOW_CHECK(pStubMsg
);
2398 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2399 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
2401 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2402 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
2403 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2405 pStubMsg
->Buffer
= saved_buffer
+ 4;
2411 case RPC_FC_ALIGNM4
:
2412 ALIGN_POINTER_CLEAR(pMemory
, 4);
2414 case RPC_FC_ALIGNM8
:
2415 ALIGN_POINTER_CLEAR(pMemory
, 8);
2417 case RPC_FC_STRUCTPAD1
:
2418 case RPC_FC_STRUCTPAD2
:
2419 case RPC_FC_STRUCTPAD3
:
2420 case RPC_FC_STRUCTPAD4
:
2421 case RPC_FC_STRUCTPAD5
:
2422 case RPC_FC_STRUCTPAD6
:
2423 case RPC_FC_STRUCTPAD7
:
2424 memset(pMemory
, 0, *pFormat
- RPC_FC_STRUCTPAD1
+ 1);
2425 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2427 case RPC_FC_EMBEDDED_COMPLEX
:
2428 pMemory
+= pFormat
[1];
2430 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2431 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2432 TRACE("embedded complex (size=%ld) => %p\n", size
, pMemory
);
2433 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
2436 /* for some reason interface pointers aren't generated as
2437 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2438 * they still need the derefencing treatment that pointers are
2440 if (*desc
== RPC_FC_IP
)
2441 m(pStubMsg
, (unsigned char **)pMemory
, desc
, FALSE
);
2443 m(pStubMsg
, &pMemory
, desc
, FALSE
);
2445 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
2452 FIXME("unhandled format %d\n", *pFormat
);
2460 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2461 unsigned char *pMemory
,
2462 PFORMAT_STRING pFormat
,
2463 PFORMAT_STRING pPointer
)
2465 PFORMAT_STRING desc
;
2469 while (*pFormat
!= RPC_FC_END
) {
2475 safe_buffer_length_increment(pStubMsg
, 1);
2481 safe_buffer_length_increment(pStubMsg
, 2);
2485 safe_buffer_length_increment(pStubMsg
, 2);
2491 safe_buffer_length_increment(pStubMsg
, 4);
2495 safe_buffer_length_increment(pStubMsg
, 8);
2498 case RPC_FC_POINTER
:
2499 if (!pStubMsg
->IgnoreEmbeddedPointers
)
2501 int saved_buffer_length
= pStubMsg
->BufferLength
;
2502 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2503 pStubMsg
->PointerLength
= 0;
2504 if(!pStubMsg
->BufferLength
)
2505 ERR("BufferLength == 0??\n");
2506 PointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
2507 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2508 pStubMsg
->BufferLength
= saved_buffer_length
;
2510 safe_buffer_length_increment(pStubMsg
, 4);
2514 case RPC_FC_ALIGNM4
:
2515 ALIGN_POINTER(pMemory
, 4);
2517 case RPC_FC_ALIGNM8
:
2518 ALIGN_POINTER(pMemory
, 8);
2520 case RPC_FC_STRUCTPAD1
:
2521 case RPC_FC_STRUCTPAD2
:
2522 case RPC_FC_STRUCTPAD3
:
2523 case RPC_FC_STRUCTPAD4
:
2524 case RPC_FC_STRUCTPAD5
:
2525 case RPC_FC_STRUCTPAD6
:
2526 case RPC_FC_STRUCTPAD7
:
2527 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2529 case RPC_FC_EMBEDDED_COMPLEX
:
2530 pMemory
+= pFormat
[1];
2532 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2533 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2534 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
2537 /* for some reason interface pointers aren't generated as
2538 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2539 * they still need the derefencing treatment that pointers are
2541 if (*desc
== RPC_FC_IP
)
2542 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2544 m(pStubMsg
, pMemory
, desc
);
2546 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
2553 FIXME("unhandled format 0x%02x\n", *pFormat
);
2561 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
2562 unsigned char *pMemory
,
2563 PFORMAT_STRING pFormat
,
2564 PFORMAT_STRING pPointer
)
2566 PFORMAT_STRING desc
;
2570 while (*pFormat
!= RPC_FC_END
) {
2592 case RPC_FC_POINTER
:
2593 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
2597 case RPC_FC_ALIGNM4
:
2598 ALIGN_POINTER(pMemory
, 4);
2600 case RPC_FC_ALIGNM8
:
2601 ALIGN_POINTER(pMemory
, 8);
2603 case RPC_FC_STRUCTPAD1
:
2604 case RPC_FC_STRUCTPAD2
:
2605 case RPC_FC_STRUCTPAD3
:
2606 case RPC_FC_STRUCTPAD4
:
2607 case RPC_FC_STRUCTPAD5
:
2608 case RPC_FC_STRUCTPAD6
:
2609 case RPC_FC_STRUCTPAD7
:
2610 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2612 case RPC_FC_EMBEDDED_COMPLEX
:
2613 pMemory
+= pFormat
[1];
2615 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2616 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2617 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
2620 /* for some reason interface pointers aren't generated as
2621 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2622 * they still need the derefencing treatment that pointers are
2624 if (*desc
== RPC_FC_IP
)
2625 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2627 m(pStubMsg
, pMemory
, desc
);
2635 FIXME("unhandled format 0x%02x\n", *pFormat
);
2643 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2644 PFORMAT_STRING pFormat
)
2646 PFORMAT_STRING desc
;
2647 unsigned long size
= 0;
2649 while (*pFormat
!= RPC_FC_END
) {
2656 safe_buffer_increment(pStubMsg
, 1);
2662 safe_buffer_increment(pStubMsg
, 2);
2666 safe_buffer_increment(pStubMsg
, 2);
2672 safe_buffer_increment(pStubMsg
, 4);
2676 safe_buffer_increment(pStubMsg
, 8);
2678 case RPC_FC_POINTER
:
2680 safe_buffer_increment(pStubMsg
, 4);
2681 if (!pStubMsg
->IgnoreEmbeddedPointers
)
2682 FIXME("embedded pointers\n");
2684 case RPC_FC_ALIGNM4
:
2685 ALIGN_LENGTH(size
, 4);
2686 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2688 case RPC_FC_ALIGNM8
:
2689 ALIGN_LENGTH(size
, 8);
2690 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
2692 case RPC_FC_STRUCTPAD1
:
2693 case RPC_FC_STRUCTPAD2
:
2694 case RPC_FC_STRUCTPAD3
:
2695 case RPC_FC_STRUCTPAD4
:
2696 case RPC_FC_STRUCTPAD5
:
2697 case RPC_FC_STRUCTPAD6
:
2698 case RPC_FC_STRUCTPAD7
:
2699 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2701 case RPC_FC_EMBEDDED_COMPLEX
:
2704 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2705 size
+= EmbeddedComplexMemorySize(pStubMsg
, desc
);
2711 FIXME("unhandled format 0x%02x\n", *pFormat
);
2719 unsigned long ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg
,
2720 PFORMAT_STRING pFormat
)
2722 PFORMAT_STRING desc
;
2723 unsigned long size
= 0;
2725 while (*pFormat
!= RPC_FC_END
) {
2747 case RPC_FC_POINTER
:
2748 size
+= sizeof(void *);
2750 case RPC_FC_ALIGNM4
:
2751 ALIGN_LENGTH(size
, 4);
2753 case RPC_FC_ALIGNM8
:
2754 ALIGN_LENGTH(size
, 8);
2756 case RPC_FC_STRUCTPAD1
:
2757 case RPC_FC_STRUCTPAD2
:
2758 case RPC_FC_STRUCTPAD3
:
2759 case RPC_FC_STRUCTPAD4
:
2760 case RPC_FC_STRUCTPAD5
:
2761 case RPC_FC_STRUCTPAD6
:
2762 case RPC_FC_STRUCTPAD7
:
2763 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2765 case RPC_FC_EMBEDDED_COMPLEX
:
2768 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2769 size
+= EmbeddedComplexSize(pStubMsg
, desc
);
2775 FIXME("unhandled format 0x%02x\n", *pFormat
);
2783 /***********************************************************************
2784 * NdrComplexStructMarshall [RPCRT4.@]
2786 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2787 unsigned char *pMemory
,
2788 PFORMAT_STRING pFormat
)
2790 PFORMAT_STRING conf_array
= NULL
;
2791 PFORMAT_STRING pointer_desc
= NULL
;
2792 unsigned char *OldMemory
= pStubMsg
->Memory
;
2793 int pointer_buffer_mark_set
= 0;
2795 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2797 if (!pStubMsg
->PointerBufferMark
)
2799 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2800 /* save buffer length */
2801 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2803 /* get the buffer pointer after complex array data, but before
2805 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- pStubMsg
->BufferStart
;
2806 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2807 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
2808 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2810 /* save it for use by embedded pointer code later */
2811 pStubMsg
->PointerBufferMark
= pStubMsg
->BufferStart
+ pStubMsg
->BufferLength
;
2812 TRACE("difference = 0x%x\n", pStubMsg
->PointerBufferMark
- pStubMsg
->Buffer
);
2813 pointer_buffer_mark_set
= 1;
2815 /* restore the original buffer length */
2816 pStubMsg
->BufferLength
= saved_buffer_length
;
2819 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pFormat
[1] + 1);
2822 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
2824 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2827 pStubMsg
->Memory
= pMemory
;
2829 ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2832 NdrConformantArrayMarshall(pStubMsg
, pMemory
, conf_array
);
2834 pStubMsg
->Memory
= OldMemory
;
2836 if (pointer_buffer_mark_set
)
2838 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2839 pStubMsg
->PointerBufferMark
= NULL
;
2842 STD_OVERFLOW_CHECK(pStubMsg
);
2847 /***********************************************************************
2848 * NdrComplexStructUnmarshall [RPCRT4.@]
2850 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2851 unsigned char **ppMemory
,
2852 PFORMAT_STRING pFormat
,
2853 unsigned char fMustAlloc
)
2855 unsigned size
= *(const WORD
*)(pFormat
+2);
2856 PFORMAT_STRING conf_array
= NULL
;
2857 PFORMAT_STRING pointer_desc
= NULL
;
2858 unsigned char *pMemory
;
2859 int pointer_buffer_mark_set
= 0;
2861 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2863 if (!pStubMsg
->PointerBufferMark
)
2865 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2866 /* save buffer pointer */
2867 unsigned char *saved_buffer
= pStubMsg
->Buffer
;
2869 /* get the buffer pointer after complex array data, but before
2871 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2872 NdrComplexStructMemorySize(pStubMsg
, pFormat
);
2873 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2875 /* save it for use by embedded pointer code later */
2876 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2877 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->PointerBufferMark
- saved_buffer
));
2878 pointer_buffer_mark_set
= 1;
2880 /* restore the original buffer */
2881 pStubMsg
->Buffer
= saved_buffer
;
2884 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2886 if (fMustAlloc
|| !*ppMemory
)
2887 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2890 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
2892 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2895 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
, fMustAlloc
);
2898 NdrConformantArrayUnmarshall(pStubMsg
, &pMemory
, conf_array
, fMustAlloc
);
2900 if (pointer_buffer_mark_set
)
2902 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2903 pStubMsg
->PointerBufferMark
= NULL
;
2909 /***********************************************************************
2910 * NdrComplexStructBufferSize [RPCRT4.@]
2912 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2913 unsigned char *pMemory
,
2914 PFORMAT_STRING pFormat
)
2916 PFORMAT_STRING conf_array
= NULL
;
2917 PFORMAT_STRING pointer_desc
= NULL
;
2918 unsigned char *OldMemory
= pStubMsg
->Memory
;
2919 int pointer_length_set
= 0;
2921 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2923 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
2925 if(!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
2927 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2928 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2930 /* get the buffer length after complex struct data, but before
2932 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2933 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
2934 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2936 /* save it for use by embedded pointer code later */
2937 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2938 pointer_length_set
= 1;
2939 TRACE("difference = 0x%lx\n", pStubMsg
->PointerLength
- saved_buffer_length
);
2941 /* restore the original buffer length */
2942 pStubMsg
->BufferLength
= saved_buffer_length
;
2946 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
2948 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2951 pStubMsg
->Memory
= pMemory
;
2953 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2956 NdrConformantArrayBufferSize(pStubMsg
, pMemory
, conf_array
);
2958 pStubMsg
->Memory
= OldMemory
;
2960 if(pointer_length_set
)
2962 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2963 pStubMsg
->PointerLength
= 0;
2968 /***********************************************************************
2969 * NdrComplexStructMemorySize [RPCRT4.@]
2971 ULONG WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2972 PFORMAT_STRING pFormat
)
2974 unsigned size
= *(const WORD
*)(pFormat
+2);
2975 PFORMAT_STRING conf_array
= NULL
;
2977 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2979 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2982 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
2985 ComplexStructMemorySize(pStubMsg
, pFormat
);
2988 NdrConformantArrayMemorySize(pStubMsg
, conf_array
);
2993 /***********************************************************************
2994 * NdrComplexStructFree [RPCRT4.@]
2996 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
2997 unsigned char *pMemory
,
2998 PFORMAT_STRING pFormat
)
3000 PFORMAT_STRING conf_array
= NULL
;
3001 PFORMAT_STRING pointer_desc
= NULL
;
3002 unsigned char *OldMemory
= pStubMsg
->Memory
;
3004 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3007 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3009 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3012 pStubMsg
->Memory
= pMemory
;
3014 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3017 NdrConformantArrayFree(pStubMsg
, pMemory
, conf_array
);
3019 pStubMsg
->Memory
= OldMemory
;
3022 /***********************************************************************
3023 * NdrConformantArrayMarshall [RPCRT4.@]
3025 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3026 unsigned char *pMemory
,
3027 PFORMAT_STRING pFormat
)
3029 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
3030 unsigned char alignment
= pFormat
[1] + 1;
3032 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3033 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
3035 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
3037 WriteConformance(pStubMsg
);
3039 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
3041 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3042 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3043 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
3045 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3050 /***********************************************************************
3051 * NdrConformantArrayUnmarshall [RPCRT4.@]
3053 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3054 unsigned char **ppMemory
,
3055 PFORMAT_STRING pFormat
,
3056 unsigned char fMustAlloc
)
3058 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
3059 unsigned char alignment
= pFormat
[1] + 1;
3060 unsigned char *saved_buffer
;
3062 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3063 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
3065 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
3067 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3068 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3071 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3074 if (!pStubMsg
->IsClient
&& !*ppMemory
)
3075 /* for servers, we just point straight into the RPC buffer */
3076 *ppMemory
= pStubMsg
->Buffer
;
3079 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3080 safe_buffer_increment(pStubMsg
, size
);
3081 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
3083 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
3084 if (*ppMemory
!= saved_buffer
)
3085 memcpy(*ppMemory
, saved_buffer
, size
);
3090 /***********************************************************************
3091 * NdrConformantArrayBufferSize [RPCRT4.@]
3093 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3094 unsigned char *pMemory
,
3095 PFORMAT_STRING pFormat
)
3097 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
3098 unsigned char alignment
= pFormat
[1] + 1;
3100 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3101 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
3103 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
3105 SizeConformance(pStubMsg
);
3107 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
3109 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3110 /* conformance value plus array */
3111 safe_buffer_length_increment(pStubMsg
, size
);
3113 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3116 /***********************************************************************
3117 * NdrConformantArrayMemorySize [RPCRT4.@]
3119 ULONG WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3120 PFORMAT_STRING pFormat
)
3122 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
3123 unsigned char alignment
= pFormat
[1] + 1;
3125 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3126 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
3128 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
3129 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3130 pStubMsg
->MemorySize
+= size
;
3132 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3133 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3134 safe_buffer_increment(pStubMsg
, size
);
3136 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
3138 return pStubMsg
->MemorySize
;
3141 /***********************************************************************
3142 * NdrConformantArrayFree [RPCRT4.@]
3144 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3145 unsigned char *pMemory
,
3146 PFORMAT_STRING pFormat
)
3148 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3149 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
3151 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
3153 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
3157 /***********************************************************************
3158 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3160 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
3161 unsigned char* pMemory
,
3162 PFORMAT_STRING pFormat
)
3165 unsigned char alignment
= pFormat
[1] + 1;
3166 DWORD esize
= *(const WORD
*)(pFormat
+2);
3168 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3170 if (pFormat
[0] != RPC_FC_CVARRAY
)
3172 ERR("invalid format type %x\n", pFormat
[0]);
3173 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3177 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
3178 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
3180 WriteConformance(pStubMsg
);
3181 WriteVariance(pStubMsg
);
3183 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
3185 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3187 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3188 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
3190 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3196 /***********************************************************************
3197 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
3199 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
3200 unsigned char** ppMemory
,
3201 PFORMAT_STRING pFormat
,
3202 unsigned char fMustAlloc
)
3204 ULONG bufsize
, memsize
;
3205 unsigned char alignment
= pFormat
[1] + 1;
3206 DWORD esize
= *(const WORD
*)(pFormat
+2);
3207 unsigned char *saved_buffer
;
3210 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3212 if (pFormat
[0] != RPC_FC_CVARRAY
)
3214 ERR("invalid format type %x\n", pFormat
[0]);
3215 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3219 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
3220 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3222 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3224 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3225 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3226 offset
= pStubMsg
->Offset
;
3228 if (!*ppMemory
|| fMustAlloc
)
3229 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
3230 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3231 safe_buffer_increment(pStubMsg
, bufsize
);
3233 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
3235 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
3241 /***********************************************************************
3242 * NdrConformantVaryingArrayFree [RPCRT4.@]
3244 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
3245 unsigned char* pMemory
,
3246 PFORMAT_STRING pFormat
)
3248 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3250 if (pFormat
[0] != RPC_FC_CVARRAY
)
3252 ERR("invalid format type %x\n", pFormat
[0]);
3253 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3257 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
3258 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
3260 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
3264 /***********************************************************************
3265 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
3267 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
3268 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
3270 unsigned char alignment
= pFormat
[1] + 1;
3271 DWORD esize
= *(const WORD
*)(pFormat
+2);
3273 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3275 if (pFormat
[0] != RPC_FC_CVARRAY
)
3277 ERR("invalid format type %x\n", pFormat
[0]);
3278 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3283 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
3284 /* compute length */
3285 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
3287 SizeConformance(pStubMsg
);
3288 SizeVariance(pStubMsg
);
3290 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
3292 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
3294 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3298 /***********************************************************************
3299 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
3301 ULONG WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
3302 PFORMAT_STRING pFormat
)
3304 ULONG bufsize
, memsize
;
3305 unsigned char alignment
= pFormat
[1] + 1;
3306 DWORD esize
= *(const WORD
*)(pFormat
+2);
3308 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
3310 if (pFormat
[0] != RPC_FC_CVARRAY
)
3312 ERR("invalid format type %x\n", pFormat
[0]);
3313 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3314 return pStubMsg
->MemorySize
;
3317 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
3318 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3320 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3322 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3323 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3325 safe_buffer_increment(pStubMsg
, bufsize
);
3326 pStubMsg
->MemorySize
+= memsize
;
3328 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
3330 return pStubMsg
->MemorySize
;
3334 /***********************************************************************
3335 * NdrComplexArrayMarshall [RPCRT4.@]
3337 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3338 unsigned char *pMemory
,
3339 PFORMAT_STRING pFormat
)
3341 ULONG i
, count
, def
;
3342 BOOL variance_present
;
3343 unsigned char alignment
;
3344 int pointer_buffer_mark_set
= 0;
3346 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3348 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3350 ERR("invalid format type %x\n", pFormat
[0]);
3351 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3355 alignment
= pFormat
[1] + 1;
3357 if (!pStubMsg
->PointerBufferMark
)
3359 /* save buffer fields that may be changed by buffer sizer functions
3360 * and that may be needed later on */
3361 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3362 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
3363 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
3364 unsigned long saved_offset
= pStubMsg
->Offset
;
3365 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
3367 /* get the buffer pointer after complex array data, but before
3369 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- pStubMsg
->BufferStart
;
3370 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3371 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
3372 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3374 /* save it for use by embedded pointer code later */
3375 pStubMsg
->PointerBufferMark
= pStubMsg
->BufferStart
+ pStubMsg
->BufferLength
;
3376 TRACE("difference = 0x%x\n", pStubMsg
->Buffer
- pStubMsg
->BufferStart
);
3377 pointer_buffer_mark_set
= 1;
3379 /* restore fields */
3380 pStubMsg
->ActualCount
= saved_actual_count
;
3381 pStubMsg
->Offset
= saved_offset
;
3382 pStubMsg
->MaxCount
= saved_max_count
;
3383 pStubMsg
->BufferLength
= saved_buffer_length
;
3386 def
= *(const WORD
*)&pFormat
[2];
3389 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3390 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3392 variance_present
= IsConformanceOrVariancePresent(pFormat
);
3393 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3394 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3396 WriteConformance(pStubMsg
);
3397 if (variance_present
)
3398 WriteVariance(pStubMsg
);
3400 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
3402 count
= pStubMsg
->ActualCount
;
3403 for (i
= 0; i
< count
; i
++)
3404 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
3406 STD_OVERFLOW_CHECK(pStubMsg
);
3408 if (pointer_buffer_mark_set
)
3410 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3411 pStubMsg
->PointerBufferMark
= NULL
;
3417 /***********************************************************************
3418 * NdrComplexArrayUnmarshall [RPCRT4.@]
3420 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3421 unsigned char **ppMemory
,
3422 PFORMAT_STRING pFormat
,
3423 unsigned char fMustAlloc
)
3425 ULONG i
, count
, size
;
3426 unsigned char alignment
;
3427 unsigned char *pMemory
;
3428 unsigned char *saved_buffer
;
3429 int pointer_buffer_mark_set
= 0;
3430 int saved_ignore_embedded
;
3432 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3434 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3436 ERR("invalid format type %x\n", pFormat
[0]);
3437 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3441 alignment
= pFormat
[1] + 1;
3443 saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3444 /* save buffer pointer */
3445 saved_buffer
= pStubMsg
->Buffer
;
3446 /* get the buffer pointer after complex array data, but before
3448 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3449 pStubMsg
->MemorySize
= 0;
3450 NdrComplexArrayMemorySize(pStubMsg
, pFormat
);
3451 size
= pStubMsg
->MemorySize
;
3452 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3454 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->Buffer
- saved_buffer
));
3455 if (!pStubMsg
->PointerBufferMark
)
3457 /* save it for use by embedded pointer code later */
3458 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3459 pointer_buffer_mark_set
= 1;
3461 /* restore the original buffer */
3462 pStubMsg
->Buffer
= saved_buffer
;
3466 pFormat
= ReadConformance(pStubMsg
, pFormat
);
3467 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3469 if (fMustAlloc
|| !*ppMemory
)
3470 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3472 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3474 pMemory
= *ppMemory
;
3475 count
= pStubMsg
->ActualCount
;
3476 for (i
= 0; i
< count
; i
++)
3477 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
, fMustAlloc
);
3479 if (pointer_buffer_mark_set
)
3481 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3482 pStubMsg
->PointerBufferMark
= NULL
;
3488 /***********************************************************************
3489 * NdrComplexArrayBufferSize [RPCRT4.@]
3491 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3492 unsigned char *pMemory
,
3493 PFORMAT_STRING pFormat
)
3495 ULONG i
, count
, def
;
3496 unsigned char alignment
;
3497 BOOL variance_present
;
3498 int pointer_length_set
= 0;
3500 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3502 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3504 ERR("invalid format type %x\n", pFormat
[0]);
3505 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3509 alignment
= pFormat
[1] + 1;
3511 if (!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
3513 /* save buffer fields that may be changed by buffer sizer functions
3514 * and that may be needed later on */
3515 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3516 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
3517 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
3518 unsigned long saved_offset
= pStubMsg
->Offset
;
3519 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
3521 /* get the buffer pointer after complex array data, but before
3523 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3524 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
3525 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3527 /* save it for use by embedded pointer code later */
3528 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3529 pointer_length_set
= 1;
3531 /* restore fields */
3532 pStubMsg
->ActualCount
= saved_actual_count
;
3533 pStubMsg
->Offset
= saved_offset
;
3534 pStubMsg
->MaxCount
= saved_max_count
;
3535 pStubMsg
->BufferLength
= saved_buffer_length
;
3537 def
= *(const WORD
*)&pFormat
[2];
3540 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3541 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3542 SizeConformance(pStubMsg
);
3544 variance_present
= IsConformanceOrVariancePresent(pFormat
);
3545 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3546 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3548 if (variance_present
)
3549 SizeVariance(pStubMsg
);
3551 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
3553 count
= pStubMsg
->ActualCount
;
3554 for (i
= 0; i
< count
; i
++)
3555 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
3557 if(pointer_length_set
)
3559 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3560 pStubMsg
->PointerLength
= 0;
3564 /***********************************************************************
3565 * NdrComplexArrayMemorySize [RPCRT4.@]
3567 ULONG WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3568 PFORMAT_STRING pFormat
)
3570 ULONG i
, count
, esize
, SavedMemorySize
, MemorySize
;
3571 unsigned char alignment
;
3573 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3575 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3577 ERR("invalid format type %x\n", pFormat
[0]);
3578 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3582 alignment
= pFormat
[1] + 1;
3586 pFormat
= ReadConformance(pStubMsg
, pFormat
);
3587 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3589 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3591 SavedMemorySize
= pStubMsg
->MemorySize
;
3593 esize
= ComplexStructSize(pStubMsg
, pFormat
);
3595 MemorySize
= safe_multiply(pStubMsg
->MaxCount
, esize
);
3597 count
= pStubMsg
->ActualCount
;
3598 for (i
= 0; i
< count
; i
++)
3599 ComplexStructMemorySize(pStubMsg
, pFormat
);
3601 pStubMsg
->MemorySize
= SavedMemorySize
;
3603 pStubMsg
->MemorySize
+= MemorySize
;
3607 /***********************************************************************
3608 * NdrComplexArrayFree [RPCRT4.@]
3610 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3611 unsigned char *pMemory
,
3612 PFORMAT_STRING pFormat
)
3614 ULONG i
, count
, def
;
3616 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3618 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3620 ERR("invalid format type %x\n", pFormat
[0]);
3621 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3625 def
= *(const WORD
*)&pFormat
[2];
3628 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3629 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3631 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3632 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3634 count
= pStubMsg
->ActualCount
;
3635 for (i
= 0; i
< count
; i
++)
3636 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
3639 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg
,
3640 USER_MARSHAL_CB_TYPE cbtype
, PFORMAT_STRING pFormat
,
3641 USER_MARSHAL_CB
*umcb
)
3643 umcb
->Flags
= MAKELONG(pStubMsg
->dwDestContext
,
3644 pStubMsg
->RpcMsg
->DataRepresentation
);
3645 umcb
->pStubMsg
= pStubMsg
;
3646 umcb
->pReserve
= NULL
;
3647 umcb
->Signature
= USER_MARSHAL_CB_SIGNATURE
;
3648 umcb
->CBType
= cbtype
;
3649 umcb
->pFormat
= pFormat
;
3650 umcb
->pTypeFormat
= NULL
/* FIXME */;
3653 #define USER_MARSHAL_PTR_PREFIX \
3654 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3655 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3657 /***********************************************************************
3658 * NdrUserMarshalMarshall [RPCRT4.@]
3660 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3661 unsigned char *pMemory
,
3662 PFORMAT_STRING pFormat
)
3664 unsigned flags
= pFormat
[1];
3665 unsigned index
= *(const WORD
*)&pFormat
[2];
3666 unsigned char *saved_buffer
= NULL
;
3667 USER_MARSHAL_CB umcb
;
3669 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3670 TRACE("index=%d\n", index
);
3672 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_MARSHALL
, pFormat
, &umcb
);
3674 if (flags
& USER_MARSHAL_POINTER
)
3676 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
3677 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, USER_MARSHAL_PTR_PREFIX
);
3678 pStubMsg
->Buffer
+= 4;
3679 if (pStubMsg
->PointerBufferMark
)
3681 saved_buffer
= pStubMsg
->Buffer
;
3682 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3683 pStubMsg
->PointerBufferMark
= NULL
;
3685 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 8);
3688 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3691 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
3692 &umcb
.Flags
, pStubMsg
->Buffer
, pMemory
);
3696 STD_OVERFLOW_CHECK(pStubMsg
);
3697 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3698 pStubMsg
->Buffer
= saved_buffer
;
3701 STD_OVERFLOW_CHECK(pStubMsg
);
3706 /***********************************************************************
3707 * NdrUserMarshalUnmarshall [RPCRT4.@]
3709 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3710 unsigned char **ppMemory
,
3711 PFORMAT_STRING pFormat
,
3712 unsigned char fMustAlloc
)
3714 unsigned flags
= pFormat
[1];
3715 unsigned index
= *(const WORD
*)&pFormat
[2];
3716 DWORD memsize
= *(const WORD
*)&pFormat
[4];
3717 unsigned char *saved_buffer
= NULL
;
3718 USER_MARSHAL_CB umcb
;
3720 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3721 TRACE("index=%d\n", index
);
3723 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_UNMARSHALL
, pFormat
, &umcb
);
3725 if (flags
& USER_MARSHAL_POINTER
)
3727 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3728 /* skip pointer prefix */
3729 pStubMsg
->Buffer
+= 4;
3730 if (pStubMsg
->PointerBufferMark
)
3732 saved_buffer
= pStubMsg
->Buffer
;
3733 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3734 pStubMsg
->PointerBufferMark
= NULL
;
3736 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3739 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3741 if (fMustAlloc
|| !*ppMemory
)
3742 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
3745 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
3746 &umcb
.Flags
, pStubMsg
->Buffer
, *ppMemory
);
3750 STD_OVERFLOW_CHECK(pStubMsg
);
3751 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3752 pStubMsg
->Buffer
= saved_buffer
;
3758 /***********************************************************************
3759 * NdrUserMarshalBufferSize [RPCRT4.@]
3761 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3762 unsigned char *pMemory
,
3763 PFORMAT_STRING pFormat
)
3765 unsigned flags
= pFormat
[1];
3766 unsigned index
= *(const WORD
*)&pFormat
[2];
3767 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
3768 USER_MARSHAL_CB umcb
;
3769 unsigned long saved_buffer_length
= 0;
3771 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3772 TRACE("index=%d\n", index
);
3774 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_BUFFER_SIZE
, pFormat
, &umcb
);
3776 if (flags
& USER_MARSHAL_POINTER
)
3778 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
3779 /* skip pointer prefix */
3780 safe_buffer_length_increment(pStubMsg
, 4);
3781 if (pStubMsg
->IgnoreEmbeddedPointers
)
3783 if (pStubMsg
->PointerLength
)
3785 saved_buffer_length
= pStubMsg
->BufferLength
;
3786 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3787 pStubMsg
->PointerLength
= 0;
3789 ALIGN_LENGTH(pStubMsg
->BufferLength
, 8);
3792 ALIGN_LENGTH(pStubMsg
->BufferLength
, (flags
& 0xf) + 1);
3795 TRACE("size=%d\n", bufsize
);
3796 safe_buffer_length_increment(pStubMsg
, bufsize
);
3799 pStubMsg
->BufferLength
=
3800 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
3801 &umcb
.Flags
, pStubMsg
->BufferLength
, pMemory
);
3803 if (saved_buffer_length
)
3805 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3806 pStubMsg
->BufferLength
= saved_buffer_length
;
3811 /***********************************************************************
3812 * NdrUserMarshalMemorySize [RPCRT4.@]
3814 ULONG WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3815 PFORMAT_STRING pFormat
)
3817 unsigned flags
= pFormat
[1];
3818 unsigned index
= *(const WORD
*)&pFormat
[2];
3819 DWORD memsize
= *(const WORD
*)&pFormat
[4];
3820 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
3822 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3823 TRACE("index=%d\n", index
);
3825 pStubMsg
->MemorySize
+= memsize
;
3827 if (flags
& USER_MARSHAL_POINTER
)
3829 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3830 /* skip pointer prefix */
3831 pStubMsg
->Buffer
+= 4;
3832 if (pStubMsg
->IgnoreEmbeddedPointers
)
3833 return pStubMsg
->MemorySize
;
3834 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3837 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3840 FIXME("not implemented for varying buffer size\n");
3842 pStubMsg
->Buffer
+= bufsize
;
3844 return pStubMsg
->MemorySize
;
3847 /***********************************************************************
3848 * NdrUserMarshalFree [RPCRT4.@]
3850 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
3851 unsigned char *pMemory
,
3852 PFORMAT_STRING pFormat
)
3854 /* unsigned flags = pFormat[1]; */
3855 unsigned index
= *(const WORD
*)&pFormat
[2];
3856 USER_MARSHAL_CB umcb
;
3858 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3859 TRACE("index=%d\n", index
);
3861 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_FREE
, pFormat
, &umcb
);
3863 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
3864 &umcb
.Flags
, pMemory
);
3867 /***********************************************************************
3868 * NdrClearOutParameters [RPCRT4.@]
3870 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
3871 PFORMAT_STRING pFormat
,
3874 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
3877 /***********************************************************************
3878 * NdrConvert [RPCRT4.@]
3880 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
3882 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
3883 /* FIXME: since this stub doesn't do any converting, the proper behavior
3884 is to raise an exception */
3887 /***********************************************************************
3888 * NdrConvert2 [RPCRT4.@]
3890 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, LONG NumberParams
)
3892 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3893 pStubMsg
, pFormat
, NumberParams
);
3894 /* FIXME: since this stub doesn't do any converting, the proper behavior
3895 is to raise an exception */
3898 #include "pshpack1.h"
3899 typedef struct _NDR_CSTRUCT_FORMAT
3902 unsigned char alignment
;
3903 unsigned short memory_size
;
3904 short offset_to_array_description
;
3905 } NDR_CSTRUCT_FORMAT
, NDR_CVSTRUCT_FORMAT
;
3906 #include "poppack.h"
3908 /***********************************************************************
3909 * NdrConformantStructMarshall [RPCRT4.@]
3911 unsigned char * WINAPI
NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3912 unsigned char *pMemory
,
3913 PFORMAT_STRING pFormat
)
3915 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3916 PFORMAT_STRING pCArrayFormat
;
3917 ULONG esize
, bufsize
;
3919 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3921 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3922 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3924 ERR("invalid format type %x\n", pCStructFormat
->type
);
3925 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3929 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3930 pCStructFormat
->offset_to_array_description
;
3931 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3933 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3934 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3937 esize
= *(const WORD
*)(pCArrayFormat
+2);
3939 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
3940 pCArrayFormat
+ 4, 0);
3942 WriteConformance(pStubMsg
);
3944 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
3946 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3948 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3949 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
3951 ERR("integer overflow of memory_size %u with bufsize %u\n",
3952 pCStructFormat
->memory_size
, bufsize
);
3953 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3955 /* copy constant sized part of struct */
3956 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3957 safe_copy_to_buffer(pStubMsg
, pMemory
, pCStructFormat
->memory_size
+ bufsize
);
3959 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3960 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3965 /***********************************************************************
3966 * NdrConformantStructUnmarshall [RPCRT4.@]
3968 unsigned char * WINAPI
NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3969 unsigned char **ppMemory
,
3970 PFORMAT_STRING pFormat
,
3971 unsigned char fMustAlloc
)
3973 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3974 PFORMAT_STRING pCArrayFormat
;
3975 ULONG esize
, bufsize
;
3976 unsigned char *saved_buffer
;
3978 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3980 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3981 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3983 ERR("invalid format type %x\n", pCStructFormat
->type
);
3984 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3987 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3988 pCStructFormat
->offset_to_array_description
;
3989 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3991 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3992 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3995 esize
= *(const WORD
*)(pCArrayFormat
+2);
3997 pCArrayFormat
= ReadConformance(pStubMsg
, pCArrayFormat
+ 4);
3999 ALIGN_POINTER(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4001 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4003 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4004 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4006 ERR("integer overflow of memory_size %u with bufsize %u\n",
4007 pCStructFormat
->memory_size
, bufsize
);
4008 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4013 SIZE_T size
= pCStructFormat
->memory_size
+ bufsize
;
4014 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4018 if (!pStubMsg
->IsClient
&& !*ppMemory
)
4019 /* for servers, we just point straight into the RPC buffer */
4020 *ppMemory
= pStubMsg
->Buffer
;
4023 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4024 safe_buffer_increment(pStubMsg
, pCStructFormat
->memory_size
+ bufsize
);
4025 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4026 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4028 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
4029 if (*ppMemory
!= saved_buffer
)
4030 memcpy(*ppMemory
, saved_buffer
, pCStructFormat
->memory_size
+ bufsize
);
4035 /***********************************************************************
4036 * NdrConformantStructBufferSize [RPCRT4.@]
4038 void WINAPI
NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4039 unsigned char *pMemory
,
4040 PFORMAT_STRING pFormat
)
4042 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4043 PFORMAT_STRING pCArrayFormat
;
4046 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4048 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4049 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4051 ERR("invalid format type %x\n", pCStructFormat
->type
);
4052 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4055 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4056 pCStructFormat
->offset_to_array_description
;
4057 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4059 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4060 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4063 esize
= *(const WORD
*)(pCArrayFormat
+2);
4065 pCArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
, pCArrayFormat
+4, 0);
4066 SizeConformance(pStubMsg
);
4068 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCStructFormat
->alignment
+ 1);
4070 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4072 safe_buffer_length_increment(pStubMsg
, pCStructFormat
->memory_size
);
4073 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
4075 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4076 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4079 /***********************************************************************
4080 * NdrConformantStructMemorySize [RPCRT4.@]
4082 ULONG WINAPI
NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4083 PFORMAT_STRING pFormat
)
4089 /***********************************************************************
4090 * NdrConformantStructFree [RPCRT4.@]
4092 void WINAPI
NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
4093 unsigned char *pMemory
,
4094 PFORMAT_STRING pFormat
)
4096 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4097 PFORMAT_STRING pCArrayFormat
;
4099 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4101 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4102 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4104 ERR("invalid format type %x\n", pCStructFormat
->type
);
4105 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4109 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4110 pCStructFormat
->offset_to_array_description
;
4111 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4113 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4114 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4118 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4119 pCArrayFormat
+ 4, 0);
4121 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4123 /* copy constant sized part of struct */
4124 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4126 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4127 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4130 /***********************************************************************
4131 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4133 unsigned char * WINAPI
NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4134 unsigned char *pMemory
,
4135 PFORMAT_STRING pFormat
)
4137 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4138 PFORMAT_STRING pCVArrayFormat
;
4139 ULONG esize
, bufsize
;
4141 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4143 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4144 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4146 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4147 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4151 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4152 pCVStructFormat
->offset_to_array_description
;
4153 switch (*pCVArrayFormat
)
4155 case RPC_FC_CVARRAY
:
4156 esize
= *(const WORD
*)(pCVArrayFormat
+2);
4158 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4159 pCVArrayFormat
+ 4, 0);
4160 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4163 case RPC_FC_C_CSTRING
:
4164 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
4165 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
4166 esize
= sizeof(char);
4167 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4168 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4169 pCVArrayFormat
+ 2, 0);
4171 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4173 case RPC_FC_C_WSTRING
:
4174 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
4175 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
4176 esize
= sizeof(WCHAR
);
4177 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4178 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4179 pCVArrayFormat
+ 2, 0);
4181 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4184 ERR("invalid array format type %x\n", *pCVArrayFormat
);
4185 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4189 WriteConformance(pStubMsg
);
4191 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4193 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4195 /* write constant sized part */
4196 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4197 safe_copy_to_buffer(pStubMsg
, pMemory
, pCVStructFormat
->memory_size
);
4199 WriteVariance(pStubMsg
);
4201 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4203 /* write array part */
4204 safe_copy_to_buffer(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
, bufsize
);
4206 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4211 /***********************************************************************
4212 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4214 unsigned char * WINAPI
NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4215 unsigned char **ppMemory
,
4216 PFORMAT_STRING pFormat
,
4217 unsigned char fMustAlloc
)
4219 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4220 PFORMAT_STRING pCVArrayFormat
;
4221 ULONG esize
, bufsize
;
4222 unsigned char cvarray_type
;
4223 unsigned char *saved_buffer
, *saved_array_buffer
;
4225 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4227 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4228 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4230 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4231 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4235 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4236 pCVStructFormat
->offset_to_array_description
;
4237 cvarray_type
= *pCVArrayFormat
;
4238 switch (cvarray_type
)
4240 case RPC_FC_CVARRAY
:
4241 esize
= *(const WORD
*)(pCVArrayFormat
+2);
4242 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 4);
4244 case RPC_FC_C_CSTRING
:
4245 esize
= sizeof(char);
4246 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4247 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
4249 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
4251 case RPC_FC_C_WSTRING
:
4252 esize
= sizeof(WCHAR
);
4253 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4254 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
4256 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
4259 ERR("invalid array format type %x\n", *pCVArrayFormat
);
4260 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4264 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4266 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4268 /* work out how much memory to allocate if we need to do so */
4269 if (!*ppMemory
|| fMustAlloc
)
4271 SIZE_T size
= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->MaxCount
);
4272 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4275 /* mark the start of the constant data */
4276 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4277 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4279 pCVArrayFormat
= ReadVariance(pStubMsg
, pCVArrayFormat
, pStubMsg
->MaxCount
);
4281 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4283 if ((cvarray_type
== RPC_FC_C_CSTRING
) ||
4284 (cvarray_type
== RPC_FC_C_WSTRING
))
4285 validate_string_data(pStubMsg
, bufsize
, esize
);
4287 /* mark the start of the array data */
4288 saved_array_buffer
= pStubMsg
->Buffer
;
4289 safe_buffer_increment(pStubMsg
, bufsize
);
4291 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4293 /* copy the constant data */
4294 memcpy(*ppMemory
, saved_buffer
, pCVStructFormat
->memory_size
);
4295 /* copy the array data */
4296 TRACE("copying %p to %p\n", saved_array_buffer
, *ppMemory
+ pCVStructFormat
->memory_size
);
4297 memcpy(*ppMemory
+ pCVStructFormat
->memory_size
, saved_array_buffer
, bufsize
);
4299 if (cvarray_type
== RPC_FC_C_CSTRING
)
4300 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory
+ pCVStructFormat
->memory_size
)));
4301 else if (cvarray_type
== RPC_FC_C_WSTRING
)
4302 TRACE("string=%s\n", debugstr_w((WCHAR
*)(*ppMemory
+ pCVStructFormat
->memory_size
)));
4307 /***********************************************************************
4308 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
4310 void WINAPI
NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4311 unsigned char *pMemory
,
4312 PFORMAT_STRING pFormat
)
4314 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4315 PFORMAT_STRING pCVArrayFormat
;
4318 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4320 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4321 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4323 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4324 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4328 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4329 pCVStructFormat
->offset_to_array_description
;
4330 switch (*pCVArrayFormat
)
4332 case RPC_FC_CVARRAY
:
4333 esize
= *(const WORD
*)(pCVArrayFormat
+2);
4335 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4336 pCVArrayFormat
+ 4, 0);
4337 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4340 case RPC_FC_C_CSTRING
:
4341 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
4342 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
4343 esize
= sizeof(char);
4344 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4345 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4346 pCVArrayFormat
+ 2, 0);
4348 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4350 case RPC_FC_C_WSTRING
:
4351 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
4352 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
4353 esize
= sizeof(WCHAR
);
4354 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4355 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4356 pCVArrayFormat
+ 2, 0);
4358 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4361 ERR("invalid array format type %x\n", *pCVArrayFormat
);
4362 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4366 SizeConformance(pStubMsg
);
4368 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCVStructFormat
->alignment
+ 1);
4370 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4372 safe_buffer_length_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4373 SizeVariance(pStubMsg
);
4374 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
4376 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4379 /***********************************************************************
4380 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4382 ULONG WINAPI
NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4383 PFORMAT_STRING pFormat
)
4385 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4386 PFORMAT_STRING pCVArrayFormat
;
4388 unsigned char cvarray_type
;
4390 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4392 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4393 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4395 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4396 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4400 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4401 pCVStructFormat
->offset_to_array_description
;
4402 cvarray_type
= *pCVArrayFormat
;
4403 switch (cvarray_type
)
4405 case RPC_FC_CVARRAY
:
4406 esize
= *(const WORD
*)(pCVArrayFormat
+2);
4407 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 4);
4409 case RPC_FC_C_CSTRING
:
4410 esize
= sizeof(char);
4411 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4412 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
4414 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
4416 case RPC_FC_C_WSTRING
:
4417 esize
= sizeof(WCHAR
);
4418 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4419 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
4421 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
4424 ERR("invalid array format type %x\n", *pCVArrayFormat
);
4425 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4429 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4431 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4433 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4434 pCVArrayFormat
= ReadVariance(pStubMsg
, pCVArrayFormat
, pStubMsg
->MaxCount
);
4435 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
4437 pStubMsg
->MemorySize
+= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->MaxCount
);
4439 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4441 return pCVStructFormat
->memory_size
+ pStubMsg
->MaxCount
* esize
;
4444 /***********************************************************************
4445 * NdrConformantVaryingStructFree [RPCRT4.@]
4447 void WINAPI
NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
4448 unsigned char *pMemory
,
4449 PFORMAT_STRING pFormat
)
4451 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4452 PFORMAT_STRING pCVArrayFormat
;
4454 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4456 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4457 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4459 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4460 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4464 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4465 pCVStructFormat
->offset_to_array_description
;
4466 switch (*pCVArrayFormat
)
4468 case RPC_FC_CVARRAY
:
4469 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4470 pCVArrayFormat
+ 4, 0);
4471 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4474 case RPC_FC_C_CSTRING
:
4475 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
4476 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
4477 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4478 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4479 pCVArrayFormat
+ 2, 0);
4481 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4483 case RPC_FC_C_WSTRING
:
4484 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
4485 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
4486 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4487 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4488 pCVArrayFormat
+ 2, 0);
4490 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4493 ERR("invalid array format type %x\n", *pCVArrayFormat
);
4494 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4498 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4500 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4503 #include "pshpack1.h"
4507 unsigned char alignment
;
4508 unsigned short total_size
;
4509 } NDR_SMFARRAY_FORMAT
;
4514 unsigned char alignment
;
4515 unsigned long total_size
;
4516 } NDR_LGFARRAY_FORMAT
;
4517 #include "poppack.h"
4519 /***********************************************************************
4520 * NdrFixedArrayMarshall [RPCRT4.@]
4522 unsigned char * WINAPI
NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4523 unsigned char *pMemory
,
4524 PFORMAT_STRING pFormat
)
4526 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4527 unsigned long total_size
;
4529 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4531 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4532 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4534 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4535 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4539 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4541 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4543 total_size
= pSmFArrayFormat
->total_size
;
4544 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4548 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4549 total_size
= pLgFArrayFormat
->total_size
;
4550 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4553 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4554 safe_copy_to_buffer(pStubMsg
, pMemory
, total_size
);
4556 pFormat
= EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4561 /***********************************************************************
4562 * NdrFixedArrayUnmarshall [RPCRT4.@]
4564 unsigned char * WINAPI
NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4565 unsigned char **ppMemory
,
4566 PFORMAT_STRING pFormat
,
4567 unsigned char fMustAlloc
)
4569 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4570 unsigned long total_size
;
4571 unsigned char *saved_buffer
;
4573 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4575 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4576 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4578 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4579 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4583 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4585 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4587 total_size
= pSmFArrayFormat
->total_size
;
4588 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4592 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4593 total_size
= pLgFArrayFormat
->total_size
;
4594 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4598 *ppMemory
= NdrAllocate(pStubMsg
, total_size
);
4601 if (!pStubMsg
->IsClient
&& !*ppMemory
)
4602 /* for servers, we just point straight into the RPC buffer */
4603 *ppMemory
= pStubMsg
->Buffer
;
4606 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4607 safe_buffer_increment(pStubMsg
, total_size
);
4608 pFormat
= EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4610 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
4611 if (*ppMemory
!= saved_buffer
)
4612 memcpy(*ppMemory
, saved_buffer
, total_size
);
4617 /***********************************************************************
4618 * NdrFixedArrayBufferSize [RPCRT4.@]
4620 void WINAPI
NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4621 unsigned char *pMemory
,
4622 PFORMAT_STRING pFormat
)
4624 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4625 unsigned long total_size
;
4627 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4629 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4630 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4632 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4633 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4637 ALIGN_LENGTH(pStubMsg
->BufferLength
, pSmFArrayFormat
->alignment
+ 1);
4639 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4641 total_size
= pSmFArrayFormat
->total_size
;
4642 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4646 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4647 total_size
= pLgFArrayFormat
->total_size
;
4648 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4650 safe_buffer_length_increment(pStubMsg
, total_size
);
4652 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4655 /***********************************************************************
4656 * NdrFixedArrayMemorySize [RPCRT4.@]
4658 ULONG WINAPI
NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4659 PFORMAT_STRING pFormat
)
4661 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4664 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4666 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4667 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4669 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4670 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4674 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4676 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4678 total_size
= pSmFArrayFormat
->total_size
;
4679 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4683 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4684 total_size
= pLgFArrayFormat
->total_size
;
4685 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4687 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4688 safe_buffer_increment(pStubMsg
, total_size
);
4689 pStubMsg
->MemorySize
+= total_size
;
4691 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4696 /***********************************************************************
4697 * NdrFixedArrayFree [RPCRT4.@]
4699 void WINAPI
NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4700 unsigned char *pMemory
,
4701 PFORMAT_STRING pFormat
)
4703 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4705 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4707 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4708 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4710 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4711 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4715 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4716 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4719 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4720 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4723 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4726 /***********************************************************************
4727 * NdrVaryingArrayMarshall [RPCRT4.@]
4729 unsigned char * WINAPI
NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4730 unsigned char *pMemory
,
4731 PFORMAT_STRING pFormat
)
4733 unsigned char alignment
;
4734 DWORD elements
, esize
;
4737 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4739 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4740 (pFormat
[0] != RPC_FC_LGVARRAY
))
4742 ERR("invalid format type %x\n", pFormat
[0]);
4743 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4747 alignment
= pFormat
[1] + 1;
4749 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4752 pFormat
+= sizeof(WORD
);
4753 elements
= *(const WORD
*)pFormat
;
4754 pFormat
+= sizeof(WORD
);
4759 pFormat
+= sizeof(DWORD
);
4760 elements
= *(const DWORD
*)pFormat
;
4761 pFormat
+= sizeof(DWORD
);
4764 esize
= *(const WORD
*)pFormat
;
4765 pFormat
+= sizeof(WORD
);
4767 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4768 if ((pStubMsg
->ActualCount
> elements
) ||
4769 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4771 RpcRaiseException(RPC_S_INVALID_BOUND
);
4775 WriteVariance(pStubMsg
);
4777 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
4779 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4780 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4781 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
4783 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4788 /***********************************************************************
4789 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4791 unsigned char * WINAPI
NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4792 unsigned char **ppMemory
,
4793 PFORMAT_STRING pFormat
,
4794 unsigned char fMustAlloc
)
4796 unsigned char alignment
;
4797 DWORD size
, elements
, esize
;
4799 unsigned char *saved_buffer
;
4802 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4804 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4805 (pFormat
[0] != RPC_FC_LGVARRAY
))
4807 ERR("invalid format type %x\n", pFormat
[0]);
4808 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4812 alignment
= pFormat
[1] + 1;
4814 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4817 size
= *(const WORD
*)pFormat
;
4818 pFormat
+= sizeof(WORD
);
4819 elements
= *(const WORD
*)pFormat
;
4820 pFormat
+= sizeof(WORD
);
4825 size
= *(const DWORD
*)pFormat
;
4826 pFormat
+= sizeof(DWORD
);
4827 elements
= *(const DWORD
*)pFormat
;
4828 pFormat
+= sizeof(DWORD
);
4831 esize
= *(const WORD
*)pFormat
;
4832 pFormat
+= sizeof(WORD
);
4834 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
4836 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4838 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4839 offset
= pStubMsg
->Offset
;
4841 if (!*ppMemory
|| fMustAlloc
)
4842 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4843 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4844 safe_buffer_increment(pStubMsg
, bufsize
);
4846 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4848 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
4853 /***********************************************************************
4854 * NdrVaryingArrayBufferSize [RPCRT4.@]
4856 void WINAPI
NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4857 unsigned char *pMemory
,
4858 PFORMAT_STRING pFormat
)
4860 unsigned char alignment
;
4861 DWORD elements
, esize
;
4863 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4865 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4866 (pFormat
[0] != RPC_FC_LGVARRAY
))
4868 ERR("invalid format type %x\n", pFormat
[0]);
4869 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4873 alignment
= pFormat
[1] + 1;
4875 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4878 pFormat
+= sizeof(WORD
);
4879 elements
= *(const WORD
*)pFormat
;
4880 pFormat
+= sizeof(WORD
);
4885 pFormat
+= sizeof(DWORD
);
4886 elements
= *(const DWORD
*)pFormat
;
4887 pFormat
+= sizeof(DWORD
);
4890 esize
= *(const WORD
*)pFormat
;
4891 pFormat
+= sizeof(WORD
);
4893 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4894 if ((pStubMsg
->ActualCount
> elements
) ||
4895 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4897 RpcRaiseException(RPC_S_INVALID_BOUND
);
4901 SizeVariance(pStubMsg
);
4903 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
4905 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
4907 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4910 /***********************************************************************
4911 * NdrVaryingArrayMemorySize [RPCRT4.@]
4913 ULONG WINAPI
NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4914 PFORMAT_STRING pFormat
)
4916 unsigned char alignment
;
4917 DWORD size
, elements
, esize
;
4919 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4921 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4922 (pFormat
[0] != RPC_FC_LGVARRAY
))
4924 ERR("invalid format type %x\n", pFormat
[0]);
4925 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4929 alignment
= pFormat
[1] + 1;
4931 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4934 size
= *(const WORD
*)pFormat
;
4935 pFormat
+= sizeof(WORD
);
4936 elements
= *(const WORD
*)pFormat
;
4937 pFormat
+= sizeof(WORD
);
4942 size
= *(const DWORD
*)pFormat
;
4943 pFormat
+= sizeof(DWORD
);
4944 elements
= *(const DWORD
*)pFormat
;
4945 pFormat
+= sizeof(DWORD
);
4948 esize
= *(const WORD
*)pFormat
;
4949 pFormat
+= sizeof(WORD
);
4951 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
4953 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4955 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
4956 pStubMsg
->MemorySize
+= size
;
4958 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4960 return pStubMsg
->MemorySize
;
4963 /***********************************************************************
4964 * NdrVaryingArrayFree [RPCRT4.@]
4966 void WINAPI
NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4967 unsigned char *pMemory
,
4968 PFORMAT_STRING pFormat
)
4972 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4974 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4975 (pFormat
[0] != RPC_FC_LGVARRAY
))
4977 ERR("invalid format type %x\n", pFormat
[0]);
4978 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4982 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4985 pFormat
+= sizeof(WORD
);
4986 elements
= *(const WORD
*)pFormat
;
4987 pFormat
+= sizeof(WORD
);
4992 pFormat
+= sizeof(DWORD
);
4993 elements
= *(const DWORD
*)pFormat
;
4994 pFormat
+= sizeof(DWORD
);
4997 pFormat
+= sizeof(WORD
);
4999 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5000 if ((pStubMsg
->ActualCount
> elements
) ||
5001 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5003 RpcRaiseException(RPC_S_INVALID_BOUND
);
5007 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5010 static ULONG
get_discriminant(unsigned char fc
, const unsigned char *pMemory
)
5023 return *(const USHORT
*)pMemory
;
5027 return *(const ULONG
*)pMemory
;
5029 FIXME("Unhandled base type: 0x%02x\n", fc
);
5034 static PFORMAT_STRING
get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg
,
5035 unsigned long discriminant
,
5036 PFORMAT_STRING pFormat
)
5038 unsigned short num_arms
, arm
, type
;
5040 num_arms
= *(const SHORT
*)pFormat
& 0x0fff;
5042 for(arm
= 0; arm
< num_arms
; arm
++)
5044 if(discriminant
== *(const ULONG
*)pFormat
)
5052 type
= *(const unsigned short*)pFormat
;
5053 TRACE("type %04x\n", type
);
5054 if(arm
== num_arms
) /* default arm extras */
5058 ERR("no arm for 0x%lx and no default case\n", discriminant
);
5059 RpcRaiseException(RPC_S_INVALID_TAG
);
5064 TRACE("falling back to empty default case for 0x%lx\n", discriminant
);
5071 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
, ULONG discriminant
, PFORMAT_STRING pFormat
)
5073 unsigned short type
;
5077 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5081 type
= *(const unsigned short*)pFormat
;
5082 if((type
& 0xff00) == 0x8000)
5084 unsigned char basetype
= LOBYTE(type
);
5085 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &basetype
);
5089 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5090 NDR_MARSHALL m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
5093 unsigned char *saved_buffer
= NULL
;
5094 int pointer_buffer_mark_set
= 0;
5101 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
5102 saved_buffer
= pStubMsg
->Buffer
;
5103 if (pStubMsg
->PointerBufferMark
)
5105 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5106 pStubMsg
->PointerBufferMark
= NULL
;
5107 pointer_buffer_mark_set
= 1;
5110 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
5112 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char **)pMemory
, desc
);
5113 if (pointer_buffer_mark_set
)
5115 STD_OVERFLOW_CHECK(pStubMsg
);
5116 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5117 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5119 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5120 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
5121 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5123 pStubMsg
->Buffer
= saved_buffer
+ 4;
5127 m(pStubMsg
, pMemory
, desc
);
5130 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5135 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5136 unsigned char **ppMemory
,
5138 PFORMAT_STRING pFormat
,
5139 unsigned char fMustAlloc
)
5141 unsigned short type
;
5145 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5149 type
= *(const unsigned short*)pFormat
;
5150 if((type
& 0xff00) == 0x8000)
5152 unsigned char basetype
= LOBYTE(type
);
5153 return NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &basetype
, FALSE
);
5157 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5158 NDR_UNMARSHALL m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
5161 unsigned char *saved_buffer
= NULL
;
5162 int pointer_buffer_mark_set
= 0;
5169 **(void***)ppMemory
= NULL
;
5170 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5171 saved_buffer
= pStubMsg
->Buffer
;
5172 if (pStubMsg
->PointerBufferMark
)
5174 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5175 pStubMsg
->PointerBufferMark
= NULL
;
5176 pointer_buffer_mark_set
= 1;
5179 pStubMsg
->Buffer
+= 4; /* for pointer ID */
5181 if (saved_buffer
+ 4 > pStubMsg
->BufferEnd
)
5183 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5184 saved_buffer
, pStubMsg
->BufferEnd
);
5185 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5188 PointerUnmarshall(pStubMsg
, saved_buffer
, *(unsigned char ***)ppMemory
, **(unsigned char ***)ppMemory
, desc
, fMustAlloc
);
5189 if (pointer_buffer_mark_set
)
5191 STD_OVERFLOW_CHECK(pStubMsg
);
5192 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5193 pStubMsg
->Buffer
= saved_buffer
+ 4;
5197 m(pStubMsg
, ppMemory
, desc
, fMustAlloc
);
5200 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5205 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg
,
5206 unsigned char *pMemory
,
5208 PFORMAT_STRING pFormat
)
5210 unsigned short type
;
5214 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5218 type
= *(const unsigned short*)pFormat
;
5219 if((type
& 0xff00) == 0x8000)
5221 unsigned char basetype
= LOBYTE(type
);
5222 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &basetype
);
5226 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5227 NDR_BUFFERSIZE m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
5236 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
5237 safe_buffer_length_increment(pStubMsg
, 4); /* for pointer ID */
5238 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5240 int saved_buffer_length
= pStubMsg
->BufferLength
;
5241 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
5242 pStubMsg
->PointerLength
= 0;
5243 if(!pStubMsg
->BufferLength
)
5244 ERR("BufferLength == 0??\n");
5245 PointerBufferSize(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5246 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
5247 pStubMsg
->BufferLength
= saved_buffer_length
;
5251 m(pStubMsg
, pMemory
, desc
);
5254 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
5258 static ULONG
union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg
,
5260 PFORMAT_STRING pFormat
)
5262 unsigned short type
, size
;
5264 size
= *(const unsigned short*)pFormat
;
5265 pStubMsg
->Memory
+= size
;
5268 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5272 type
= *(const unsigned short*)pFormat
;
5273 if((type
& 0xff00) == 0x8000)
5275 return NdrBaseTypeMemorySize(pStubMsg
, pFormat
);
5279 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5280 NDR_MEMORYSIZE m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
5281 unsigned char *saved_buffer
;
5290 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5291 saved_buffer
= pStubMsg
->Buffer
;
5292 safe_buffer_increment(pStubMsg
, 4);
5293 ALIGN_LENGTH(pStubMsg
->MemorySize
, 4);
5294 pStubMsg
->MemorySize
+= 4;
5295 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5296 PointerMemorySize(pStubMsg
, saved_buffer
, pFormat
);
5299 return m(pStubMsg
, desc
);
5302 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5305 TRACE("size %d\n", size
);
5309 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg
,
5310 unsigned char *pMemory
,
5312 PFORMAT_STRING pFormat
)
5314 unsigned short type
;
5318 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5322 type
= *(const unsigned short*)pFormat
;
5323 if((type
& 0xff00) != 0x8000)
5325 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5326 NDR_FREE m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
5335 PointerFree(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5338 m(pStubMsg
, pMemory
, desc
);
5344 /***********************************************************************
5345 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5347 unsigned char * WINAPI
NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5348 unsigned char *pMemory
,
5349 PFORMAT_STRING pFormat
)
5351 unsigned char switch_type
;
5352 unsigned char increment
;
5355 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5358 switch_type
= *pFormat
& 0xf;
5359 increment
= (*pFormat
& 0xf0) >> 4;
5362 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, increment
);
5364 switch_value
= get_discriminant(switch_type
, pMemory
);
5365 TRACE("got switch value 0x%x\n", switch_value
);
5367 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &switch_type
);
5368 pMemory
+= increment
;
5370 return union_arm_marshall(pStubMsg
, pMemory
, switch_value
, pFormat
);
5373 /***********************************************************************
5374 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5376 unsigned char * WINAPI
NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5377 unsigned char **ppMemory
,
5378 PFORMAT_STRING pFormat
,
5379 unsigned char fMustAlloc
)
5381 unsigned char switch_type
;
5382 unsigned char increment
;
5384 unsigned short size
;
5385 unsigned char *pMemoryArm
;
5387 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5390 switch_type
= *pFormat
& 0xf;
5391 increment
= (*pFormat
& 0xf0) >> 4;
5394 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
5395 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
5396 TRACE("got switch value 0x%x\n", switch_value
);
5398 size
= *(const unsigned short*)pFormat
+ increment
;
5399 if(!*ppMemory
|| fMustAlloc
)
5400 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5402 NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &switch_type
, FALSE
);
5403 pMemoryArm
= *ppMemory
+ increment
;
5405 return union_arm_unmarshall(pStubMsg
, &pMemoryArm
, switch_value
, pFormat
, fMustAlloc
);
5408 /***********************************************************************
5409 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5411 void WINAPI
NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5412 unsigned char *pMemory
,
5413 PFORMAT_STRING pFormat
)
5415 unsigned char switch_type
;
5416 unsigned char increment
;
5419 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5422 switch_type
= *pFormat
& 0xf;
5423 increment
= (*pFormat
& 0xf0) >> 4;
5426 ALIGN_LENGTH(pStubMsg
->BufferLength
, increment
);
5427 switch_value
= get_discriminant(switch_type
, pMemory
);
5428 TRACE("got switch value 0x%x\n", switch_value
);
5430 /* Add discriminant size */
5431 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&switch_value
, &switch_type
);
5432 pMemory
+= increment
;
5434 union_arm_buffer_size(pStubMsg
, pMemory
, switch_value
, pFormat
);
5437 /***********************************************************************
5438 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5440 ULONG WINAPI
NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5441 PFORMAT_STRING pFormat
)
5443 unsigned char switch_type
;
5444 unsigned char increment
;
5447 switch_type
= *pFormat
& 0xf;
5448 increment
= (*pFormat
& 0xf0) >> 4;
5451 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
5452 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
5453 TRACE("got switch value 0x%x\n", switch_value
);
5455 pStubMsg
->Memory
+= increment
;
5457 return increment
+ union_arm_memory_size(pStubMsg
, switch_value
, pFormat
+ *(const SHORT
*)pFormat
);
5460 /***********************************************************************
5461 * NdrEncapsulatedUnionFree [RPCRT4.@]
5463 void WINAPI
NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
5464 unsigned char *pMemory
,
5465 PFORMAT_STRING pFormat
)
5467 unsigned char switch_type
;
5468 unsigned char increment
;
5471 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5474 switch_type
= *pFormat
& 0xf;
5475 increment
= (*pFormat
& 0xf0) >> 4;
5478 switch_value
= get_discriminant(switch_type
, pMemory
);
5479 TRACE("got switch value 0x%x\n", switch_value
);
5481 pMemory
+= increment
;
5483 union_arm_free(pStubMsg
, pMemory
, switch_value
, pFormat
);
5486 /***********************************************************************
5487 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5489 unsigned char * WINAPI
NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5490 unsigned char *pMemory
,
5491 PFORMAT_STRING pFormat
)
5493 unsigned char switch_type
;
5495 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5498 switch_type
= *pFormat
;
5501 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5502 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5503 /* Marshall discriminant */
5504 NdrBaseTypeMarshall(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
5506 return union_arm_marshall(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5509 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg
,
5510 PFORMAT_STRING
*ppFormat
)
5512 long discriminant
= 0;
5522 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5531 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5532 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5540 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
5541 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5546 FIXME("Unhandled base type: 0x%02x\n", **ppFormat
);
5550 if (pStubMsg
->fHasNewCorrDesc
)
5554 return discriminant
;
5557 /**********************************************************************
5558 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5560 unsigned char * WINAPI
NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5561 unsigned char **ppMemory
,
5562 PFORMAT_STRING pFormat
,
5563 unsigned char fMustAlloc
)
5566 unsigned short size
;
5568 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5571 /* Unmarshall discriminant */
5572 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
5573 TRACE("unmarshalled discriminant %lx\n", discriminant
);
5575 pFormat
+= *(const SHORT
*)pFormat
;
5577 size
= *(const unsigned short*)pFormat
;
5579 if(!*ppMemory
|| fMustAlloc
)
5580 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5582 return union_arm_unmarshall(pStubMsg
, ppMemory
, discriminant
, pFormat
, fMustAlloc
);
5585 /***********************************************************************
5586 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5588 void WINAPI
NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5589 unsigned char *pMemory
,
5590 PFORMAT_STRING pFormat
)
5592 unsigned char switch_type
;
5594 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5597 switch_type
= *pFormat
;
5600 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5601 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5602 /* Add discriminant size */
5603 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
5605 union_arm_buffer_size(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5608 /***********************************************************************
5609 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5611 ULONG WINAPI
NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5612 PFORMAT_STRING pFormat
)
5617 /* Unmarshall discriminant */
5618 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
5619 TRACE("unmarshalled discriminant 0x%x\n", discriminant
);
5621 return union_arm_memory_size(pStubMsg
, discriminant
, pFormat
+ *(const SHORT
*)pFormat
);
5624 /***********************************************************************
5625 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5627 void WINAPI
NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
5628 unsigned char *pMemory
,
5629 PFORMAT_STRING pFormat
)
5631 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5635 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5636 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5638 union_arm_free(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5641 /***********************************************************************
5642 * NdrByteCountPointerMarshall [RPCRT4.@]
5644 unsigned char * WINAPI
NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5645 unsigned char *pMemory
,
5646 PFORMAT_STRING pFormat
)
5652 /***********************************************************************
5653 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5655 unsigned char * WINAPI
NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5656 unsigned char **ppMemory
,
5657 PFORMAT_STRING pFormat
,
5658 unsigned char fMustAlloc
)
5664 /***********************************************************************
5665 * NdrByteCountPointerBufferSize [RPCRT4.@]
5667 void WINAPI
NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5668 unsigned char *pMemory
,
5669 PFORMAT_STRING pFormat
)
5674 /***********************************************************************
5675 * NdrByteCountPointerMemorySize [RPCRT4.@]
5677 ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5678 PFORMAT_STRING pFormat
)
5684 /***********************************************************************
5685 * NdrByteCountPointerFree [RPCRT4.@]
5687 void WINAPI
NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
5688 unsigned char *pMemory
,
5689 PFORMAT_STRING pFormat
)
5694 /***********************************************************************
5695 * NdrXmitOrRepAsMarshall [RPCRT4.@]
5697 unsigned char * WINAPI
NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5698 unsigned char *pMemory
,
5699 PFORMAT_STRING pFormat
)
5705 /***********************************************************************
5706 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
5708 unsigned char * WINAPI
NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5709 unsigned char **ppMemory
,
5710 PFORMAT_STRING pFormat
,
5711 unsigned char fMustAlloc
)
5717 /***********************************************************************
5718 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
5720 void WINAPI
NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5721 unsigned char *pMemory
,
5722 PFORMAT_STRING pFormat
)
5727 /***********************************************************************
5728 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
5730 ULONG WINAPI
NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5731 PFORMAT_STRING pFormat
)
5737 /***********************************************************************
5738 * NdrXmitOrRepAsFree [RPCRT4.@]
5740 void WINAPI
NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg
,
5741 unsigned char *pMemory
,
5742 PFORMAT_STRING pFormat
)
5747 /***********************************************************************
5748 * NdrRangeMarshall [internal]
5750 unsigned char *WINAPI
NdrRangeMarshall(
5751 PMIDL_STUB_MESSAGE pStubMsg
,
5752 unsigned char *pMemory
,
5753 PFORMAT_STRING pFormat
)
5755 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5756 unsigned char base_type
;
5758 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5760 if (pRange
->type
!= RPC_FC_RANGE
)
5762 ERR("invalid format type %x\n", pRange
->type
);
5763 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5767 base_type
= pRange
->flags_type
& 0xf;
5769 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &base_type
);
5772 /***********************************************************************
5773 * NdrRangeUnmarshall
5775 unsigned char *WINAPI
NdrRangeUnmarshall(
5776 PMIDL_STUB_MESSAGE pStubMsg
,
5777 unsigned char **ppMemory
,
5778 PFORMAT_STRING pFormat
,
5779 unsigned char fMustAlloc
)
5781 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5782 unsigned char base_type
;
5784 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
5786 if (pRange
->type
!= RPC_FC_RANGE
)
5788 ERR("invalid format type %x\n", pRange
->type
);
5789 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5792 base_type
= pRange
->flags_type
& 0xf;
5794 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5795 base_type
, pRange
->low_value
, pRange
->high_value
);
5797 #define RANGE_UNMARSHALL(type, format_spec) \
5800 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5801 if (fMustAlloc || !*ppMemory) \
5802 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5803 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
5805 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
5806 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
5807 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
5809 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5810 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5812 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5813 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5814 (type)pRange->high_value); \
5815 RpcRaiseException(RPC_S_INVALID_BOUND); \
5818 TRACE("*ppMemory: %p\n", *ppMemory); \
5819 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5820 pStubMsg->Buffer += sizeof(type); \
5827 RANGE_UNMARSHALL(UCHAR
, "%d");
5828 TRACE("value: 0x%02x\n", **ppMemory
);
5832 RANGE_UNMARSHALL(CHAR
, "%u");
5833 TRACE("value: 0x%02x\n", **ppMemory
);
5835 case RPC_FC_WCHAR
: /* FIXME: valid? */
5837 RANGE_UNMARSHALL(USHORT
, "%u");
5838 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5841 RANGE_UNMARSHALL(SHORT
, "%d");
5842 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5845 RANGE_UNMARSHALL(LONG
, "%d");
5846 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5849 RANGE_UNMARSHALL(ULONG
, "%u");
5850 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5854 FIXME("Unhandled enum type\n");
5856 case RPC_FC_ERROR_STATUS_T
: /* FIXME: valid? */
5861 ERR("invalid range base type: 0x%02x\n", base_type
);
5862 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5868 /***********************************************************************
5869 * NdrRangeBufferSize [internal]
5871 void WINAPI
NdrRangeBufferSize(
5872 PMIDL_STUB_MESSAGE pStubMsg
,
5873 unsigned char *pMemory
,
5874 PFORMAT_STRING pFormat
)
5876 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5877 unsigned char base_type
;
5879 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5881 if (pRange
->type
!= RPC_FC_RANGE
)
5883 ERR("invalid format type %x\n", pRange
->type
);
5884 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5886 base_type
= pRange
->flags_type
& 0xf;
5888 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &base_type
);
5891 /***********************************************************************
5892 * NdrRangeMemorySize [internal]
5894 ULONG WINAPI
NdrRangeMemorySize(
5895 PMIDL_STUB_MESSAGE pStubMsg
,
5896 PFORMAT_STRING pFormat
)
5898 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5899 unsigned char base_type
;
5901 if (pRange
->type
!= RPC_FC_RANGE
)
5903 ERR("invalid format type %x\n", pRange
->type
);
5904 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5907 base_type
= pRange
->flags_type
& 0xf;
5909 return NdrBaseTypeMemorySize(pStubMsg
, &base_type
);
5912 /***********************************************************************
5913 * NdrRangeFree [internal]
5915 void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg
,
5916 unsigned char *pMemory
,
5917 PFORMAT_STRING pFormat
)
5919 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5924 /***********************************************************************
5925 * NdrBaseTypeMarshall [internal]
5927 static unsigned char *WINAPI
NdrBaseTypeMarshall(
5928 PMIDL_STUB_MESSAGE pStubMsg
,
5929 unsigned char *pMemory
,
5930 PFORMAT_STRING pFormat
)
5932 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5940 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(UCHAR
));
5941 TRACE("value: 0x%02x\n", *pMemory
);
5946 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(USHORT
));
5947 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(USHORT
));
5948 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
5952 case RPC_FC_ERROR_STATUS_T
:
5954 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(ULONG
));
5955 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONG
));
5956 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
5959 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(float));
5960 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
5963 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(double));
5964 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
5967 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(ULONGLONG
));
5968 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONGLONG
));
5969 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
5972 /* only 16-bits on the wire, so do a sanity check */
5973 if (*(UINT
*)pMemory
> SHRT_MAX
)
5974 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
5975 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(USHORT
));
5976 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5977 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5978 *(USHORT
*)pStubMsg
->Buffer
= *(UINT
*)pMemory
;
5979 pStubMsg
->Buffer
+= sizeof(USHORT
);
5980 TRACE("value: 0x%04x\n", *(UINT
*)pMemory
);
5985 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5988 /* FIXME: what is the correct return value? */
5992 /***********************************************************************
5993 * NdrBaseTypeUnmarshall [internal]
5995 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(
5996 PMIDL_STUB_MESSAGE pStubMsg
,
5997 unsigned char **ppMemory
,
5998 PFORMAT_STRING pFormat
,
5999 unsigned char fMustAlloc
)
6001 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6003 #define BASE_TYPE_UNMARSHALL(type) \
6004 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6005 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6007 *ppMemory = pStubMsg->Buffer; \
6008 TRACE("*ppMemory: %p\n", *ppMemory); \
6009 safe_buffer_increment(pStubMsg, sizeof(type)); \
6014 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6015 TRACE("*ppMemory: %p\n", *ppMemory); \
6016 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6025 BASE_TYPE_UNMARSHALL(UCHAR
);
6026 TRACE("value: 0x%02x\n", **ppMemory
);
6031 BASE_TYPE_UNMARSHALL(USHORT
);
6032 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6036 case RPC_FC_ERROR_STATUS_T
:
6038 BASE_TYPE_UNMARSHALL(ULONG
);
6039 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6042 BASE_TYPE_UNMARSHALL(float);
6043 TRACE("value: %f\n", **(float **)ppMemory
);
6046 BASE_TYPE_UNMARSHALL(double);
6047 TRACE("value: %f\n", **(double **)ppMemory
);
6050 BASE_TYPE_UNMARSHALL(ULONGLONG
);
6051 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG
**)ppMemory
));
6054 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
6055 if (fMustAlloc
|| !*ppMemory
)
6056 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT
));
6057 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > pStubMsg
->BufferEnd
)
6058 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6059 TRACE("*ppMemory: %p\n", *ppMemory
);
6060 /* 16-bits on the wire, but int in memory */
6061 **(UINT
**)ppMemory
= *(USHORT
*)pStubMsg
->Buffer
;
6062 pStubMsg
->Buffer
+= sizeof(USHORT
);
6063 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
6068 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6070 #undef BASE_TYPE_UNMARSHALL
6072 /* FIXME: what is the correct return value? */
6077 /***********************************************************************
6078 * NdrBaseTypeBufferSize [internal]
6080 static void WINAPI
NdrBaseTypeBufferSize(
6081 PMIDL_STUB_MESSAGE pStubMsg
,
6082 unsigned char *pMemory
,
6083 PFORMAT_STRING pFormat
)
6085 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6093 safe_buffer_length_increment(pStubMsg
, sizeof(UCHAR
));
6099 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(USHORT
));
6100 safe_buffer_length_increment(pStubMsg
, sizeof(USHORT
));
6105 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONG
));
6106 safe_buffer_length_increment(pStubMsg
, sizeof(ULONG
));
6109 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(float));
6110 safe_buffer_length_increment(pStubMsg
, sizeof(float));
6113 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(double));
6114 safe_buffer_length_increment(pStubMsg
, sizeof(double));
6117 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONGLONG
));
6118 safe_buffer_length_increment(pStubMsg
, sizeof(ULONGLONG
));
6120 case RPC_FC_ERROR_STATUS_T
:
6121 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(error_status_t
));
6122 safe_buffer_length_increment(pStubMsg
, sizeof(error_status_t
));
6127 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6131 /***********************************************************************
6132 * NdrBaseTypeMemorySize [internal]
6134 static ULONG WINAPI
NdrBaseTypeMemorySize(
6135 PMIDL_STUB_MESSAGE pStubMsg
,
6136 PFORMAT_STRING pFormat
)
6138 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg
, *pFormat
);
6146 safe_buffer_increment(pStubMsg
, sizeof(UCHAR
));
6147 pStubMsg
->MemorySize
+= sizeof(UCHAR
);
6148 return sizeof(UCHAR
);
6152 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6153 pStubMsg
->MemorySize
+= sizeof(USHORT
);
6154 return sizeof(USHORT
);
6158 safe_buffer_increment(pStubMsg
, sizeof(ULONG
));
6159 pStubMsg
->MemorySize
+= sizeof(ULONG
);
6160 return sizeof(ULONG
);
6162 safe_buffer_increment(pStubMsg
, sizeof(float));
6163 pStubMsg
->MemorySize
+= sizeof(float);
6164 return sizeof(float);
6166 safe_buffer_increment(pStubMsg
, sizeof(double));
6167 pStubMsg
->MemorySize
+= sizeof(double);
6168 return sizeof(double);
6170 safe_buffer_increment(pStubMsg
, sizeof(ULONGLONG
));
6171 pStubMsg
->MemorySize
+= sizeof(ULONGLONG
);
6172 return sizeof(ULONGLONG
);
6173 case RPC_FC_ERROR_STATUS_T
:
6174 safe_buffer_increment(pStubMsg
, sizeof(error_status_t
));
6175 pStubMsg
->MemorySize
+= sizeof(error_status_t
);
6176 return sizeof(error_status_t
);
6178 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6179 pStubMsg
->MemorySize
+= sizeof(UINT
);
6180 return sizeof(UINT
);
6182 pStubMsg
->MemorySize
+= sizeof(void *);
6183 return sizeof(void *);
6185 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6190 /***********************************************************************
6191 * NdrBaseTypeFree [internal]
6193 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6194 unsigned char *pMemory
,
6195 PFORMAT_STRING pFormat
)
6197 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6202 /***********************************************************************
6203 * NdrContextHandleBufferSize [internal]
6205 static void WINAPI
NdrContextHandleBufferSize(
6206 PMIDL_STUB_MESSAGE pStubMsg
,
6207 unsigned char *pMemory
,
6208 PFORMAT_STRING pFormat
)
6210 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6212 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6214 ERR("invalid format type %x\n", *pFormat
);
6215 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6217 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
6218 safe_buffer_length_increment(pStubMsg
, cbNDRContext
);
6221 /***********************************************************************
6222 * NdrContextHandleMarshall [internal]
6224 static unsigned char *WINAPI
NdrContextHandleMarshall(
6225 PMIDL_STUB_MESSAGE pStubMsg
,
6226 unsigned char *pMemory
,
6227 PFORMAT_STRING pFormat
)
6229 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6231 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6233 ERR("invalid format type %x\n", *pFormat
);
6234 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6236 TRACE("flags: 0x%02x\n", pFormat
[1]);
6238 if (pFormat
[1] & 0x80)
6239 NdrClientContextMarshall(pStubMsg
, *(NDR_CCONTEXT
**)pMemory
, FALSE
);
6241 NdrClientContextMarshall(pStubMsg
, (NDR_CCONTEXT
*)pMemory
, FALSE
);
6246 /***********************************************************************
6247 * NdrContextHandleUnmarshall [internal]
6249 static unsigned char *WINAPI
NdrContextHandleUnmarshall(
6250 PMIDL_STUB_MESSAGE pStubMsg
,
6251 unsigned char **ppMemory
,
6252 PFORMAT_STRING pFormat
,
6253 unsigned char fMustAlloc
)
6255 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg
,
6256 ppMemory
, pFormat
, fMustAlloc
? "TRUE": "FALSE");
6258 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6260 ERR("invalid format type %x\n", *pFormat
);
6261 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6263 TRACE("flags: 0x%02x\n", pFormat
[1]);
6265 /* [out]-only or [ret] param */
6266 if ((pFormat
[1] & 0x60) == 0x20)
6267 **(NDR_CCONTEXT
**)ppMemory
= NULL
;
6268 NdrClientContextUnmarshall(pStubMsg
, *(NDR_CCONTEXT
**)ppMemory
, pStubMsg
->RpcMsg
->Handle
);
6273 /***********************************************************************
6274 * NdrClientContextMarshall [RPCRT4.@]
6276 void WINAPI
NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6277 NDR_CCONTEXT ContextHandle
,
6280 TRACE("(%p, %p, %d)\n", pStubMsg
, ContextHandle
, fCheck
);
6282 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
6284 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6286 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6287 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6288 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6291 /* FIXME: what does fCheck do? */
6292 NDRCContextMarshall(ContextHandle
,
6295 pStubMsg
->Buffer
+= cbNDRContext
;
6298 /***********************************************************************
6299 * NdrClientContextUnmarshall [RPCRT4.@]
6301 void WINAPI
NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6302 NDR_CCONTEXT
* pContextHandle
,
6303 RPC_BINDING_HANDLE BindHandle
)
6305 TRACE("(%p, %p, %p)\n", pStubMsg
, pContextHandle
, BindHandle
);
6307 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6309 if (pStubMsg
->Buffer
+ cbNDRContext
> pStubMsg
->BufferEnd
)
6310 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6312 NDRCContextUnmarshall(pContextHandle
,
6315 pStubMsg
->RpcMsg
->DataRepresentation
);
6317 pStubMsg
->Buffer
+= cbNDRContext
;
6320 void WINAPI
NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6321 NDR_SCONTEXT ContextHandle
,
6322 NDR_RUNDOWN RundownRoutine
)
6324 TRACE("(%p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
);
6326 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6328 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6330 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6331 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6332 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6335 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
6336 pStubMsg
->Buffer
, RundownRoutine
, NULL
,
6337 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
6338 pStubMsg
->Buffer
+= cbNDRContext
;
6341 NDR_SCONTEXT WINAPI
NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
)
6343 NDR_SCONTEXT ContextHandle
;
6345 TRACE("(%p)\n", pStubMsg
);
6347 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6349 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6351 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6352 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6353 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6356 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
6358 pStubMsg
->RpcMsg
->DataRepresentation
,
6359 NULL
, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
6360 pStubMsg
->Buffer
+= cbNDRContext
;
6362 return ContextHandle
;
6365 void WINAPI
NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg
,
6366 unsigned char* pMemory
,
6367 PFORMAT_STRING pFormat
)
6369 FIXME("(%p, %p, %p): stub\n", pStubMsg
, pMemory
, pFormat
);
6372 NDR_SCONTEXT WINAPI
NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg
,
6373 PFORMAT_STRING pFormat
)
6375 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6376 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6378 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
6380 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
6381 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
6382 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
6383 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
6384 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
6386 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
6387 if_id
= &sif
->InterfaceId
;
6390 return NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
, NULL
,
6391 pStubMsg
->RpcMsg
->DataRepresentation
, if_id
,
6395 void WINAPI
NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6396 NDR_SCONTEXT ContextHandle
,
6397 NDR_RUNDOWN RundownRoutine
,
6398 PFORMAT_STRING pFormat
)
6400 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6401 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6403 TRACE("(%p, %p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
, pFormat
);
6405 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6407 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6409 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6410 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6411 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6414 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
6415 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
6416 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
6417 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
6418 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
6420 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
6421 if_id
= &sif
->InterfaceId
;
6424 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
6425 pStubMsg
->Buffer
, RundownRoutine
, if_id
, flags
);
6426 pStubMsg
->Buffer
+= cbNDRContext
;
6429 NDR_SCONTEXT WINAPI
NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6430 PFORMAT_STRING pFormat
)
6432 NDR_SCONTEXT ContextHandle
;
6433 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6434 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6436 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
6438 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6440 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6442 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6443 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6444 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6447 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
6448 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
6449 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
6450 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
6451 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
6453 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
6454 if_id
= &sif
->InterfaceId
;
6457 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
6459 pStubMsg
->RpcMsg
->DataRepresentation
,
6461 pStubMsg
->Buffer
+= cbNDRContext
;
6463 return ContextHandle
;
6466 /***********************************************************************
6467 * NdrCorrelationInitialize [RPCRT4.@]
6469 * Initializes correlation validity checking.
6472 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6473 * pMemory [I] Pointer to memory to use as a cache.
6474 * CacheSize [I] Size of the memory pointed to by pMemory.
6475 * Flags [I] Reserved. Set to zero.
6480 void WINAPI
NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg
, void *pMemory
, ULONG CacheSize
, ULONG Flags
)
6482 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg
, pMemory
, CacheSize
, Flags
);
6483 pStubMsg
->fHasNewCorrDesc
= TRUE
;
6486 /***********************************************************************
6487 * NdrCorrelationPass [RPCRT4.@]
6489 * Performs correlation validity checking.
6492 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6497 void WINAPI
NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg
)
6499 FIXME("(%p): stub\n", pStubMsg
);
6502 /***********************************************************************
6503 * NdrCorrelationFree [RPCRT4.@]
6505 * Frees any resources used while unmarshalling parameters that need
6506 * correlation validity checking.
6509 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6514 void WINAPI
NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg
)
6516 FIXME("(%p): stub\n", pStubMsg
);