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 TRACE("pStubMsg->Buffer before %p\n", pStubMsg
->Buffer
);
2257 if (*pPointer
!= RPC_FC_RP
)
2258 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
2259 saved_buffer
= pStubMsg
->Buffer
;
2260 if (pStubMsg
->PointerBufferMark
)
2262 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2263 pStubMsg
->PointerBufferMark
= NULL
;
2264 pointer_buffer_mark_set
= 1;
2266 else if (*pPointer
!= RPC_FC_RP
)
2267 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2268 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char**)pMemory
, pPointer
);
2269 if (pointer_buffer_mark_set
)
2271 STD_OVERFLOW_CHECK(pStubMsg
);
2272 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2273 pStubMsg
->Buffer
= saved_buffer
;
2274 if (*pPointer
!= RPC_FC_RP
)
2275 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2277 TRACE("pStubMsg->Buffer after %p\n", pStubMsg
->Buffer
);
2282 case RPC_FC_ALIGNM4
:
2283 ALIGN_POINTER(pMemory
, 4);
2285 case RPC_FC_ALIGNM8
:
2286 ALIGN_POINTER(pMemory
, 8);
2288 case RPC_FC_STRUCTPAD1
:
2289 case RPC_FC_STRUCTPAD2
:
2290 case RPC_FC_STRUCTPAD3
:
2291 case RPC_FC_STRUCTPAD4
:
2292 case RPC_FC_STRUCTPAD5
:
2293 case RPC_FC_STRUCTPAD6
:
2294 case RPC_FC_STRUCTPAD7
:
2295 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2297 case RPC_FC_EMBEDDED_COMPLEX
:
2298 pMemory
+= pFormat
[1];
2300 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2301 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2302 TRACE("embedded complex (size=%ld) <= %p\n", size
, pMemory
);
2303 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
2306 /* for some reason interface pointers aren't generated as
2307 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2308 * they still need the derefencing treatment that pointers are
2310 if (*desc
== RPC_FC_IP
)
2311 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2313 m(pStubMsg
, pMemory
, desc
);
2315 else FIXME("no marshaller for embedded type %02x\n", *desc
);
2322 FIXME("unhandled format 0x%02x\n", *pFormat
);
2330 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2331 unsigned char *pMemory
,
2332 PFORMAT_STRING pFormat
,
2333 PFORMAT_STRING pPointer
,
2334 unsigned char fMustAlloc
)
2336 PFORMAT_STRING desc
;
2340 while (*pFormat
!= RPC_FC_END
) {
2346 safe_copy_from_buffer(pStubMsg
, pMemory
, 1);
2347 TRACE("byte=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2353 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
2354 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2358 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
2359 *(DWORD
*)pMemory
&= 0xffff;
2360 TRACE("enum16=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
2361 if (32767 < *(DWORD
*)pMemory
)
2362 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
2368 safe_copy_from_buffer(pStubMsg
, pMemory
, 4);
2369 TRACE("long=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
2373 safe_copy_from_buffer(pStubMsg
, pMemory
, 8);
2374 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2377 case RPC_FC_POINTER
:
2379 unsigned char *saved_buffer
;
2380 int pointer_buffer_mark_set
= 0;
2381 TRACE("pointer => %p\n", pMemory
);
2382 if (*pPointer
!= RPC_FC_RP
)
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;
2391 else if (*pPointer
!= RPC_FC_RP
)
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 pStubMsg
->Buffer
= saved_buffer
;
2400 if (*pPointer
!= RPC_FC_RP
)
2401 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2407 case RPC_FC_ALIGNM4
:
2408 ALIGN_POINTER_CLEAR(pMemory
, 4);
2410 case RPC_FC_ALIGNM8
:
2411 ALIGN_POINTER_CLEAR(pMemory
, 8);
2413 case RPC_FC_STRUCTPAD1
:
2414 case RPC_FC_STRUCTPAD2
:
2415 case RPC_FC_STRUCTPAD3
:
2416 case RPC_FC_STRUCTPAD4
:
2417 case RPC_FC_STRUCTPAD5
:
2418 case RPC_FC_STRUCTPAD6
:
2419 case RPC_FC_STRUCTPAD7
:
2420 memset(pMemory
, 0, *pFormat
- RPC_FC_STRUCTPAD1
+ 1);
2421 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2423 case RPC_FC_EMBEDDED_COMPLEX
:
2424 pMemory
+= pFormat
[1];
2426 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2427 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2428 TRACE("embedded complex (size=%ld) => %p\n", size
, pMemory
);
2430 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
2431 * since the type is part of the memory block that is encompassed by
2432 * the whole complex type. Memory is forced to allocate when pointers
2433 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
2434 * clearing the memory we pass in to the unmarshaller */
2435 memset(pMemory
, 0, size
);
2436 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
2439 /* for some reason interface pointers aren't generated as
2440 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2441 * they still need the derefencing treatment that pointers are
2443 if (*desc
== RPC_FC_IP
)
2444 m(pStubMsg
, (unsigned char **)pMemory
, desc
, FALSE
);
2446 m(pStubMsg
, &pMemory
, desc
, FALSE
);
2448 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
2455 FIXME("unhandled format %d\n", *pFormat
);
2463 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2464 unsigned char *pMemory
,
2465 PFORMAT_STRING pFormat
,
2466 PFORMAT_STRING pPointer
)
2468 PFORMAT_STRING desc
;
2472 while (*pFormat
!= RPC_FC_END
) {
2478 safe_buffer_length_increment(pStubMsg
, 1);
2484 safe_buffer_length_increment(pStubMsg
, 2);
2488 safe_buffer_length_increment(pStubMsg
, 2);
2494 safe_buffer_length_increment(pStubMsg
, 4);
2498 safe_buffer_length_increment(pStubMsg
, 8);
2501 case RPC_FC_POINTER
:
2502 if (!pStubMsg
->IgnoreEmbeddedPointers
)
2504 int saved_buffer_length
= pStubMsg
->BufferLength
;
2505 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2506 pStubMsg
->PointerLength
= 0;
2507 if(!pStubMsg
->BufferLength
)
2508 ERR("BufferLength == 0??\n");
2509 PointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
2510 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2511 pStubMsg
->BufferLength
= saved_buffer_length
;
2513 if (*pPointer
!= RPC_FC_RP
)
2515 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
2516 safe_buffer_length_increment(pStubMsg
, 4);
2521 case RPC_FC_ALIGNM4
:
2522 ALIGN_POINTER(pMemory
, 4);
2524 case RPC_FC_ALIGNM8
:
2525 ALIGN_POINTER(pMemory
, 8);
2527 case RPC_FC_STRUCTPAD1
:
2528 case RPC_FC_STRUCTPAD2
:
2529 case RPC_FC_STRUCTPAD3
:
2530 case RPC_FC_STRUCTPAD4
:
2531 case RPC_FC_STRUCTPAD5
:
2532 case RPC_FC_STRUCTPAD6
:
2533 case RPC_FC_STRUCTPAD7
:
2534 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2536 case RPC_FC_EMBEDDED_COMPLEX
:
2537 pMemory
+= pFormat
[1];
2539 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2540 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2541 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
2544 /* for some reason interface pointers aren't generated as
2545 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2546 * they still need the derefencing treatment that pointers are
2548 if (*desc
== RPC_FC_IP
)
2549 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2551 m(pStubMsg
, pMemory
, desc
);
2553 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
2560 FIXME("unhandled format 0x%02x\n", *pFormat
);
2568 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
2569 unsigned char *pMemory
,
2570 PFORMAT_STRING pFormat
,
2571 PFORMAT_STRING pPointer
)
2573 PFORMAT_STRING desc
;
2577 while (*pFormat
!= RPC_FC_END
) {
2599 case RPC_FC_POINTER
:
2600 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
2604 case RPC_FC_ALIGNM4
:
2605 ALIGN_POINTER(pMemory
, 4);
2607 case RPC_FC_ALIGNM8
:
2608 ALIGN_POINTER(pMemory
, 8);
2610 case RPC_FC_STRUCTPAD1
:
2611 case RPC_FC_STRUCTPAD2
:
2612 case RPC_FC_STRUCTPAD3
:
2613 case RPC_FC_STRUCTPAD4
:
2614 case RPC_FC_STRUCTPAD5
:
2615 case RPC_FC_STRUCTPAD6
:
2616 case RPC_FC_STRUCTPAD7
:
2617 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2619 case RPC_FC_EMBEDDED_COMPLEX
:
2620 pMemory
+= pFormat
[1];
2622 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2623 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2624 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
2627 /* for some reason interface pointers aren't generated as
2628 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2629 * they still need the derefencing treatment that pointers are
2631 if (*desc
== RPC_FC_IP
)
2632 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2634 m(pStubMsg
, pMemory
, desc
);
2642 FIXME("unhandled format 0x%02x\n", *pFormat
);
2650 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2651 PFORMAT_STRING pFormat
,
2652 PFORMAT_STRING pPointer
)
2654 PFORMAT_STRING desc
;
2655 unsigned long size
= 0;
2657 while (*pFormat
!= RPC_FC_END
) {
2664 safe_buffer_increment(pStubMsg
, 1);
2670 safe_buffer_increment(pStubMsg
, 2);
2674 safe_buffer_increment(pStubMsg
, 2);
2680 safe_buffer_increment(pStubMsg
, 4);
2684 safe_buffer_increment(pStubMsg
, 8);
2686 case RPC_FC_POINTER
:
2688 unsigned char *saved_buffer
;
2689 int pointer_buffer_mark_set
= 0;
2690 if (*pPointer
!= RPC_FC_RP
)
2691 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2692 saved_buffer
= pStubMsg
->Buffer
;
2693 if (pStubMsg
->PointerBufferMark
)
2695 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2696 pStubMsg
->PointerBufferMark
= NULL
;
2697 pointer_buffer_mark_set
= 1;
2699 else if (*pPointer
!= RPC_FC_RP
)
2700 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2702 if (!pStubMsg
->IgnoreEmbeddedPointers
)
2703 PointerMemorySize(pStubMsg
, saved_buffer
, pPointer
);
2704 if (pointer_buffer_mark_set
)
2706 STD_OVERFLOW_CHECK(pStubMsg
);
2707 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2708 pStubMsg
->Buffer
= saved_buffer
;
2709 if (*pPointer
!= RPC_FC_RP
)
2710 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2716 case RPC_FC_ALIGNM4
:
2717 ALIGN_LENGTH(size
, 4);
2718 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2720 case RPC_FC_ALIGNM8
:
2721 ALIGN_LENGTH(size
, 8);
2722 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
2724 case RPC_FC_STRUCTPAD1
:
2725 case RPC_FC_STRUCTPAD2
:
2726 case RPC_FC_STRUCTPAD3
:
2727 case RPC_FC_STRUCTPAD4
:
2728 case RPC_FC_STRUCTPAD5
:
2729 case RPC_FC_STRUCTPAD6
:
2730 case RPC_FC_STRUCTPAD7
:
2731 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2733 case RPC_FC_EMBEDDED_COMPLEX
:
2736 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2737 size
+= EmbeddedComplexMemorySize(pStubMsg
, desc
);
2743 FIXME("unhandled format 0x%02x\n", *pFormat
);
2751 unsigned long ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg
,
2752 PFORMAT_STRING pFormat
)
2754 PFORMAT_STRING desc
;
2755 unsigned long size
= 0;
2757 while (*pFormat
!= RPC_FC_END
) {
2779 case RPC_FC_POINTER
:
2780 size
+= sizeof(void *);
2782 case RPC_FC_ALIGNM4
:
2783 ALIGN_LENGTH(size
, 4);
2785 case RPC_FC_ALIGNM8
:
2786 ALIGN_LENGTH(size
, 8);
2788 case RPC_FC_STRUCTPAD1
:
2789 case RPC_FC_STRUCTPAD2
:
2790 case RPC_FC_STRUCTPAD3
:
2791 case RPC_FC_STRUCTPAD4
:
2792 case RPC_FC_STRUCTPAD5
:
2793 case RPC_FC_STRUCTPAD6
:
2794 case RPC_FC_STRUCTPAD7
:
2795 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2797 case RPC_FC_EMBEDDED_COMPLEX
:
2800 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2801 size
+= EmbeddedComplexSize(pStubMsg
, desc
);
2807 FIXME("unhandled format 0x%02x\n", *pFormat
);
2815 /***********************************************************************
2816 * NdrComplexStructMarshall [RPCRT4.@]
2818 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2819 unsigned char *pMemory
,
2820 PFORMAT_STRING pFormat
)
2822 PFORMAT_STRING conf_array
= NULL
;
2823 PFORMAT_STRING pointer_desc
= NULL
;
2824 unsigned char *OldMemory
= pStubMsg
->Memory
;
2825 int pointer_buffer_mark_set
= 0;
2827 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2829 if (!pStubMsg
->PointerBufferMark
)
2831 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2832 /* save buffer length */
2833 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2835 /* get the buffer pointer after complex array data, but before
2837 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- pStubMsg
->BufferStart
;
2838 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2839 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
2840 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2842 /* save it for use by embedded pointer code later */
2843 pStubMsg
->PointerBufferMark
= pStubMsg
->BufferStart
+ pStubMsg
->BufferLength
;
2844 TRACE("difference = 0x%x\n", pStubMsg
->PointerBufferMark
- pStubMsg
->Buffer
);
2845 pointer_buffer_mark_set
= 1;
2847 /* restore the original buffer length */
2848 pStubMsg
->BufferLength
= saved_buffer_length
;
2851 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pFormat
[1] + 1);
2854 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
2856 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2859 pStubMsg
->Memory
= pMemory
;
2861 ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2864 NdrConformantArrayMarshall(pStubMsg
, pMemory
, conf_array
);
2866 pStubMsg
->Memory
= OldMemory
;
2868 if (pointer_buffer_mark_set
)
2870 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2871 pStubMsg
->PointerBufferMark
= NULL
;
2874 STD_OVERFLOW_CHECK(pStubMsg
);
2879 /***********************************************************************
2880 * NdrComplexStructUnmarshall [RPCRT4.@]
2882 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2883 unsigned char **ppMemory
,
2884 PFORMAT_STRING pFormat
,
2885 unsigned char fMustAlloc
)
2887 unsigned size
= *(const WORD
*)(pFormat
+2);
2888 PFORMAT_STRING conf_array
= NULL
;
2889 PFORMAT_STRING pointer_desc
= NULL
;
2890 unsigned char *pMemory
;
2891 int pointer_buffer_mark_set
= 0;
2893 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2895 if (!pStubMsg
->PointerBufferMark
)
2897 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2898 /* save buffer pointer */
2899 unsigned char *saved_buffer
= pStubMsg
->Buffer
;
2901 /* get the buffer pointer after complex array data, but before
2903 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2904 NdrComplexStructMemorySize(pStubMsg
, pFormat
);
2905 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2907 /* save it for use by embedded pointer code later */
2908 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2909 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->PointerBufferMark
- saved_buffer
));
2910 pointer_buffer_mark_set
= 1;
2912 /* restore the original buffer */
2913 pStubMsg
->Buffer
= saved_buffer
;
2916 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2918 if (fMustAlloc
|| !*ppMemory
)
2919 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2922 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
2924 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2927 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
, fMustAlloc
);
2930 NdrConformantArrayUnmarshall(pStubMsg
, &pMemory
, conf_array
, fMustAlloc
);
2932 if (pointer_buffer_mark_set
)
2934 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2935 pStubMsg
->PointerBufferMark
= NULL
;
2941 /***********************************************************************
2942 * NdrComplexStructBufferSize [RPCRT4.@]
2944 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2945 unsigned char *pMemory
,
2946 PFORMAT_STRING pFormat
)
2948 PFORMAT_STRING conf_array
= NULL
;
2949 PFORMAT_STRING pointer_desc
= NULL
;
2950 unsigned char *OldMemory
= pStubMsg
->Memory
;
2951 int pointer_length_set
= 0;
2953 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2955 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
2957 if(!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
2959 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2960 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2962 /* get the buffer length after complex struct data, but before
2964 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2965 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
2966 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2968 /* save it for use by embedded pointer code later */
2969 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2970 pointer_length_set
= 1;
2971 TRACE("difference = 0x%lx\n", pStubMsg
->PointerLength
- saved_buffer_length
);
2973 /* restore the original buffer length */
2974 pStubMsg
->BufferLength
= saved_buffer_length
;
2978 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
2980 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2983 pStubMsg
->Memory
= pMemory
;
2985 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2988 NdrConformantArrayBufferSize(pStubMsg
, pMemory
, conf_array
);
2990 pStubMsg
->Memory
= OldMemory
;
2992 if(pointer_length_set
)
2994 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2995 pStubMsg
->PointerLength
= 0;
3000 /***********************************************************************
3001 * NdrComplexStructMemorySize [RPCRT4.@]
3003 ULONG WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3004 PFORMAT_STRING pFormat
)
3006 unsigned size
= *(const WORD
*)(pFormat
+2);
3007 PFORMAT_STRING conf_array
= NULL
;
3008 PFORMAT_STRING pointer_desc
= NULL
;
3010 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3012 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
3015 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3017 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3020 ComplexStructMemorySize(pStubMsg
, pFormat
, pointer_desc
);
3023 NdrConformantArrayMemorySize(pStubMsg
, conf_array
);
3028 /***********************************************************************
3029 * NdrComplexStructFree [RPCRT4.@]
3031 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3032 unsigned char *pMemory
,
3033 PFORMAT_STRING pFormat
)
3035 PFORMAT_STRING conf_array
= NULL
;
3036 PFORMAT_STRING pointer_desc
= NULL
;
3037 unsigned char *OldMemory
= pStubMsg
->Memory
;
3039 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3042 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3044 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3047 pStubMsg
->Memory
= pMemory
;
3049 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3052 NdrConformantArrayFree(pStubMsg
, pMemory
, conf_array
);
3054 pStubMsg
->Memory
= OldMemory
;
3057 /***********************************************************************
3058 * NdrConformantArrayMarshall [RPCRT4.@]
3060 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3061 unsigned char *pMemory
,
3062 PFORMAT_STRING pFormat
)
3064 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
3065 unsigned char alignment
= pFormat
[1] + 1;
3067 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3068 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
3070 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
3072 WriteConformance(pStubMsg
);
3074 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
3076 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3077 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3078 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
3080 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3085 /***********************************************************************
3086 * NdrConformantArrayUnmarshall [RPCRT4.@]
3088 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3089 unsigned char **ppMemory
,
3090 PFORMAT_STRING pFormat
,
3091 unsigned char fMustAlloc
)
3093 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
3094 unsigned char alignment
= pFormat
[1] + 1;
3095 unsigned char *saved_buffer
;
3097 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3098 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
3100 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
3102 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3103 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3106 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3109 if (!pStubMsg
->IsClient
&& !*ppMemory
)
3110 /* for servers, we just point straight into the RPC buffer */
3111 *ppMemory
= pStubMsg
->Buffer
;
3114 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3115 safe_buffer_increment(pStubMsg
, size
);
3116 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
3118 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
3119 if (*ppMemory
!= saved_buffer
)
3120 memcpy(*ppMemory
, saved_buffer
, size
);
3125 /***********************************************************************
3126 * NdrConformantArrayBufferSize [RPCRT4.@]
3128 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3129 unsigned char *pMemory
,
3130 PFORMAT_STRING pFormat
)
3132 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
3133 unsigned char alignment
= pFormat
[1] + 1;
3135 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3136 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
3138 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
3140 SizeConformance(pStubMsg
);
3142 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
3144 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3145 /* conformance value plus array */
3146 safe_buffer_length_increment(pStubMsg
, size
);
3148 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3151 /***********************************************************************
3152 * NdrConformantArrayMemorySize [RPCRT4.@]
3154 ULONG WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3155 PFORMAT_STRING pFormat
)
3157 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
3158 unsigned char alignment
= pFormat
[1] + 1;
3160 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3161 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
3163 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
3164 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3165 pStubMsg
->MemorySize
+= size
;
3167 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3168 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3169 safe_buffer_increment(pStubMsg
, size
);
3171 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
3173 return pStubMsg
->MemorySize
;
3176 /***********************************************************************
3177 * NdrConformantArrayFree [RPCRT4.@]
3179 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3180 unsigned char *pMemory
,
3181 PFORMAT_STRING pFormat
)
3183 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3184 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
3186 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
3188 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
3192 /***********************************************************************
3193 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3195 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
3196 unsigned char* pMemory
,
3197 PFORMAT_STRING pFormat
)
3200 unsigned char alignment
= pFormat
[1] + 1;
3201 DWORD esize
= *(const WORD
*)(pFormat
+2);
3203 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3205 if (pFormat
[0] != RPC_FC_CVARRAY
)
3207 ERR("invalid format type %x\n", pFormat
[0]);
3208 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3212 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
3213 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
3215 WriteConformance(pStubMsg
);
3216 WriteVariance(pStubMsg
);
3218 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
3220 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3222 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3223 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
3225 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3231 /***********************************************************************
3232 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
3234 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
3235 unsigned char** ppMemory
,
3236 PFORMAT_STRING pFormat
,
3237 unsigned char fMustAlloc
)
3239 ULONG bufsize
, memsize
;
3240 unsigned char alignment
= pFormat
[1] + 1;
3241 DWORD esize
= *(const WORD
*)(pFormat
+2);
3242 unsigned char *saved_buffer
;
3245 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3247 if (pFormat
[0] != RPC_FC_CVARRAY
)
3249 ERR("invalid format type %x\n", pFormat
[0]);
3250 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3254 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
3255 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3257 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3259 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3260 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3261 offset
= pStubMsg
->Offset
;
3263 if (!*ppMemory
|| fMustAlloc
)
3264 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
3265 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3266 safe_buffer_increment(pStubMsg
, bufsize
);
3268 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
3270 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
3276 /***********************************************************************
3277 * NdrConformantVaryingArrayFree [RPCRT4.@]
3279 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
3280 unsigned char* pMemory
,
3281 PFORMAT_STRING pFormat
)
3283 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3285 if (pFormat
[0] != RPC_FC_CVARRAY
)
3287 ERR("invalid format type %x\n", pFormat
[0]);
3288 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3292 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
3293 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
3295 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
3299 /***********************************************************************
3300 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
3302 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
3303 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
3305 unsigned char alignment
= pFormat
[1] + 1;
3306 DWORD esize
= *(const WORD
*)(pFormat
+2);
3308 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3310 if (pFormat
[0] != RPC_FC_CVARRAY
)
3312 ERR("invalid format type %x\n", pFormat
[0]);
3313 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3318 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
3319 /* compute length */
3320 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
3322 SizeConformance(pStubMsg
);
3323 SizeVariance(pStubMsg
);
3325 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
3327 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
3329 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3333 /***********************************************************************
3334 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
3336 ULONG WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
3337 PFORMAT_STRING pFormat
)
3339 ULONG bufsize
, memsize
;
3340 unsigned char alignment
= pFormat
[1] + 1;
3341 DWORD esize
= *(const WORD
*)(pFormat
+2);
3343 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
3345 if (pFormat
[0] != RPC_FC_CVARRAY
)
3347 ERR("invalid format type %x\n", pFormat
[0]);
3348 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3349 return pStubMsg
->MemorySize
;
3352 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
3353 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3355 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3357 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3358 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3360 safe_buffer_increment(pStubMsg
, bufsize
);
3361 pStubMsg
->MemorySize
+= memsize
;
3363 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
3365 return pStubMsg
->MemorySize
;
3369 /***********************************************************************
3370 * NdrComplexArrayMarshall [RPCRT4.@]
3372 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3373 unsigned char *pMemory
,
3374 PFORMAT_STRING pFormat
)
3376 ULONG i
, count
, def
;
3377 BOOL variance_present
;
3378 unsigned char alignment
;
3379 int pointer_buffer_mark_set
= 0;
3381 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3383 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3385 ERR("invalid format type %x\n", pFormat
[0]);
3386 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3390 alignment
= pFormat
[1] + 1;
3392 if (!pStubMsg
->PointerBufferMark
)
3394 /* save buffer fields that may be changed by buffer sizer functions
3395 * and that may be needed later on */
3396 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3397 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
3398 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
3399 unsigned long saved_offset
= pStubMsg
->Offset
;
3400 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
3402 /* get the buffer pointer after complex array data, but before
3404 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- pStubMsg
->BufferStart
;
3405 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3406 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
3407 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3409 /* save it for use by embedded pointer code later */
3410 pStubMsg
->PointerBufferMark
= pStubMsg
->BufferStart
+ pStubMsg
->BufferLength
;
3411 TRACE("difference = 0x%x\n", pStubMsg
->Buffer
- pStubMsg
->BufferStart
);
3412 pointer_buffer_mark_set
= 1;
3414 /* restore fields */
3415 pStubMsg
->ActualCount
= saved_actual_count
;
3416 pStubMsg
->Offset
= saved_offset
;
3417 pStubMsg
->MaxCount
= saved_max_count
;
3418 pStubMsg
->BufferLength
= saved_buffer_length
;
3421 def
= *(const WORD
*)&pFormat
[2];
3424 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3425 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3427 variance_present
= IsConformanceOrVariancePresent(pFormat
);
3428 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3429 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3431 WriteConformance(pStubMsg
);
3432 if (variance_present
)
3433 WriteVariance(pStubMsg
);
3435 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
3437 count
= pStubMsg
->ActualCount
;
3438 for (i
= 0; i
< count
; i
++)
3439 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
3441 STD_OVERFLOW_CHECK(pStubMsg
);
3443 if (pointer_buffer_mark_set
)
3445 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3446 pStubMsg
->PointerBufferMark
= NULL
;
3452 /***********************************************************************
3453 * NdrComplexArrayUnmarshall [RPCRT4.@]
3455 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3456 unsigned char **ppMemory
,
3457 PFORMAT_STRING pFormat
,
3458 unsigned char fMustAlloc
)
3460 ULONG i
, count
, size
;
3461 unsigned char alignment
;
3462 unsigned char *pMemory
;
3463 unsigned char *saved_buffer
;
3464 int pointer_buffer_mark_set
= 0;
3465 int saved_ignore_embedded
;
3467 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3469 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3471 ERR("invalid format type %x\n", pFormat
[0]);
3472 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3476 alignment
= pFormat
[1] + 1;
3478 saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3479 /* save buffer pointer */
3480 saved_buffer
= pStubMsg
->Buffer
;
3481 /* get the buffer pointer after complex array data, but before
3483 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3484 pStubMsg
->MemorySize
= 0;
3485 NdrComplexArrayMemorySize(pStubMsg
, pFormat
);
3486 size
= pStubMsg
->MemorySize
;
3487 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3489 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->Buffer
- saved_buffer
));
3490 if (!pStubMsg
->PointerBufferMark
)
3492 /* save it for use by embedded pointer code later */
3493 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3494 pointer_buffer_mark_set
= 1;
3496 /* restore the original buffer */
3497 pStubMsg
->Buffer
= saved_buffer
;
3501 pFormat
= ReadConformance(pStubMsg
, pFormat
);
3502 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3504 if (fMustAlloc
|| !*ppMemory
)
3505 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3507 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3509 pMemory
= *ppMemory
;
3510 count
= pStubMsg
->ActualCount
;
3511 for (i
= 0; i
< count
; i
++)
3512 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
, fMustAlloc
);
3514 if (pointer_buffer_mark_set
)
3516 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3517 pStubMsg
->PointerBufferMark
= NULL
;
3523 /***********************************************************************
3524 * NdrComplexArrayBufferSize [RPCRT4.@]
3526 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3527 unsigned char *pMemory
,
3528 PFORMAT_STRING pFormat
)
3530 ULONG i
, count
, def
;
3531 unsigned char alignment
;
3532 BOOL variance_present
;
3533 int pointer_length_set
= 0;
3535 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3537 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3539 ERR("invalid format type %x\n", pFormat
[0]);
3540 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3544 alignment
= pFormat
[1] + 1;
3546 if (!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
3548 /* save buffer fields that may be changed by buffer sizer functions
3549 * and that may be needed later on */
3550 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3551 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
3552 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
3553 unsigned long saved_offset
= pStubMsg
->Offset
;
3554 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
3556 /* get the buffer pointer after complex array data, but before
3558 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3559 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
3560 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3562 /* save it for use by embedded pointer code later */
3563 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3564 pointer_length_set
= 1;
3566 /* restore fields */
3567 pStubMsg
->ActualCount
= saved_actual_count
;
3568 pStubMsg
->Offset
= saved_offset
;
3569 pStubMsg
->MaxCount
= saved_max_count
;
3570 pStubMsg
->BufferLength
= saved_buffer_length
;
3572 def
= *(const WORD
*)&pFormat
[2];
3575 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3576 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3577 SizeConformance(pStubMsg
);
3579 variance_present
= IsConformanceOrVariancePresent(pFormat
);
3580 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3581 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3583 if (variance_present
)
3584 SizeVariance(pStubMsg
);
3586 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
3588 count
= pStubMsg
->ActualCount
;
3589 for (i
= 0; i
< count
; i
++)
3590 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
3592 if(pointer_length_set
)
3594 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3595 pStubMsg
->PointerLength
= 0;
3599 /***********************************************************************
3600 * NdrComplexArrayMemorySize [RPCRT4.@]
3602 ULONG WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3603 PFORMAT_STRING pFormat
)
3605 ULONG i
, count
, esize
, SavedMemorySize
, MemorySize
;
3606 unsigned char alignment
;
3608 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3610 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3612 ERR("invalid format type %x\n", pFormat
[0]);
3613 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3617 alignment
= pFormat
[1] + 1;
3621 pFormat
= ReadConformance(pStubMsg
, pFormat
);
3622 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3624 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3626 SavedMemorySize
= pStubMsg
->MemorySize
;
3628 esize
= ComplexStructSize(pStubMsg
, pFormat
);
3630 MemorySize
= safe_multiply(pStubMsg
->MaxCount
, esize
);
3632 count
= pStubMsg
->ActualCount
;
3633 for (i
= 0; i
< count
; i
++)
3634 ComplexStructMemorySize(pStubMsg
, pFormat
, NULL
);
3636 pStubMsg
->MemorySize
= SavedMemorySize
;
3638 pStubMsg
->MemorySize
+= MemorySize
;
3642 /***********************************************************************
3643 * NdrComplexArrayFree [RPCRT4.@]
3645 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3646 unsigned char *pMemory
,
3647 PFORMAT_STRING pFormat
)
3649 ULONG i
, count
, def
;
3651 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3653 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3655 ERR("invalid format type %x\n", pFormat
[0]);
3656 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3660 def
= *(const WORD
*)&pFormat
[2];
3663 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3664 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3666 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3667 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3669 count
= pStubMsg
->ActualCount
;
3670 for (i
= 0; i
< count
; i
++)
3671 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
3674 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg
,
3675 USER_MARSHAL_CB_TYPE cbtype
, PFORMAT_STRING pFormat
,
3676 USER_MARSHAL_CB
*umcb
)
3678 umcb
->Flags
= MAKELONG(pStubMsg
->dwDestContext
,
3679 pStubMsg
->RpcMsg
->DataRepresentation
);
3680 umcb
->pStubMsg
= pStubMsg
;
3681 umcb
->pReserve
= NULL
;
3682 umcb
->Signature
= USER_MARSHAL_CB_SIGNATURE
;
3683 umcb
->CBType
= cbtype
;
3684 umcb
->pFormat
= pFormat
;
3685 umcb
->pTypeFormat
= NULL
/* FIXME */;
3688 #define USER_MARSHAL_PTR_PREFIX \
3689 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3690 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3692 /***********************************************************************
3693 * NdrUserMarshalMarshall [RPCRT4.@]
3695 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3696 unsigned char *pMemory
,
3697 PFORMAT_STRING pFormat
)
3699 unsigned flags
= pFormat
[1];
3700 unsigned index
= *(const WORD
*)&pFormat
[2];
3701 unsigned char *saved_buffer
= NULL
;
3702 USER_MARSHAL_CB umcb
;
3704 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3705 TRACE("index=%d\n", index
);
3707 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_MARSHALL
, pFormat
, &umcb
);
3709 if (flags
& USER_MARSHAL_POINTER
)
3711 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
3712 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, USER_MARSHAL_PTR_PREFIX
);
3713 pStubMsg
->Buffer
+= 4;
3714 if (pStubMsg
->PointerBufferMark
)
3716 saved_buffer
= pStubMsg
->Buffer
;
3717 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3718 pStubMsg
->PointerBufferMark
= NULL
;
3720 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 8);
3723 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3726 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
3727 &umcb
.Flags
, pStubMsg
->Buffer
, pMemory
);
3731 STD_OVERFLOW_CHECK(pStubMsg
);
3732 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3733 pStubMsg
->Buffer
= saved_buffer
;
3736 STD_OVERFLOW_CHECK(pStubMsg
);
3741 /***********************************************************************
3742 * NdrUserMarshalUnmarshall [RPCRT4.@]
3744 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3745 unsigned char **ppMemory
,
3746 PFORMAT_STRING pFormat
,
3747 unsigned char fMustAlloc
)
3749 unsigned flags
= pFormat
[1];
3750 unsigned index
= *(const WORD
*)&pFormat
[2];
3751 DWORD memsize
= *(const WORD
*)&pFormat
[4];
3752 unsigned char *saved_buffer
= NULL
;
3753 USER_MARSHAL_CB umcb
;
3755 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3756 TRACE("index=%d\n", index
);
3758 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_UNMARSHALL
, pFormat
, &umcb
);
3760 if (flags
& USER_MARSHAL_POINTER
)
3762 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3763 /* skip pointer prefix */
3764 pStubMsg
->Buffer
+= 4;
3765 if (pStubMsg
->PointerBufferMark
)
3767 saved_buffer
= pStubMsg
->Buffer
;
3768 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3769 pStubMsg
->PointerBufferMark
= NULL
;
3771 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3774 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3776 if (fMustAlloc
|| !*ppMemory
)
3777 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
3780 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
3781 &umcb
.Flags
, pStubMsg
->Buffer
, *ppMemory
);
3785 STD_OVERFLOW_CHECK(pStubMsg
);
3786 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3787 pStubMsg
->Buffer
= saved_buffer
;
3793 /***********************************************************************
3794 * NdrUserMarshalBufferSize [RPCRT4.@]
3796 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3797 unsigned char *pMemory
,
3798 PFORMAT_STRING pFormat
)
3800 unsigned flags
= pFormat
[1];
3801 unsigned index
= *(const WORD
*)&pFormat
[2];
3802 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
3803 USER_MARSHAL_CB umcb
;
3804 unsigned long saved_buffer_length
= 0;
3806 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3807 TRACE("index=%d\n", index
);
3809 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_BUFFER_SIZE
, pFormat
, &umcb
);
3811 if (flags
& USER_MARSHAL_POINTER
)
3813 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
3814 /* skip pointer prefix */
3815 safe_buffer_length_increment(pStubMsg
, 4);
3816 if (pStubMsg
->IgnoreEmbeddedPointers
)
3818 if (pStubMsg
->PointerLength
)
3820 saved_buffer_length
= pStubMsg
->BufferLength
;
3821 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3822 pStubMsg
->PointerLength
= 0;
3824 ALIGN_LENGTH(pStubMsg
->BufferLength
, 8);
3827 ALIGN_LENGTH(pStubMsg
->BufferLength
, (flags
& 0xf) + 1);
3830 TRACE("size=%d\n", bufsize
);
3831 safe_buffer_length_increment(pStubMsg
, bufsize
);
3834 pStubMsg
->BufferLength
=
3835 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
3836 &umcb
.Flags
, pStubMsg
->BufferLength
, pMemory
);
3838 if (saved_buffer_length
)
3840 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3841 pStubMsg
->BufferLength
= saved_buffer_length
;
3846 /***********************************************************************
3847 * NdrUserMarshalMemorySize [RPCRT4.@]
3849 ULONG WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3850 PFORMAT_STRING pFormat
)
3852 unsigned flags
= pFormat
[1];
3853 unsigned index
= *(const WORD
*)&pFormat
[2];
3854 DWORD memsize
= *(const WORD
*)&pFormat
[4];
3855 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
3857 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3858 TRACE("index=%d\n", index
);
3860 pStubMsg
->MemorySize
+= memsize
;
3862 if (flags
& USER_MARSHAL_POINTER
)
3864 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3865 /* skip pointer prefix */
3866 pStubMsg
->Buffer
+= 4;
3867 if (pStubMsg
->IgnoreEmbeddedPointers
)
3868 return pStubMsg
->MemorySize
;
3869 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3872 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3875 FIXME("not implemented for varying buffer size\n");
3877 pStubMsg
->Buffer
+= bufsize
;
3879 return pStubMsg
->MemorySize
;
3882 /***********************************************************************
3883 * NdrUserMarshalFree [RPCRT4.@]
3885 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
3886 unsigned char *pMemory
,
3887 PFORMAT_STRING pFormat
)
3889 /* unsigned flags = pFormat[1]; */
3890 unsigned index
= *(const WORD
*)&pFormat
[2];
3891 USER_MARSHAL_CB umcb
;
3893 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3894 TRACE("index=%d\n", index
);
3896 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_FREE
, pFormat
, &umcb
);
3898 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
3899 &umcb
.Flags
, pMemory
);
3902 /***********************************************************************
3903 * NdrClearOutParameters [RPCRT4.@]
3905 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
3906 PFORMAT_STRING pFormat
,
3909 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
3912 /***********************************************************************
3913 * NdrConvert [RPCRT4.@]
3915 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
3917 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
3918 /* FIXME: since this stub doesn't do any converting, the proper behavior
3919 is to raise an exception */
3922 /***********************************************************************
3923 * NdrConvert2 [RPCRT4.@]
3925 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, LONG NumberParams
)
3927 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3928 pStubMsg
, pFormat
, NumberParams
);
3929 /* FIXME: since this stub doesn't do any converting, the proper behavior
3930 is to raise an exception */
3933 #include "pshpack1.h"
3934 typedef struct _NDR_CSTRUCT_FORMAT
3937 unsigned char alignment
;
3938 unsigned short memory_size
;
3939 short offset_to_array_description
;
3940 } NDR_CSTRUCT_FORMAT
, NDR_CVSTRUCT_FORMAT
;
3941 #include "poppack.h"
3943 /***********************************************************************
3944 * NdrConformantStructMarshall [RPCRT4.@]
3946 unsigned char * WINAPI
NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3947 unsigned char *pMemory
,
3948 PFORMAT_STRING pFormat
)
3950 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3951 PFORMAT_STRING pCArrayFormat
;
3952 ULONG esize
, bufsize
;
3954 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3956 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3957 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3959 ERR("invalid format type %x\n", pCStructFormat
->type
);
3960 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3964 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3965 pCStructFormat
->offset_to_array_description
;
3966 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3968 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3969 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3972 esize
= *(const WORD
*)(pCArrayFormat
+2);
3974 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
3975 pCArrayFormat
+ 4, 0);
3977 WriteConformance(pStubMsg
);
3979 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
3981 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3983 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3984 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
3986 ERR("integer overflow of memory_size %u with bufsize %u\n",
3987 pCStructFormat
->memory_size
, bufsize
);
3988 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3990 /* copy constant sized part of struct */
3991 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3992 safe_copy_to_buffer(pStubMsg
, pMemory
, pCStructFormat
->memory_size
+ bufsize
);
3994 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3995 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4000 /***********************************************************************
4001 * NdrConformantStructUnmarshall [RPCRT4.@]
4003 unsigned char * WINAPI
NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4004 unsigned char **ppMemory
,
4005 PFORMAT_STRING pFormat
,
4006 unsigned char fMustAlloc
)
4008 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4009 PFORMAT_STRING pCArrayFormat
;
4010 ULONG esize
, bufsize
;
4011 unsigned char *saved_buffer
;
4013 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4015 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4016 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4018 ERR("invalid format type %x\n", pCStructFormat
->type
);
4019 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4022 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4023 pCStructFormat
->offset_to_array_description
;
4024 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4026 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4027 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4030 esize
= *(const WORD
*)(pCArrayFormat
+2);
4032 pCArrayFormat
= ReadConformance(pStubMsg
, pCArrayFormat
+ 4);
4034 ALIGN_POINTER(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4036 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4038 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4039 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4041 ERR("integer overflow of memory_size %u with bufsize %u\n",
4042 pCStructFormat
->memory_size
, bufsize
);
4043 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4048 SIZE_T size
= pCStructFormat
->memory_size
+ bufsize
;
4049 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4053 if (!pStubMsg
->IsClient
&& !*ppMemory
)
4054 /* for servers, we just point straight into the RPC buffer */
4055 *ppMemory
= pStubMsg
->Buffer
;
4058 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4059 safe_buffer_increment(pStubMsg
, pCStructFormat
->memory_size
+ bufsize
);
4060 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4061 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4063 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
4064 if (*ppMemory
!= saved_buffer
)
4065 memcpy(*ppMemory
, saved_buffer
, pCStructFormat
->memory_size
+ bufsize
);
4070 /***********************************************************************
4071 * NdrConformantStructBufferSize [RPCRT4.@]
4073 void WINAPI
NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4074 unsigned char *pMemory
,
4075 PFORMAT_STRING pFormat
)
4077 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4078 PFORMAT_STRING pCArrayFormat
;
4081 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4083 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4084 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4086 ERR("invalid format type %x\n", pCStructFormat
->type
);
4087 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4090 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4091 pCStructFormat
->offset_to_array_description
;
4092 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4094 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4095 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4098 esize
= *(const WORD
*)(pCArrayFormat
+2);
4100 pCArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
, pCArrayFormat
+4, 0);
4101 SizeConformance(pStubMsg
);
4103 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCStructFormat
->alignment
+ 1);
4105 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4107 safe_buffer_length_increment(pStubMsg
, pCStructFormat
->memory_size
);
4108 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
4110 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4111 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4114 /***********************************************************************
4115 * NdrConformantStructMemorySize [RPCRT4.@]
4117 ULONG WINAPI
NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4118 PFORMAT_STRING pFormat
)
4124 /***********************************************************************
4125 * NdrConformantStructFree [RPCRT4.@]
4127 void WINAPI
NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
4128 unsigned char *pMemory
,
4129 PFORMAT_STRING pFormat
)
4131 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4132 PFORMAT_STRING pCArrayFormat
;
4134 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4136 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4137 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4139 ERR("invalid format type %x\n", pCStructFormat
->type
);
4140 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4144 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4145 pCStructFormat
->offset_to_array_description
;
4146 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4148 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4149 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4153 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4154 pCArrayFormat
+ 4, 0);
4156 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4158 /* copy constant sized part of struct */
4159 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4161 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4162 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4165 /***********************************************************************
4166 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4168 unsigned char * WINAPI
NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4169 unsigned char *pMemory
,
4170 PFORMAT_STRING pFormat
)
4172 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4173 PFORMAT_STRING pCVArrayFormat
;
4174 ULONG esize
, bufsize
;
4176 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4178 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4179 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4181 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4182 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4186 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4187 pCVStructFormat
->offset_to_array_description
;
4188 switch (*pCVArrayFormat
)
4190 case RPC_FC_CVARRAY
:
4191 esize
= *(const WORD
*)(pCVArrayFormat
+2);
4193 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4194 pCVArrayFormat
+ 4, 0);
4195 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4198 case RPC_FC_C_CSTRING
:
4199 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
4200 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
4201 esize
= sizeof(char);
4202 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4203 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4204 pCVArrayFormat
+ 2, 0);
4206 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4208 case RPC_FC_C_WSTRING
:
4209 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
4210 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
4211 esize
= sizeof(WCHAR
);
4212 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4213 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4214 pCVArrayFormat
+ 2, 0);
4216 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4219 ERR("invalid array format type %x\n", *pCVArrayFormat
);
4220 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4224 WriteConformance(pStubMsg
);
4226 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4228 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4230 /* write constant sized part */
4231 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4232 safe_copy_to_buffer(pStubMsg
, pMemory
, pCVStructFormat
->memory_size
);
4234 WriteVariance(pStubMsg
);
4236 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4238 /* write array part */
4239 safe_copy_to_buffer(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
, bufsize
);
4241 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4246 /***********************************************************************
4247 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4249 unsigned char * WINAPI
NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4250 unsigned char **ppMemory
,
4251 PFORMAT_STRING pFormat
,
4252 unsigned char fMustAlloc
)
4254 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4255 PFORMAT_STRING pCVArrayFormat
;
4256 ULONG esize
, bufsize
;
4257 unsigned char cvarray_type
;
4258 unsigned char *saved_buffer
, *saved_array_buffer
;
4260 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4262 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4263 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4265 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4266 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4270 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4271 pCVStructFormat
->offset_to_array_description
;
4272 cvarray_type
= *pCVArrayFormat
;
4273 switch (cvarray_type
)
4275 case RPC_FC_CVARRAY
:
4276 esize
= *(const WORD
*)(pCVArrayFormat
+2);
4277 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 4);
4279 case RPC_FC_C_CSTRING
:
4280 esize
= sizeof(char);
4281 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4282 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
4284 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
4286 case RPC_FC_C_WSTRING
:
4287 esize
= sizeof(WCHAR
);
4288 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4289 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
4291 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
4294 ERR("invalid array format type %x\n", *pCVArrayFormat
);
4295 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4299 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4301 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4303 /* work out how much memory to allocate if we need to do so */
4304 if (!*ppMemory
|| fMustAlloc
)
4306 SIZE_T size
= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->MaxCount
);
4307 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4310 /* mark the start of the constant data */
4311 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4312 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4314 pCVArrayFormat
= ReadVariance(pStubMsg
, pCVArrayFormat
, pStubMsg
->MaxCount
);
4316 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4318 if ((cvarray_type
== RPC_FC_C_CSTRING
) ||
4319 (cvarray_type
== RPC_FC_C_WSTRING
))
4320 validate_string_data(pStubMsg
, bufsize
, esize
);
4322 /* mark the start of the array data */
4323 saved_array_buffer
= pStubMsg
->Buffer
;
4324 safe_buffer_increment(pStubMsg
, bufsize
);
4326 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4328 /* copy the constant data */
4329 memcpy(*ppMemory
, saved_buffer
, pCVStructFormat
->memory_size
);
4330 /* copy the array data */
4331 TRACE("copying %p to %p\n", saved_array_buffer
, *ppMemory
+ pCVStructFormat
->memory_size
);
4332 memcpy(*ppMemory
+ pCVStructFormat
->memory_size
, saved_array_buffer
, bufsize
);
4334 if (cvarray_type
== RPC_FC_C_CSTRING
)
4335 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory
+ pCVStructFormat
->memory_size
)));
4336 else if (cvarray_type
== RPC_FC_C_WSTRING
)
4337 TRACE("string=%s\n", debugstr_w((WCHAR
*)(*ppMemory
+ pCVStructFormat
->memory_size
)));
4342 /***********************************************************************
4343 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
4345 void WINAPI
NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4346 unsigned char *pMemory
,
4347 PFORMAT_STRING pFormat
)
4349 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4350 PFORMAT_STRING pCVArrayFormat
;
4353 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4355 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4356 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4358 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4359 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4363 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4364 pCVStructFormat
->offset_to_array_description
;
4365 switch (*pCVArrayFormat
)
4367 case RPC_FC_CVARRAY
:
4368 esize
= *(const WORD
*)(pCVArrayFormat
+2);
4370 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4371 pCVArrayFormat
+ 4, 0);
4372 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4375 case RPC_FC_C_CSTRING
:
4376 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
4377 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
4378 esize
= sizeof(char);
4379 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4380 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4381 pCVArrayFormat
+ 2, 0);
4383 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4385 case RPC_FC_C_WSTRING
:
4386 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
4387 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
4388 esize
= sizeof(WCHAR
);
4389 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4390 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4391 pCVArrayFormat
+ 2, 0);
4393 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4396 ERR("invalid array format type %x\n", *pCVArrayFormat
);
4397 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4401 SizeConformance(pStubMsg
);
4403 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCVStructFormat
->alignment
+ 1);
4405 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4407 safe_buffer_length_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4408 SizeVariance(pStubMsg
);
4409 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
4411 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4414 /***********************************************************************
4415 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4417 ULONG WINAPI
NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4418 PFORMAT_STRING pFormat
)
4420 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4421 PFORMAT_STRING pCVArrayFormat
;
4423 unsigned char cvarray_type
;
4425 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4427 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4428 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4430 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4431 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4435 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4436 pCVStructFormat
->offset_to_array_description
;
4437 cvarray_type
= *pCVArrayFormat
;
4438 switch (cvarray_type
)
4440 case RPC_FC_CVARRAY
:
4441 esize
= *(const WORD
*)(pCVArrayFormat
+2);
4442 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 4);
4444 case RPC_FC_C_CSTRING
:
4445 esize
= sizeof(char);
4446 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4447 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
4449 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
4451 case RPC_FC_C_WSTRING
:
4452 esize
= sizeof(WCHAR
);
4453 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4454 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
4456 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
4459 ERR("invalid array format type %x\n", *pCVArrayFormat
);
4460 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4464 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4466 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4468 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4469 pCVArrayFormat
= ReadVariance(pStubMsg
, pCVArrayFormat
, pStubMsg
->MaxCount
);
4470 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
4472 pStubMsg
->MemorySize
+= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->MaxCount
);
4474 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4476 return pCVStructFormat
->memory_size
+ pStubMsg
->MaxCount
* esize
;
4479 /***********************************************************************
4480 * NdrConformantVaryingStructFree [RPCRT4.@]
4482 void WINAPI
NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
4483 unsigned char *pMemory
,
4484 PFORMAT_STRING pFormat
)
4486 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4487 PFORMAT_STRING pCVArrayFormat
;
4489 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4491 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4492 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4494 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4495 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4499 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4500 pCVStructFormat
->offset_to_array_description
;
4501 switch (*pCVArrayFormat
)
4503 case RPC_FC_CVARRAY
:
4504 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4505 pCVArrayFormat
+ 4, 0);
4506 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4509 case RPC_FC_C_CSTRING
:
4510 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
4511 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
4512 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4513 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4514 pCVArrayFormat
+ 2, 0);
4516 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4518 case RPC_FC_C_WSTRING
:
4519 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
4520 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
4521 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4522 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4523 pCVArrayFormat
+ 2, 0);
4525 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4528 ERR("invalid array format type %x\n", *pCVArrayFormat
);
4529 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4533 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4535 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4538 #include "pshpack1.h"
4542 unsigned char alignment
;
4543 unsigned short total_size
;
4544 } NDR_SMFARRAY_FORMAT
;
4549 unsigned char alignment
;
4550 unsigned long total_size
;
4551 } NDR_LGFARRAY_FORMAT
;
4552 #include "poppack.h"
4554 /***********************************************************************
4555 * NdrFixedArrayMarshall [RPCRT4.@]
4557 unsigned char * WINAPI
NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4558 unsigned char *pMemory
,
4559 PFORMAT_STRING pFormat
)
4561 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4562 unsigned long total_size
;
4564 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4566 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4567 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4569 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4570 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4574 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4576 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4578 total_size
= pSmFArrayFormat
->total_size
;
4579 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4583 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4584 total_size
= pLgFArrayFormat
->total_size
;
4585 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4588 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4589 safe_copy_to_buffer(pStubMsg
, pMemory
, total_size
);
4591 pFormat
= EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4596 /***********************************************************************
4597 * NdrFixedArrayUnmarshall [RPCRT4.@]
4599 unsigned char * WINAPI
NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4600 unsigned char **ppMemory
,
4601 PFORMAT_STRING pFormat
,
4602 unsigned char fMustAlloc
)
4604 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4605 unsigned long total_size
;
4606 unsigned char *saved_buffer
;
4608 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4610 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4611 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4613 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4614 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4618 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4620 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4622 total_size
= pSmFArrayFormat
->total_size
;
4623 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4627 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4628 total_size
= pLgFArrayFormat
->total_size
;
4629 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4633 *ppMemory
= NdrAllocate(pStubMsg
, total_size
);
4636 if (!pStubMsg
->IsClient
&& !*ppMemory
)
4637 /* for servers, we just point straight into the RPC buffer */
4638 *ppMemory
= pStubMsg
->Buffer
;
4641 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4642 safe_buffer_increment(pStubMsg
, total_size
);
4643 pFormat
= EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4645 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
4646 if (*ppMemory
!= saved_buffer
)
4647 memcpy(*ppMemory
, saved_buffer
, total_size
);
4652 /***********************************************************************
4653 * NdrFixedArrayBufferSize [RPCRT4.@]
4655 void WINAPI
NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4656 unsigned char *pMemory
,
4657 PFORMAT_STRING pFormat
)
4659 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4660 unsigned long total_size
;
4662 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4664 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4665 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4667 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4668 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4672 ALIGN_LENGTH(pStubMsg
->BufferLength
, pSmFArrayFormat
->alignment
+ 1);
4674 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4676 total_size
= pSmFArrayFormat
->total_size
;
4677 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4681 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4682 total_size
= pLgFArrayFormat
->total_size
;
4683 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4685 safe_buffer_length_increment(pStubMsg
, total_size
);
4687 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4690 /***********************************************************************
4691 * NdrFixedArrayMemorySize [RPCRT4.@]
4693 ULONG WINAPI
NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4694 PFORMAT_STRING pFormat
)
4696 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4699 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4701 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4702 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4704 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4705 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4709 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4711 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4713 total_size
= pSmFArrayFormat
->total_size
;
4714 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4718 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4719 total_size
= pLgFArrayFormat
->total_size
;
4720 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4722 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4723 safe_buffer_increment(pStubMsg
, total_size
);
4724 pStubMsg
->MemorySize
+= total_size
;
4726 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4731 /***********************************************************************
4732 * NdrFixedArrayFree [RPCRT4.@]
4734 void WINAPI
NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4735 unsigned char *pMemory
,
4736 PFORMAT_STRING pFormat
)
4738 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4740 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4742 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4743 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4745 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4746 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4750 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4751 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4754 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4755 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4758 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4761 /***********************************************************************
4762 * NdrVaryingArrayMarshall [RPCRT4.@]
4764 unsigned char * WINAPI
NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4765 unsigned char *pMemory
,
4766 PFORMAT_STRING pFormat
)
4768 unsigned char alignment
;
4769 DWORD elements
, esize
;
4772 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4774 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4775 (pFormat
[0] != RPC_FC_LGVARRAY
))
4777 ERR("invalid format type %x\n", pFormat
[0]);
4778 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4782 alignment
= pFormat
[1] + 1;
4784 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4787 pFormat
+= sizeof(WORD
);
4788 elements
= *(const WORD
*)pFormat
;
4789 pFormat
+= sizeof(WORD
);
4794 pFormat
+= sizeof(DWORD
);
4795 elements
= *(const DWORD
*)pFormat
;
4796 pFormat
+= sizeof(DWORD
);
4799 esize
= *(const WORD
*)pFormat
;
4800 pFormat
+= sizeof(WORD
);
4802 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4803 if ((pStubMsg
->ActualCount
> elements
) ||
4804 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4806 RpcRaiseException(RPC_S_INVALID_BOUND
);
4810 WriteVariance(pStubMsg
);
4812 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
4814 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4815 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4816 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
4818 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4823 /***********************************************************************
4824 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4826 unsigned char * WINAPI
NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4827 unsigned char **ppMemory
,
4828 PFORMAT_STRING pFormat
,
4829 unsigned char fMustAlloc
)
4831 unsigned char alignment
;
4832 DWORD size
, elements
, esize
;
4834 unsigned char *saved_buffer
;
4837 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4839 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4840 (pFormat
[0] != RPC_FC_LGVARRAY
))
4842 ERR("invalid format type %x\n", pFormat
[0]);
4843 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4847 alignment
= pFormat
[1] + 1;
4849 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4852 size
= *(const WORD
*)pFormat
;
4853 pFormat
+= sizeof(WORD
);
4854 elements
= *(const WORD
*)pFormat
;
4855 pFormat
+= sizeof(WORD
);
4860 size
= *(const DWORD
*)pFormat
;
4861 pFormat
+= sizeof(DWORD
);
4862 elements
= *(const DWORD
*)pFormat
;
4863 pFormat
+= sizeof(DWORD
);
4866 esize
= *(const WORD
*)pFormat
;
4867 pFormat
+= sizeof(WORD
);
4869 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
4871 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4873 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4874 offset
= pStubMsg
->Offset
;
4876 if (!*ppMemory
|| fMustAlloc
)
4877 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4878 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4879 safe_buffer_increment(pStubMsg
, bufsize
);
4881 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4883 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
4888 /***********************************************************************
4889 * NdrVaryingArrayBufferSize [RPCRT4.@]
4891 void WINAPI
NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4892 unsigned char *pMemory
,
4893 PFORMAT_STRING pFormat
)
4895 unsigned char alignment
;
4896 DWORD elements
, esize
;
4898 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4900 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4901 (pFormat
[0] != RPC_FC_LGVARRAY
))
4903 ERR("invalid format type %x\n", pFormat
[0]);
4904 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4908 alignment
= pFormat
[1] + 1;
4910 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4913 pFormat
+= sizeof(WORD
);
4914 elements
= *(const WORD
*)pFormat
;
4915 pFormat
+= sizeof(WORD
);
4920 pFormat
+= sizeof(DWORD
);
4921 elements
= *(const DWORD
*)pFormat
;
4922 pFormat
+= sizeof(DWORD
);
4925 esize
= *(const WORD
*)pFormat
;
4926 pFormat
+= sizeof(WORD
);
4928 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4929 if ((pStubMsg
->ActualCount
> elements
) ||
4930 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4932 RpcRaiseException(RPC_S_INVALID_BOUND
);
4936 SizeVariance(pStubMsg
);
4938 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
4940 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
4942 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4945 /***********************************************************************
4946 * NdrVaryingArrayMemorySize [RPCRT4.@]
4948 ULONG WINAPI
NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4949 PFORMAT_STRING pFormat
)
4951 unsigned char alignment
;
4952 DWORD size
, elements
, esize
;
4954 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4956 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4957 (pFormat
[0] != RPC_FC_LGVARRAY
))
4959 ERR("invalid format type %x\n", pFormat
[0]);
4960 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4964 alignment
= pFormat
[1] + 1;
4966 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4969 size
= *(const WORD
*)pFormat
;
4970 pFormat
+= sizeof(WORD
);
4971 elements
= *(const WORD
*)pFormat
;
4972 pFormat
+= sizeof(WORD
);
4977 size
= *(const DWORD
*)pFormat
;
4978 pFormat
+= sizeof(DWORD
);
4979 elements
= *(const DWORD
*)pFormat
;
4980 pFormat
+= sizeof(DWORD
);
4983 esize
= *(const WORD
*)pFormat
;
4984 pFormat
+= sizeof(WORD
);
4986 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
4988 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4990 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
4991 pStubMsg
->MemorySize
+= size
;
4993 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4995 return pStubMsg
->MemorySize
;
4998 /***********************************************************************
4999 * NdrVaryingArrayFree [RPCRT4.@]
5001 void WINAPI
NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
5002 unsigned char *pMemory
,
5003 PFORMAT_STRING pFormat
)
5007 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5009 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5010 (pFormat
[0] != RPC_FC_LGVARRAY
))
5012 ERR("invalid format type %x\n", pFormat
[0]);
5013 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5017 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5020 pFormat
+= sizeof(WORD
);
5021 elements
= *(const WORD
*)pFormat
;
5022 pFormat
+= sizeof(WORD
);
5027 pFormat
+= sizeof(DWORD
);
5028 elements
= *(const DWORD
*)pFormat
;
5029 pFormat
+= sizeof(DWORD
);
5032 pFormat
+= sizeof(WORD
);
5034 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5035 if ((pStubMsg
->ActualCount
> elements
) ||
5036 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5038 RpcRaiseException(RPC_S_INVALID_BOUND
);
5042 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5045 static ULONG
get_discriminant(unsigned char fc
, const unsigned char *pMemory
)
5058 return *(const USHORT
*)pMemory
;
5062 return *(const ULONG
*)pMemory
;
5064 FIXME("Unhandled base type: 0x%02x\n", fc
);
5069 static PFORMAT_STRING
get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg
,
5070 unsigned long discriminant
,
5071 PFORMAT_STRING pFormat
)
5073 unsigned short num_arms
, arm
, type
;
5075 num_arms
= *(const SHORT
*)pFormat
& 0x0fff;
5077 for(arm
= 0; arm
< num_arms
; arm
++)
5079 if(discriminant
== *(const ULONG
*)pFormat
)
5087 type
= *(const unsigned short*)pFormat
;
5088 TRACE("type %04x\n", type
);
5089 if(arm
== num_arms
) /* default arm extras */
5093 ERR("no arm for 0x%lx and no default case\n", discriminant
);
5094 RpcRaiseException(RPC_S_INVALID_TAG
);
5099 TRACE("falling back to empty default case for 0x%lx\n", discriminant
);
5106 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
, ULONG discriminant
, PFORMAT_STRING pFormat
)
5108 unsigned short type
;
5112 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5116 type
= *(const unsigned short*)pFormat
;
5117 if((type
& 0xff00) == 0x8000)
5119 unsigned char basetype
= LOBYTE(type
);
5120 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &basetype
);
5124 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5125 NDR_MARSHALL m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
5128 unsigned char *saved_buffer
= NULL
;
5129 int pointer_buffer_mark_set
= 0;
5136 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
5137 saved_buffer
= pStubMsg
->Buffer
;
5138 if (pStubMsg
->PointerBufferMark
)
5140 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5141 pStubMsg
->PointerBufferMark
= NULL
;
5142 pointer_buffer_mark_set
= 1;
5145 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
5147 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char **)pMemory
, desc
);
5148 if (pointer_buffer_mark_set
)
5150 STD_OVERFLOW_CHECK(pStubMsg
);
5151 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5152 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5154 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5155 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
5156 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5158 pStubMsg
->Buffer
= saved_buffer
+ 4;
5162 m(pStubMsg
, pMemory
, desc
);
5165 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5170 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5171 unsigned char **ppMemory
,
5173 PFORMAT_STRING pFormat
,
5174 unsigned char fMustAlloc
)
5176 unsigned short type
;
5180 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5184 type
= *(const unsigned short*)pFormat
;
5185 if((type
& 0xff00) == 0x8000)
5187 unsigned char basetype
= LOBYTE(type
);
5188 return NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &basetype
, FALSE
);
5192 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5193 NDR_UNMARSHALL m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
5196 unsigned char *saved_buffer
= NULL
;
5197 int pointer_buffer_mark_set
= 0;
5204 **(void***)ppMemory
= NULL
;
5205 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5206 saved_buffer
= pStubMsg
->Buffer
;
5207 if (pStubMsg
->PointerBufferMark
)
5209 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5210 pStubMsg
->PointerBufferMark
= NULL
;
5211 pointer_buffer_mark_set
= 1;
5214 pStubMsg
->Buffer
+= 4; /* for pointer ID */
5216 if (saved_buffer
+ 4 > pStubMsg
->BufferEnd
)
5218 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5219 saved_buffer
, pStubMsg
->BufferEnd
);
5220 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5223 PointerUnmarshall(pStubMsg
, saved_buffer
, *(unsigned char ***)ppMemory
, **(unsigned char ***)ppMemory
, desc
, fMustAlloc
);
5224 if (pointer_buffer_mark_set
)
5226 STD_OVERFLOW_CHECK(pStubMsg
);
5227 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5228 pStubMsg
->Buffer
= saved_buffer
+ 4;
5232 m(pStubMsg
, ppMemory
, desc
, fMustAlloc
);
5235 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5240 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg
,
5241 unsigned char *pMemory
,
5243 PFORMAT_STRING pFormat
)
5245 unsigned short type
;
5249 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5253 type
= *(const unsigned short*)pFormat
;
5254 if((type
& 0xff00) == 0x8000)
5256 unsigned char basetype
= LOBYTE(type
);
5257 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &basetype
);
5261 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5262 NDR_BUFFERSIZE m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
5271 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
5272 safe_buffer_length_increment(pStubMsg
, 4); /* for pointer ID */
5273 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5275 int saved_buffer_length
= pStubMsg
->BufferLength
;
5276 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
5277 pStubMsg
->PointerLength
= 0;
5278 if(!pStubMsg
->BufferLength
)
5279 ERR("BufferLength == 0??\n");
5280 PointerBufferSize(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5281 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
5282 pStubMsg
->BufferLength
= saved_buffer_length
;
5286 m(pStubMsg
, pMemory
, desc
);
5289 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
5293 static ULONG
union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg
,
5295 PFORMAT_STRING pFormat
)
5297 unsigned short type
, size
;
5299 size
= *(const unsigned short*)pFormat
;
5300 pStubMsg
->Memory
+= size
;
5303 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5307 type
= *(const unsigned short*)pFormat
;
5308 if((type
& 0xff00) == 0x8000)
5310 return NdrBaseTypeMemorySize(pStubMsg
, pFormat
);
5314 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5315 NDR_MEMORYSIZE m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
5316 unsigned char *saved_buffer
;
5325 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5326 saved_buffer
= pStubMsg
->Buffer
;
5327 safe_buffer_increment(pStubMsg
, 4);
5328 ALIGN_LENGTH(pStubMsg
->MemorySize
, 4);
5329 pStubMsg
->MemorySize
+= 4;
5330 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5331 PointerMemorySize(pStubMsg
, saved_buffer
, pFormat
);
5334 return m(pStubMsg
, desc
);
5337 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5340 TRACE("size %d\n", size
);
5344 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg
,
5345 unsigned char *pMemory
,
5347 PFORMAT_STRING pFormat
)
5349 unsigned short type
;
5353 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5357 type
= *(const unsigned short*)pFormat
;
5358 if((type
& 0xff00) != 0x8000)
5360 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5361 NDR_FREE m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
5370 PointerFree(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5373 m(pStubMsg
, pMemory
, desc
);
5379 /***********************************************************************
5380 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5382 unsigned char * WINAPI
NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5383 unsigned char *pMemory
,
5384 PFORMAT_STRING pFormat
)
5386 unsigned char switch_type
;
5387 unsigned char increment
;
5390 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5393 switch_type
= *pFormat
& 0xf;
5394 increment
= (*pFormat
& 0xf0) >> 4;
5397 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, increment
);
5399 switch_value
= get_discriminant(switch_type
, pMemory
);
5400 TRACE("got switch value 0x%x\n", switch_value
);
5402 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &switch_type
);
5403 pMemory
+= increment
;
5405 return union_arm_marshall(pStubMsg
, pMemory
, switch_value
, pFormat
);
5408 /***********************************************************************
5409 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5411 unsigned char * WINAPI
NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5412 unsigned char **ppMemory
,
5413 PFORMAT_STRING pFormat
,
5414 unsigned char fMustAlloc
)
5416 unsigned char switch_type
;
5417 unsigned char increment
;
5419 unsigned short size
;
5420 unsigned char *pMemoryArm
;
5422 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5425 switch_type
= *pFormat
& 0xf;
5426 increment
= (*pFormat
& 0xf0) >> 4;
5429 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
5430 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
5431 TRACE("got switch value 0x%x\n", switch_value
);
5433 size
= *(const unsigned short*)pFormat
+ increment
;
5434 if(!*ppMemory
|| fMustAlloc
)
5435 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5437 NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &switch_type
, FALSE
);
5438 pMemoryArm
= *ppMemory
+ increment
;
5440 return union_arm_unmarshall(pStubMsg
, &pMemoryArm
, switch_value
, pFormat
, fMustAlloc
);
5443 /***********************************************************************
5444 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5446 void WINAPI
NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5447 unsigned char *pMemory
,
5448 PFORMAT_STRING pFormat
)
5450 unsigned char switch_type
;
5451 unsigned char increment
;
5454 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5457 switch_type
= *pFormat
& 0xf;
5458 increment
= (*pFormat
& 0xf0) >> 4;
5461 ALIGN_LENGTH(pStubMsg
->BufferLength
, increment
);
5462 switch_value
= get_discriminant(switch_type
, pMemory
);
5463 TRACE("got switch value 0x%x\n", switch_value
);
5465 /* Add discriminant size */
5466 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&switch_value
, &switch_type
);
5467 pMemory
+= increment
;
5469 union_arm_buffer_size(pStubMsg
, pMemory
, switch_value
, pFormat
);
5472 /***********************************************************************
5473 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5475 ULONG WINAPI
NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5476 PFORMAT_STRING pFormat
)
5478 unsigned char switch_type
;
5479 unsigned char increment
;
5482 switch_type
= *pFormat
& 0xf;
5483 increment
= (*pFormat
& 0xf0) >> 4;
5486 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
5487 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
5488 TRACE("got switch value 0x%x\n", switch_value
);
5490 pStubMsg
->Memory
+= increment
;
5492 return increment
+ union_arm_memory_size(pStubMsg
, switch_value
, pFormat
+ *(const SHORT
*)pFormat
);
5495 /***********************************************************************
5496 * NdrEncapsulatedUnionFree [RPCRT4.@]
5498 void WINAPI
NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
5499 unsigned char *pMemory
,
5500 PFORMAT_STRING pFormat
)
5502 unsigned char switch_type
;
5503 unsigned char increment
;
5506 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5509 switch_type
= *pFormat
& 0xf;
5510 increment
= (*pFormat
& 0xf0) >> 4;
5513 switch_value
= get_discriminant(switch_type
, pMemory
);
5514 TRACE("got switch value 0x%x\n", switch_value
);
5516 pMemory
+= increment
;
5518 union_arm_free(pStubMsg
, pMemory
, switch_value
, pFormat
);
5521 /***********************************************************************
5522 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5524 unsigned char * WINAPI
NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5525 unsigned char *pMemory
,
5526 PFORMAT_STRING pFormat
)
5528 unsigned char switch_type
;
5530 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5533 switch_type
= *pFormat
;
5536 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5537 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5538 /* Marshall discriminant */
5539 NdrBaseTypeMarshall(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
5541 return union_arm_marshall(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5544 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg
,
5545 PFORMAT_STRING
*ppFormat
)
5547 long discriminant
= 0;
5557 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5566 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5567 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5575 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
5576 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5581 FIXME("Unhandled base type: 0x%02x\n", **ppFormat
);
5585 if (pStubMsg
->fHasNewCorrDesc
)
5589 return discriminant
;
5592 /**********************************************************************
5593 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5595 unsigned char * WINAPI
NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5596 unsigned char **ppMemory
,
5597 PFORMAT_STRING pFormat
,
5598 unsigned char fMustAlloc
)
5601 unsigned short size
;
5603 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5606 /* Unmarshall discriminant */
5607 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
5608 TRACE("unmarshalled discriminant %lx\n", discriminant
);
5610 pFormat
+= *(const SHORT
*)pFormat
;
5612 size
= *(const unsigned short*)pFormat
;
5614 if(!*ppMemory
|| fMustAlloc
)
5615 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5617 return union_arm_unmarshall(pStubMsg
, ppMemory
, discriminant
, pFormat
, fMustAlloc
);
5620 /***********************************************************************
5621 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5623 void WINAPI
NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5624 unsigned char *pMemory
,
5625 PFORMAT_STRING pFormat
)
5627 unsigned char switch_type
;
5629 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5632 switch_type
= *pFormat
;
5635 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5636 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5637 /* Add discriminant size */
5638 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
5640 union_arm_buffer_size(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5643 /***********************************************************************
5644 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5646 ULONG WINAPI
NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5647 PFORMAT_STRING pFormat
)
5652 /* Unmarshall discriminant */
5653 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
5654 TRACE("unmarshalled discriminant 0x%x\n", discriminant
);
5656 return union_arm_memory_size(pStubMsg
, discriminant
, pFormat
+ *(const SHORT
*)pFormat
);
5659 /***********************************************************************
5660 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5662 void WINAPI
NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
5663 unsigned char *pMemory
,
5664 PFORMAT_STRING pFormat
)
5666 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5670 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5671 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5673 union_arm_free(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5676 /***********************************************************************
5677 * NdrByteCountPointerMarshall [RPCRT4.@]
5679 unsigned char * WINAPI
NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5680 unsigned char *pMemory
,
5681 PFORMAT_STRING pFormat
)
5687 /***********************************************************************
5688 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5690 unsigned char * WINAPI
NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5691 unsigned char **ppMemory
,
5692 PFORMAT_STRING pFormat
,
5693 unsigned char fMustAlloc
)
5699 /***********************************************************************
5700 * NdrByteCountPointerBufferSize [RPCRT4.@]
5702 void WINAPI
NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5703 unsigned char *pMemory
,
5704 PFORMAT_STRING pFormat
)
5709 /***********************************************************************
5710 * NdrByteCountPointerMemorySize [RPCRT4.@]
5712 ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5713 PFORMAT_STRING pFormat
)
5719 /***********************************************************************
5720 * NdrByteCountPointerFree [RPCRT4.@]
5722 void WINAPI
NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
5723 unsigned char *pMemory
,
5724 PFORMAT_STRING pFormat
)
5729 /***********************************************************************
5730 * NdrXmitOrRepAsMarshall [RPCRT4.@]
5732 unsigned char * WINAPI
NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5733 unsigned char *pMemory
,
5734 PFORMAT_STRING pFormat
)
5740 /***********************************************************************
5741 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
5743 unsigned char * WINAPI
NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5744 unsigned char **ppMemory
,
5745 PFORMAT_STRING pFormat
,
5746 unsigned char fMustAlloc
)
5752 /***********************************************************************
5753 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
5755 void WINAPI
NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5756 unsigned char *pMemory
,
5757 PFORMAT_STRING pFormat
)
5762 /***********************************************************************
5763 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
5765 ULONG WINAPI
NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5766 PFORMAT_STRING pFormat
)
5772 /***********************************************************************
5773 * NdrXmitOrRepAsFree [RPCRT4.@]
5775 void WINAPI
NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg
,
5776 unsigned char *pMemory
,
5777 PFORMAT_STRING pFormat
)
5782 /***********************************************************************
5783 * NdrRangeMarshall [internal]
5785 unsigned char *WINAPI
NdrRangeMarshall(
5786 PMIDL_STUB_MESSAGE pStubMsg
,
5787 unsigned char *pMemory
,
5788 PFORMAT_STRING pFormat
)
5790 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5791 unsigned char base_type
;
5793 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5795 if (pRange
->type
!= RPC_FC_RANGE
)
5797 ERR("invalid format type %x\n", pRange
->type
);
5798 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5802 base_type
= pRange
->flags_type
& 0xf;
5804 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &base_type
);
5807 /***********************************************************************
5808 * NdrRangeUnmarshall
5810 unsigned char *WINAPI
NdrRangeUnmarshall(
5811 PMIDL_STUB_MESSAGE pStubMsg
,
5812 unsigned char **ppMemory
,
5813 PFORMAT_STRING pFormat
,
5814 unsigned char fMustAlloc
)
5816 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5817 unsigned char base_type
;
5819 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
5821 if (pRange
->type
!= RPC_FC_RANGE
)
5823 ERR("invalid format type %x\n", pRange
->type
);
5824 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5827 base_type
= pRange
->flags_type
& 0xf;
5829 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5830 base_type
, pRange
->low_value
, pRange
->high_value
);
5832 #define RANGE_UNMARSHALL(type, format_spec) \
5835 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5836 if (fMustAlloc || !*ppMemory) \
5837 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5838 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
5840 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
5841 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
5842 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
5844 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5845 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5847 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5848 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5849 (type)pRange->high_value); \
5850 RpcRaiseException(RPC_S_INVALID_BOUND); \
5853 TRACE("*ppMemory: %p\n", *ppMemory); \
5854 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5855 pStubMsg->Buffer += sizeof(type); \
5862 RANGE_UNMARSHALL(UCHAR
, "%d");
5863 TRACE("value: 0x%02x\n", **ppMemory
);
5867 RANGE_UNMARSHALL(CHAR
, "%u");
5868 TRACE("value: 0x%02x\n", **ppMemory
);
5870 case RPC_FC_WCHAR
: /* FIXME: valid? */
5872 RANGE_UNMARSHALL(USHORT
, "%u");
5873 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5876 RANGE_UNMARSHALL(SHORT
, "%d");
5877 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5880 RANGE_UNMARSHALL(LONG
, "%d");
5881 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5884 RANGE_UNMARSHALL(ULONG
, "%u");
5885 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5889 FIXME("Unhandled enum type\n");
5891 case RPC_FC_ERROR_STATUS_T
: /* FIXME: valid? */
5896 ERR("invalid range base type: 0x%02x\n", base_type
);
5897 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5903 /***********************************************************************
5904 * NdrRangeBufferSize [internal]
5906 void WINAPI
NdrRangeBufferSize(
5907 PMIDL_STUB_MESSAGE pStubMsg
,
5908 unsigned char *pMemory
,
5909 PFORMAT_STRING pFormat
)
5911 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5912 unsigned char base_type
;
5914 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5916 if (pRange
->type
!= RPC_FC_RANGE
)
5918 ERR("invalid format type %x\n", pRange
->type
);
5919 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5921 base_type
= pRange
->flags_type
& 0xf;
5923 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &base_type
);
5926 /***********************************************************************
5927 * NdrRangeMemorySize [internal]
5929 ULONG WINAPI
NdrRangeMemorySize(
5930 PMIDL_STUB_MESSAGE pStubMsg
,
5931 PFORMAT_STRING pFormat
)
5933 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5934 unsigned char base_type
;
5936 if (pRange
->type
!= RPC_FC_RANGE
)
5938 ERR("invalid format type %x\n", pRange
->type
);
5939 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5942 base_type
= pRange
->flags_type
& 0xf;
5944 return NdrBaseTypeMemorySize(pStubMsg
, &base_type
);
5947 /***********************************************************************
5948 * NdrRangeFree [internal]
5950 void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg
,
5951 unsigned char *pMemory
,
5952 PFORMAT_STRING pFormat
)
5954 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5959 /***********************************************************************
5960 * NdrBaseTypeMarshall [internal]
5962 static unsigned char *WINAPI
NdrBaseTypeMarshall(
5963 PMIDL_STUB_MESSAGE pStubMsg
,
5964 unsigned char *pMemory
,
5965 PFORMAT_STRING pFormat
)
5967 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5975 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(UCHAR
));
5976 TRACE("value: 0x%02x\n", *pMemory
);
5981 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(USHORT
));
5982 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(USHORT
));
5983 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
5987 case RPC_FC_ERROR_STATUS_T
:
5989 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(ULONG
));
5990 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONG
));
5991 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
5994 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(float));
5995 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
5998 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(double));
5999 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
6002 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(ULONGLONG
));
6003 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONGLONG
));
6004 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
6007 /* only 16-bits on the wire, so do a sanity check */
6008 if (*(UINT
*)pMemory
> SHRT_MAX
)
6009 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
6010 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(USHORT
));
6011 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6012 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6013 *(USHORT
*)pStubMsg
->Buffer
= *(UINT
*)pMemory
;
6014 pStubMsg
->Buffer
+= sizeof(USHORT
);
6015 TRACE("value: 0x%04x\n", *(UINT
*)pMemory
);
6020 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6023 /* FIXME: what is the correct return value? */
6027 /***********************************************************************
6028 * NdrBaseTypeUnmarshall [internal]
6030 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(
6031 PMIDL_STUB_MESSAGE pStubMsg
,
6032 unsigned char **ppMemory
,
6033 PFORMAT_STRING pFormat
,
6034 unsigned char fMustAlloc
)
6036 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6038 #define BASE_TYPE_UNMARSHALL(type) \
6039 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6040 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6042 *ppMemory = pStubMsg->Buffer; \
6043 TRACE("*ppMemory: %p\n", *ppMemory); \
6044 safe_buffer_increment(pStubMsg, sizeof(type)); \
6049 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6050 TRACE("*ppMemory: %p\n", *ppMemory); \
6051 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6060 BASE_TYPE_UNMARSHALL(UCHAR
);
6061 TRACE("value: 0x%02x\n", **ppMemory
);
6066 BASE_TYPE_UNMARSHALL(USHORT
);
6067 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6071 case RPC_FC_ERROR_STATUS_T
:
6073 BASE_TYPE_UNMARSHALL(ULONG
);
6074 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6077 BASE_TYPE_UNMARSHALL(float);
6078 TRACE("value: %f\n", **(float **)ppMemory
);
6081 BASE_TYPE_UNMARSHALL(double);
6082 TRACE("value: %f\n", **(double **)ppMemory
);
6085 BASE_TYPE_UNMARSHALL(ULONGLONG
);
6086 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG
**)ppMemory
));
6089 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
6090 if (fMustAlloc
|| !*ppMemory
)
6091 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT
));
6092 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > pStubMsg
->BufferEnd
)
6093 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6094 TRACE("*ppMemory: %p\n", *ppMemory
);
6095 /* 16-bits on the wire, but int in memory */
6096 **(UINT
**)ppMemory
= *(USHORT
*)pStubMsg
->Buffer
;
6097 pStubMsg
->Buffer
+= sizeof(USHORT
);
6098 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
6103 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6105 #undef BASE_TYPE_UNMARSHALL
6107 /* FIXME: what is the correct return value? */
6112 /***********************************************************************
6113 * NdrBaseTypeBufferSize [internal]
6115 static void WINAPI
NdrBaseTypeBufferSize(
6116 PMIDL_STUB_MESSAGE pStubMsg
,
6117 unsigned char *pMemory
,
6118 PFORMAT_STRING pFormat
)
6120 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6128 safe_buffer_length_increment(pStubMsg
, sizeof(UCHAR
));
6134 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(USHORT
));
6135 safe_buffer_length_increment(pStubMsg
, sizeof(USHORT
));
6140 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONG
));
6141 safe_buffer_length_increment(pStubMsg
, sizeof(ULONG
));
6144 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(float));
6145 safe_buffer_length_increment(pStubMsg
, sizeof(float));
6148 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(double));
6149 safe_buffer_length_increment(pStubMsg
, sizeof(double));
6152 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONGLONG
));
6153 safe_buffer_length_increment(pStubMsg
, sizeof(ULONGLONG
));
6155 case RPC_FC_ERROR_STATUS_T
:
6156 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(error_status_t
));
6157 safe_buffer_length_increment(pStubMsg
, sizeof(error_status_t
));
6162 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6166 /***********************************************************************
6167 * NdrBaseTypeMemorySize [internal]
6169 static ULONG WINAPI
NdrBaseTypeMemorySize(
6170 PMIDL_STUB_MESSAGE pStubMsg
,
6171 PFORMAT_STRING pFormat
)
6173 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg
, *pFormat
);
6181 safe_buffer_increment(pStubMsg
, sizeof(UCHAR
));
6182 pStubMsg
->MemorySize
+= sizeof(UCHAR
);
6183 return sizeof(UCHAR
);
6187 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6188 pStubMsg
->MemorySize
+= sizeof(USHORT
);
6189 return sizeof(USHORT
);
6193 safe_buffer_increment(pStubMsg
, sizeof(ULONG
));
6194 pStubMsg
->MemorySize
+= sizeof(ULONG
);
6195 return sizeof(ULONG
);
6197 safe_buffer_increment(pStubMsg
, sizeof(float));
6198 pStubMsg
->MemorySize
+= sizeof(float);
6199 return sizeof(float);
6201 safe_buffer_increment(pStubMsg
, sizeof(double));
6202 pStubMsg
->MemorySize
+= sizeof(double);
6203 return sizeof(double);
6205 safe_buffer_increment(pStubMsg
, sizeof(ULONGLONG
));
6206 pStubMsg
->MemorySize
+= sizeof(ULONGLONG
);
6207 return sizeof(ULONGLONG
);
6208 case RPC_FC_ERROR_STATUS_T
:
6209 safe_buffer_increment(pStubMsg
, sizeof(error_status_t
));
6210 pStubMsg
->MemorySize
+= sizeof(error_status_t
);
6211 return sizeof(error_status_t
);
6213 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6214 pStubMsg
->MemorySize
+= sizeof(UINT
);
6215 return sizeof(UINT
);
6217 pStubMsg
->MemorySize
+= sizeof(void *);
6218 return sizeof(void *);
6220 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6225 /***********************************************************************
6226 * NdrBaseTypeFree [internal]
6228 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6229 unsigned char *pMemory
,
6230 PFORMAT_STRING pFormat
)
6232 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6237 /***********************************************************************
6238 * NdrContextHandleBufferSize [internal]
6240 static void WINAPI
NdrContextHandleBufferSize(
6241 PMIDL_STUB_MESSAGE pStubMsg
,
6242 unsigned char *pMemory
,
6243 PFORMAT_STRING pFormat
)
6245 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6247 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6249 ERR("invalid format type %x\n", *pFormat
);
6250 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6252 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
6253 safe_buffer_length_increment(pStubMsg
, cbNDRContext
);
6256 /***********************************************************************
6257 * NdrContextHandleMarshall [internal]
6259 static unsigned char *WINAPI
NdrContextHandleMarshall(
6260 PMIDL_STUB_MESSAGE pStubMsg
,
6261 unsigned char *pMemory
,
6262 PFORMAT_STRING pFormat
)
6264 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6266 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6268 ERR("invalid format type %x\n", *pFormat
);
6269 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6271 TRACE("flags: 0x%02x\n", pFormat
[1]);
6273 if (pFormat
[1] & 0x80)
6274 NdrClientContextMarshall(pStubMsg
, *(NDR_CCONTEXT
**)pMemory
, FALSE
);
6276 NdrClientContextMarshall(pStubMsg
, (NDR_CCONTEXT
*)pMemory
, FALSE
);
6281 /***********************************************************************
6282 * NdrContextHandleUnmarshall [internal]
6284 static unsigned char *WINAPI
NdrContextHandleUnmarshall(
6285 PMIDL_STUB_MESSAGE pStubMsg
,
6286 unsigned char **ppMemory
,
6287 PFORMAT_STRING pFormat
,
6288 unsigned char fMustAlloc
)
6290 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg
,
6291 ppMemory
, pFormat
, fMustAlloc
? "TRUE": "FALSE");
6293 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6295 ERR("invalid format type %x\n", *pFormat
);
6296 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6298 TRACE("flags: 0x%02x\n", pFormat
[1]);
6300 /* [out]-only or [ret] param */
6301 if ((pFormat
[1] & 0x60) == 0x20)
6302 **(NDR_CCONTEXT
**)ppMemory
= NULL
;
6303 NdrClientContextUnmarshall(pStubMsg
, *(NDR_CCONTEXT
**)ppMemory
, pStubMsg
->RpcMsg
->Handle
);
6308 /***********************************************************************
6309 * NdrClientContextMarshall [RPCRT4.@]
6311 void WINAPI
NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6312 NDR_CCONTEXT ContextHandle
,
6315 TRACE("(%p, %p, %d)\n", pStubMsg
, ContextHandle
, fCheck
);
6317 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
6319 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6321 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6322 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6323 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6326 /* FIXME: what does fCheck do? */
6327 NDRCContextMarshall(ContextHandle
,
6330 pStubMsg
->Buffer
+= cbNDRContext
;
6333 /***********************************************************************
6334 * NdrClientContextUnmarshall [RPCRT4.@]
6336 void WINAPI
NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6337 NDR_CCONTEXT
* pContextHandle
,
6338 RPC_BINDING_HANDLE BindHandle
)
6340 TRACE("(%p, %p, %p)\n", pStubMsg
, pContextHandle
, BindHandle
);
6342 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6344 if (pStubMsg
->Buffer
+ cbNDRContext
> pStubMsg
->BufferEnd
)
6345 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6347 NDRCContextUnmarshall(pContextHandle
,
6350 pStubMsg
->RpcMsg
->DataRepresentation
);
6352 pStubMsg
->Buffer
+= cbNDRContext
;
6355 void WINAPI
NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6356 NDR_SCONTEXT ContextHandle
,
6357 NDR_RUNDOWN RundownRoutine
)
6359 TRACE("(%p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
);
6361 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6363 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6365 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6366 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6367 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6370 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
6371 pStubMsg
->Buffer
, RundownRoutine
, NULL
,
6372 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
6373 pStubMsg
->Buffer
+= cbNDRContext
;
6376 NDR_SCONTEXT WINAPI
NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
)
6378 NDR_SCONTEXT ContextHandle
;
6380 TRACE("(%p)\n", pStubMsg
);
6382 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6384 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6386 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6387 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6388 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6391 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
6393 pStubMsg
->RpcMsg
->DataRepresentation
,
6394 NULL
, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
6395 pStubMsg
->Buffer
+= cbNDRContext
;
6397 return ContextHandle
;
6400 void WINAPI
NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg
,
6401 unsigned char* pMemory
,
6402 PFORMAT_STRING pFormat
)
6404 FIXME("(%p, %p, %p): stub\n", pStubMsg
, pMemory
, pFormat
);
6407 NDR_SCONTEXT WINAPI
NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg
,
6408 PFORMAT_STRING pFormat
)
6410 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6411 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6413 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
6415 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
6416 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
6417 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
6418 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
6419 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
6421 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
6422 if_id
= &sif
->InterfaceId
;
6425 return NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
, NULL
,
6426 pStubMsg
->RpcMsg
->DataRepresentation
, if_id
,
6430 void WINAPI
NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6431 NDR_SCONTEXT ContextHandle
,
6432 NDR_RUNDOWN RundownRoutine
,
6433 PFORMAT_STRING pFormat
)
6435 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6436 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6438 TRACE("(%p, %p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
, pFormat
);
6440 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6442 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6444 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6445 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6446 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6449 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
6450 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
6451 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
6452 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
6453 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
6455 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
6456 if_id
= &sif
->InterfaceId
;
6459 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
6460 pStubMsg
->Buffer
, RundownRoutine
, if_id
, flags
);
6461 pStubMsg
->Buffer
+= cbNDRContext
;
6464 NDR_SCONTEXT WINAPI
NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6465 PFORMAT_STRING pFormat
)
6467 NDR_SCONTEXT ContextHandle
;
6468 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6469 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6471 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
6473 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6475 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6477 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6478 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6479 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6482 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
6483 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
6484 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
6485 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
6486 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
6488 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
6489 if_id
= &sif
->InterfaceId
;
6492 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
6494 pStubMsg
->RpcMsg
->DataRepresentation
,
6496 pStubMsg
->Buffer
+= cbNDRContext
;
6498 return ContextHandle
;
6501 /***********************************************************************
6502 * NdrCorrelationInitialize [RPCRT4.@]
6504 * Initializes correlation validity checking.
6507 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6508 * pMemory [I] Pointer to memory to use as a cache.
6509 * CacheSize [I] Size of the memory pointed to by pMemory.
6510 * Flags [I] Reserved. Set to zero.
6515 void WINAPI
NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg
, void *pMemory
, ULONG CacheSize
, ULONG Flags
)
6517 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg
, pMemory
, CacheSize
, Flags
);
6518 pStubMsg
->fHasNewCorrDesc
= TRUE
;
6521 /***********************************************************************
6522 * NdrCorrelationPass [RPCRT4.@]
6524 * Performs correlation validity checking.
6527 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6532 void WINAPI
NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg
)
6534 FIXME("(%p): stub\n", pStubMsg
);
6537 /***********************************************************************
6538 * NdrCorrelationFree [RPCRT4.@]
6540 * Frees any resources used while unmarshalling parameters that need
6541 * correlation validity checking.
6544 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6549 void WINAPI
NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg
)
6551 FIXME("(%p): stub\n", pStubMsg
);