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_TABLE_SIZE 128
114 #define NDR_TABLE_MASK 127
116 static unsigned char *WINAPI
NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
117 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
118 static void WINAPI
NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
119 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
120 static ULONG WINAPI
NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
122 static unsigned char *WINAPI
NdrContextHandleMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
123 static void WINAPI
NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
124 static unsigned char *WINAPI
NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
126 const NDR_MARSHALL NdrMarshaller
[NDR_TABLE_SIZE
] = {
128 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
129 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
130 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
131 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
135 NdrPointerMarshall
, NdrPointerMarshall
,
136 NdrPointerMarshall
, NdrPointerMarshall
,
138 NdrSimpleStructMarshall
, NdrSimpleStructMarshall
,
139 NdrConformantStructMarshall
, NdrConformantStructMarshall
,
140 NdrConformantVaryingStructMarshall
,
141 NdrComplexStructMarshall
,
143 NdrConformantArrayMarshall
,
144 NdrConformantVaryingArrayMarshall
,
145 NdrFixedArrayMarshall
, NdrFixedArrayMarshall
,
146 NdrVaryingArrayMarshall
, NdrVaryingArrayMarshall
,
147 NdrComplexArrayMarshall
,
149 NdrConformantStringMarshall
, 0, 0,
150 NdrConformantStringMarshall
,
151 NdrNonConformantStringMarshall
, 0, 0, 0,
153 NdrEncapsulatedUnionMarshall
,
154 NdrNonEncapsulatedUnionMarshall
,
155 NdrByteCountPointerMarshall
,
156 NdrXmitOrRepAsMarshall
, NdrXmitOrRepAsMarshall
,
158 NdrInterfacePointerMarshall
,
160 NdrContextHandleMarshall
,
163 NdrUserMarshalMarshall
,
168 const NDR_UNMARSHALL NdrUnmarshaller
[NDR_TABLE_SIZE
] = {
170 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
171 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
172 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
173 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
175 NdrBaseTypeUnmarshall
,
177 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
178 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
180 NdrSimpleStructUnmarshall
, NdrSimpleStructUnmarshall
,
181 NdrConformantStructUnmarshall
, NdrConformantStructUnmarshall
,
182 NdrConformantVaryingStructUnmarshall
,
183 NdrComplexStructUnmarshall
,
185 NdrConformantArrayUnmarshall
,
186 NdrConformantVaryingArrayUnmarshall
,
187 NdrFixedArrayUnmarshall
, NdrFixedArrayUnmarshall
,
188 NdrVaryingArrayUnmarshall
, NdrVaryingArrayUnmarshall
,
189 NdrComplexArrayUnmarshall
,
191 NdrConformantStringUnmarshall
, 0, 0,
192 NdrConformantStringUnmarshall
,
193 NdrNonConformantStringUnmarshall
, 0, 0, 0,
195 NdrEncapsulatedUnionUnmarshall
,
196 NdrNonEncapsulatedUnionUnmarshall
,
197 NdrByteCountPointerUnmarshall
,
198 NdrXmitOrRepAsUnmarshall
, NdrXmitOrRepAsUnmarshall
,
200 NdrInterfacePointerUnmarshall
,
202 NdrContextHandleUnmarshall
,
205 NdrUserMarshalUnmarshall
,
210 const NDR_BUFFERSIZE NdrBufferSizer
[NDR_TABLE_SIZE
] = {
212 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
213 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
214 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
215 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
217 NdrBaseTypeBufferSize
,
219 NdrPointerBufferSize
, NdrPointerBufferSize
,
220 NdrPointerBufferSize
, NdrPointerBufferSize
,
222 NdrSimpleStructBufferSize
, NdrSimpleStructBufferSize
,
223 NdrConformantStructBufferSize
, NdrConformantStructBufferSize
,
224 NdrConformantVaryingStructBufferSize
,
225 NdrComplexStructBufferSize
,
227 NdrConformantArrayBufferSize
,
228 NdrConformantVaryingArrayBufferSize
,
229 NdrFixedArrayBufferSize
, NdrFixedArrayBufferSize
,
230 NdrVaryingArrayBufferSize
, NdrVaryingArrayBufferSize
,
231 NdrComplexArrayBufferSize
,
233 NdrConformantStringBufferSize
, 0, 0,
234 NdrConformantStringBufferSize
,
235 NdrNonConformantStringBufferSize
, 0, 0, 0,
237 NdrEncapsulatedUnionBufferSize
,
238 NdrNonEncapsulatedUnionBufferSize
,
239 NdrByteCountPointerBufferSize
,
240 NdrXmitOrRepAsBufferSize
, NdrXmitOrRepAsBufferSize
,
242 NdrInterfacePointerBufferSize
,
244 NdrContextHandleBufferSize
,
247 NdrUserMarshalBufferSize
,
252 const NDR_MEMORYSIZE NdrMemorySizer
[NDR_TABLE_SIZE
] = {
254 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
255 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
256 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
257 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
259 NdrBaseTypeMemorySize
,
261 NdrPointerMemorySize
, NdrPointerMemorySize
,
262 NdrPointerMemorySize
, NdrPointerMemorySize
,
264 NdrSimpleStructMemorySize
, NdrSimpleStructMemorySize
,
265 NdrConformantStructMemorySize
, NdrConformantStructMemorySize
,
266 NdrConformantVaryingStructMemorySize
,
267 NdrComplexStructMemorySize
,
269 NdrConformantArrayMemorySize
,
270 NdrConformantVaryingArrayMemorySize
,
271 NdrFixedArrayMemorySize
, NdrFixedArrayMemorySize
,
272 NdrVaryingArrayMemorySize
, NdrVaryingArrayMemorySize
,
273 NdrComplexArrayMemorySize
,
275 NdrConformantStringMemorySize
, 0, 0,
276 NdrConformantStringMemorySize
,
277 NdrNonConformantStringMemorySize
, 0, 0, 0,
279 NdrEncapsulatedUnionMemorySize
,
280 NdrNonEncapsulatedUnionMemorySize
,
281 NdrByteCountPointerMemorySize
,
282 NdrXmitOrRepAsMemorySize
, NdrXmitOrRepAsMemorySize
,
284 NdrInterfacePointerMemorySize
,
289 NdrUserMarshalMemorySize
,
294 const NDR_FREE NdrFreer
[NDR_TABLE_SIZE
] = {
296 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
297 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
298 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
299 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
303 NdrPointerFree
, NdrPointerFree
,
304 NdrPointerFree
, NdrPointerFree
,
306 NdrSimpleStructFree
, NdrSimpleStructFree
,
307 NdrConformantStructFree
, NdrConformantStructFree
,
308 NdrConformantVaryingStructFree
,
309 NdrComplexStructFree
,
311 NdrConformantArrayFree
,
312 NdrConformantVaryingArrayFree
,
313 NdrFixedArrayFree
, NdrFixedArrayFree
,
314 NdrVaryingArrayFree
, NdrVaryingArrayFree
,
320 NdrEncapsulatedUnionFree
,
321 NdrNonEncapsulatedUnionFree
,
323 NdrXmitOrRepAsFree
, NdrXmitOrRepAsFree
,
325 NdrInterfacePointerFree
,
336 typedef struct _NDR_MEMORY_LIST
341 struct _NDR_MEMORY_LIST
*next
;
344 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
346 /***********************************************************************
347 * NdrAllocate [RPCRT4.@]
349 * Allocates a block of memory using pStubMsg->pfnAllocate.
352 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
353 * len [I] Size of memory block to allocate.
356 * The memory block of size len that was allocated.
359 * The memory block is always 8-byte aligned.
360 * If the function is unable to allocate memory an ERROR_OUTOFMEMORY
361 * exception is raised.
363 void * WINAPI
NdrAllocate(MIDL_STUB_MESSAGE
*pStubMsg
, size_t len
)
368 NDR_MEMORY_LIST
*mem_list
;
370 aligned_len
= ALIGNED_LENGTH(len
, 8);
371 adjusted_len
= aligned_len
+ sizeof(NDR_MEMORY_LIST
);
372 /* check for overflow */
373 if (adjusted_len
< len
)
375 ERR("overflow of adjusted_len %d, len %d\n", adjusted_len
, len
);
376 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
379 p
= pStubMsg
->pfnAllocate(adjusted_len
);
380 if (!p
) RpcRaiseException(ERROR_OUTOFMEMORY
);
382 mem_list
= (NDR_MEMORY_LIST
*)((char *)p
+ aligned_len
);
383 mem_list
->magic
= MEML_MAGIC
;
384 mem_list
->size
= aligned_len
;
385 mem_list
->reserved
= 0;
386 mem_list
->next
= pStubMsg
->pMemoryList
;
387 pStubMsg
->pMemoryList
= mem_list
;
393 static void WINAPI
NdrFree(MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *Pointer
)
395 TRACE("(%p, %p)\n", pStubMsg
, Pointer
);
397 pStubMsg
->pfnFree(Pointer
);
400 static inline BOOL
IsConformanceOrVariancePresent(PFORMAT_STRING pFormat
)
402 return (*(const ULONG
*)pFormat
!= -1);
405 static PFORMAT_STRING
ReadConformance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
)
407 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
408 if (pStubMsg
->Buffer
+ 4 > pStubMsg
->BufferEnd
)
409 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
410 pStubMsg
->MaxCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
411 pStubMsg
->Buffer
+= 4;
412 TRACE("unmarshalled conformance is %ld\n", pStubMsg
->MaxCount
);
413 if (pStubMsg
->fHasNewCorrDesc
)
419 static inline PFORMAT_STRING
ReadVariance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
, ULONG MaxValue
)
421 if (pFormat
&& !IsConformanceOrVariancePresent(pFormat
))
423 pStubMsg
->Offset
= 0;
424 pStubMsg
->ActualCount
= pStubMsg
->MaxCount
;
428 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
429 if (pStubMsg
->Buffer
+ 8 > pStubMsg
->BufferEnd
)
430 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
431 pStubMsg
->Offset
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
432 pStubMsg
->Buffer
+= 4;
433 TRACE("offset is %d\n", pStubMsg
->Offset
);
434 pStubMsg
->ActualCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
435 pStubMsg
->Buffer
+= 4;
436 TRACE("variance is %d\n", pStubMsg
->ActualCount
);
438 if ((pStubMsg
->ActualCount
> MaxValue
) ||
439 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> MaxValue
))
441 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
442 pStubMsg
->ActualCount
, pStubMsg
->Offset
, MaxValue
);
443 RpcRaiseException(RPC_S_INVALID_BOUND
);
448 if (pStubMsg
->fHasNewCorrDesc
)
454 /* writes the conformance value to the buffer */
455 static inline void WriteConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
457 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
458 if (pStubMsg
->Buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
459 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
460 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->MaxCount
);
461 pStubMsg
->Buffer
+= 4;
464 /* writes the variance values to the buffer */
465 static inline void WriteVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
467 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
468 if (pStubMsg
->Buffer
+ 8 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
469 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
470 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->Offset
);
471 pStubMsg
->Buffer
+= 4;
472 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->ActualCount
);
473 pStubMsg
->Buffer
+= 4;
476 /* requests buffer space for the conformance value */
477 static inline void SizeConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
479 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
480 if (pStubMsg
->BufferLength
+ 4 < pStubMsg
->BufferLength
)
481 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
482 pStubMsg
->BufferLength
+= 4;
485 /* requests buffer space for the variance values */
486 static inline void SizeVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
488 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
489 if (pStubMsg
->BufferLength
+ 8 < pStubMsg
->BufferLength
)
490 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
491 pStubMsg
->BufferLength
+= 8;
494 PFORMAT_STRING
ComputeConformanceOrVariance(
495 MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *pMemory
,
496 PFORMAT_STRING pFormat
, ULONG_PTR def
, ULONG_PTR
*pCount
)
498 BYTE dtype
= pFormat
[0] & 0xf;
499 short ofs
= *(const short *)&pFormat
[2];
503 if (!IsConformanceOrVariancePresent(pFormat
)) {
504 /* null descriptor */
509 switch (pFormat
[0] & 0xf0) {
510 case RPC_FC_NORMAL_CONFORMANCE
:
511 TRACE("normal conformance, ofs=%d\n", ofs
);
514 case RPC_FC_POINTER_CONFORMANCE
:
515 TRACE("pointer conformance, ofs=%d\n", ofs
);
516 ptr
= pStubMsg
->Memory
;
518 case RPC_FC_TOP_LEVEL_CONFORMANCE
:
519 TRACE("toplevel conformance, ofs=%d\n", ofs
);
520 if (pStubMsg
->StackTop
) {
521 ptr
= pStubMsg
->StackTop
;
524 /* -Os mode, *pCount is already set */
528 case RPC_FC_CONSTANT_CONFORMANCE
:
529 data
= ofs
| ((DWORD
)pFormat
[1] << 16);
530 TRACE("constant conformance, val=%d\n", data
);
533 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE
:
534 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs
);
535 if (pStubMsg
->StackTop
) {
536 ptr
= pStubMsg
->StackTop
;
544 FIXME("unknown conformance type %x\n", pFormat
[0] & 0xf0);
547 switch (pFormat
[1]) {
548 case RPC_FC_DEREFERENCE
:
549 ptr
= *(LPVOID
*)((char *)ptr
+ ofs
);
551 case RPC_FC_CALLBACK
:
553 unsigned char *old_stack_top
= pStubMsg
->StackTop
;
554 pStubMsg
->StackTop
= ptr
;
556 /* ofs is index into StubDesc->apfnExprEval */
557 TRACE("callback conformance into apfnExprEval[%d]\n", ofs
);
558 pStubMsg
->StubDesc
->apfnExprEval
[ofs
](pStubMsg
);
560 pStubMsg
->StackTop
= old_stack_top
;
562 /* the callback function always stores the computed value in MaxCount */
563 *pCount
= pStubMsg
->MaxCount
;
567 ptr
= (char *)ptr
+ ofs
;
580 data
= *(USHORT
*)ptr
;
591 FIXME("unknown conformance data type %x\n", dtype
);
594 TRACE("dereferenced data type %x at %p, got %d\n", dtype
, ptr
, data
);
597 switch (pFormat
[1]) {
598 case RPC_FC_DEREFERENCE
: /* already handled */
615 FIXME("unknown conformance op %d\n", pFormat
[1]);
620 TRACE("resulting conformance is %ld\n", *pCount
);
621 if (pStubMsg
->fHasNewCorrDesc
)
627 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
628 * the result overflows 32-bits */
629 static inline ULONG
safe_multiply(ULONG a
, ULONG b
)
631 ULONGLONG ret
= (ULONGLONG
)a
* b
;
632 if (ret
> 0xffffffff)
634 RpcRaiseException(RPC_S_INVALID_BOUND
);
640 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
642 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
643 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
644 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
645 pStubMsg
->Buffer
+= size
;
648 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
650 if (pStubMsg
->BufferLength
+ size
< pStubMsg
->BufferLength
) /* integer overflow of pStubMsg->BufferSize */
652 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
653 pStubMsg
->BufferLength
, size
);
654 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
656 pStubMsg
->BufferLength
+= size
;
659 /* copies data from the buffer, checking that there is enough data in the buffer
661 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, void *p
, ULONG size
)
663 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
664 (pStubMsg
->Buffer
+ size
> pStubMsg
->BufferEnd
))
666 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
667 pStubMsg
->Buffer
, pStubMsg
->BufferEnd
, size
);
668 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
670 if (p
== pStubMsg
->Buffer
)
671 ERR("pointer is the same as the buffer\n");
672 memcpy(p
, pStubMsg
->Buffer
, size
);
673 pStubMsg
->Buffer
+= size
;
676 /* copies data to the buffer, checking that there is enough space to do so */
677 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, const void *p
, ULONG size
)
679 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
680 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
682 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
683 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
,
685 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
687 memcpy(pStubMsg
->Buffer
, p
, size
);
688 pStubMsg
->Buffer
+= size
;
692 * NdrConformantString:
694 * What MS calls a ConformantString is, in DCE terminology,
695 * a Varying-Conformant String.
697 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
698 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
699 * into unmarshalled string)
700 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
702 * data: CHARTYPE[maxlen]
704 * ], where CHARTYPE is the appropriate character type (specified externally)
708 /***********************************************************************
709 * NdrConformantStringMarshall [RPCRT4.@]
711 unsigned char *WINAPI
NdrConformantStringMarshall(MIDL_STUB_MESSAGE
*pStubMsg
,
712 unsigned char *pszMessage
, PFORMAT_STRING pFormat
)
716 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg
, pszMessage
, pFormat
);
718 if (*pFormat
== RPC_FC_C_CSTRING
) {
719 TRACE("string=%s\n", debugstr_a((char*)pszMessage
));
720 pStubMsg
->ActualCount
= strlen((char*)pszMessage
)+1;
723 else if (*pFormat
== RPC_FC_C_WSTRING
) {
724 TRACE("string=%s\n", debugstr_w((LPWSTR
)pszMessage
));
725 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pszMessage
)+1;
729 ERR("Unhandled string type: %#x\n", *pFormat
);
730 /* FIXME: raise an exception. */
734 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
735 pFormat
= ComputeConformance(pStubMsg
, pszMessage
, pFormat
+ 2, 0);
737 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
738 pStubMsg
->Offset
= 0;
739 WriteConformance(pStubMsg
);
740 WriteVariance(pStubMsg
);
742 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
743 safe_copy_to_buffer(pStubMsg
, pszMessage
, size
); /* the string itself */
746 return NULL
; /* is this always right? */
749 /***********************************************************************
750 * NdrConformantStringBufferSize [RPCRT4.@]
752 void WINAPI
NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
753 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
757 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
759 SizeConformance(pStubMsg
);
760 SizeVariance(pStubMsg
);
762 if (*pFormat
== RPC_FC_C_CSTRING
) {
763 TRACE("string=%s\n", debugstr_a((char*)pMemory
));
764 pStubMsg
->ActualCount
= strlen((char*)pMemory
)+1;
767 else if (*pFormat
== RPC_FC_C_WSTRING
) {
768 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
));
769 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
)+1;
773 ERR("Unhandled string type: %#x\n", *pFormat
);
774 /* FIXME: raise an exception */
778 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
779 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
781 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
783 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
786 /************************************************************************
787 * NdrConformantStringMemorySize [RPCRT4.@]
789 ULONG WINAPI
NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
790 PFORMAT_STRING pFormat
)
792 ULONG bufsize
, memsize
, esize
, i
;
794 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
796 ReadConformance(pStubMsg
, NULL
);
797 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
799 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
801 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
802 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
803 RpcRaiseException(RPC_S_INVALID_BOUND
);
805 if (pStubMsg
->Offset
)
807 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
808 RpcRaiseException(RPC_S_INVALID_BOUND
);
811 if (*pFormat
== RPC_FC_C_CSTRING
) esize
= 1;
812 else if (*pFormat
== RPC_FC_C_WSTRING
) esize
= 2;
814 ERR("Unhandled string type: %#x\n", *pFormat
);
815 /* FIXME: raise an exception */
819 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
820 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
822 /* strings must always have null terminating bytes */
825 ERR("invalid string length of %d\n", pStubMsg
->ActualCount
);
826 RpcRaiseException(RPC_S_INVALID_BOUND
);
829 /* verify the buffer is safe to access */
830 if ((pStubMsg
->Buffer
+ bufsize
< pStubMsg
->Buffer
) ||
831 (pStubMsg
->Buffer
+ bufsize
> pStubMsg
->BufferEnd
))
833 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize
,
834 pStubMsg
->BufferEnd
, pStubMsg
->Buffer
);
835 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
838 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
839 if (pStubMsg
->Buffer
[i
] != 0)
841 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
842 i
, pStubMsg
->Buffer
[i
]);
843 RpcRaiseException(RPC_S_INVALID_BOUND
);
846 safe_buffer_increment(pStubMsg
, bufsize
);
847 pStubMsg
->MemorySize
+= memsize
;
849 return pStubMsg
->MemorySize
;
852 /************************************************************************
853 * NdrConformantStringUnmarshall [RPCRT4.@]
855 unsigned char *WINAPI
NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
856 unsigned char** ppMemory
, PFORMAT_STRING pFormat
, unsigned char fMustAlloc
)
858 ULONG bufsize
, memsize
, esize
, i
;
860 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
861 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
863 assert(pFormat
&& ppMemory
&& pStubMsg
);
865 ReadConformance(pStubMsg
, NULL
);
866 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
868 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
870 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
871 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
872 RpcRaiseException(RPC_S_INVALID_BOUND
);
875 if (pStubMsg
->Offset
)
877 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
878 RpcRaiseException(RPC_S_INVALID_BOUND
);
882 if (*pFormat
== RPC_FC_C_CSTRING
) esize
= 1;
883 else if (*pFormat
== RPC_FC_C_WSTRING
) esize
= 2;
885 ERR("Unhandled string type: %#x\n", *pFormat
);
886 /* FIXME: raise an exception */
890 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
891 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
893 /* strings must always have null terminating bytes */
896 ERR("invalid string length of %d\n", pStubMsg
->ActualCount
);
897 RpcRaiseException(RPC_S_INVALID_BOUND
);
901 /* verify the buffer is safe to access */
902 if ((pStubMsg
->Buffer
+ bufsize
< pStubMsg
->Buffer
) ||
903 (pStubMsg
->Buffer
+ bufsize
> pStubMsg
->BufferEnd
))
905 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize
,
906 pStubMsg
->BufferEnd
, pStubMsg
->Buffer
);
907 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
911 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
912 if (pStubMsg
->Buffer
[i
] != 0)
914 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
915 i
, pStubMsg
->Buffer
[i
]);
916 RpcRaiseException(RPC_S_INVALID_BOUND
);
921 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
924 if (!pStubMsg
->IsClient
&& !*ppMemory
&& (pStubMsg
->MaxCount
== pStubMsg
->ActualCount
))
925 /* if the data in the RPC buffer is big enough, we just point straight
927 *ppMemory
= pStubMsg
->Buffer
;
929 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
932 if (*ppMemory
== pStubMsg
->Buffer
)
933 safe_buffer_increment(pStubMsg
, bufsize
);
935 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
937 if (*pFormat
== RPC_FC_C_CSTRING
) {
938 TRACE("string=%s\n", debugstr_a((char*)*ppMemory
));
940 else if (*pFormat
== RPC_FC_C_WSTRING
) {
941 TRACE("string=%s\n", debugstr_w((LPWSTR
)*ppMemory
));
944 return NULL
; /* FIXME: is this always right? */
947 /***********************************************************************
948 * NdrNonConformantStringMarshall [RPCRT4.@]
950 unsigned char * WINAPI
NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
951 unsigned char *pMemory
,
952 PFORMAT_STRING pFormat
)
954 ULONG esize
, size
, maxsize
;
956 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
958 maxsize
= *(USHORT
*)&pFormat
[2];
960 if (*pFormat
== RPC_FC_CSTRING
)
963 const char *str
= (const char *)pMemory
;
964 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
966 TRACE("string=%s\n", debugstr_an(str
, i
));
967 pStubMsg
->ActualCount
= i
+ 1;
970 else if (*pFormat
== RPC_FC_WSTRING
)
973 const WCHAR
*str
= (const WCHAR
*)pMemory
;
974 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
976 TRACE("string=%s\n", debugstr_wn(str
, i
));
977 pStubMsg
->ActualCount
= i
+ 1;
982 ERR("Unhandled string type: %#x\n", *pFormat
);
983 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
986 pStubMsg
->Offset
= 0;
987 WriteVariance(pStubMsg
);
989 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
990 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
995 /***********************************************************************
996 * NdrNonConformantStringUnmarshall [RPCRT4.@]
998 unsigned char * WINAPI
NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
999 unsigned char **ppMemory
,
1000 PFORMAT_STRING pFormat
,
1001 unsigned char fMustAlloc
)
1003 ULONG bufsize
, memsize
, esize
, i
, maxsize
;
1005 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
1006 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
1008 maxsize
= *(USHORT
*)&pFormat
[2];
1010 ReadVariance(pStubMsg
, NULL
, maxsize
);
1011 if (pStubMsg
->Offset
)
1013 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
1014 RpcRaiseException(RPC_S_INVALID_BOUND
);
1017 if (*pFormat
== RPC_FC_CSTRING
) esize
= 1;
1018 else if (*pFormat
== RPC_FC_WSTRING
) esize
= 2;
1021 ERR("Unhandled string type: %#x\n", *pFormat
);
1022 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1025 memsize
= esize
* maxsize
;
1026 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1028 if (bufsize
< esize
)
1030 ERR("invalid string length of %d\n", pStubMsg
->ActualCount
);
1031 RpcRaiseException(RPC_S_INVALID_BOUND
);
1035 /* verify the buffer is safe to access */
1036 if ((pStubMsg
->Buffer
+ bufsize
< pStubMsg
->Buffer
) ||
1037 (pStubMsg
->Buffer
+ bufsize
> pStubMsg
->BufferEnd
))
1039 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize
,
1040 pStubMsg
->BufferEnd
, pStubMsg
->Buffer
);
1041 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1045 /* strings must always have null terminating bytes */
1046 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
1047 if (pStubMsg
->Buffer
[i
] != 0)
1049 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
1050 i
, pStubMsg
->Buffer
[i
]);
1051 RpcRaiseException(RPC_S_INVALID_BOUND
);
1054 if (fMustAlloc
|| !*ppMemory
)
1055 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
1057 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
1059 if (*pFormat
== RPC_FC_CSTRING
) {
1060 TRACE("string=%s\n", debugstr_an((char*)*ppMemory
, pStubMsg
->ActualCount
));
1062 else if (*pFormat
== RPC_FC_WSTRING
) {
1063 TRACE("string=%s\n", debugstr_wn((LPWSTR
)*ppMemory
, pStubMsg
->ActualCount
));
1069 /***********************************************************************
1070 * NdrNonConformantStringBufferSize [RPCRT4.@]
1072 void WINAPI
NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1073 unsigned char *pMemory
,
1074 PFORMAT_STRING pFormat
)
1076 ULONG esize
, maxsize
;
1078 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
1080 maxsize
= *(USHORT
*)&pFormat
[2];
1082 SizeVariance(pStubMsg
);
1084 if (*pFormat
== RPC_FC_CSTRING
)
1087 const char *str
= (const char *)pMemory
;
1088 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
1090 TRACE("string=%s\n", debugstr_an(str
, i
));
1091 pStubMsg
->ActualCount
= i
+ 1;
1094 else if (*pFormat
== RPC_FC_WSTRING
)
1097 const WCHAR
*str
= (const WCHAR
*)pMemory
;
1098 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
1100 TRACE("string=%s\n", debugstr_wn(str
, i
));
1101 pStubMsg
->ActualCount
= i
+ 1;
1106 ERR("Unhandled string type: %#x\n", *pFormat
);
1107 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1110 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
1113 /***********************************************************************
1114 * NdrNonConformantStringMemorySize [RPCRT4.@]
1116 ULONG WINAPI
NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1117 PFORMAT_STRING pFormat
)
1119 ULONG bufsize
, memsize
, esize
, i
, maxsize
;
1121 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
1123 maxsize
= *(USHORT
*)&pFormat
[2];
1125 ReadVariance(pStubMsg
, NULL
, maxsize
);
1127 if (pStubMsg
->Offset
)
1129 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
1130 RpcRaiseException(RPC_S_INVALID_BOUND
);
1133 if (*pFormat
== RPC_FC_CSTRING
) esize
= 1;
1134 else if (*pFormat
== RPC_FC_WSTRING
) esize
= 2;
1137 ERR("Unhandled string type: %#x\n", *pFormat
);
1138 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1141 memsize
= esize
* maxsize
;
1142 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1144 /* strings must always have null terminating bytes */
1145 if (bufsize
< esize
)
1147 ERR("invalid string length of %d\n", pStubMsg
->ActualCount
);
1148 RpcRaiseException(RPC_S_INVALID_BOUND
);
1151 /* verify the buffer is safe to access */
1152 if ((pStubMsg
->Buffer
+ bufsize
< pStubMsg
->Buffer
) ||
1153 (pStubMsg
->Buffer
+ bufsize
> pStubMsg
->BufferEnd
))
1155 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize
,
1156 pStubMsg
->BufferEnd
, pStubMsg
->Buffer
);
1157 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1160 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
1161 if (pStubMsg
->Buffer
[i
] != 0)
1163 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
1164 i
, pStubMsg
->Buffer
[i
]);
1165 RpcRaiseException(RPC_S_INVALID_BOUND
);
1168 safe_buffer_increment(pStubMsg
, bufsize
);
1169 pStubMsg
->MemorySize
+= memsize
;
1171 return pStubMsg
->MemorySize
;
1174 static inline void dump_pointer_attr(unsigned char attr
)
1176 if (attr
& RPC_FC_P_ALLOCALLNODES
)
1177 TRACE(" RPC_FC_P_ALLOCALLNODES");
1178 if (attr
& RPC_FC_P_DONTFREE
)
1179 TRACE(" RPC_FC_P_DONTFREE");
1180 if (attr
& RPC_FC_P_ONSTACK
)
1181 TRACE(" RPC_FC_P_ONSTACK");
1182 if (attr
& RPC_FC_P_SIMPLEPOINTER
)
1183 TRACE(" RPC_FC_P_SIMPLEPOINTER");
1184 if (attr
& RPC_FC_P_DEREF
)
1185 TRACE(" RPC_FC_P_DEREF");
1189 /***********************************************************************
1190 * PointerMarshall [internal]
1192 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1193 unsigned char *Buffer
,
1194 unsigned char *Pointer
,
1195 PFORMAT_STRING pFormat
)
1197 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1198 PFORMAT_STRING desc
;
1201 int pointer_needs_marshaling
;
1203 TRACE("(%p,%p,%p,%p)\n", pStubMsg
, Buffer
, Pointer
, pFormat
);
1204 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1206 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1207 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1210 case RPC_FC_RP
: /* ref pointer (always non-null) */
1213 ERR("NULL ref pointer is not allowed\n");
1214 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
1216 pointer_needs_marshaling
= 1;
1218 case RPC_FC_UP
: /* unique pointer */
1219 case RPC_FC_OP
: /* object pointer - same as unique here */
1221 pointer_needs_marshaling
= 1;
1223 pointer_needs_marshaling
= 0;
1224 pointer_id
= (ULONG
)Pointer
;
1225 TRACE("writing 0x%08x to buffer\n", pointer_id
);
1226 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
1229 pointer_needs_marshaling
= !NdrFullPointerQueryPointer(
1230 pStubMsg
->FullPtrXlatTables
, Pointer
, 1, &pointer_id
);
1231 TRACE("writing 0x%08x to buffer\n", pointer_id
);
1232 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
1235 FIXME("unhandled ptr type=%02x\n", type
);
1236 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1240 TRACE("calling marshaller for type 0x%x\n", (int)*desc
);
1242 if (pointer_needs_marshaling
) {
1243 if (attr
& RPC_FC_P_DEREF
) {
1244 Pointer
= *(unsigned char**)Pointer
;
1245 TRACE("deref => %p\n", Pointer
);
1247 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
1248 if (m
) m(pStubMsg
, Pointer
, desc
);
1249 else FIXME("no marshaller for data type=%02x\n", *desc
);
1252 STD_OVERFLOW_CHECK(pStubMsg
);
1255 /***********************************************************************
1256 * PointerUnmarshall [internal]
1258 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1259 unsigned char *Buffer
,
1260 unsigned char **pPointer
,
1261 unsigned char *pSrcPointer
,
1262 PFORMAT_STRING pFormat
,
1263 unsigned char fMustAlloc
)
1265 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1266 PFORMAT_STRING desc
;
1268 DWORD pointer_id
= 0;
1269 int pointer_needs_unmarshaling
;
1271 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg
, Buffer
, pPointer
, pSrcPointer
, pFormat
, fMustAlloc
);
1272 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1274 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1275 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1278 case RPC_FC_RP
: /* ref pointer (always non-null) */
1279 pointer_needs_unmarshaling
= 1;
1281 case RPC_FC_UP
: /* unique pointer */
1282 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1283 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1285 pointer_needs_unmarshaling
= 1;
1288 pointer_needs_unmarshaling
= 0;
1291 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
1292 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1293 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1294 if (!fMustAlloc
&& pSrcPointer
)
1296 FIXME("free object pointer %p\n", pSrcPointer
);
1300 pointer_needs_unmarshaling
= 1;
1302 pointer_needs_unmarshaling
= 0;
1305 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1306 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1307 pointer_needs_unmarshaling
= !NdrFullPointerQueryRefId(
1308 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, (void **)pPointer
);
1311 FIXME("unhandled ptr type=%02x\n", type
);
1312 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1316 if (pointer_needs_unmarshaling
) {
1317 unsigned char *base_ptr_val
= *pPointer
;
1318 unsigned char **current_ptr
= pPointer
;
1319 if (pStubMsg
->IsClient
) {
1321 /* if we aren't forcing allocation of memory then try to use the existing
1322 * (source) pointer to unmarshall the data into so that [in,out]
1323 * parameters behave correctly. it doesn't matter if the parameter is
1324 * [out] only since in that case the pointer will be NULL. we force
1325 * allocation when the source pointer is NULL here instead of in the type
1326 * unmarshalling routine for the benefit of the deref code below */
1329 TRACE("setting *pPointer to %p\n", pSrcPointer
);
1330 *pPointer
= base_ptr_val
= pSrcPointer
;
1336 /* the memory in a stub is never initialised, so we have to work out here
1337 * whether we have to initialise it so we can use the optimisation of
1338 * setting the pointer to the buffer, if possible, or set fMustAlloc to
1340 if (attr
& RPC_FC_P_DEREF
) {
1343 base_ptr_val
= NULL
;
1344 *current_ptr
= NULL
;
1348 if (attr
& RPC_FC_P_ALLOCALLNODES
)
1349 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
1351 if (attr
& RPC_FC_P_DEREF
) {
1353 base_ptr_val
= NdrAllocate(pStubMsg
, sizeof(void *));
1354 *pPointer
= base_ptr_val
;
1355 current_ptr
= (unsigned char **)base_ptr_val
;
1357 current_ptr
= *(unsigned char***)current_ptr
;
1358 TRACE("deref => %p\n", current_ptr
);
1359 if (!fMustAlloc
&& !*current_ptr
) fMustAlloc
= TRUE
;
1361 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
1362 if (m
) m(pStubMsg
, current_ptr
, desc
, fMustAlloc
);
1363 else FIXME("no unmarshaller for data type=%02x\n", *desc
);
1365 if (type
== RPC_FC_FP
)
1366 NdrFullPointerInsertRefId(pStubMsg
->FullPtrXlatTables
, pointer_id
,
1370 TRACE("pointer=%p\n", *pPointer
);
1373 /***********************************************************************
1374 * PointerBufferSize [internal]
1376 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1377 unsigned char *Pointer
,
1378 PFORMAT_STRING pFormat
)
1380 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1381 PFORMAT_STRING desc
;
1383 int pointer_needs_sizing
;
1386 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1387 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1389 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1390 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1393 case RPC_FC_RP
: /* ref pointer (always non-null) */
1396 ERR("NULL ref pointer is not allowed\n");
1397 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
1402 /* NULL pointer has no further representation */
1407 pointer_needs_sizing
= !NdrFullPointerQueryPointer(
1408 pStubMsg
->FullPtrXlatTables
, Pointer
, 0, &pointer_id
);
1409 if (!pointer_needs_sizing
)
1413 FIXME("unhandled ptr type=%02x\n", type
);
1414 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1418 if (attr
& RPC_FC_P_DEREF
) {
1419 Pointer
= *(unsigned char**)Pointer
;
1420 TRACE("deref => %p\n", Pointer
);
1423 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
1424 if (m
) m(pStubMsg
, Pointer
, desc
);
1425 else FIXME("no buffersizer for data type=%02x\n", *desc
);
1428 /***********************************************************************
1429 * PointerMemorySize [internal]
1431 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1432 unsigned char *Buffer
,
1433 PFORMAT_STRING pFormat
)
1435 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1436 PFORMAT_STRING desc
;
1438 DWORD pointer_id
= 0;
1439 int pointer_needs_sizing
;
1441 TRACE("(%p,%p,%p)\n", pStubMsg
, Buffer
, pFormat
);
1442 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1444 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1445 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1448 case RPC_FC_RP
: /* ref pointer (always non-null) */
1449 pointer_needs_sizing
= 1;
1451 case RPC_FC_UP
: /* unique pointer */
1452 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
1453 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1454 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1456 pointer_needs_sizing
= 1;
1458 pointer_needs_sizing
= 0;
1463 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1464 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1465 pointer_needs_sizing
= !NdrFullPointerQueryRefId(
1466 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, &pointer
);
1470 FIXME("unhandled ptr type=%02x\n", type
);
1471 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1475 if (attr
& RPC_FC_P_DEREF
) {
1479 if (pointer_needs_sizing
) {
1480 m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
1481 if (m
) m(pStubMsg
, desc
);
1482 else FIXME("no memorysizer for data type=%02x\n", *desc
);
1485 return pStubMsg
->MemorySize
;
1488 /***********************************************************************
1489 * PointerFree [internal]
1491 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1492 unsigned char *Pointer
,
1493 PFORMAT_STRING pFormat
)
1495 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1496 PFORMAT_STRING desc
;
1498 unsigned char *current_pointer
= Pointer
;
1500 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1501 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1502 if (attr
& RPC_FC_P_DONTFREE
) return;
1504 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1505 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1507 if (!Pointer
) return;
1509 if (type
== RPC_FC_FP
) {
1510 int pointer_needs_freeing
= NdrFullPointerFree(
1511 pStubMsg
->FullPtrXlatTables
, Pointer
);
1512 if (!pointer_needs_freeing
)
1516 if (attr
& RPC_FC_P_DEREF
) {
1517 current_pointer
= *(unsigned char**)Pointer
;
1518 TRACE("deref => %p\n", current_pointer
);
1521 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
1522 if (m
) m(pStubMsg
, current_pointer
, desc
);
1524 /* this check stops us from trying to free buffer memory. we don't have to
1525 * worry about clients, since they won't call this function.
1526 * we don't have to check for the buffer being reallocated because
1527 * BufferStart and BufferEnd won't be reset when allocating memory for
1528 * sending the response. we don't have to check for the new buffer here as
1529 * it won't be used a type memory, only for buffer memory */
1530 if (Pointer
>= pStubMsg
->BufferStart
&& Pointer
< pStubMsg
->BufferEnd
)
1533 if (attr
& RPC_FC_P_ONSTACK
) {
1534 TRACE("not freeing stack ptr %p\n", Pointer
);
1537 TRACE("freeing %p\n", Pointer
);
1538 NdrFree(pStubMsg
, Pointer
);
1541 TRACE("not freeing %p\n", Pointer
);
1544 /***********************************************************************
1545 * EmbeddedPointerMarshall
1547 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1548 unsigned char *pMemory
,
1549 PFORMAT_STRING pFormat
)
1551 unsigned char *Mark
= pStubMsg
->BufferMark
;
1552 unsigned rep
, count
, stride
;
1554 unsigned char *saved_buffer
= NULL
;
1556 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1558 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1561 if (pStubMsg
->PointerBufferMark
)
1563 saved_buffer
= pStubMsg
->Buffer
;
1564 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1565 pStubMsg
->PointerBufferMark
= NULL
;
1568 while (pFormat
[0] != RPC_FC_END
) {
1569 switch (pFormat
[0]) {
1571 FIXME("unknown repeat type %d\n", pFormat
[0]);
1572 case RPC_FC_NO_REPEAT
:
1578 case RPC_FC_FIXED_REPEAT
:
1579 rep
= *(const WORD
*)&pFormat
[2];
1580 stride
= *(const WORD
*)&pFormat
[4];
1581 count
= *(const WORD
*)&pFormat
[8];
1584 case RPC_FC_VARIABLE_REPEAT
:
1585 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1586 stride
= *(const WORD
*)&pFormat
[2];
1587 count
= *(const WORD
*)&pFormat
[6];
1591 for (i
= 0; i
< rep
; i
++) {
1592 PFORMAT_STRING info
= pFormat
;
1593 unsigned char *membase
= pMemory
+ (i
* stride
);
1594 unsigned char *bufbase
= Mark
+ (i
* stride
);
1597 for (u
=0; u
<count
; u
++,info
+=8) {
1598 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1599 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1600 unsigned char *saved_memory
= pStubMsg
->Memory
;
1602 pStubMsg
->Memory
= pMemory
;
1603 PointerMarshall(pStubMsg
, bufptr
, *(unsigned char**)memptr
, info
+4);
1604 pStubMsg
->Memory
= saved_memory
;
1607 pFormat
+= 8 * count
;
1612 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1613 pStubMsg
->Buffer
= saved_buffer
;
1616 STD_OVERFLOW_CHECK(pStubMsg
);
1621 /***********************************************************************
1622 * EmbeddedPointerUnmarshall
1624 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1625 unsigned char *pDstMemoryPtrs
,
1626 unsigned char *pSrcMemoryPtrs
,
1627 PFORMAT_STRING pFormat
,
1628 unsigned char fMustAlloc
)
1630 unsigned char *Mark
= pStubMsg
->BufferMark
;
1631 unsigned rep
, count
, stride
;
1633 unsigned char *saved_buffer
= NULL
;
1635 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg
, pDstMemoryPtrs
, pSrcMemoryPtrs
, pFormat
, fMustAlloc
);
1637 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1640 if (pStubMsg
->PointerBufferMark
)
1642 saved_buffer
= pStubMsg
->Buffer
;
1643 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1644 pStubMsg
->PointerBufferMark
= NULL
;
1647 while (pFormat
[0] != RPC_FC_END
) {
1648 TRACE("pFormat[0] = 0x%x\n", pFormat
[0]);
1649 switch (pFormat
[0]) {
1651 FIXME("unknown repeat type %d\n", pFormat
[0]);
1652 case RPC_FC_NO_REPEAT
:
1658 case RPC_FC_FIXED_REPEAT
:
1659 rep
= *(const WORD
*)&pFormat
[2];
1660 stride
= *(const WORD
*)&pFormat
[4];
1661 count
= *(const WORD
*)&pFormat
[8];
1664 case RPC_FC_VARIABLE_REPEAT
:
1665 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1666 stride
= *(const WORD
*)&pFormat
[2];
1667 count
= *(const WORD
*)&pFormat
[6];
1671 for (i
= 0; i
< rep
; i
++) {
1672 PFORMAT_STRING info
= pFormat
;
1673 unsigned char *memdstbase
= pDstMemoryPtrs
+ (i
* stride
);
1674 unsigned char *memsrcbase
= pSrcMemoryPtrs
+ (i
* stride
);
1675 unsigned char *bufbase
= Mark
+ (i
* stride
);
1678 for (u
=0; u
<count
; u
++,info
+=8) {
1679 unsigned char **memdstptr
= (unsigned char **)(memdstbase
+ *(const SHORT
*)&info
[0]);
1680 unsigned char **memsrcptr
= (unsigned char **)(memsrcbase
+ *(const SHORT
*)&info
[0]);
1681 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1682 PointerUnmarshall(pStubMsg
, bufptr
, memdstptr
, *memsrcptr
, info
+4, fMustAlloc
);
1685 pFormat
+= 8 * count
;
1690 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1691 pStubMsg
->Buffer
= saved_buffer
;
1697 /***********************************************************************
1698 * EmbeddedPointerBufferSize
1700 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1701 unsigned char *pMemory
,
1702 PFORMAT_STRING pFormat
)
1704 unsigned rep
, count
, stride
;
1706 ULONG saved_buffer_length
= 0;
1708 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1710 if (pStubMsg
->IgnoreEmbeddedPointers
) return;
1712 if (*pFormat
!= RPC_FC_PP
) return;
1715 if (pStubMsg
->PointerLength
)
1717 saved_buffer_length
= pStubMsg
->BufferLength
;
1718 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
1719 pStubMsg
->PointerLength
= 0;
1722 while (pFormat
[0] != RPC_FC_END
) {
1723 switch (pFormat
[0]) {
1725 FIXME("unknown repeat type %d\n", pFormat
[0]);
1726 case RPC_FC_NO_REPEAT
:
1732 case RPC_FC_FIXED_REPEAT
:
1733 rep
= *(const WORD
*)&pFormat
[2];
1734 stride
= *(const WORD
*)&pFormat
[4];
1735 count
= *(const WORD
*)&pFormat
[8];
1738 case RPC_FC_VARIABLE_REPEAT
:
1739 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1740 stride
= *(const WORD
*)&pFormat
[2];
1741 count
= *(const WORD
*)&pFormat
[6];
1745 for (i
= 0; i
< rep
; i
++) {
1746 PFORMAT_STRING info
= pFormat
;
1747 unsigned char *membase
= pMemory
+ (i
* stride
);
1750 for (u
=0; u
<count
; u
++,info
+=8) {
1751 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1752 unsigned char *saved_memory
= pStubMsg
->Memory
;
1754 pStubMsg
->Memory
= pMemory
;
1755 PointerBufferSize(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1756 pStubMsg
->Memory
= saved_memory
;
1759 pFormat
+= 8 * count
;
1762 if (saved_buffer_length
)
1764 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
1765 pStubMsg
->BufferLength
= saved_buffer_length
;
1769 /***********************************************************************
1770 * EmbeddedPointerMemorySize [internal]
1772 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1773 PFORMAT_STRING pFormat
)
1775 unsigned char *Mark
= pStubMsg
->BufferMark
;
1776 unsigned rep
, count
, stride
;
1778 unsigned char *saved_buffer
= NULL
;
1780 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1782 if (pStubMsg
->IgnoreEmbeddedPointers
) return 0;
1784 if (pStubMsg
->PointerBufferMark
)
1786 saved_buffer
= pStubMsg
->Buffer
;
1787 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1788 pStubMsg
->PointerBufferMark
= NULL
;
1791 if (*pFormat
!= RPC_FC_PP
) return 0;
1794 while (pFormat
[0] != RPC_FC_END
) {
1795 switch (pFormat
[0]) {
1797 FIXME("unknown repeat type %d\n", pFormat
[0]);
1798 case RPC_FC_NO_REPEAT
:
1804 case RPC_FC_FIXED_REPEAT
:
1805 rep
= *(const WORD
*)&pFormat
[2];
1806 stride
= *(const WORD
*)&pFormat
[4];
1807 count
= *(const WORD
*)&pFormat
[8];
1810 case RPC_FC_VARIABLE_REPEAT
:
1811 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1812 stride
= *(const WORD
*)&pFormat
[2];
1813 count
= *(const WORD
*)&pFormat
[6];
1817 for (i
= 0; i
< rep
; i
++) {
1818 PFORMAT_STRING info
= pFormat
;
1819 unsigned char *bufbase
= Mark
+ (i
* stride
);
1821 for (u
=0; u
<count
; u
++,info
+=8) {
1822 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1823 PointerMemorySize(pStubMsg
, bufptr
, info
+4);
1826 pFormat
+= 8 * count
;
1831 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1832 pStubMsg
->Buffer
= saved_buffer
;
1838 /***********************************************************************
1839 * EmbeddedPointerFree [internal]
1841 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1842 unsigned char *pMemory
,
1843 PFORMAT_STRING pFormat
)
1845 unsigned rep
, count
, stride
;
1848 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1849 if (*pFormat
!= RPC_FC_PP
) return;
1852 while (pFormat
[0] != RPC_FC_END
) {
1853 switch (pFormat
[0]) {
1855 FIXME("unknown repeat type %d\n", pFormat
[0]);
1856 case RPC_FC_NO_REPEAT
:
1862 case RPC_FC_FIXED_REPEAT
:
1863 rep
= *(const WORD
*)&pFormat
[2];
1864 stride
= *(const WORD
*)&pFormat
[4];
1865 count
= *(const WORD
*)&pFormat
[8];
1868 case RPC_FC_VARIABLE_REPEAT
:
1869 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1870 stride
= *(const WORD
*)&pFormat
[2];
1871 count
= *(const WORD
*)&pFormat
[6];
1875 for (i
= 0; i
< rep
; i
++) {
1876 PFORMAT_STRING info
= pFormat
;
1877 unsigned char *membase
= pMemory
+ (i
* stride
);
1880 for (u
=0; u
<count
; u
++,info
+=8) {
1881 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1882 unsigned char *saved_memory
= pStubMsg
->Memory
;
1884 pStubMsg
->Memory
= pMemory
;
1885 PointerFree(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1886 pStubMsg
->Memory
= saved_memory
;
1889 pFormat
+= 8 * count
;
1893 /***********************************************************************
1894 * NdrPointerMarshall [RPCRT4.@]
1896 unsigned char * WINAPI
NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1897 unsigned char *pMemory
,
1898 PFORMAT_STRING pFormat
)
1900 unsigned char *Buffer
;
1902 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1904 /* Increment the buffer here instead of in PointerMarshall,
1905 * as that is used by embedded pointers which already handle the incrementing
1906 * the buffer, and shouldn't write any additional pointer data to the wire */
1907 if (*pFormat
!= RPC_FC_RP
)
1909 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
1910 Buffer
= pStubMsg
->Buffer
;
1911 safe_buffer_increment(pStubMsg
, 4);
1914 Buffer
= pStubMsg
->Buffer
;
1916 PointerMarshall(pStubMsg
, Buffer
, pMemory
, pFormat
);
1921 /***********************************************************************
1922 * NdrPointerUnmarshall [RPCRT4.@]
1924 unsigned char * WINAPI
NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1925 unsigned char **ppMemory
,
1926 PFORMAT_STRING pFormat
,
1927 unsigned char fMustAlloc
)
1929 unsigned char *Buffer
;
1931 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1933 /* Increment the buffer here instead of in PointerUnmarshall,
1934 * as that is used by embedded pointers which already handle the incrementing
1935 * the buffer, and shouldn't read any additional pointer data from the
1937 if (*pFormat
!= RPC_FC_RP
)
1939 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1940 Buffer
= pStubMsg
->Buffer
;
1941 safe_buffer_increment(pStubMsg
, 4);
1944 Buffer
= pStubMsg
->Buffer
;
1946 PointerUnmarshall(pStubMsg
, Buffer
, ppMemory
, *ppMemory
, pFormat
, fMustAlloc
);
1951 /***********************************************************************
1952 * NdrPointerBufferSize [RPCRT4.@]
1954 void WINAPI
NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1955 unsigned char *pMemory
,
1956 PFORMAT_STRING pFormat
)
1958 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1960 /* Increment the buffer length here instead of in PointerBufferSize,
1961 * as that is used by embedded pointers which already handle the buffer
1962 * length, and shouldn't write anything more to the wire */
1963 if (*pFormat
!= RPC_FC_RP
)
1965 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
1966 safe_buffer_length_increment(pStubMsg
, 4);
1969 PointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1972 /***********************************************************************
1973 * NdrPointerMemorySize [RPCRT4.@]
1975 ULONG WINAPI
NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1976 PFORMAT_STRING pFormat
)
1978 /* unsigned size = *(LPWORD)(pFormat+2); */
1979 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1980 PointerMemorySize(pStubMsg
, pStubMsg
->Buffer
, pFormat
);
1984 /***********************************************************************
1985 * NdrPointerFree [RPCRT4.@]
1987 void WINAPI
NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1988 unsigned char *pMemory
,
1989 PFORMAT_STRING pFormat
)
1991 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1992 PointerFree(pStubMsg
, pMemory
, pFormat
);
1995 /***********************************************************************
1996 * NdrSimpleTypeMarshall [RPCRT4.@]
1998 void WINAPI
NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1999 unsigned char FormatChar
)
2001 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &FormatChar
);
2004 /***********************************************************************
2005 * NdrSimpleTypeUnmarshall [RPCRT4.@]
2007 * Unmarshall a base type.
2010 * Doesn't check that the buffer is long enough before copying, so the caller
2013 void WINAPI
NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
2014 unsigned char FormatChar
)
2016 #define BASE_TYPE_UNMARSHALL(type) \
2017 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
2018 TRACE("pMemory: %p\n", pMemory); \
2019 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
2020 pStubMsg->Buffer += sizeof(type);
2028 BASE_TYPE_UNMARSHALL(UCHAR
);
2029 TRACE("value: 0x%02x\n", *pMemory
);
2034 BASE_TYPE_UNMARSHALL(USHORT
);
2035 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
2039 case RPC_FC_ERROR_STATUS_T
:
2041 BASE_TYPE_UNMARSHALL(ULONG
);
2042 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
2045 BASE_TYPE_UNMARSHALL(float);
2046 TRACE("value: %f\n", *(float *)pMemory
);
2049 BASE_TYPE_UNMARSHALL(double);
2050 TRACE("value: %f\n", *(double *)pMemory
);
2053 BASE_TYPE_UNMARSHALL(ULONGLONG
);
2054 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
2057 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
2058 TRACE("pMemory: %p\n", pMemory
);
2059 /* 16-bits on the wire, but int in memory */
2060 *(UINT
*)pMemory
= *(USHORT
*)pStubMsg
->Buffer
;
2061 pStubMsg
->Buffer
+= sizeof(USHORT
);
2062 TRACE("value: 0x%08x\n", *(UINT
*)pMemory
);
2067 FIXME("Unhandled base type: 0x%02x\n", FormatChar
);
2069 #undef BASE_TYPE_UNMARSHALL
2072 /***********************************************************************
2073 * NdrSimpleStructMarshall [RPCRT4.@]
2075 unsigned char * WINAPI
NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2076 unsigned char *pMemory
,
2077 PFORMAT_STRING pFormat
)
2079 unsigned size
= *(const WORD
*)(pFormat
+2);
2080 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2082 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pFormat
[1] + 1);
2084 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2085 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
2087 if (pFormat
[0] != RPC_FC_STRUCT
)
2088 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
+4);
2093 /***********************************************************************
2094 * NdrSimpleStructUnmarshall [RPCRT4.@]
2096 unsigned char * WINAPI
NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2097 unsigned char **ppMemory
,
2098 PFORMAT_STRING pFormat
,
2099 unsigned char fMustAlloc
)
2101 unsigned size
= *(const WORD
*)(pFormat
+2);
2102 unsigned char *saved_buffer
;
2103 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2105 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2108 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2111 if (!pStubMsg
->IsClient
&& !*ppMemory
)
2112 /* for servers, we just point straight into the RPC buffer */
2113 *ppMemory
= pStubMsg
->Buffer
;
2116 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2117 safe_buffer_increment(pStubMsg
, size
);
2118 if (pFormat
[0] == RPC_FC_PSTRUCT
)
2119 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
+4, fMustAlloc
);
2121 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
2122 if (*ppMemory
!= saved_buffer
)
2123 memcpy(*ppMemory
, saved_buffer
, size
);
2128 /***********************************************************************
2129 * NdrSimpleStructBufferSize [RPCRT4.@]
2131 void WINAPI
NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2132 unsigned char *pMemory
,
2133 PFORMAT_STRING pFormat
)
2135 unsigned size
= *(const WORD
*)(pFormat
+2);
2136 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2138 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
2140 safe_buffer_length_increment(pStubMsg
, size
);
2141 if (pFormat
[0] != RPC_FC_STRUCT
)
2142 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
+4);
2145 /***********************************************************************
2146 * NdrSimpleStructMemorySize [RPCRT4.@]
2148 ULONG WINAPI
NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2149 PFORMAT_STRING pFormat
)
2151 unsigned short size
= *(const WORD
*)(pFormat
+2);
2153 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2155 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2156 pStubMsg
->MemorySize
+= size
;
2157 safe_buffer_increment(pStubMsg
, size
);
2159 if (pFormat
[0] != RPC_FC_STRUCT
)
2160 EmbeddedPointerMemorySize(pStubMsg
, pFormat
+4);
2161 return pStubMsg
->MemorySize
;
2164 /***********************************************************************
2165 * NdrSimpleStructFree [RPCRT4.@]
2167 void WINAPI
NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
2168 unsigned char *pMemory
,
2169 PFORMAT_STRING pFormat
)
2171 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2172 if (pFormat
[0] != RPC_FC_STRUCT
)
2173 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
+4);
2177 static unsigned long EmbeddedComplexSize(const MIDL_STUB_MESSAGE
*pStubMsg
,
2178 PFORMAT_STRING pFormat
)
2182 case RPC_FC_PSTRUCT
:
2183 case RPC_FC_CSTRUCT
:
2184 case RPC_FC_BOGUS_STRUCT
:
2185 case RPC_FC_SMFARRAY
:
2186 case RPC_FC_SMVARRAY
:
2187 case RPC_FC_CSTRING
:
2188 return *(const WORD
*)&pFormat
[2];
2189 case RPC_FC_USER_MARSHAL
:
2190 return *(const WORD
*)&pFormat
[4];
2191 case RPC_FC_NON_ENCAPSULATED_UNION
:
2193 if (pStubMsg
->fHasNewCorrDesc
)
2198 pFormat
+= *(const SHORT
*)pFormat
;
2199 return *(const SHORT
*)pFormat
;
2201 return sizeof(void *);
2202 case RPC_FC_WSTRING
:
2203 return *(const WORD
*)&pFormat
[2] * 2;
2205 FIXME("unhandled embedded type %02x\n", *pFormat
);
2211 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2212 PFORMAT_STRING pFormat
)
2214 NDR_MEMORYSIZE m
= NdrMemorySizer
[*pFormat
& NDR_TABLE_MASK
];
2218 FIXME("no memorysizer for data type=%02x\n", *pFormat
);
2222 return m(pStubMsg
, pFormat
);
2226 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2227 unsigned char *pMemory
,
2228 PFORMAT_STRING pFormat
,
2229 PFORMAT_STRING pPointer
)
2231 PFORMAT_STRING desc
;
2235 while (*pFormat
!= RPC_FC_END
) {
2241 TRACE("byte=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2242 safe_copy_to_buffer(pStubMsg
, pMemory
, 1);
2248 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2249 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
2253 TRACE("enum16=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2254 if (32767 < *(DWORD
*)pMemory
)
2255 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
2256 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
2262 TRACE("long=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2263 safe_copy_to_buffer(pStubMsg
, pMemory
, 4);
2267 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2268 safe_copy_to_buffer(pStubMsg
, pMemory
, 8);
2271 case RPC_FC_POINTER
:
2273 unsigned char *saved_buffer
;
2274 int pointer_buffer_mark_set
= 0;
2275 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
2276 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
2277 saved_buffer
= pStubMsg
->Buffer
;
2278 if (pStubMsg
->PointerBufferMark
)
2280 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2281 pStubMsg
->PointerBufferMark
= NULL
;
2282 pointer_buffer_mark_set
= 1;
2285 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2286 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char**)pMemory
, pPointer
);
2287 if (pointer_buffer_mark_set
)
2289 STD_OVERFLOW_CHECK(pStubMsg
);
2290 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2291 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
2293 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2294 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
2295 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2297 pStubMsg
->Buffer
= saved_buffer
+ 4;
2303 case RPC_FC_ALIGNM4
:
2304 ALIGN_POINTER(pMemory
, 4);
2306 case RPC_FC_ALIGNM8
:
2307 ALIGN_POINTER(pMemory
, 8);
2309 case RPC_FC_STRUCTPAD1
:
2310 case RPC_FC_STRUCTPAD2
:
2311 case RPC_FC_STRUCTPAD3
:
2312 case RPC_FC_STRUCTPAD4
:
2313 case RPC_FC_STRUCTPAD5
:
2314 case RPC_FC_STRUCTPAD6
:
2315 case RPC_FC_STRUCTPAD7
:
2316 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2318 case RPC_FC_EMBEDDED_COMPLEX
:
2319 pMemory
+= pFormat
[1];
2321 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2322 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2323 TRACE("embedded complex (size=%ld) <= %p\n", size
, pMemory
);
2324 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
2327 /* for some reason interface pointers aren't generated as
2328 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2329 * they still need the derefencing treatment that pointers are
2331 if (*desc
== RPC_FC_IP
)
2332 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2334 m(pStubMsg
, pMemory
, desc
);
2336 else FIXME("no marshaller for embedded type %02x\n", *desc
);
2343 FIXME("unhandled format 0x%02x\n", *pFormat
);
2351 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2352 unsigned char *pMemory
,
2353 PFORMAT_STRING pFormat
,
2354 PFORMAT_STRING pPointer
)
2356 PFORMAT_STRING desc
;
2360 while (*pFormat
!= RPC_FC_END
) {
2366 safe_copy_from_buffer(pStubMsg
, pMemory
, 1);
2367 TRACE("byte=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2373 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
2374 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2378 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
2379 *(DWORD
*)pMemory
&= 0xffff;
2380 TRACE("enum16=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
2381 if (32767 < *(DWORD
*)pMemory
)
2382 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
2388 safe_copy_from_buffer(pStubMsg
, pMemory
, 4);
2389 TRACE("long=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
2393 safe_copy_from_buffer(pStubMsg
, pMemory
, 8);
2394 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2397 case RPC_FC_POINTER
:
2399 unsigned char *saved_buffer
;
2400 int pointer_buffer_mark_set
= 0;
2401 TRACE("pointer => %p\n", pMemory
);
2402 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2403 saved_buffer
= pStubMsg
->Buffer
;
2404 if (pStubMsg
->PointerBufferMark
)
2406 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2407 pStubMsg
->PointerBufferMark
= NULL
;
2408 pointer_buffer_mark_set
= 1;
2411 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2413 PointerUnmarshall(pStubMsg
, saved_buffer
, (unsigned char**)pMemory
, *(unsigned char**)pMemory
, pPointer
, TRUE
);
2414 if (pointer_buffer_mark_set
)
2416 STD_OVERFLOW_CHECK(pStubMsg
);
2417 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2418 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
2420 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2421 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
2422 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2424 pStubMsg
->Buffer
= saved_buffer
+ 4;
2430 case RPC_FC_ALIGNM4
:
2431 ALIGN_POINTER_CLEAR(pMemory
, 4);
2433 case RPC_FC_ALIGNM8
:
2434 ALIGN_POINTER_CLEAR(pMemory
, 8);
2436 case RPC_FC_STRUCTPAD1
:
2437 case RPC_FC_STRUCTPAD2
:
2438 case RPC_FC_STRUCTPAD3
:
2439 case RPC_FC_STRUCTPAD4
:
2440 case RPC_FC_STRUCTPAD5
:
2441 case RPC_FC_STRUCTPAD6
:
2442 case RPC_FC_STRUCTPAD7
:
2443 memset(pMemory
, 0, *pFormat
- RPC_FC_STRUCTPAD1
+ 1);
2444 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2446 case RPC_FC_EMBEDDED_COMPLEX
:
2447 pMemory
+= pFormat
[1];
2449 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2450 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2451 TRACE("embedded complex (size=%ld) => %p\n", size
, pMemory
);
2452 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
2453 memset(pMemory
, 0, size
); /* just in case */
2456 /* for some reason interface pointers aren't generated as
2457 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2458 * they still need the derefencing treatment that pointers are
2460 if (*desc
== RPC_FC_IP
)
2461 m(pStubMsg
, (unsigned char **)pMemory
, desc
, FALSE
);
2463 m(pStubMsg
, &pMemory
, desc
, FALSE
);
2465 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
2472 FIXME("unhandled format %d\n", *pFormat
);
2480 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2481 unsigned char *pMemory
,
2482 PFORMAT_STRING pFormat
,
2483 PFORMAT_STRING pPointer
)
2485 PFORMAT_STRING desc
;
2489 while (*pFormat
!= RPC_FC_END
) {
2495 safe_buffer_length_increment(pStubMsg
, 1);
2501 safe_buffer_length_increment(pStubMsg
, 2);
2505 safe_buffer_length_increment(pStubMsg
, 2);
2511 safe_buffer_length_increment(pStubMsg
, 4);
2515 safe_buffer_length_increment(pStubMsg
, 8);
2518 case RPC_FC_POINTER
:
2519 if (!pStubMsg
->IgnoreEmbeddedPointers
)
2521 int saved_buffer_length
= pStubMsg
->BufferLength
;
2522 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2523 pStubMsg
->PointerLength
= 0;
2524 if(!pStubMsg
->BufferLength
)
2525 ERR("BufferLength == 0??\n");
2526 PointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
2527 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2528 pStubMsg
->BufferLength
= saved_buffer_length
;
2530 safe_buffer_length_increment(pStubMsg
, 4);
2534 case RPC_FC_ALIGNM4
:
2535 ALIGN_POINTER(pMemory
, 4);
2537 case RPC_FC_ALIGNM8
:
2538 ALIGN_POINTER(pMemory
, 8);
2540 case RPC_FC_STRUCTPAD1
:
2541 case RPC_FC_STRUCTPAD2
:
2542 case RPC_FC_STRUCTPAD3
:
2543 case RPC_FC_STRUCTPAD4
:
2544 case RPC_FC_STRUCTPAD5
:
2545 case RPC_FC_STRUCTPAD6
:
2546 case RPC_FC_STRUCTPAD7
:
2547 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2549 case RPC_FC_EMBEDDED_COMPLEX
:
2550 pMemory
+= pFormat
[1];
2552 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2553 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2554 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
2557 /* for some reason interface pointers aren't generated as
2558 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2559 * they still need the derefencing treatment that pointers are
2561 if (*desc
== RPC_FC_IP
)
2562 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2564 m(pStubMsg
, pMemory
, desc
);
2566 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
2573 FIXME("unhandled format 0x%02x\n", *pFormat
);
2581 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
2582 unsigned char *pMemory
,
2583 PFORMAT_STRING pFormat
,
2584 PFORMAT_STRING pPointer
)
2586 PFORMAT_STRING desc
;
2590 while (*pFormat
!= RPC_FC_END
) {
2612 case RPC_FC_POINTER
:
2613 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
2617 case RPC_FC_ALIGNM4
:
2618 ALIGN_POINTER(pMemory
, 4);
2620 case RPC_FC_ALIGNM8
:
2621 ALIGN_POINTER(pMemory
, 8);
2623 case RPC_FC_STRUCTPAD1
:
2624 case RPC_FC_STRUCTPAD2
:
2625 case RPC_FC_STRUCTPAD3
:
2626 case RPC_FC_STRUCTPAD4
:
2627 case RPC_FC_STRUCTPAD5
:
2628 case RPC_FC_STRUCTPAD6
:
2629 case RPC_FC_STRUCTPAD7
:
2630 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2632 case RPC_FC_EMBEDDED_COMPLEX
:
2633 pMemory
+= pFormat
[1];
2635 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2636 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2637 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
2640 /* for some reason interface pointers aren't generated as
2641 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2642 * they still need the derefencing treatment that pointers are
2644 if (*desc
== RPC_FC_IP
)
2645 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2647 m(pStubMsg
, pMemory
, desc
);
2655 FIXME("unhandled format 0x%02x\n", *pFormat
);
2663 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2664 PFORMAT_STRING pFormat
)
2666 PFORMAT_STRING desc
;
2667 unsigned long size
= 0;
2669 while (*pFormat
!= RPC_FC_END
) {
2676 safe_buffer_increment(pStubMsg
, 1);
2682 safe_buffer_increment(pStubMsg
, 2);
2686 safe_buffer_increment(pStubMsg
, 2);
2692 safe_buffer_increment(pStubMsg
, 4);
2696 safe_buffer_increment(pStubMsg
, 8);
2698 case RPC_FC_POINTER
:
2700 safe_buffer_increment(pStubMsg
, 4);
2701 if (!pStubMsg
->IgnoreEmbeddedPointers
)
2702 FIXME("embedded pointers\n");
2704 case RPC_FC_ALIGNM4
:
2705 ALIGN_LENGTH(size
, 4);
2706 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2708 case RPC_FC_ALIGNM8
:
2709 ALIGN_LENGTH(size
, 8);
2710 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
2712 case RPC_FC_STRUCTPAD1
:
2713 case RPC_FC_STRUCTPAD2
:
2714 case RPC_FC_STRUCTPAD3
:
2715 case RPC_FC_STRUCTPAD4
:
2716 case RPC_FC_STRUCTPAD5
:
2717 case RPC_FC_STRUCTPAD6
:
2718 case RPC_FC_STRUCTPAD7
:
2719 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2721 case RPC_FC_EMBEDDED_COMPLEX
:
2724 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2725 size
+= EmbeddedComplexMemorySize(pStubMsg
, desc
);
2731 FIXME("unhandled format 0x%02x\n", *pFormat
);
2739 unsigned long ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg
,
2740 PFORMAT_STRING pFormat
)
2742 PFORMAT_STRING desc
;
2743 unsigned long size
= 0;
2745 while (*pFormat
!= RPC_FC_END
) {
2767 case RPC_FC_POINTER
:
2768 size
+= sizeof(void *);
2770 case RPC_FC_ALIGNM4
:
2771 ALIGN_LENGTH(size
, 4);
2773 case RPC_FC_ALIGNM8
:
2774 ALIGN_LENGTH(size
, 8);
2776 case RPC_FC_STRUCTPAD1
:
2777 case RPC_FC_STRUCTPAD2
:
2778 case RPC_FC_STRUCTPAD3
:
2779 case RPC_FC_STRUCTPAD4
:
2780 case RPC_FC_STRUCTPAD5
:
2781 case RPC_FC_STRUCTPAD6
:
2782 case RPC_FC_STRUCTPAD7
:
2783 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2785 case RPC_FC_EMBEDDED_COMPLEX
:
2788 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2789 size
+= EmbeddedComplexSize(pStubMsg
, desc
);
2795 FIXME("unhandled format 0x%02x\n", *pFormat
);
2803 /***********************************************************************
2804 * NdrComplexStructMarshall [RPCRT4.@]
2806 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2807 unsigned char *pMemory
,
2808 PFORMAT_STRING pFormat
)
2810 PFORMAT_STRING conf_array
= NULL
;
2811 PFORMAT_STRING pointer_desc
= NULL
;
2812 unsigned char *OldMemory
= pStubMsg
->Memory
;
2813 int pointer_buffer_mark_set
= 0;
2815 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2817 if (!pStubMsg
->PointerBufferMark
)
2819 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2820 /* save buffer length */
2821 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2823 /* get the buffer pointer after complex array data, but before
2825 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- pStubMsg
->BufferStart
;
2826 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2827 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
2828 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2830 /* save it for use by embedded pointer code later */
2831 pStubMsg
->PointerBufferMark
= pStubMsg
->BufferStart
+ pStubMsg
->BufferLength
;
2832 TRACE("difference = 0x%x\n", pStubMsg
->PointerBufferMark
- pStubMsg
->Buffer
);
2833 pointer_buffer_mark_set
= 1;
2835 /* restore the original buffer length */
2836 pStubMsg
->BufferLength
= saved_buffer_length
;
2839 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pFormat
[1] + 1);
2842 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2844 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2847 pStubMsg
->Memory
= pMemory
;
2849 ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2852 NdrConformantArrayMarshall(pStubMsg
, pMemory
, conf_array
);
2854 pStubMsg
->Memory
= OldMemory
;
2856 if (pointer_buffer_mark_set
)
2858 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2859 pStubMsg
->PointerBufferMark
= NULL
;
2862 STD_OVERFLOW_CHECK(pStubMsg
);
2867 /***********************************************************************
2868 * NdrComplexStructUnmarshall [RPCRT4.@]
2870 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2871 unsigned char **ppMemory
,
2872 PFORMAT_STRING pFormat
,
2873 unsigned char fMustAlloc
)
2875 unsigned size
= *(const WORD
*)(pFormat
+2);
2876 PFORMAT_STRING conf_array
= NULL
;
2877 PFORMAT_STRING pointer_desc
= NULL
;
2878 unsigned char *pMemory
;
2879 int pointer_buffer_mark_set
= 0;
2881 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2883 if (!pStubMsg
->PointerBufferMark
)
2885 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2886 /* save buffer pointer */
2887 unsigned char *saved_buffer
= pStubMsg
->Buffer
;
2889 /* get the buffer pointer after complex array data, but before
2891 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2892 NdrComplexStructMemorySize(pStubMsg
, pFormat
);
2893 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2895 /* save it for use by embedded pointer code later */
2896 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2897 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->PointerBufferMark
- saved_buffer
));
2898 pointer_buffer_mark_set
= 1;
2900 /* restore the original buffer */
2901 pStubMsg
->Buffer
= saved_buffer
;
2904 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2906 if (fMustAlloc
|| !*ppMemory
)
2908 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2909 memset(*ppMemory
, 0, size
);
2913 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2915 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2918 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
);
2921 NdrConformantArrayUnmarshall(pStubMsg
, &pMemory
, conf_array
, fMustAlloc
);
2923 if (pointer_buffer_mark_set
)
2925 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2926 pStubMsg
->PointerBufferMark
= NULL
;
2932 /***********************************************************************
2933 * NdrComplexStructBufferSize [RPCRT4.@]
2935 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2936 unsigned char *pMemory
,
2937 PFORMAT_STRING pFormat
)
2939 PFORMAT_STRING conf_array
= NULL
;
2940 PFORMAT_STRING pointer_desc
= NULL
;
2941 unsigned char *OldMemory
= pStubMsg
->Memory
;
2942 int pointer_length_set
= 0;
2944 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2946 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
2948 if(!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
2950 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2951 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2953 /* get the buffer length after complex struct data, but before
2955 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2956 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
2957 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2959 /* save it for use by embedded pointer code later */
2960 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2961 pointer_length_set
= 1;
2962 TRACE("difference = 0x%lx\n", pStubMsg
->PointerLength
- saved_buffer_length
);
2964 /* restore the original buffer length */
2965 pStubMsg
->BufferLength
= saved_buffer_length
;
2969 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2971 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2974 pStubMsg
->Memory
= pMemory
;
2976 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2979 NdrConformantArrayBufferSize(pStubMsg
, pMemory
, conf_array
);
2981 pStubMsg
->Memory
= OldMemory
;
2983 if(pointer_length_set
)
2985 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2986 pStubMsg
->PointerLength
= 0;
2991 /***********************************************************************
2992 * NdrComplexStructMemorySize [RPCRT4.@]
2994 ULONG WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2995 PFORMAT_STRING pFormat
)
2997 unsigned size
= *(const WORD
*)(pFormat
+2);
2998 PFORMAT_STRING conf_array
= NULL
;
3000 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3002 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
3005 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
3008 ComplexStructMemorySize(pStubMsg
, pFormat
);
3011 NdrConformantArrayMemorySize(pStubMsg
, conf_array
);
3016 /***********************************************************************
3017 * NdrComplexStructFree [RPCRT4.@]
3019 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3020 unsigned char *pMemory
,
3021 PFORMAT_STRING pFormat
)
3023 PFORMAT_STRING conf_array
= NULL
;
3024 PFORMAT_STRING pointer_desc
= NULL
;
3025 unsigned char *OldMemory
= pStubMsg
->Memory
;
3027 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3030 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
3032 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3035 pStubMsg
->Memory
= pMemory
;
3037 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3040 NdrConformantArrayFree(pStubMsg
, pMemory
, conf_array
);
3042 pStubMsg
->Memory
= OldMemory
;
3045 /***********************************************************************
3046 * NdrConformantArrayMarshall [RPCRT4.@]
3048 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3049 unsigned char *pMemory
,
3050 PFORMAT_STRING pFormat
)
3052 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
3053 unsigned char alignment
= pFormat
[1] + 1;
3055 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3056 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
3058 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
3060 WriteConformance(pStubMsg
);
3062 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
3064 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3065 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3066 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
3068 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3073 /***********************************************************************
3074 * NdrConformantArrayUnmarshall [RPCRT4.@]
3076 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3077 unsigned char **ppMemory
,
3078 PFORMAT_STRING pFormat
,
3079 unsigned char fMustAlloc
)
3081 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
3082 unsigned char alignment
= pFormat
[1] + 1;
3083 unsigned char *saved_buffer
;
3085 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3086 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
3088 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
3090 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3091 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3094 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3097 if (!pStubMsg
->IsClient
&& !*ppMemory
)
3098 /* for servers, we just point straight into the RPC buffer */
3099 *ppMemory
= pStubMsg
->Buffer
;
3102 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3103 safe_buffer_increment(pStubMsg
, size
);
3104 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
3106 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
3107 if (*ppMemory
!= saved_buffer
)
3108 memcpy(*ppMemory
, saved_buffer
, size
);
3113 /***********************************************************************
3114 * NdrConformantArrayBufferSize [RPCRT4.@]
3116 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3117 unsigned char *pMemory
,
3118 PFORMAT_STRING pFormat
)
3120 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
3121 unsigned char alignment
= pFormat
[1] + 1;
3123 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3124 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
3126 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
3128 SizeConformance(pStubMsg
);
3130 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
3132 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3133 /* conformance value plus array */
3134 safe_buffer_length_increment(pStubMsg
, size
);
3136 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3139 /***********************************************************************
3140 * NdrConformantArrayMemorySize [RPCRT4.@]
3142 ULONG WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3143 PFORMAT_STRING pFormat
)
3145 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
3146 unsigned char alignment
= pFormat
[1] + 1;
3148 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3149 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
3151 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
3152 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3153 pStubMsg
->MemorySize
+= size
;
3155 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3156 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3157 safe_buffer_increment(pStubMsg
, size
);
3159 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
3161 return pStubMsg
->MemorySize
;
3164 /***********************************************************************
3165 * NdrConformantArrayFree [RPCRT4.@]
3167 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3168 unsigned char *pMemory
,
3169 PFORMAT_STRING pFormat
)
3171 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3172 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
3174 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
3176 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
3180 /***********************************************************************
3181 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3183 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
3184 unsigned char* pMemory
,
3185 PFORMAT_STRING pFormat
)
3188 unsigned char alignment
= pFormat
[1] + 1;
3189 DWORD esize
= *(const WORD
*)(pFormat
+2);
3191 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3193 if (pFormat
[0] != RPC_FC_CVARRAY
)
3195 ERR("invalid format type %x\n", pFormat
[0]);
3196 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3200 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
3201 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
3203 WriteConformance(pStubMsg
);
3204 WriteVariance(pStubMsg
);
3206 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
3208 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3210 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3211 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
3213 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3219 /***********************************************************************
3220 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
3222 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
3223 unsigned char** ppMemory
,
3224 PFORMAT_STRING pFormat
,
3225 unsigned char fMustAlloc
)
3227 ULONG bufsize
, memsize
;
3228 unsigned char alignment
= pFormat
[1] + 1;
3229 DWORD esize
= *(const WORD
*)(pFormat
+2);
3230 unsigned char *saved_buffer
;
3233 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3235 if (pFormat
[0] != RPC_FC_CVARRAY
)
3237 ERR("invalid format type %x\n", pFormat
[0]);
3238 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3242 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
3243 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3245 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3247 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3248 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3249 offset
= pStubMsg
->Offset
;
3251 if (!*ppMemory
|| fMustAlloc
)
3252 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
3253 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3254 safe_buffer_increment(pStubMsg
, bufsize
);
3256 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
3258 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
3264 /***********************************************************************
3265 * NdrConformantVaryingArrayFree [RPCRT4.@]
3267 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
3268 unsigned char* pMemory
,
3269 PFORMAT_STRING pFormat
)
3271 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3273 if (pFormat
[0] != RPC_FC_CVARRAY
)
3275 ERR("invalid format type %x\n", pFormat
[0]);
3276 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3280 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
3281 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
3283 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
3287 /***********************************************************************
3288 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
3290 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
3291 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
3293 unsigned char alignment
= pFormat
[1] + 1;
3294 DWORD esize
= *(const WORD
*)(pFormat
+2);
3296 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3298 if (pFormat
[0] != RPC_FC_CVARRAY
)
3300 ERR("invalid format type %x\n", pFormat
[0]);
3301 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3306 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
3307 /* compute length */
3308 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
3310 SizeConformance(pStubMsg
);
3311 SizeVariance(pStubMsg
);
3313 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
3315 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
3317 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3321 /***********************************************************************
3322 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
3324 ULONG WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
3325 PFORMAT_STRING pFormat
)
3327 ULONG bufsize
, memsize
;
3328 unsigned char alignment
= pFormat
[1] + 1;
3329 DWORD esize
= *(const WORD
*)(pFormat
+2);
3331 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
3333 if (pFormat
[0] != RPC_FC_CVARRAY
)
3335 ERR("invalid format type %x\n", pFormat
[0]);
3336 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3337 return pStubMsg
->MemorySize
;
3340 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
3341 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3343 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3345 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3346 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3348 safe_buffer_increment(pStubMsg
, bufsize
);
3349 pStubMsg
->MemorySize
+= memsize
;
3351 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
3353 return pStubMsg
->MemorySize
;
3357 /***********************************************************************
3358 * NdrComplexArrayMarshall [RPCRT4.@]
3360 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3361 unsigned char *pMemory
,
3362 PFORMAT_STRING pFormat
)
3364 ULONG i
, count
, def
;
3365 BOOL variance_present
;
3366 unsigned char alignment
;
3367 int pointer_buffer_mark_set
= 0;
3369 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3371 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3373 ERR("invalid format type %x\n", pFormat
[0]);
3374 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3378 alignment
= pFormat
[1] + 1;
3380 if (!pStubMsg
->PointerBufferMark
)
3382 /* save buffer fields that may be changed by buffer sizer functions
3383 * and that may be needed later on */
3384 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3385 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
3386 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
3387 unsigned long saved_offset
= pStubMsg
->Offset
;
3388 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
3390 /* get the buffer pointer after complex array data, but before
3392 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- pStubMsg
->BufferStart
;
3393 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3394 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
3395 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3397 /* save it for use by embedded pointer code later */
3398 pStubMsg
->PointerBufferMark
= pStubMsg
->BufferStart
+ pStubMsg
->BufferLength
;
3399 TRACE("difference = 0x%x\n", pStubMsg
->Buffer
- pStubMsg
->BufferStart
);
3400 pointer_buffer_mark_set
= 1;
3402 /* restore fields */
3403 pStubMsg
->ActualCount
= saved_actual_count
;
3404 pStubMsg
->Offset
= saved_offset
;
3405 pStubMsg
->MaxCount
= saved_max_count
;
3406 pStubMsg
->BufferLength
= saved_buffer_length
;
3409 def
= *(const WORD
*)&pFormat
[2];
3412 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3413 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3415 variance_present
= IsConformanceOrVariancePresent(pFormat
);
3416 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3417 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3419 WriteConformance(pStubMsg
);
3420 if (variance_present
)
3421 WriteVariance(pStubMsg
);
3423 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
3425 count
= pStubMsg
->ActualCount
;
3426 for (i
= 0; i
< count
; i
++)
3427 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
3429 STD_OVERFLOW_CHECK(pStubMsg
);
3431 if (pointer_buffer_mark_set
)
3433 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3434 pStubMsg
->PointerBufferMark
= NULL
;
3440 /***********************************************************************
3441 * NdrComplexArrayUnmarshall [RPCRT4.@]
3443 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3444 unsigned char **ppMemory
,
3445 PFORMAT_STRING pFormat
,
3446 unsigned char fMustAlloc
)
3448 ULONG i
, count
, size
;
3449 unsigned char alignment
;
3450 unsigned char *pMemory
;
3451 unsigned char *saved_buffer
;
3452 int pointer_buffer_mark_set
= 0;
3453 int saved_ignore_embedded
;
3455 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3457 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3459 ERR("invalid format type %x\n", pFormat
[0]);
3460 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3464 alignment
= pFormat
[1] + 1;
3466 saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3467 /* save buffer pointer */
3468 saved_buffer
= pStubMsg
->Buffer
;
3469 /* get the buffer pointer after complex array data, but before
3471 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3472 pStubMsg
->MemorySize
= 0;
3473 NdrComplexArrayMemorySize(pStubMsg
, pFormat
);
3474 size
= pStubMsg
->MemorySize
;
3475 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3477 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->Buffer
- saved_buffer
));
3478 if (!pStubMsg
->PointerBufferMark
)
3480 /* save it for use by embedded pointer code later */
3481 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3482 pointer_buffer_mark_set
= 1;
3484 /* restore the original buffer */
3485 pStubMsg
->Buffer
= saved_buffer
;
3489 pFormat
= ReadConformance(pStubMsg
, pFormat
);
3490 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3492 if (fMustAlloc
|| !*ppMemory
)
3494 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3495 memset(*ppMemory
, 0, size
);
3498 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3500 pMemory
= *ppMemory
;
3501 count
= pStubMsg
->ActualCount
;
3502 for (i
= 0; i
< count
; i
++)
3503 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
3505 if (pointer_buffer_mark_set
)
3507 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3508 pStubMsg
->PointerBufferMark
= NULL
;
3514 /***********************************************************************
3515 * NdrComplexArrayBufferSize [RPCRT4.@]
3517 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3518 unsigned char *pMemory
,
3519 PFORMAT_STRING pFormat
)
3521 ULONG i
, count
, def
;
3522 unsigned char alignment
;
3523 BOOL variance_present
;
3524 int pointer_length_set
= 0;
3526 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3528 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3530 ERR("invalid format type %x\n", pFormat
[0]);
3531 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3535 alignment
= pFormat
[1] + 1;
3537 if (!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
3539 /* save buffer fields that may be changed by buffer sizer functions
3540 * and that may be needed later on */
3541 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3542 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
3543 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
3544 unsigned long saved_offset
= pStubMsg
->Offset
;
3545 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
3547 /* get the buffer pointer after complex array data, but before
3549 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3550 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
3551 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3553 /* save it for use by embedded pointer code later */
3554 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3555 pointer_length_set
= 1;
3557 /* restore fields */
3558 pStubMsg
->ActualCount
= saved_actual_count
;
3559 pStubMsg
->Offset
= saved_offset
;
3560 pStubMsg
->MaxCount
= saved_max_count
;
3561 pStubMsg
->BufferLength
= saved_buffer_length
;
3563 def
= *(const WORD
*)&pFormat
[2];
3566 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3567 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3568 SizeConformance(pStubMsg
);
3570 variance_present
= IsConformanceOrVariancePresent(pFormat
);
3571 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3572 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3574 if (variance_present
)
3575 SizeVariance(pStubMsg
);
3577 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
3579 count
= pStubMsg
->ActualCount
;
3580 for (i
= 0; i
< count
; i
++)
3581 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
3583 if(pointer_length_set
)
3585 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3586 pStubMsg
->PointerLength
= 0;
3590 /***********************************************************************
3591 * NdrComplexArrayMemorySize [RPCRT4.@]
3593 ULONG WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3594 PFORMAT_STRING pFormat
)
3596 ULONG i
, count
, esize
, SavedMemorySize
, MemorySize
;
3597 unsigned char alignment
;
3599 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3601 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3603 ERR("invalid format type %x\n", pFormat
[0]);
3604 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3608 alignment
= pFormat
[1] + 1;
3612 pFormat
= ReadConformance(pStubMsg
, pFormat
);
3613 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3615 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3617 SavedMemorySize
= pStubMsg
->MemorySize
;
3619 esize
= ComplexStructSize(pStubMsg
, pFormat
);
3621 MemorySize
= safe_multiply(pStubMsg
->MaxCount
, esize
);
3623 count
= pStubMsg
->ActualCount
;
3624 for (i
= 0; i
< count
; i
++)
3625 ComplexStructMemorySize(pStubMsg
, pFormat
);
3627 pStubMsg
->MemorySize
= SavedMemorySize
;
3629 pStubMsg
->MemorySize
+= MemorySize
;
3633 /***********************************************************************
3634 * NdrComplexArrayFree [RPCRT4.@]
3636 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3637 unsigned char *pMemory
,
3638 PFORMAT_STRING pFormat
)
3640 ULONG i
, count
, def
;
3642 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3644 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3646 ERR("invalid format type %x\n", pFormat
[0]);
3647 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3651 def
= *(const WORD
*)&pFormat
[2];
3654 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3655 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3657 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3658 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3660 count
= pStubMsg
->ActualCount
;
3661 for (i
= 0; i
< count
; i
++)
3662 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
3665 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg
,
3666 USER_MARSHAL_CB_TYPE cbtype
, PFORMAT_STRING pFormat
,
3667 USER_MARSHAL_CB
*umcb
)
3669 umcb
->Flags
= MAKELONG(pStubMsg
->dwDestContext
,
3670 pStubMsg
->RpcMsg
->DataRepresentation
);
3671 umcb
->pStubMsg
= pStubMsg
;
3672 umcb
->pReserve
= NULL
;
3673 umcb
->Signature
= USER_MARSHAL_CB_SIGNATURE
;
3674 umcb
->CBType
= cbtype
;
3675 umcb
->pFormat
= pFormat
;
3676 umcb
->pTypeFormat
= NULL
/* FIXME */;
3679 #define USER_MARSHAL_PTR_PREFIX \
3680 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3681 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3683 /***********************************************************************
3684 * NdrUserMarshalMarshall [RPCRT4.@]
3686 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3687 unsigned char *pMemory
,
3688 PFORMAT_STRING pFormat
)
3690 unsigned flags
= pFormat
[1];
3691 unsigned index
= *(const WORD
*)&pFormat
[2];
3692 unsigned char *saved_buffer
= NULL
;
3693 USER_MARSHAL_CB umcb
;
3695 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3696 TRACE("index=%d\n", index
);
3698 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_MARSHALL
, pFormat
, &umcb
);
3700 if (flags
& USER_MARSHAL_POINTER
)
3702 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
3703 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, USER_MARSHAL_PTR_PREFIX
);
3704 pStubMsg
->Buffer
+= 4;
3705 if (pStubMsg
->PointerBufferMark
)
3707 saved_buffer
= pStubMsg
->Buffer
;
3708 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3709 pStubMsg
->PointerBufferMark
= NULL
;
3711 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 8);
3714 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3717 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
3718 &umcb
.Flags
, pStubMsg
->Buffer
, pMemory
);
3722 STD_OVERFLOW_CHECK(pStubMsg
);
3723 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3724 pStubMsg
->Buffer
= saved_buffer
;
3727 STD_OVERFLOW_CHECK(pStubMsg
);
3732 /***********************************************************************
3733 * NdrUserMarshalUnmarshall [RPCRT4.@]
3735 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3736 unsigned char **ppMemory
,
3737 PFORMAT_STRING pFormat
,
3738 unsigned char fMustAlloc
)
3740 unsigned flags
= pFormat
[1];
3741 unsigned index
= *(const WORD
*)&pFormat
[2];
3742 DWORD memsize
= *(const WORD
*)&pFormat
[4];
3743 unsigned char *saved_buffer
= NULL
;
3744 USER_MARSHAL_CB umcb
;
3746 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3747 TRACE("index=%d\n", index
);
3749 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_UNMARSHALL
, pFormat
, &umcb
);
3751 if (flags
& USER_MARSHAL_POINTER
)
3753 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3754 /* skip pointer prefix */
3755 pStubMsg
->Buffer
+= 4;
3756 if (pStubMsg
->PointerBufferMark
)
3758 saved_buffer
= pStubMsg
->Buffer
;
3759 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3760 pStubMsg
->PointerBufferMark
= NULL
;
3762 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3765 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3767 if (fMustAlloc
|| !*ppMemory
)
3768 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
3771 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
3772 &umcb
.Flags
, pStubMsg
->Buffer
, *ppMemory
);
3776 STD_OVERFLOW_CHECK(pStubMsg
);
3777 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3778 pStubMsg
->Buffer
= saved_buffer
;
3784 /***********************************************************************
3785 * NdrUserMarshalBufferSize [RPCRT4.@]
3787 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3788 unsigned char *pMemory
,
3789 PFORMAT_STRING pFormat
)
3791 unsigned flags
= pFormat
[1];
3792 unsigned index
= *(const WORD
*)&pFormat
[2];
3793 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
3794 USER_MARSHAL_CB umcb
;
3795 unsigned long saved_buffer_length
= 0;
3797 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3798 TRACE("index=%d\n", index
);
3800 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_BUFFER_SIZE
, pFormat
, &umcb
);
3802 if (flags
& USER_MARSHAL_POINTER
)
3804 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
3805 /* skip pointer prefix */
3806 safe_buffer_length_increment(pStubMsg
, 4);
3807 if (pStubMsg
->IgnoreEmbeddedPointers
)
3809 if (pStubMsg
->PointerLength
)
3811 saved_buffer_length
= pStubMsg
->BufferLength
;
3812 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3813 pStubMsg
->PointerLength
= 0;
3815 ALIGN_LENGTH(pStubMsg
->BufferLength
, 8);
3818 ALIGN_LENGTH(pStubMsg
->BufferLength
, (flags
& 0xf) + 1);
3821 TRACE("size=%d\n", bufsize
);
3822 safe_buffer_length_increment(pStubMsg
, bufsize
);
3825 pStubMsg
->BufferLength
=
3826 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
3827 &umcb
.Flags
, pStubMsg
->BufferLength
, pMemory
);
3829 if (saved_buffer_length
)
3831 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3832 pStubMsg
->BufferLength
= saved_buffer_length
;
3837 /***********************************************************************
3838 * NdrUserMarshalMemorySize [RPCRT4.@]
3840 ULONG WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3841 PFORMAT_STRING pFormat
)
3843 unsigned flags
= pFormat
[1];
3844 unsigned index
= *(const WORD
*)&pFormat
[2];
3845 DWORD memsize
= *(const WORD
*)&pFormat
[4];
3846 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
3848 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3849 TRACE("index=%d\n", index
);
3851 pStubMsg
->MemorySize
+= memsize
;
3853 if (flags
& USER_MARSHAL_POINTER
)
3855 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3856 /* skip pointer prefix */
3857 pStubMsg
->Buffer
+= 4;
3858 if (pStubMsg
->IgnoreEmbeddedPointers
)
3859 return pStubMsg
->MemorySize
;
3860 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3863 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3866 FIXME("not implemented for varying buffer size\n");
3868 pStubMsg
->Buffer
+= bufsize
;
3870 return pStubMsg
->MemorySize
;
3873 /***********************************************************************
3874 * NdrUserMarshalFree [RPCRT4.@]
3876 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
3877 unsigned char *pMemory
,
3878 PFORMAT_STRING pFormat
)
3880 /* unsigned flags = pFormat[1]; */
3881 unsigned index
= *(const WORD
*)&pFormat
[2];
3882 USER_MARSHAL_CB umcb
;
3884 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3885 TRACE("index=%d\n", index
);
3887 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_FREE
, pFormat
, &umcb
);
3889 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
3890 &umcb
.Flags
, pMemory
);
3893 /***********************************************************************
3894 * NdrClearOutParameters [RPCRT4.@]
3896 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
3897 PFORMAT_STRING pFormat
,
3900 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
3903 /***********************************************************************
3904 * NdrConvert [RPCRT4.@]
3906 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
3908 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
3909 /* FIXME: since this stub doesn't do any converting, the proper behavior
3910 is to raise an exception */
3913 /***********************************************************************
3914 * NdrConvert2 [RPCRT4.@]
3916 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, LONG NumberParams
)
3918 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3919 pStubMsg
, pFormat
, NumberParams
);
3920 /* FIXME: since this stub doesn't do any converting, the proper behavior
3921 is to raise an exception */
3924 #include "pshpack1.h"
3925 typedef struct _NDR_CSTRUCT_FORMAT
3928 unsigned char alignment
;
3929 unsigned short memory_size
;
3930 short offset_to_array_description
;
3931 } NDR_CSTRUCT_FORMAT
, NDR_CVSTRUCT_FORMAT
;
3932 #include "poppack.h"
3934 /***********************************************************************
3935 * NdrConformantStructMarshall [RPCRT4.@]
3937 unsigned char * WINAPI
NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3938 unsigned char *pMemory
,
3939 PFORMAT_STRING pFormat
)
3941 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3942 PFORMAT_STRING pCArrayFormat
;
3943 ULONG esize
, bufsize
;
3945 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3947 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3948 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3950 ERR("invalid format type %x\n", pCStructFormat
->type
);
3951 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3955 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3956 pCStructFormat
->offset_to_array_description
;
3957 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3959 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3960 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3963 esize
= *(const WORD
*)(pCArrayFormat
+2);
3965 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
3966 pCArrayFormat
+ 4, 0);
3968 WriteConformance(pStubMsg
);
3970 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
3972 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3974 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3975 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
3977 ERR("integer overflow of memory_size %u with bufsize %u\n",
3978 pCStructFormat
->memory_size
, bufsize
);
3979 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3981 /* copy constant sized part of struct */
3982 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3983 safe_copy_to_buffer(pStubMsg
, pMemory
, pCStructFormat
->memory_size
+ bufsize
);
3985 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3986 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3991 /***********************************************************************
3992 * NdrConformantStructUnmarshall [RPCRT4.@]
3994 unsigned char * WINAPI
NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3995 unsigned char **ppMemory
,
3996 PFORMAT_STRING pFormat
,
3997 unsigned char fMustAlloc
)
3999 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4000 PFORMAT_STRING pCArrayFormat
;
4001 ULONG esize
, bufsize
;
4002 unsigned char *saved_buffer
;
4004 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4006 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4007 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4009 ERR("invalid format type %x\n", pCStructFormat
->type
);
4010 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4013 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4014 pCStructFormat
->offset_to_array_description
;
4015 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4017 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4018 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4021 esize
= *(const WORD
*)(pCArrayFormat
+2);
4023 pCArrayFormat
= ReadConformance(pStubMsg
, pCArrayFormat
+ 4);
4025 ALIGN_POINTER(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4027 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4029 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4030 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4032 ERR("integer overflow of memory_size %u with bufsize %u\n",
4033 pCStructFormat
->memory_size
, bufsize
);
4034 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4039 SIZE_T size
= pCStructFormat
->memory_size
+ bufsize
;
4040 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4044 if (!pStubMsg
->IsClient
&& !*ppMemory
)
4045 /* for servers, we just point straight into the RPC buffer */
4046 *ppMemory
= pStubMsg
->Buffer
;
4049 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4050 safe_buffer_increment(pStubMsg
, pCStructFormat
->memory_size
+ bufsize
);
4051 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4052 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4054 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
4055 if (*ppMemory
!= saved_buffer
)
4056 memcpy(*ppMemory
, saved_buffer
, pCStructFormat
->memory_size
+ bufsize
);
4061 /***********************************************************************
4062 * NdrConformantStructBufferSize [RPCRT4.@]
4064 void WINAPI
NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4065 unsigned char *pMemory
,
4066 PFORMAT_STRING pFormat
)
4068 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4069 PFORMAT_STRING pCArrayFormat
;
4072 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4074 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4075 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4077 ERR("invalid format type %x\n", pCStructFormat
->type
);
4078 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4081 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4082 pCStructFormat
->offset_to_array_description
;
4083 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4085 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4086 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4089 esize
= *(const WORD
*)(pCArrayFormat
+2);
4091 pCArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
, pCArrayFormat
+4, 0);
4092 SizeConformance(pStubMsg
);
4094 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCStructFormat
->alignment
+ 1);
4096 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4098 safe_buffer_length_increment(pStubMsg
, pCStructFormat
->memory_size
);
4099 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
4101 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4102 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4105 /***********************************************************************
4106 * NdrConformantStructMemorySize [RPCRT4.@]
4108 ULONG WINAPI
NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4109 PFORMAT_STRING pFormat
)
4115 /***********************************************************************
4116 * NdrConformantStructFree [RPCRT4.@]
4118 void WINAPI
NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
4119 unsigned char *pMemory
,
4120 PFORMAT_STRING pFormat
)
4122 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4123 PFORMAT_STRING pCArrayFormat
;
4125 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4127 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4128 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4130 ERR("invalid format type %x\n", pCStructFormat
->type
);
4131 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4135 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4136 pCStructFormat
->offset_to_array_description
;
4137 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4139 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4140 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4144 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4145 pCArrayFormat
+ 4, 0);
4147 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4149 /* copy constant sized part of struct */
4150 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4152 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4153 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4156 /***********************************************************************
4157 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4159 unsigned char * WINAPI
NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4160 unsigned char *pMemory
,
4161 PFORMAT_STRING pFormat
)
4163 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4164 PFORMAT_STRING pCVArrayFormat
;
4165 ULONG esize
, bufsize
;
4167 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4169 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4170 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4172 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4173 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4177 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4178 pCVStructFormat
->offset_to_array_description
;
4179 switch (*pCVArrayFormat
)
4181 case RPC_FC_CVARRAY
:
4182 esize
= *(const WORD
*)(pCVArrayFormat
+2);
4184 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4185 pCVArrayFormat
+ 4, 0);
4186 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4189 case RPC_FC_C_CSTRING
:
4190 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
4191 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
4192 esize
= sizeof(char);
4193 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4194 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4195 pCVArrayFormat
+ 2, 0);
4197 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4199 case RPC_FC_C_WSTRING
:
4200 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
4201 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
4202 esize
= sizeof(WCHAR
);
4203 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4204 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4205 pCVArrayFormat
+ 2, 0);
4207 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4210 ERR("invalid array format type %x\n", *pCVArrayFormat
);
4211 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4215 WriteConformance(pStubMsg
);
4217 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4219 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4221 /* write constant sized part */
4222 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4223 safe_copy_to_buffer(pStubMsg
, pMemory
, pCVStructFormat
->memory_size
);
4225 WriteVariance(pStubMsg
);
4227 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4229 /* write array part */
4230 safe_copy_to_buffer(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
, bufsize
);
4232 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4237 /***********************************************************************
4238 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4240 unsigned char * WINAPI
NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4241 unsigned char **ppMemory
,
4242 PFORMAT_STRING pFormat
,
4243 unsigned char fMustAlloc
)
4245 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4246 PFORMAT_STRING pCVArrayFormat
;
4247 ULONG esize
, bufsize
;
4248 unsigned char cvarray_type
;
4250 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4252 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4253 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4255 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4256 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4260 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4261 pCVStructFormat
->offset_to_array_description
;
4262 cvarray_type
= *pCVArrayFormat
;
4263 switch (cvarray_type
)
4265 case RPC_FC_CVARRAY
:
4266 esize
= *(const WORD
*)(pCVArrayFormat
+2);
4267 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 4);
4269 case RPC_FC_C_CSTRING
:
4270 esize
= sizeof(char);
4271 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4272 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
4274 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
4276 case RPC_FC_C_WSTRING
:
4277 esize
= sizeof(WCHAR
);
4278 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4279 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
4281 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
4284 ERR("invalid array format type %x\n", *pCVArrayFormat
);
4285 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4289 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4291 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4293 /* work out how much memory to allocate if we need to do so */
4294 if (!*ppMemory
|| fMustAlloc
)
4296 SIZE_T size
= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->MaxCount
);
4297 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4300 /* copy the constant data */
4301 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4302 safe_copy_from_buffer(pStubMsg
, *ppMemory
, pCVStructFormat
->memory_size
);
4304 pCVArrayFormat
= ReadVariance(pStubMsg
, pCVArrayFormat
, pStubMsg
->MaxCount
);
4306 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4308 if ((cvarray_type
== RPC_FC_C_CSTRING
) ||
4309 (cvarray_type
== RPC_FC_C_WSTRING
))
4312 /* strings must always have null terminating bytes */
4313 if (bufsize
< esize
)
4315 ERR("invalid string length of %d\n", pStubMsg
->ActualCount
);
4316 RpcRaiseException(RPC_S_INVALID_BOUND
);
4319 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
4320 if (pStubMsg
->Buffer
[i
] != 0)
4322 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
4323 i
, pStubMsg
->Buffer
[i
]);
4324 RpcRaiseException(RPC_S_INVALID_BOUND
);
4329 /* copy the array data */
4330 safe_copy_from_buffer(pStubMsg
, *ppMemory
+ pCVStructFormat
->memory_size
, bufsize
);
4332 if (cvarray_type
== RPC_FC_C_CSTRING
)
4333 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory
+ pCVStructFormat
->memory_size
)));
4334 else if (cvarray_type
== RPC_FC_C_WSTRING
)
4335 TRACE("string=%s\n", debugstr_w((WCHAR
*)(*ppMemory
+ pCVStructFormat
->memory_size
)));
4337 EmbeddedPointerUnmarshall(pStubMsg
, *ppMemory
, *ppMemory
, pFormat
, TRUE
/* FIXME */);
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 #include "pshpack1.h"
5786 unsigned char flags_type
; /* flags in upper nibble, type in lower nibble */
5790 #include "poppack.h"
5792 /***********************************************************************
5793 * NdrRangeMarshall [internal]
5795 unsigned char *WINAPI
NdrRangeMarshall(
5796 PMIDL_STUB_MESSAGE pStubMsg
,
5797 unsigned char *pMemory
,
5798 PFORMAT_STRING pFormat
)
5800 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5801 unsigned char base_type
;
5803 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5805 if (pRange
->type
!= RPC_FC_RANGE
)
5807 ERR("invalid format type %x\n", pRange
->type
);
5808 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5812 base_type
= pRange
->flags_type
& 0xf;
5814 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &base_type
);
5817 /***********************************************************************
5818 * NdrRangeUnmarshall
5820 unsigned char *WINAPI
NdrRangeUnmarshall(
5821 PMIDL_STUB_MESSAGE pStubMsg
,
5822 unsigned char **ppMemory
,
5823 PFORMAT_STRING pFormat
,
5824 unsigned char fMustAlloc
)
5826 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5827 unsigned char base_type
;
5829 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
5831 if (pRange
->type
!= RPC_FC_RANGE
)
5833 ERR("invalid format type %x\n", pRange
->type
);
5834 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5837 base_type
= pRange
->flags_type
& 0xf;
5839 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5840 base_type
, pRange
->low_value
, pRange
->high_value
);
5842 #define RANGE_UNMARSHALL(type, format_spec) \
5845 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5846 if (fMustAlloc || !*ppMemory) \
5847 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5848 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
5850 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
5851 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
5852 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
5854 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5855 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5857 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5858 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5859 (type)pRange->high_value); \
5860 RpcRaiseException(RPC_S_INVALID_BOUND); \
5863 TRACE("*ppMemory: %p\n", *ppMemory); \
5864 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5865 pStubMsg->Buffer += sizeof(type); \
5872 RANGE_UNMARSHALL(UCHAR
, "%d");
5873 TRACE("value: 0x%02x\n", **ppMemory
);
5877 RANGE_UNMARSHALL(CHAR
, "%u");
5878 TRACE("value: 0x%02x\n", **ppMemory
);
5880 case RPC_FC_WCHAR
: /* FIXME: valid? */
5882 RANGE_UNMARSHALL(USHORT
, "%u");
5883 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5886 RANGE_UNMARSHALL(SHORT
, "%d");
5887 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5890 RANGE_UNMARSHALL(LONG
, "%d");
5891 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5894 RANGE_UNMARSHALL(ULONG
, "%u");
5895 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5899 FIXME("Unhandled enum type\n");
5901 case RPC_FC_ERROR_STATUS_T
: /* FIXME: valid? */
5906 ERR("invalid range base type: 0x%02x\n", base_type
);
5907 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5913 /***********************************************************************
5914 * NdrRangeBufferSize [internal]
5916 void WINAPI
NdrRangeBufferSize(
5917 PMIDL_STUB_MESSAGE pStubMsg
,
5918 unsigned char *pMemory
,
5919 PFORMAT_STRING pFormat
)
5921 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5922 unsigned char base_type
;
5924 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5926 if (pRange
->type
!= RPC_FC_RANGE
)
5928 ERR("invalid format type %x\n", pRange
->type
);
5929 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5931 base_type
= pRange
->flags_type
& 0xf;
5933 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &base_type
);
5936 /***********************************************************************
5937 * NdrRangeMemorySize [internal]
5939 ULONG WINAPI
NdrRangeMemorySize(
5940 PMIDL_STUB_MESSAGE pStubMsg
,
5941 PFORMAT_STRING pFormat
)
5943 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5944 unsigned char base_type
;
5946 if (pRange
->type
!= RPC_FC_RANGE
)
5948 ERR("invalid format type %x\n", pRange
->type
);
5949 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5952 base_type
= pRange
->flags_type
& 0xf;
5954 return NdrBaseTypeMemorySize(pStubMsg
, &base_type
);
5957 /***********************************************************************
5958 * NdrRangeFree [internal]
5960 void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg
,
5961 unsigned char *pMemory
,
5962 PFORMAT_STRING pFormat
)
5964 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5969 /***********************************************************************
5970 * NdrBaseTypeMarshall [internal]
5972 static unsigned char *WINAPI
NdrBaseTypeMarshall(
5973 PMIDL_STUB_MESSAGE pStubMsg
,
5974 unsigned char *pMemory
,
5975 PFORMAT_STRING pFormat
)
5977 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5985 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(UCHAR
));
5986 TRACE("value: 0x%02x\n", *pMemory
);
5991 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(USHORT
));
5992 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(USHORT
));
5993 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
5997 case RPC_FC_ERROR_STATUS_T
:
5999 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(ULONG
));
6000 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONG
));
6001 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
6004 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(float));
6005 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
6008 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(double));
6009 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
6012 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(ULONGLONG
));
6013 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONGLONG
));
6014 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
6017 /* only 16-bits on the wire, so do a sanity check */
6018 if (*(UINT
*)pMemory
> SHRT_MAX
)
6019 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
6020 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(USHORT
));
6021 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6022 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6023 *(USHORT
*)pStubMsg
->Buffer
= *(UINT
*)pMemory
;
6024 pStubMsg
->Buffer
+= sizeof(USHORT
);
6025 TRACE("value: 0x%04x\n", *(UINT
*)pMemory
);
6030 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6033 /* FIXME: what is the correct return value? */
6037 /***********************************************************************
6038 * NdrBaseTypeUnmarshall [internal]
6040 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(
6041 PMIDL_STUB_MESSAGE pStubMsg
,
6042 unsigned char **ppMemory
,
6043 PFORMAT_STRING pFormat
,
6044 unsigned char fMustAlloc
)
6046 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6048 #define BASE_TYPE_UNMARSHALL(type) \
6049 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6050 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6052 *ppMemory = pStubMsg->Buffer; \
6053 TRACE("*ppMemory: %p\n", *ppMemory); \
6054 safe_buffer_increment(pStubMsg, sizeof(type)); \
6059 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6060 TRACE("*ppMemory: %p\n", *ppMemory); \
6061 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6070 BASE_TYPE_UNMARSHALL(UCHAR
);
6071 TRACE("value: 0x%02x\n", **ppMemory
);
6076 BASE_TYPE_UNMARSHALL(USHORT
);
6077 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6081 case RPC_FC_ERROR_STATUS_T
:
6083 BASE_TYPE_UNMARSHALL(ULONG
);
6084 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6087 BASE_TYPE_UNMARSHALL(float);
6088 TRACE("value: %f\n", **(float **)ppMemory
);
6091 BASE_TYPE_UNMARSHALL(double);
6092 TRACE("value: %f\n", **(double **)ppMemory
);
6095 BASE_TYPE_UNMARSHALL(ULONGLONG
);
6096 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG
**)ppMemory
));
6099 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
6100 if (fMustAlloc
|| !*ppMemory
)
6101 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT
));
6102 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > pStubMsg
->BufferEnd
)
6103 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6104 TRACE("*ppMemory: %p\n", *ppMemory
);
6105 /* 16-bits on the wire, but int in memory */
6106 **(UINT
**)ppMemory
= *(USHORT
*)pStubMsg
->Buffer
;
6107 pStubMsg
->Buffer
+= sizeof(USHORT
);
6108 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
6113 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6115 #undef BASE_TYPE_UNMARSHALL
6117 /* FIXME: what is the correct return value? */
6122 /***********************************************************************
6123 * NdrBaseTypeBufferSize [internal]
6125 static void WINAPI
NdrBaseTypeBufferSize(
6126 PMIDL_STUB_MESSAGE pStubMsg
,
6127 unsigned char *pMemory
,
6128 PFORMAT_STRING pFormat
)
6130 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6138 safe_buffer_length_increment(pStubMsg
, sizeof(UCHAR
));
6144 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(USHORT
));
6145 safe_buffer_length_increment(pStubMsg
, sizeof(USHORT
));
6150 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONG
));
6151 safe_buffer_length_increment(pStubMsg
, sizeof(ULONG
));
6154 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(float));
6155 safe_buffer_length_increment(pStubMsg
, sizeof(float));
6158 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(double));
6159 safe_buffer_length_increment(pStubMsg
, sizeof(double));
6162 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONGLONG
));
6163 safe_buffer_length_increment(pStubMsg
, sizeof(ULONGLONG
));
6165 case RPC_FC_ERROR_STATUS_T
:
6166 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(error_status_t
));
6167 safe_buffer_length_increment(pStubMsg
, sizeof(error_status_t
));
6172 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6176 /***********************************************************************
6177 * NdrBaseTypeMemorySize [internal]
6179 static ULONG WINAPI
NdrBaseTypeMemorySize(
6180 PMIDL_STUB_MESSAGE pStubMsg
,
6181 PFORMAT_STRING pFormat
)
6183 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg
, *pFormat
);
6191 safe_buffer_increment(pStubMsg
, sizeof(UCHAR
));
6192 pStubMsg
->MemorySize
+= sizeof(UCHAR
);
6193 return sizeof(UCHAR
);
6197 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6198 pStubMsg
->MemorySize
+= sizeof(USHORT
);
6199 return sizeof(USHORT
);
6203 safe_buffer_increment(pStubMsg
, sizeof(ULONG
));
6204 pStubMsg
->MemorySize
+= sizeof(ULONG
);
6205 return sizeof(ULONG
);
6207 safe_buffer_increment(pStubMsg
, sizeof(float));
6208 pStubMsg
->MemorySize
+= sizeof(float);
6209 return sizeof(float);
6211 safe_buffer_increment(pStubMsg
, sizeof(double));
6212 pStubMsg
->MemorySize
+= sizeof(double);
6213 return sizeof(double);
6215 safe_buffer_increment(pStubMsg
, sizeof(ULONGLONG
));
6216 pStubMsg
->MemorySize
+= sizeof(ULONGLONG
);
6217 return sizeof(ULONGLONG
);
6218 case RPC_FC_ERROR_STATUS_T
:
6219 safe_buffer_increment(pStubMsg
, sizeof(error_status_t
));
6220 pStubMsg
->MemorySize
+= sizeof(error_status_t
);
6221 return sizeof(error_status_t
);
6223 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6224 pStubMsg
->MemorySize
+= sizeof(UINT
);
6225 return sizeof(UINT
);
6227 pStubMsg
->MemorySize
+= sizeof(void *);
6228 return sizeof(void *);
6230 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6235 /***********************************************************************
6236 * NdrBaseTypeFree [internal]
6238 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6239 unsigned char *pMemory
,
6240 PFORMAT_STRING pFormat
)
6242 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6247 /***********************************************************************
6248 * NdrContextHandleBufferSize [internal]
6250 static void WINAPI
NdrContextHandleBufferSize(
6251 PMIDL_STUB_MESSAGE pStubMsg
,
6252 unsigned char *pMemory
,
6253 PFORMAT_STRING pFormat
)
6255 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6257 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6259 ERR("invalid format type %x\n", *pFormat
);
6260 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6262 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
6263 safe_buffer_length_increment(pStubMsg
, cbNDRContext
);
6266 /***********************************************************************
6267 * NdrContextHandleMarshall [internal]
6269 static unsigned char *WINAPI
NdrContextHandleMarshall(
6270 PMIDL_STUB_MESSAGE pStubMsg
,
6271 unsigned char *pMemory
,
6272 PFORMAT_STRING pFormat
)
6274 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6276 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6278 ERR("invalid format type %x\n", *pFormat
);
6279 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6281 TRACE("flags: 0x%02x\n", pFormat
[1]);
6283 if (pFormat
[1] & 0x80)
6284 NdrClientContextMarshall(pStubMsg
, *(NDR_CCONTEXT
**)pMemory
, FALSE
);
6286 NdrClientContextMarshall(pStubMsg
, (NDR_CCONTEXT
*)pMemory
, FALSE
);
6291 /***********************************************************************
6292 * NdrContextHandleUnmarshall [internal]
6294 static unsigned char *WINAPI
NdrContextHandleUnmarshall(
6295 PMIDL_STUB_MESSAGE pStubMsg
,
6296 unsigned char **ppMemory
,
6297 PFORMAT_STRING pFormat
,
6298 unsigned char fMustAlloc
)
6300 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg
,
6301 ppMemory
, pFormat
, fMustAlloc
? "TRUE": "FALSE");
6303 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6305 ERR("invalid format type %x\n", *pFormat
);
6306 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6308 TRACE("flags: 0x%02x\n", pFormat
[1]);
6310 /* [out]-only or [ret] param */
6311 if ((pFormat
[1] & 0x60) == 0x20)
6312 **(NDR_CCONTEXT
**)ppMemory
= NULL
;
6313 NdrClientContextUnmarshall(pStubMsg
, *(NDR_CCONTEXT
**)ppMemory
, pStubMsg
->RpcMsg
->Handle
);
6318 /***********************************************************************
6319 * NdrClientContextMarshall [RPCRT4.@]
6321 void WINAPI
NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6322 NDR_CCONTEXT ContextHandle
,
6325 TRACE("(%p, %p, %d)\n", pStubMsg
, ContextHandle
, fCheck
);
6327 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
6329 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6331 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6332 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6333 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6336 /* FIXME: what does fCheck do? */
6337 NDRCContextMarshall(ContextHandle
,
6340 pStubMsg
->Buffer
+= cbNDRContext
;
6343 /***********************************************************************
6344 * NdrClientContextUnmarshall [RPCRT4.@]
6346 void WINAPI
NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6347 NDR_CCONTEXT
* pContextHandle
,
6348 RPC_BINDING_HANDLE BindHandle
)
6350 TRACE("(%p, %p, %p)\n", pStubMsg
, pContextHandle
, BindHandle
);
6352 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6354 if (pStubMsg
->Buffer
+ cbNDRContext
> pStubMsg
->BufferEnd
)
6355 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6357 NDRCContextUnmarshall(pContextHandle
,
6360 pStubMsg
->RpcMsg
->DataRepresentation
);
6362 pStubMsg
->Buffer
+= cbNDRContext
;
6365 void WINAPI
NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6366 NDR_SCONTEXT ContextHandle
,
6367 NDR_RUNDOWN RundownRoutine
)
6369 TRACE("(%p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
);
6371 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6373 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6375 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6376 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6377 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6380 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
6381 pStubMsg
->Buffer
, RundownRoutine
, NULL
,
6382 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
6383 pStubMsg
->Buffer
+= cbNDRContext
;
6386 NDR_SCONTEXT WINAPI
NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
)
6388 NDR_SCONTEXT ContextHandle
;
6390 TRACE("(%p)\n", pStubMsg
);
6392 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6394 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6396 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6397 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6398 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6401 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
6403 pStubMsg
->RpcMsg
->DataRepresentation
,
6404 NULL
, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
6405 pStubMsg
->Buffer
+= cbNDRContext
;
6407 return ContextHandle
;
6410 void WINAPI
NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg
,
6411 unsigned char* pMemory
,
6412 PFORMAT_STRING pFormat
)
6414 FIXME("(%p, %p, %p): stub\n", pStubMsg
, pMemory
, pFormat
);
6417 NDR_SCONTEXT WINAPI
NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg
,
6418 PFORMAT_STRING pFormat
)
6420 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6421 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6423 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
6425 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
6426 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
6427 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
6428 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
6429 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
6431 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
6432 if_id
= &sif
->InterfaceId
;
6435 return NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
, NULL
,
6436 pStubMsg
->RpcMsg
->DataRepresentation
, if_id
,
6440 void WINAPI
NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6441 NDR_SCONTEXT ContextHandle
,
6442 NDR_RUNDOWN RundownRoutine
,
6443 PFORMAT_STRING pFormat
)
6445 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6446 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6448 TRACE("(%p, %p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
, pFormat
);
6450 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6452 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6454 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6455 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6456 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6459 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
6460 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
6461 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
6462 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
6463 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
6465 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
6466 if_id
= &sif
->InterfaceId
;
6469 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
6470 pStubMsg
->Buffer
, RundownRoutine
, if_id
, flags
);
6471 pStubMsg
->Buffer
+= cbNDRContext
;
6474 NDR_SCONTEXT WINAPI
NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6475 PFORMAT_STRING pFormat
)
6477 NDR_SCONTEXT ContextHandle
;
6478 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6479 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6481 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
6483 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6485 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6487 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6488 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6489 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6492 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
6493 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
6494 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
6495 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
6496 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
6498 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
6499 if_id
= &sif
->InterfaceId
;
6502 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
6504 pStubMsg
->RpcMsg
->DataRepresentation
,
6506 pStubMsg
->Buffer
+= cbNDRContext
;
6508 return ContextHandle
;
6511 /***********************************************************************
6512 * NdrCorrelationInitialize [RPCRT4.@]
6514 * Initializes correlation validity checking.
6517 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6518 * pMemory [I] Pointer to memory to use as a cache.
6519 * CacheSize [I] Size of the memory pointed to by pMemory.
6520 * Flags [I] Reserved. Set to zero.
6525 void WINAPI
NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg
, void *pMemory
, ULONG CacheSize
, ULONG Flags
)
6527 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg
, pMemory
, CacheSize
, Flags
);
6528 pStubMsg
->fHasNewCorrDesc
= TRUE
;
6531 /***********************************************************************
6532 * NdrCorrelationPass [RPCRT4.@]
6534 * Performs correlation validity checking.
6537 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6542 void WINAPI
NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg
)
6544 FIXME("(%p): stub\n", pStubMsg
);
6547 /***********************************************************************
6548 * NdrCorrelationFree [RPCRT4.@]
6550 * Frees any resources used while unmarshalling parameters that need
6551 * correlation validity checking.
6554 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6559 void WINAPI
NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg
)
6561 FIXME("(%p): stub\n", pStubMsg
);