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 base type and 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 /* incremement 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 /* incremement 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 /* incremement 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 void WINAPI
NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
2008 unsigned char FormatChar
)
2010 NdrBaseTypeUnmarshall(pStubMsg
, &pMemory
, &FormatChar
, 0);
2013 /***********************************************************************
2014 * NdrSimpleStructMarshall [RPCRT4.@]
2016 unsigned char * WINAPI
NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2017 unsigned char *pMemory
,
2018 PFORMAT_STRING pFormat
)
2020 unsigned size
= *(const WORD
*)(pFormat
+2);
2021 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2023 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pFormat
[1] + 1);
2025 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2026 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
2028 if (pFormat
[0] != RPC_FC_STRUCT
)
2029 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
+4);
2034 /***********************************************************************
2035 * NdrSimpleStructUnmarshall [RPCRT4.@]
2037 unsigned char * WINAPI
NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2038 unsigned char **ppMemory
,
2039 PFORMAT_STRING pFormat
,
2040 unsigned char fMustAlloc
)
2042 unsigned size
= *(const WORD
*)(pFormat
+2);
2043 unsigned char *saved_buffer
;
2044 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2046 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2049 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2052 if (!pStubMsg
->IsClient
&& !*ppMemory
)
2053 /* for servers, we just point straight into the RPC buffer */
2054 *ppMemory
= pStubMsg
->Buffer
;
2057 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2058 safe_buffer_increment(pStubMsg
, size
);
2059 if (pFormat
[0] == RPC_FC_PSTRUCT
)
2060 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
+4, fMustAlloc
);
2062 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
2063 if (*ppMemory
!= saved_buffer
)
2064 memcpy(*ppMemory
, saved_buffer
, size
);
2069 /***********************************************************************
2070 * NdrSimpleStructBufferSize [RPCRT4.@]
2072 void WINAPI
NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2073 unsigned char *pMemory
,
2074 PFORMAT_STRING pFormat
)
2076 unsigned size
= *(const WORD
*)(pFormat
+2);
2077 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2079 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
2081 safe_buffer_length_increment(pStubMsg
, size
);
2082 if (pFormat
[0] != RPC_FC_STRUCT
)
2083 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
+4);
2086 /***********************************************************************
2087 * NdrSimpleStructMemorySize [RPCRT4.@]
2089 ULONG WINAPI
NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2090 PFORMAT_STRING pFormat
)
2092 unsigned short size
= *(const WORD
*)(pFormat
+2);
2094 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2096 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2097 pStubMsg
->MemorySize
+= size
;
2098 safe_buffer_increment(pStubMsg
, size
);
2100 if (pFormat
[0] != RPC_FC_STRUCT
)
2101 EmbeddedPointerMemorySize(pStubMsg
, pFormat
+4);
2102 return pStubMsg
->MemorySize
;
2105 /***********************************************************************
2106 * NdrSimpleStructFree [RPCRT4.@]
2108 void WINAPI
NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
2109 unsigned char *pMemory
,
2110 PFORMAT_STRING pFormat
)
2112 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2113 if (pFormat
[0] != RPC_FC_STRUCT
)
2114 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
+4);
2118 static unsigned long EmbeddedComplexSize(const MIDL_STUB_MESSAGE
*pStubMsg
,
2119 PFORMAT_STRING pFormat
)
2123 case RPC_FC_PSTRUCT
:
2124 case RPC_FC_CSTRUCT
:
2125 case RPC_FC_BOGUS_STRUCT
:
2126 case RPC_FC_SMFARRAY
:
2127 case RPC_FC_SMVARRAY
:
2128 case RPC_FC_CSTRING
:
2129 return *(const WORD
*)&pFormat
[2];
2130 case RPC_FC_USER_MARSHAL
:
2131 return *(const WORD
*)&pFormat
[4];
2132 case RPC_FC_NON_ENCAPSULATED_UNION
:
2134 if (pStubMsg
->fHasNewCorrDesc
)
2139 pFormat
+= *(const SHORT
*)pFormat
;
2140 return *(const SHORT
*)pFormat
;
2142 return sizeof(void *);
2143 case RPC_FC_WSTRING
:
2144 return *(const WORD
*)&pFormat
[2] * 2;
2146 FIXME("unhandled embedded type %02x\n", *pFormat
);
2152 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2153 PFORMAT_STRING pFormat
)
2155 NDR_MEMORYSIZE m
= NdrMemorySizer
[*pFormat
& NDR_TABLE_MASK
];
2159 FIXME("no memorysizer for data type=%02x\n", *pFormat
);
2163 return m(pStubMsg
, pFormat
);
2167 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2168 unsigned char *pMemory
,
2169 PFORMAT_STRING pFormat
,
2170 PFORMAT_STRING pPointer
)
2172 PFORMAT_STRING desc
;
2176 while (*pFormat
!= RPC_FC_END
) {
2182 TRACE("byte=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2183 safe_copy_to_buffer(pStubMsg
, pMemory
, 1);
2189 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2190 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
2194 TRACE("enum16=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2195 if (32767 < *(DWORD
*)pMemory
)
2196 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
2197 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
2203 TRACE("long=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2204 safe_copy_to_buffer(pStubMsg
, pMemory
, 4);
2208 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2209 safe_copy_to_buffer(pStubMsg
, pMemory
, 8);
2212 case RPC_FC_POINTER
:
2214 unsigned char *saved_buffer
;
2215 int pointer_buffer_mark_set
= 0;
2216 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
2217 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
2218 saved_buffer
= pStubMsg
->Buffer
;
2219 if (pStubMsg
->PointerBufferMark
)
2221 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2222 pStubMsg
->PointerBufferMark
= NULL
;
2223 pointer_buffer_mark_set
= 1;
2226 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2227 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char**)pMemory
, pPointer
);
2228 if (pointer_buffer_mark_set
)
2230 STD_OVERFLOW_CHECK(pStubMsg
);
2231 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2232 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
2234 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2235 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
2236 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2238 pStubMsg
->Buffer
= saved_buffer
+ 4;
2244 case RPC_FC_ALIGNM4
:
2245 ALIGN_POINTER(pMemory
, 4);
2247 case RPC_FC_ALIGNM8
:
2248 ALIGN_POINTER(pMemory
, 8);
2250 case RPC_FC_STRUCTPAD1
:
2251 case RPC_FC_STRUCTPAD2
:
2252 case RPC_FC_STRUCTPAD3
:
2253 case RPC_FC_STRUCTPAD4
:
2254 case RPC_FC_STRUCTPAD5
:
2255 case RPC_FC_STRUCTPAD6
:
2256 case RPC_FC_STRUCTPAD7
:
2257 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2259 case RPC_FC_EMBEDDED_COMPLEX
:
2260 pMemory
+= pFormat
[1];
2262 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2263 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2264 TRACE("embedded complex (size=%ld) <= %p\n", size
, pMemory
);
2265 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
2268 /* for some reason interface pointers aren't generated as
2269 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2270 * they still need the derefencing treatment that pointers are
2272 if (*desc
== RPC_FC_IP
)
2273 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2275 m(pStubMsg
, pMemory
, desc
);
2277 else FIXME("no marshaller for embedded type %02x\n", *desc
);
2284 FIXME("unhandled format 0x%02x\n", *pFormat
);
2292 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2293 unsigned char *pMemory
,
2294 PFORMAT_STRING pFormat
,
2295 PFORMAT_STRING pPointer
)
2297 PFORMAT_STRING desc
;
2301 while (*pFormat
!= RPC_FC_END
) {
2307 safe_copy_from_buffer(pStubMsg
, pMemory
, 1);
2308 TRACE("byte=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2314 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
2315 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2319 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
2320 *(DWORD
*)pMemory
&= 0xffff;
2321 TRACE("enum16=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
2322 if (32767 < *(DWORD
*)pMemory
)
2323 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
2329 safe_copy_from_buffer(pStubMsg
, pMemory
, 4);
2330 TRACE("long=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
2334 safe_copy_from_buffer(pStubMsg
, pMemory
, 8);
2335 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2338 case RPC_FC_POINTER
:
2340 unsigned char *saved_buffer
;
2341 int pointer_buffer_mark_set
= 0;
2342 TRACE("pointer => %p\n", pMemory
);
2343 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2344 saved_buffer
= pStubMsg
->Buffer
;
2345 if (pStubMsg
->PointerBufferMark
)
2347 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2348 pStubMsg
->PointerBufferMark
= NULL
;
2349 pointer_buffer_mark_set
= 1;
2352 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2354 PointerUnmarshall(pStubMsg
, saved_buffer
, (unsigned char**)pMemory
, *(unsigned char**)pMemory
, pPointer
, TRUE
);
2355 if (pointer_buffer_mark_set
)
2357 STD_OVERFLOW_CHECK(pStubMsg
);
2358 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2359 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
2361 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2362 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
2363 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2365 pStubMsg
->Buffer
= saved_buffer
+ 4;
2371 case RPC_FC_ALIGNM4
:
2372 ALIGN_POINTER_CLEAR(pMemory
, 4);
2374 case RPC_FC_ALIGNM8
:
2375 ALIGN_POINTER_CLEAR(pMemory
, 8);
2377 case RPC_FC_STRUCTPAD1
:
2378 case RPC_FC_STRUCTPAD2
:
2379 case RPC_FC_STRUCTPAD3
:
2380 case RPC_FC_STRUCTPAD4
:
2381 case RPC_FC_STRUCTPAD5
:
2382 case RPC_FC_STRUCTPAD6
:
2383 case RPC_FC_STRUCTPAD7
:
2384 memset(pMemory
, 0, *pFormat
- RPC_FC_STRUCTPAD1
+ 1);
2385 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2387 case RPC_FC_EMBEDDED_COMPLEX
:
2388 pMemory
+= pFormat
[1];
2390 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2391 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2392 TRACE("embedded complex (size=%ld) => %p\n", size
, pMemory
);
2393 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
2394 memset(pMemory
, 0, size
); /* just in case */
2397 /* for some reason interface pointers aren't generated as
2398 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2399 * they still need the derefencing treatment that pointers are
2401 if (*desc
== RPC_FC_IP
)
2402 m(pStubMsg
, (unsigned char **)pMemory
, desc
, FALSE
);
2404 m(pStubMsg
, &pMemory
, desc
, FALSE
);
2406 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
2413 FIXME("unhandled format %d\n", *pFormat
);
2421 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2422 unsigned char *pMemory
,
2423 PFORMAT_STRING pFormat
,
2424 PFORMAT_STRING pPointer
)
2426 PFORMAT_STRING desc
;
2430 while (*pFormat
!= RPC_FC_END
) {
2436 safe_buffer_length_increment(pStubMsg
, 1);
2442 safe_buffer_length_increment(pStubMsg
, 2);
2446 safe_buffer_length_increment(pStubMsg
, 2);
2452 safe_buffer_length_increment(pStubMsg
, 4);
2456 safe_buffer_length_increment(pStubMsg
, 8);
2459 case RPC_FC_POINTER
:
2460 if (!pStubMsg
->IgnoreEmbeddedPointers
)
2462 int saved_buffer_length
= pStubMsg
->BufferLength
;
2463 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2464 pStubMsg
->PointerLength
= 0;
2465 if(!pStubMsg
->BufferLength
)
2466 ERR("BufferLength == 0??\n");
2467 PointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
2468 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2469 pStubMsg
->BufferLength
= saved_buffer_length
;
2471 safe_buffer_length_increment(pStubMsg
, 4);
2475 case RPC_FC_ALIGNM4
:
2476 ALIGN_POINTER(pMemory
, 4);
2478 case RPC_FC_ALIGNM8
:
2479 ALIGN_POINTER(pMemory
, 8);
2481 case RPC_FC_STRUCTPAD1
:
2482 case RPC_FC_STRUCTPAD2
:
2483 case RPC_FC_STRUCTPAD3
:
2484 case RPC_FC_STRUCTPAD4
:
2485 case RPC_FC_STRUCTPAD5
:
2486 case RPC_FC_STRUCTPAD6
:
2487 case RPC_FC_STRUCTPAD7
:
2488 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2490 case RPC_FC_EMBEDDED_COMPLEX
:
2491 pMemory
+= pFormat
[1];
2493 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2494 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2495 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
2498 /* for some reason interface pointers aren't generated as
2499 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2500 * they still need the derefencing treatment that pointers are
2502 if (*desc
== RPC_FC_IP
)
2503 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2505 m(pStubMsg
, pMemory
, desc
);
2507 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
2514 FIXME("unhandled format 0x%02x\n", *pFormat
);
2522 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
2523 unsigned char *pMemory
,
2524 PFORMAT_STRING pFormat
,
2525 PFORMAT_STRING pPointer
)
2527 PFORMAT_STRING desc
;
2531 while (*pFormat
!= RPC_FC_END
) {
2553 case RPC_FC_POINTER
:
2554 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
2558 case RPC_FC_ALIGNM4
:
2559 ALIGN_POINTER(pMemory
, 4);
2561 case RPC_FC_ALIGNM8
:
2562 ALIGN_POINTER(pMemory
, 8);
2564 case RPC_FC_STRUCTPAD1
:
2565 case RPC_FC_STRUCTPAD2
:
2566 case RPC_FC_STRUCTPAD3
:
2567 case RPC_FC_STRUCTPAD4
:
2568 case RPC_FC_STRUCTPAD5
:
2569 case RPC_FC_STRUCTPAD6
:
2570 case RPC_FC_STRUCTPAD7
:
2571 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2573 case RPC_FC_EMBEDDED_COMPLEX
:
2574 pMemory
+= pFormat
[1];
2576 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2577 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2578 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
2581 /* for some reason interface pointers aren't generated as
2582 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2583 * they still need the derefencing treatment that pointers are
2585 if (*desc
== RPC_FC_IP
)
2586 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2588 m(pStubMsg
, pMemory
, desc
);
2596 FIXME("unhandled format 0x%02x\n", *pFormat
);
2604 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2605 PFORMAT_STRING pFormat
)
2607 PFORMAT_STRING desc
;
2608 unsigned long size
= 0;
2610 while (*pFormat
!= RPC_FC_END
) {
2617 safe_buffer_increment(pStubMsg
, 1);
2623 safe_buffer_increment(pStubMsg
, 2);
2627 safe_buffer_increment(pStubMsg
, 2);
2633 safe_buffer_increment(pStubMsg
, 4);
2637 safe_buffer_increment(pStubMsg
, 8);
2639 case RPC_FC_POINTER
:
2641 safe_buffer_increment(pStubMsg
, 4);
2642 if (!pStubMsg
->IgnoreEmbeddedPointers
)
2643 FIXME("embedded pointers\n");
2645 case RPC_FC_ALIGNM4
:
2646 ALIGN_LENGTH(size
, 4);
2647 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2649 case RPC_FC_ALIGNM8
:
2650 ALIGN_LENGTH(size
, 8);
2651 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
2653 case RPC_FC_STRUCTPAD1
:
2654 case RPC_FC_STRUCTPAD2
:
2655 case RPC_FC_STRUCTPAD3
:
2656 case RPC_FC_STRUCTPAD4
:
2657 case RPC_FC_STRUCTPAD5
:
2658 case RPC_FC_STRUCTPAD6
:
2659 case RPC_FC_STRUCTPAD7
:
2660 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2662 case RPC_FC_EMBEDDED_COMPLEX
:
2665 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2666 size
+= EmbeddedComplexMemorySize(pStubMsg
, desc
);
2672 FIXME("unhandled format 0x%02x\n", *pFormat
);
2680 unsigned long ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg
,
2681 PFORMAT_STRING pFormat
)
2683 PFORMAT_STRING desc
;
2684 unsigned long size
= 0;
2686 while (*pFormat
!= RPC_FC_END
) {
2708 case RPC_FC_POINTER
:
2709 size
+= sizeof(void *);
2711 case RPC_FC_ALIGNM4
:
2712 ALIGN_LENGTH(size
, 4);
2714 case RPC_FC_ALIGNM8
:
2715 ALIGN_LENGTH(size
, 8);
2717 case RPC_FC_STRUCTPAD1
:
2718 case RPC_FC_STRUCTPAD2
:
2719 case RPC_FC_STRUCTPAD3
:
2720 case RPC_FC_STRUCTPAD4
:
2721 case RPC_FC_STRUCTPAD5
:
2722 case RPC_FC_STRUCTPAD6
:
2723 case RPC_FC_STRUCTPAD7
:
2724 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2726 case RPC_FC_EMBEDDED_COMPLEX
:
2729 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2730 size
+= EmbeddedComplexSize(pStubMsg
, desc
);
2736 FIXME("unhandled format 0x%02x\n", *pFormat
);
2744 /***********************************************************************
2745 * NdrComplexStructMarshall [RPCRT4.@]
2747 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2748 unsigned char *pMemory
,
2749 PFORMAT_STRING pFormat
)
2751 PFORMAT_STRING conf_array
= NULL
;
2752 PFORMAT_STRING pointer_desc
= NULL
;
2753 unsigned char *OldMemory
= pStubMsg
->Memory
;
2754 int pointer_buffer_mark_set
= 0;
2756 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2758 if (!pStubMsg
->PointerBufferMark
)
2760 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2761 /* save buffer length */
2762 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2764 /* get the buffer pointer after complex array data, but before
2766 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- pStubMsg
->BufferStart
;
2767 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2768 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
2769 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2771 /* save it for use by embedded pointer code later */
2772 pStubMsg
->PointerBufferMark
= pStubMsg
->BufferStart
+ pStubMsg
->BufferLength
;
2773 TRACE("difference = 0x%x\n", pStubMsg
->PointerBufferMark
- pStubMsg
->Buffer
);
2774 pointer_buffer_mark_set
= 1;
2776 /* restore the original buffer length */
2777 pStubMsg
->BufferLength
= saved_buffer_length
;
2780 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pFormat
[1] + 1);
2783 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2785 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2788 pStubMsg
->Memory
= pMemory
;
2790 ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2793 NdrConformantArrayMarshall(pStubMsg
, pMemory
, conf_array
);
2795 pStubMsg
->Memory
= OldMemory
;
2797 if (pointer_buffer_mark_set
)
2799 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2800 pStubMsg
->PointerBufferMark
= NULL
;
2803 STD_OVERFLOW_CHECK(pStubMsg
);
2808 /***********************************************************************
2809 * NdrComplexStructUnmarshall [RPCRT4.@]
2811 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2812 unsigned char **ppMemory
,
2813 PFORMAT_STRING pFormat
,
2814 unsigned char fMustAlloc
)
2816 unsigned size
= *(const WORD
*)(pFormat
+2);
2817 PFORMAT_STRING conf_array
= NULL
;
2818 PFORMAT_STRING pointer_desc
= NULL
;
2819 unsigned char *pMemory
;
2820 int pointer_buffer_mark_set
= 0;
2822 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2824 if (!pStubMsg
->PointerBufferMark
)
2826 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2827 /* save buffer pointer */
2828 unsigned char *saved_buffer
= pStubMsg
->Buffer
;
2830 /* get the buffer pointer after complex array data, but before
2832 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2833 NdrComplexStructMemorySize(pStubMsg
, pFormat
);
2834 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2836 /* save it for use by embedded pointer code later */
2837 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2838 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->PointerBufferMark
- saved_buffer
));
2839 pointer_buffer_mark_set
= 1;
2841 /* restore the original buffer */
2842 pStubMsg
->Buffer
= saved_buffer
;
2845 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2847 if (fMustAlloc
|| !*ppMemory
)
2849 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2850 memset(*ppMemory
, 0, size
);
2854 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2856 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2859 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
);
2862 NdrConformantArrayUnmarshall(pStubMsg
, &pMemory
, conf_array
, fMustAlloc
);
2864 if (pointer_buffer_mark_set
)
2866 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2867 pStubMsg
->PointerBufferMark
= NULL
;
2873 /***********************************************************************
2874 * NdrComplexStructBufferSize [RPCRT4.@]
2876 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2877 unsigned char *pMemory
,
2878 PFORMAT_STRING pFormat
)
2880 PFORMAT_STRING conf_array
= NULL
;
2881 PFORMAT_STRING pointer_desc
= NULL
;
2882 unsigned char *OldMemory
= pStubMsg
->Memory
;
2883 int pointer_length_set
= 0;
2885 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2887 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
2889 if(!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
2891 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2892 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2894 /* get the buffer length after complex struct data, but before
2896 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2897 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
2898 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2900 /* save it for use by embedded pointer code later */
2901 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2902 pointer_length_set
= 1;
2903 TRACE("difference = 0x%lx\n", pStubMsg
->PointerLength
- saved_buffer_length
);
2905 /* restore the original buffer length */
2906 pStubMsg
->BufferLength
= saved_buffer_length
;
2910 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2912 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2915 pStubMsg
->Memory
= pMemory
;
2917 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2920 NdrConformantArrayBufferSize(pStubMsg
, pMemory
, conf_array
);
2922 pStubMsg
->Memory
= OldMemory
;
2924 if(pointer_length_set
)
2926 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2927 pStubMsg
->PointerLength
= 0;
2932 /***********************************************************************
2933 * NdrComplexStructMemorySize [RPCRT4.@]
2935 ULONG WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2936 PFORMAT_STRING pFormat
)
2938 unsigned size
= *(const WORD
*)(pFormat
+2);
2939 PFORMAT_STRING conf_array
= NULL
;
2940 PFORMAT_STRING pointer_desc
= NULL
;
2942 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2944 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2947 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2949 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2952 ComplexStructMemorySize(pStubMsg
, pFormat
);
2955 NdrConformantArrayMemorySize(pStubMsg
, conf_array
);
2960 /***********************************************************************
2961 * NdrComplexStructFree [RPCRT4.@]
2963 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
2964 unsigned char *pMemory
,
2965 PFORMAT_STRING pFormat
)
2967 PFORMAT_STRING conf_array
= NULL
;
2968 PFORMAT_STRING pointer_desc
= NULL
;
2969 unsigned char *OldMemory
= pStubMsg
->Memory
;
2971 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2974 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2976 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2979 pStubMsg
->Memory
= pMemory
;
2981 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2984 NdrConformantArrayFree(pStubMsg
, pMemory
, conf_array
);
2986 pStubMsg
->Memory
= OldMemory
;
2989 /***********************************************************************
2990 * NdrConformantArrayMarshall [RPCRT4.@]
2992 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2993 unsigned char *pMemory
,
2994 PFORMAT_STRING pFormat
)
2996 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
2997 unsigned char alignment
= pFormat
[1] + 1;
2999 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3000 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
3002 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
3004 WriteConformance(pStubMsg
);
3006 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
3008 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3009 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3010 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
3012 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3017 /***********************************************************************
3018 * NdrConformantArrayUnmarshall [RPCRT4.@]
3020 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3021 unsigned char **ppMemory
,
3022 PFORMAT_STRING pFormat
,
3023 unsigned char fMustAlloc
)
3025 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
3026 unsigned char alignment
= pFormat
[1] + 1;
3027 unsigned char *saved_buffer
;
3029 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3030 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
3032 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
3034 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3035 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3038 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3041 if (!pStubMsg
->IsClient
&& !*ppMemory
)
3042 /* for servers, we just point straight into the RPC buffer */
3043 *ppMemory
= pStubMsg
->Buffer
;
3046 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3047 safe_buffer_increment(pStubMsg
, size
);
3048 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
3050 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
3051 if (*ppMemory
!= saved_buffer
)
3052 memcpy(*ppMemory
, saved_buffer
, size
);
3057 /***********************************************************************
3058 * NdrConformantArrayBufferSize [RPCRT4.@]
3060 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3061 unsigned char *pMemory
,
3062 PFORMAT_STRING pFormat
)
3064 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
3065 unsigned char alignment
= pFormat
[1] + 1;
3067 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3068 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
3070 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
3072 SizeConformance(pStubMsg
);
3074 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
3076 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3077 /* conformance value plus array */
3078 safe_buffer_length_increment(pStubMsg
, size
);
3080 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3083 /***********************************************************************
3084 * NdrConformantArrayMemorySize [RPCRT4.@]
3086 ULONG WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3087 PFORMAT_STRING pFormat
)
3089 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
3090 unsigned char alignment
= pFormat
[1] + 1;
3092 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3093 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
3095 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
3096 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3097 pStubMsg
->MemorySize
+= size
;
3099 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3100 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3101 safe_buffer_increment(pStubMsg
, size
);
3103 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
3105 return pStubMsg
->MemorySize
;
3108 /***********************************************************************
3109 * NdrConformantArrayFree [RPCRT4.@]
3111 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3112 unsigned char *pMemory
,
3113 PFORMAT_STRING pFormat
)
3115 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3116 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
3118 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
3120 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
3124 /***********************************************************************
3125 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3127 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
3128 unsigned char* pMemory
,
3129 PFORMAT_STRING pFormat
)
3132 unsigned char alignment
= pFormat
[1] + 1;
3133 DWORD esize
= *(const WORD
*)(pFormat
+2);
3135 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3137 if (pFormat
[0] != RPC_FC_CVARRAY
)
3139 ERR("invalid format type %x\n", pFormat
[0]);
3140 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3144 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
3145 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
3147 WriteConformance(pStubMsg
);
3148 WriteVariance(pStubMsg
);
3150 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
3152 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3154 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3155 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
3157 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3163 /***********************************************************************
3164 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
3166 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
3167 unsigned char** ppMemory
,
3168 PFORMAT_STRING pFormat
,
3169 unsigned char fMustAlloc
)
3171 ULONG bufsize
, memsize
;
3172 unsigned char alignment
= pFormat
[1] + 1;
3173 DWORD esize
= *(const WORD
*)(pFormat
+2);
3174 unsigned char *saved_buffer
;
3177 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3179 if (pFormat
[0] != RPC_FC_CVARRAY
)
3181 ERR("invalid format type %x\n", pFormat
[0]);
3182 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3186 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
3187 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3189 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3191 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3192 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3193 offset
= pStubMsg
->Offset
;
3195 if (!*ppMemory
|| fMustAlloc
)
3196 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
3197 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3198 safe_buffer_increment(pStubMsg
, bufsize
);
3200 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
3202 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
3208 /***********************************************************************
3209 * NdrConformantVaryingArrayFree [RPCRT4.@]
3211 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
3212 unsigned char* pMemory
,
3213 PFORMAT_STRING pFormat
)
3215 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3217 if (pFormat
[0] != RPC_FC_CVARRAY
)
3219 ERR("invalid format type %x\n", pFormat
[0]);
3220 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3224 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
3225 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
3227 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
3231 /***********************************************************************
3232 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
3234 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
3235 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
3237 unsigned char alignment
= pFormat
[1] + 1;
3238 DWORD esize
= *(const WORD
*)(pFormat
+2);
3240 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3242 if (pFormat
[0] != RPC_FC_CVARRAY
)
3244 ERR("invalid format type %x\n", pFormat
[0]);
3245 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3250 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
3251 /* compute length */
3252 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
3254 SizeConformance(pStubMsg
);
3255 SizeVariance(pStubMsg
);
3257 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
3259 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
3261 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3265 /***********************************************************************
3266 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
3268 ULONG WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
3269 PFORMAT_STRING pFormat
)
3271 ULONG bufsize
, memsize
;
3272 unsigned char alignment
= pFormat
[1] + 1;
3273 DWORD esize
= *(const WORD
*)(pFormat
+2);
3275 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
3277 if (pFormat
[0] != RPC_FC_CVARRAY
)
3279 ERR("invalid format type %x\n", pFormat
[0]);
3280 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3281 return pStubMsg
->MemorySize
;
3284 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
3285 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3287 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3289 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3290 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3292 safe_buffer_increment(pStubMsg
, bufsize
);
3293 pStubMsg
->MemorySize
+= memsize
;
3295 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
3297 return pStubMsg
->MemorySize
;
3301 /***********************************************************************
3302 * NdrComplexArrayMarshall [RPCRT4.@]
3304 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3305 unsigned char *pMemory
,
3306 PFORMAT_STRING pFormat
)
3308 ULONG i
, count
, def
;
3309 BOOL variance_present
;
3310 unsigned char alignment
;
3311 int pointer_buffer_mark_set
= 0;
3313 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3315 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3317 ERR("invalid format type %x\n", pFormat
[0]);
3318 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3322 alignment
= pFormat
[1] + 1;
3324 if (!pStubMsg
->PointerBufferMark
)
3326 /* save buffer fields that may be changed by buffer sizer functions
3327 * and that may be needed later on */
3328 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3329 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
3330 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
3331 unsigned long saved_offset
= pStubMsg
->Offset
;
3332 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
3334 /* get the buffer pointer after complex array data, but before
3336 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- pStubMsg
->BufferStart
;
3337 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3338 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
3339 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3341 /* save it for use by embedded pointer code later */
3342 pStubMsg
->PointerBufferMark
= pStubMsg
->BufferStart
+ pStubMsg
->BufferLength
;
3343 TRACE("difference = 0x%x\n", pStubMsg
->Buffer
- pStubMsg
->BufferStart
);
3344 pointer_buffer_mark_set
= 1;
3346 /* restore fields */
3347 pStubMsg
->ActualCount
= saved_actual_count
;
3348 pStubMsg
->Offset
= saved_offset
;
3349 pStubMsg
->MaxCount
= saved_max_count
;
3350 pStubMsg
->BufferLength
= saved_buffer_length
;
3353 def
= *(const WORD
*)&pFormat
[2];
3356 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3357 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3359 variance_present
= IsConformanceOrVariancePresent(pFormat
);
3360 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3361 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3363 WriteConformance(pStubMsg
);
3364 if (variance_present
)
3365 WriteVariance(pStubMsg
);
3367 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
3369 count
= pStubMsg
->ActualCount
;
3370 for (i
= 0; i
< count
; i
++)
3371 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
3373 STD_OVERFLOW_CHECK(pStubMsg
);
3375 if (pointer_buffer_mark_set
)
3377 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3378 pStubMsg
->PointerBufferMark
= NULL
;
3384 /***********************************************************************
3385 * NdrComplexArrayUnmarshall [RPCRT4.@]
3387 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3388 unsigned char **ppMemory
,
3389 PFORMAT_STRING pFormat
,
3390 unsigned char fMustAlloc
)
3392 ULONG i
, count
, size
;
3393 unsigned char alignment
;
3394 unsigned char *pMemory
;
3395 unsigned char *saved_buffer
;
3396 int pointer_buffer_mark_set
= 0;
3397 int saved_ignore_embedded
;
3399 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3401 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3403 ERR("invalid format type %x\n", pFormat
[0]);
3404 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3408 alignment
= pFormat
[1] + 1;
3410 saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3411 /* save buffer pointer */
3412 saved_buffer
= pStubMsg
->Buffer
;
3413 /* get the buffer pointer after complex array data, but before
3415 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3416 pStubMsg
->MemorySize
= 0;
3417 NdrComplexArrayMemorySize(pStubMsg
, pFormat
);
3418 size
= pStubMsg
->MemorySize
;
3419 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3421 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->Buffer
- saved_buffer
));
3422 if (!pStubMsg
->PointerBufferMark
)
3424 /* save it for use by embedded pointer code later */
3425 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3426 pointer_buffer_mark_set
= 1;
3428 /* restore the original buffer */
3429 pStubMsg
->Buffer
= saved_buffer
;
3433 pFormat
= ReadConformance(pStubMsg
, pFormat
);
3434 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3436 if (fMustAlloc
|| !*ppMemory
)
3438 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3439 memset(*ppMemory
, 0, size
);
3442 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3444 pMemory
= *ppMemory
;
3445 count
= pStubMsg
->ActualCount
;
3446 for (i
= 0; i
< count
; i
++)
3447 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
3449 if (pointer_buffer_mark_set
)
3451 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3452 pStubMsg
->PointerBufferMark
= NULL
;
3458 /***********************************************************************
3459 * NdrComplexArrayBufferSize [RPCRT4.@]
3461 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3462 unsigned char *pMemory
,
3463 PFORMAT_STRING pFormat
)
3465 ULONG i
, count
, def
;
3466 unsigned char alignment
;
3467 BOOL variance_present
;
3468 int pointer_length_set
= 0;
3470 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3472 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3474 ERR("invalid format type %x\n", pFormat
[0]);
3475 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3479 alignment
= pFormat
[1] + 1;
3481 if (!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
3483 /* save buffer fields that may be changed by buffer sizer functions
3484 * and that may be needed later on */
3485 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3486 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
3487 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
3488 unsigned long saved_offset
= pStubMsg
->Offset
;
3489 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
3491 /* get the buffer pointer after complex array data, but before
3493 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3494 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
3495 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3497 /* save it for use by embedded pointer code later */
3498 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3499 pointer_length_set
= 1;
3501 /* restore fields */
3502 pStubMsg
->ActualCount
= saved_actual_count
;
3503 pStubMsg
->Offset
= saved_offset
;
3504 pStubMsg
->MaxCount
= saved_max_count
;
3505 pStubMsg
->BufferLength
= saved_buffer_length
;
3507 def
= *(const WORD
*)&pFormat
[2];
3510 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3511 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3512 SizeConformance(pStubMsg
);
3514 variance_present
= IsConformanceOrVariancePresent(pFormat
);
3515 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3516 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3518 if (variance_present
)
3519 SizeVariance(pStubMsg
);
3521 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
3523 count
= pStubMsg
->ActualCount
;
3524 for (i
= 0; i
< count
; i
++)
3525 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
3527 if(pointer_length_set
)
3529 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3530 pStubMsg
->PointerLength
= 0;
3534 /***********************************************************************
3535 * NdrComplexArrayMemorySize [RPCRT4.@]
3537 ULONG WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3538 PFORMAT_STRING pFormat
)
3540 ULONG i
, count
, esize
, SavedMemorySize
, MemorySize
;
3541 unsigned char alignment
;
3543 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3545 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3547 ERR("invalid format type %x\n", pFormat
[0]);
3548 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3552 alignment
= pFormat
[1] + 1;
3556 pFormat
= ReadConformance(pStubMsg
, pFormat
);
3557 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3559 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3561 SavedMemorySize
= pStubMsg
->MemorySize
;
3563 esize
= ComplexStructSize(pStubMsg
, pFormat
);
3565 MemorySize
= safe_multiply(pStubMsg
->MaxCount
, esize
);
3567 count
= pStubMsg
->ActualCount
;
3568 for (i
= 0; i
< count
; i
++)
3569 ComplexStructMemorySize(pStubMsg
, pFormat
);
3571 pStubMsg
->MemorySize
= SavedMemorySize
;
3573 pStubMsg
->MemorySize
+= MemorySize
;
3577 /***********************************************************************
3578 * NdrComplexArrayFree [RPCRT4.@]
3580 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3581 unsigned char *pMemory
,
3582 PFORMAT_STRING pFormat
)
3584 ULONG i
, count
, def
;
3586 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3588 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3590 ERR("invalid format type %x\n", pFormat
[0]);
3591 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3595 def
= *(const WORD
*)&pFormat
[2];
3598 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3599 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3601 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3602 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3604 count
= pStubMsg
->ActualCount
;
3605 for (i
= 0; i
< count
; i
++)
3606 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
3609 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg
,
3610 USER_MARSHAL_CB_TYPE cbtype
, PFORMAT_STRING pFormat
,
3611 USER_MARSHAL_CB
*umcb
)
3613 umcb
->Flags
= MAKELONG(pStubMsg
->dwDestContext
,
3614 pStubMsg
->RpcMsg
->DataRepresentation
);
3615 umcb
->pStubMsg
= pStubMsg
;
3616 umcb
->pReserve
= NULL
;
3617 umcb
->Signature
= USER_MARSHAL_CB_SIGNATURE
;
3618 umcb
->CBType
= cbtype
;
3619 umcb
->pFormat
= pFormat
;
3620 umcb
->pTypeFormat
= NULL
/* FIXME */;
3623 #define USER_MARSHAL_PTR_PREFIX \
3624 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3625 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3627 /***********************************************************************
3628 * NdrUserMarshalMarshall [RPCRT4.@]
3630 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3631 unsigned char *pMemory
,
3632 PFORMAT_STRING pFormat
)
3634 unsigned flags
= pFormat
[1];
3635 unsigned index
= *(const WORD
*)&pFormat
[2];
3636 unsigned char *saved_buffer
= NULL
;
3637 USER_MARSHAL_CB umcb
;
3639 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3640 TRACE("index=%d\n", index
);
3642 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_MARSHALL
, pFormat
, &umcb
);
3644 if (flags
& USER_MARSHAL_POINTER
)
3646 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
3647 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, USER_MARSHAL_PTR_PREFIX
);
3648 pStubMsg
->Buffer
+= 4;
3649 if (pStubMsg
->PointerBufferMark
)
3651 saved_buffer
= pStubMsg
->Buffer
;
3652 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3653 pStubMsg
->PointerBufferMark
= NULL
;
3655 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 8);
3658 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3661 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
3662 &umcb
.Flags
, pStubMsg
->Buffer
, pMemory
);
3666 STD_OVERFLOW_CHECK(pStubMsg
);
3667 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3668 pStubMsg
->Buffer
= saved_buffer
;
3671 STD_OVERFLOW_CHECK(pStubMsg
);
3676 /***********************************************************************
3677 * NdrUserMarshalUnmarshall [RPCRT4.@]
3679 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3680 unsigned char **ppMemory
,
3681 PFORMAT_STRING pFormat
,
3682 unsigned char fMustAlloc
)
3684 unsigned flags
= pFormat
[1];
3685 unsigned index
= *(const WORD
*)&pFormat
[2];
3686 DWORD memsize
= *(const WORD
*)&pFormat
[4];
3687 unsigned char *saved_buffer
= NULL
;
3688 USER_MARSHAL_CB umcb
;
3690 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3691 TRACE("index=%d\n", index
);
3693 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_UNMARSHALL
, pFormat
, &umcb
);
3695 if (flags
& USER_MARSHAL_POINTER
)
3697 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3698 /* skip pointer prefix */
3699 pStubMsg
->Buffer
+= 4;
3700 if (pStubMsg
->PointerBufferMark
)
3702 saved_buffer
= pStubMsg
->Buffer
;
3703 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3704 pStubMsg
->PointerBufferMark
= NULL
;
3706 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3709 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3711 if (fMustAlloc
|| !*ppMemory
)
3712 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
3715 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
3716 &umcb
.Flags
, pStubMsg
->Buffer
, *ppMemory
);
3720 STD_OVERFLOW_CHECK(pStubMsg
);
3721 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3722 pStubMsg
->Buffer
= saved_buffer
;
3728 /***********************************************************************
3729 * NdrUserMarshalBufferSize [RPCRT4.@]
3731 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3732 unsigned char *pMemory
,
3733 PFORMAT_STRING pFormat
)
3735 unsigned flags
= pFormat
[1];
3736 unsigned index
= *(const WORD
*)&pFormat
[2];
3737 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
3738 USER_MARSHAL_CB umcb
;
3739 unsigned long saved_buffer_length
= 0;
3741 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3742 TRACE("index=%d\n", index
);
3744 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_BUFFER_SIZE
, pFormat
, &umcb
);
3746 if (flags
& USER_MARSHAL_POINTER
)
3748 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
3749 /* skip pointer prefix */
3750 safe_buffer_length_increment(pStubMsg
, 4);
3751 if (pStubMsg
->IgnoreEmbeddedPointers
)
3753 if (pStubMsg
->PointerLength
)
3755 saved_buffer_length
= pStubMsg
->BufferLength
;
3756 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3757 pStubMsg
->PointerLength
= 0;
3759 ALIGN_LENGTH(pStubMsg
->BufferLength
, 8);
3762 ALIGN_LENGTH(pStubMsg
->BufferLength
, (flags
& 0xf) + 1);
3765 TRACE("size=%d\n", bufsize
);
3766 safe_buffer_length_increment(pStubMsg
, bufsize
);
3769 pStubMsg
->BufferLength
=
3770 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
3771 &umcb
.Flags
, pStubMsg
->BufferLength
, pMemory
);
3773 if (saved_buffer_length
)
3775 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3776 pStubMsg
->BufferLength
= saved_buffer_length
;
3781 /***********************************************************************
3782 * NdrUserMarshalMemorySize [RPCRT4.@]
3784 ULONG WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3785 PFORMAT_STRING pFormat
)
3787 unsigned flags
= pFormat
[1];
3788 unsigned index
= *(const WORD
*)&pFormat
[2];
3789 DWORD memsize
= *(const WORD
*)&pFormat
[4];
3790 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
3792 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3793 TRACE("index=%d\n", index
);
3795 pStubMsg
->MemorySize
+= memsize
;
3797 if (flags
& USER_MARSHAL_POINTER
)
3799 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3800 /* skip pointer prefix */
3801 pStubMsg
->Buffer
+= 4;
3802 if (pStubMsg
->IgnoreEmbeddedPointers
)
3803 return pStubMsg
->MemorySize
;
3804 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3807 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3810 FIXME("not implemented for varying buffer size\n");
3812 pStubMsg
->Buffer
+= bufsize
;
3814 return pStubMsg
->MemorySize
;
3817 /***********************************************************************
3818 * NdrUserMarshalFree [RPCRT4.@]
3820 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
3821 unsigned char *pMemory
,
3822 PFORMAT_STRING pFormat
)
3824 /* unsigned flags = pFormat[1]; */
3825 unsigned index
= *(const WORD
*)&pFormat
[2];
3826 USER_MARSHAL_CB umcb
;
3828 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3829 TRACE("index=%d\n", index
);
3831 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_FREE
, pFormat
, &umcb
);
3833 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
3834 &umcb
.Flags
, pMemory
);
3837 /***********************************************************************
3838 * NdrClearOutParameters [RPCRT4.@]
3840 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
3841 PFORMAT_STRING pFormat
,
3844 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
3847 /***********************************************************************
3848 * NdrConvert [RPCRT4.@]
3850 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
3852 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
3853 /* FIXME: since this stub doesn't do any converting, the proper behavior
3854 is to raise an exception */
3857 /***********************************************************************
3858 * NdrConvert2 [RPCRT4.@]
3860 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, LONG NumberParams
)
3862 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3863 pStubMsg
, pFormat
, NumberParams
);
3864 /* FIXME: since this stub doesn't do any converting, the proper behavior
3865 is to raise an exception */
3868 #include "pshpack1.h"
3869 typedef struct _NDR_CSTRUCT_FORMAT
3872 unsigned char alignment
;
3873 unsigned short memory_size
;
3874 short offset_to_array_description
;
3875 } NDR_CSTRUCT_FORMAT
, NDR_CVSTRUCT_FORMAT
;
3876 #include "poppack.h"
3878 /***********************************************************************
3879 * NdrConformantStructMarshall [RPCRT4.@]
3881 unsigned char * WINAPI
NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3882 unsigned char *pMemory
,
3883 PFORMAT_STRING pFormat
)
3885 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3886 PFORMAT_STRING pCArrayFormat
;
3887 ULONG esize
, bufsize
;
3889 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3891 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3892 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3894 ERR("invalid format type %x\n", pCStructFormat
->type
);
3895 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3899 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3900 pCStructFormat
->offset_to_array_description
;
3901 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3903 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3904 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3907 esize
= *(const WORD
*)(pCArrayFormat
+2);
3909 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
3910 pCArrayFormat
+ 4, 0);
3912 WriteConformance(pStubMsg
);
3914 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
3916 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3918 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3919 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
3921 ERR("integer overflow of memory_size %u with bufsize %u\n",
3922 pCStructFormat
->memory_size
, bufsize
);
3923 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3925 /* copy constant sized part of struct */
3926 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3927 safe_copy_to_buffer(pStubMsg
, pMemory
, pCStructFormat
->memory_size
+ bufsize
);
3929 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3930 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3935 /***********************************************************************
3936 * NdrConformantStructUnmarshall [RPCRT4.@]
3938 unsigned char * WINAPI
NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3939 unsigned char **ppMemory
,
3940 PFORMAT_STRING pFormat
,
3941 unsigned char fMustAlloc
)
3943 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3944 PFORMAT_STRING pCArrayFormat
;
3945 ULONG esize
, bufsize
;
3946 unsigned char *saved_buffer
;
3948 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3950 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3951 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3953 ERR("invalid format type %x\n", pCStructFormat
->type
);
3954 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3957 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3958 pCStructFormat
->offset_to_array_description
;
3959 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3961 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3962 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3965 esize
= *(const WORD
*)(pCArrayFormat
+2);
3967 pCArrayFormat
= ReadConformance(pStubMsg
, pCArrayFormat
+ 4);
3969 ALIGN_POINTER(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
3971 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3973 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3974 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
3976 ERR("integer overflow of memory_size %u with bufsize %u\n",
3977 pCStructFormat
->memory_size
, bufsize
);
3978 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3983 SIZE_T size
= pCStructFormat
->memory_size
+ bufsize
;
3984 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3988 if (!pStubMsg
->IsClient
&& !*ppMemory
)
3989 /* for servers, we just point straight into the RPC buffer */
3990 *ppMemory
= pStubMsg
->Buffer
;
3993 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3994 safe_buffer_increment(pStubMsg
, pCStructFormat
->memory_size
+ bufsize
);
3995 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3996 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
3998 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
3999 if (*ppMemory
!= saved_buffer
)
4000 memcpy(*ppMemory
, saved_buffer
, pCStructFormat
->memory_size
+ bufsize
);
4005 /***********************************************************************
4006 * NdrConformantStructBufferSize [RPCRT4.@]
4008 void WINAPI
NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4009 unsigned char *pMemory
,
4010 PFORMAT_STRING pFormat
)
4012 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4013 PFORMAT_STRING pCArrayFormat
;
4016 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4018 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4019 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4021 ERR("invalid format type %x\n", pCStructFormat
->type
);
4022 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4025 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4026 pCStructFormat
->offset_to_array_description
;
4027 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4029 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4030 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4033 esize
= *(const WORD
*)(pCArrayFormat
+2);
4035 pCArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
, pCArrayFormat
+4, 0);
4036 SizeConformance(pStubMsg
);
4038 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCStructFormat
->alignment
+ 1);
4040 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4042 safe_buffer_length_increment(pStubMsg
, pCStructFormat
->memory_size
);
4043 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
4045 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4046 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4049 /***********************************************************************
4050 * NdrConformantStructMemorySize [RPCRT4.@]
4052 ULONG WINAPI
NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4053 PFORMAT_STRING pFormat
)
4059 /***********************************************************************
4060 * NdrConformantStructFree [RPCRT4.@]
4062 void WINAPI
NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
4063 unsigned char *pMemory
,
4064 PFORMAT_STRING pFormat
)
4066 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4067 PFORMAT_STRING pCArrayFormat
;
4070 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4072 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4073 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4075 ERR("invalid format type %x\n", pCStructFormat
->type
);
4076 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4080 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4081 pCStructFormat
->offset_to_array_description
;
4082 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4084 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4085 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4088 esize
= *(const WORD
*)(pCArrayFormat
+2);
4090 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4091 pCArrayFormat
+ 4, 0);
4093 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4095 /* copy constant sized part of struct */
4096 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4098 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4099 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4102 /***********************************************************************
4103 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4105 unsigned char * WINAPI
NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4106 unsigned char *pMemory
,
4107 PFORMAT_STRING pFormat
)
4109 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4110 PFORMAT_STRING pCVArrayFormat
;
4111 ULONG esize
, bufsize
;
4113 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4115 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4116 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4118 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4119 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4123 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4124 pCVStructFormat
->offset_to_array_description
;
4125 switch (*pCVArrayFormat
)
4127 case RPC_FC_CVARRAY
:
4128 esize
= *(const WORD
*)(pCVArrayFormat
+2);
4130 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4131 pCVArrayFormat
+ 4, 0);
4132 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4135 case RPC_FC_C_CSTRING
:
4136 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
4137 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
4138 esize
= sizeof(char);
4139 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4140 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4141 pCVArrayFormat
+ 2, 0);
4143 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4145 case RPC_FC_C_WSTRING
:
4146 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
4147 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
4148 esize
= sizeof(WCHAR
);
4149 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4150 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4151 pCVArrayFormat
+ 2, 0);
4153 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4156 ERR("invalid array format type %x\n", *pCVArrayFormat
);
4157 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4161 WriteConformance(pStubMsg
);
4163 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4165 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4167 /* write constant sized part */
4168 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4169 safe_copy_to_buffer(pStubMsg
, pMemory
, pCVStructFormat
->memory_size
);
4171 WriteVariance(pStubMsg
);
4173 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4175 /* write array part */
4176 safe_copy_to_buffer(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
, bufsize
);
4178 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4183 /***********************************************************************
4184 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4186 unsigned char * WINAPI
NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4187 unsigned char **ppMemory
,
4188 PFORMAT_STRING pFormat
,
4189 unsigned char fMustAlloc
)
4191 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4192 PFORMAT_STRING pCVArrayFormat
;
4193 ULONG esize
, bufsize
;
4194 unsigned char cvarray_type
;
4196 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4198 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4199 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4201 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4202 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4206 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4207 pCVStructFormat
->offset_to_array_description
;
4208 cvarray_type
= *pCVArrayFormat
;
4209 switch (cvarray_type
)
4211 case RPC_FC_CVARRAY
:
4212 esize
= *(const WORD
*)(pCVArrayFormat
+2);
4213 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 4);
4215 case RPC_FC_C_CSTRING
:
4216 esize
= sizeof(char);
4217 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4218 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
4220 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
4222 case RPC_FC_C_WSTRING
:
4223 esize
= sizeof(WCHAR
);
4224 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4225 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
4227 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
4230 ERR("invalid array format type %x\n", *pCVArrayFormat
);
4231 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4235 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4237 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4239 /* work out how much memory to allocate if we need to do so */
4240 if (!*ppMemory
|| fMustAlloc
)
4242 SIZE_T size
= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->MaxCount
);
4243 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4246 /* copy the constant data */
4247 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4248 safe_copy_from_buffer(pStubMsg
, *ppMemory
, pCVStructFormat
->memory_size
);
4250 pCVArrayFormat
= ReadVariance(pStubMsg
, pCVArrayFormat
, pStubMsg
->MaxCount
);
4252 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4254 if ((cvarray_type
== RPC_FC_C_CSTRING
) ||
4255 (cvarray_type
== RPC_FC_C_WSTRING
))
4258 /* strings must always have null terminating bytes */
4259 if (bufsize
< esize
)
4261 ERR("invalid string length of %d\n", pStubMsg
->ActualCount
);
4262 RpcRaiseException(RPC_S_INVALID_BOUND
);
4265 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
4266 if (pStubMsg
->Buffer
[i
] != 0)
4268 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
4269 i
, pStubMsg
->Buffer
[i
]);
4270 RpcRaiseException(RPC_S_INVALID_BOUND
);
4275 /* copy the array data */
4276 safe_copy_from_buffer(pStubMsg
, *ppMemory
+ pCVStructFormat
->memory_size
, bufsize
);
4278 if (cvarray_type
== RPC_FC_C_CSTRING
)
4279 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory
+ pCVStructFormat
->memory_size
)));
4280 else if (cvarray_type
== RPC_FC_C_WSTRING
)
4281 TRACE("string=%s\n", debugstr_w((WCHAR
*)(*ppMemory
+ pCVStructFormat
->memory_size
)));
4283 EmbeddedPointerUnmarshall(pStubMsg
, *ppMemory
, *ppMemory
, pFormat
, TRUE
/* FIXME */);
4288 /***********************************************************************
4289 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
4291 void WINAPI
NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4292 unsigned char *pMemory
,
4293 PFORMAT_STRING pFormat
)
4295 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4296 PFORMAT_STRING pCVArrayFormat
;
4299 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4301 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4302 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4304 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4305 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4309 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4310 pCVStructFormat
->offset_to_array_description
;
4311 switch (*pCVArrayFormat
)
4313 case RPC_FC_CVARRAY
:
4314 esize
= *(const WORD
*)(pCVArrayFormat
+2);
4316 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4317 pCVArrayFormat
+ 4, 0);
4318 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4321 case RPC_FC_C_CSTRING
:
4322 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
4323 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
4324 esize
= sizeof(char);
4325 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4326 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4327 pCVArrayFormat
+ 2, 0);
4329 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4331 case RPC_FC_C_WSTRING
:
4332 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
4333 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
4334 esize
= sizeof(WCHAR
);
4335 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4336 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4337 pCVArrayFormat
+ 2, 0);
4339 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4342 ERR("invalid array format type %x\n", *pCVArrayFormat
);
4343 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4347 SizeConformance(pStubMsg
);
4349 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCVStructFormat
->alignment
+ 1);
4351 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4353 safe_buffer_length_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4354 SizeVariance(pStubMsg
);
4355 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
4357 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4360 /***********************************************************************
4361 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4363 ULONG WINAPI
NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4364 PFORMAT_STRING pFormat
)
4366 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4367 PFORMAT_STRING pCVArrayFormat
;
4369 unsigned char cvarray_type
;
4371 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4373 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4374 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4376 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4377 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4381 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4382 pCVStructFormat
->offset_to_array_description
;
4383 cvarray_type
= *pCVArrayFormat
;
4384 switch (cvarray_type
)
4386 case RPC_FC_CVARRAY
:
4387 esize
= *(const WORD
*)(pCVArrayFormat
+2);
4388 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 4);
4390 case RPC_FC_C_CSTRING
:
4391 esize
= sizeof(char);
4392 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4393 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
4395 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
4397 case RPC_FC_C_WSTRING
:
4398 esize
= sizeof(WCHAR
);
4399 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4400 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
4402 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
4405 ERR("invalid array format type %x\n", *pCVArrayFormat
);
4406 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4410 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4412 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4414 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4415 pCVArrayFormat
= ReadVariance(pStubMsg
, pCVArrayFormat
, pStubMsg
->MaxCount
);
4416 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
4418 pStubMsg
->MemorySize
+= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->MaxCount
);
4420 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4422 return pCVStructFormat
->memory_size
+ pStubMsg
->MaxCount
* esize
;
4425 /***********************************************************************
4426 * NdrConformantVaryingStructFree [RPCRT4.@]
4428 void WINAPI
NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
4429 unsigned char *pMemory
,
4430 PFORMAT_STRING pFormat
)
4432 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4433 PFORMAT_STRING pCVArrayFormat
;
4436 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4438 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4439 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4441 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4442 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4446 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4447 pCVStructFormat
->offset_to_array_description
;
4448 switch (*pCVArrayFormat
)
4450 case RPC_FC_CVARRAY
:
4451 esize
= *(const WORD
*)(pCVArrayFormat
+2);
4453 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4454 pCVArrayFormat
+ 4, 0);
4455 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4458 case RPC_FC_C_CSTRING
:
4459 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
4460 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
4461 esize
= sizeof(char);
4462 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4463 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4464 pCVArrayFormat
+ 2, 0);
4466 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4468 case RPC_FC_C_WSTRING
:
4469 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
4470 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
4471 esize
= sizeof(WCHAR
);
4472 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4473 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4474 pCVArrayFormat
+ 2, 0);
4476 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4479 ERR("invalid array format type %x\n", *pCVArrayFormat
);
4480 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4484 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4486 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4489 #include "pshpack1.h"
4493 unsigned char alignment
;
4494 unsigned short total_size
;
4495 } NDR_SMFARRAY_FORMAT
;
4500 unsigned char alignment
;
4501 unsigned long total_size
;
4502 } NDR_LGFARRAY_FORMAT
;
4503 #include "poppack.h"
4505 /***********************************************************************
4506 * NdrFixedArrayMarshall [RPCRT4.@]
4508 unsigned char * WINAPI
NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4509 unsigned char *pMemory
,
4510 PFORMAT_STRING pFormat
)
4512 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4513 unsigned long total_size
;
4515 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4517 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4518 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4520 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4521 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4525 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4527 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4529 total_size
= pSmFArrayFormat
->total_size
;
4530 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4534 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4535 total_size
= pLgFArrayFormat
->total_size
;
4536 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4539 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4540 safe_copy_to_buffer(pStubMsg
, pMemory
, total_size
);
4542 pFormat
= EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4547 /***********************************************************************
4548 * NdrFixedArrayUnmarshall [RPCRT4.@]
4550 unsigned char * WINAPI
NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4551 unsigned char **ppMemory
,
4552 PFORMAT_STRING pFormat
,
4553 unsigned char fMustAlloc
)
4555 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4556 unsigned long total_size
;
4557 unsigned char *saved_buffer
;
4559 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4561 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4562 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4564 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4565 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4569 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4571 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4573 total_size
= pSmFArrayFormat
->total_size
;
4574 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4578 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4579 total_size
= pLgFArrayFormat
->total_size
;
4580 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4584 *ppMemory
= NdrAllocate(pStubMsg
, total_size
);
4587 if (!pStubMsg
->IsClient
&& !*ppMemory
)
4588 /* for servers, we just point straight into the RPC buffer */
4589 *ppMemory
= pStubMsg
->Buffer
;
4592 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4593 safe_buffer_increment(pStubMsg
, total_size
);
4594 pFormat
= EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4596 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
4597 if (*ppMemory
!= saved_buffer
)
4598 memcpy(*ppMemory
, saved_buffer
, total_size
);
4603 /***********************************************************************
4604 * NdrFixedArrayBufferSize [RPCRT4.@]
4606 void WINAPI
NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4607 unsigned char *pMemory
,
4608 PFORMAT_STRING pFormat
)
4610 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4611 unsigned long total_size
;
4613 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4615 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4616 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4618 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4619 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4623 ALIGN_LENGTH(pStubMsg
->BufferLength
, pSmFArrayFormat
->alignment
+ 1);
4625 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4627 total_size
= pSmFArrayFormat
->total_size
;
4628 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4632 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4633 total_size
= pLgFArrayFormat
->total_size
;
4634 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4636 safe_buffer_length_increment(pStubMsg
, total_size
);
4638 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4641 /***********************************************************************
4642 * NdrFixedArrayMemorySize [RPCRT4.@]
4644 ULONG WINAPI
NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4645 PFORMAT_STRING pFormat
)
4647 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4650 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4652 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4653 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4655 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4656 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4660 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4662 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4664 total_size
= pSmFArrayFormat
->total_size
;
4665 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4669 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4670 total_size
= pLgFArrayFormat
->total_size
;
4671 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4673 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4674 safe_buffer_increment(pStubMsg
, total_size
);
4675 pStubMsg
->MemorySize
+= total_size
;
4677 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4682 /***********************************************************************
4683 * NdrFixedArrayFree [RPCRT4.@]
4685 void WINAPI
NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4686 unsigned char *pMemory
,
4687 PFORMAT_STRING pFormat
)
4689 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4691 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4693 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4694 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4696 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4697 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4701 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4702 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4705 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4706 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4709 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4712 /***********************************************************************
4713 * NdrVaryingArrayMarshall [RPCRT4.@]
4715 unsigned char * WINAPI
NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4716 unsigned char *pMemory
,
4717 PFORMAT_STRING pFormat
)
4719 unsigned char alignment
;
4720 DWORD elements
, esize
;
4723 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4725 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4726 (pFormat
[0] != RPC_FC_LGVARRAY
))
4728 ERR("invalid format type %x\n", pFormat
[0]);
4729 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4733 alignment
= pFormat
[1] + 1;
4735 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4738 pFormat
+= sizeof(WORD
);
4739 elements
= *(const WORD
*)pFormat
;
4740 pFormat
+= sizeof(WORD
);
4745 pFormat
+= sizeof(DWORD
);
4746 elements
= *(const DWORD
*)pFormat
;
4747 pFormat
+= sizeof(DWORD
);
4750 esize
= *(const WORD
*)pFormat
;
4751 pFormat
+= sizeof(WORD
);
4753 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4754 if ((pStubMsg
->ActualCount
> elements
) ||
4755 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4757 RpcRaiseException(RPC_S_INVALID_BOUND
);
4761 WriteVariance(pStubMsg
);
4763 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
4765 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4766 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4767 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
4769 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4774 /***********************************************************************
4775 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4777 unsigned char * WINAPI
NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4778 unsigned char **ppMemory
,
4779 PFORMAT_STRING pFormat
,
4780 unsigned char fMustAlloc
)
4782 unsigned char alignment
;
4783 DWORD size
, elements
, esize
;
4785 unsigned char *saved_buffer
;
4788 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4790 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4791 (pFormat
[0] != RPC_FC_LGVARRAY
))
4793 ERR("invalid format type %x\n", pFormat
[0]);
4794 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4798 alignment
= pFormat
[1] + 1;
4800 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4803 size
= *(const WORD
*)pFormat
;
4804 pFormat
+= sizeof(WORD
);
4805 elements
= *(const WORD
*)pFormat
;
4806 pFormat
+= sizeof(WORD
);
4811 size
= *(const DWORD
*)pFormat
;
4812 pFormat
+= sizeof(DWORD
);
4813 elements
= *(const DWORD
*)pFormat
;
4814 pFormat
+= sizeof(DWORD
);
4817 esize
= *(const WORD
*)pFormat
;
4818 pFormat
+= sizeof(WORD
);
4820 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
4822 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4824 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4825 offset
= pStubMsg
->Offset
;
4827 if (!*ppMemory
|| fMustAlloc
)
4828 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4829 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4830 safe_buffer_increment(pStubMsg
, bufsize
);
4832 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4834 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
4839 /***********************************************************************
4840 * NdrVaryingArrayBufferSize [RPCRT4.@]
4842 void WINAPI
NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4843 unsigned char *pMemory
,
4844 PFORMAT_STRING pFormat
)
4846 unsigned char alignment
;
4847 DWORD elements
, esize
;
4849 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4851 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4852 (pFormat
[0] != RPC_FC_LGVARRAY
))
4854 ERR("invalid format type %x\n", pFormat
[0]);
4855 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4859 alignment
= pFormat
[1] + 1;
4861 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4864 pFormat
+= sizeof(WORD
);
4865 elements
= *(const WORD
*)pFormat
;
4866 pFormat
+= sizeof(WORD
);
4871 pFormat
+= sizeof(DWORD
);
4872 elements
= *(const DWORD
*)pFormat
;
4873 pFormat
+= sizeof(DWORD
);
4876 esize
= *(const WORD
*)pFormat
;
4877 pFormat
+= sizeof(WORD
);
4879 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4880 if ((pStubMsg
->ActualCount
> elements
) ||
4881 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4883 RpcRaiseException(RPC_S_INVALID_BOUND
);
4887 SizeVariance(pStubMsg
);
4889 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
4891 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
4893 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4896 /***********************************************************************
4897 * NdrVaryingArrayMemorySize [RPCRT4.@]
4899 ULONG WINAPI
NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4900 PFORMAT_STRING pFormat
)
4902 unsigned char alignment
;
4903 DWORD size
, elements
, esize
;
4905 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4907 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4908 (pFormat
[0] != RPC_FC_LGVARRAY
))
4910 ERR("invalid format type %x\n", pFormat
[0]);
4911 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4915 alignment
= pFormat
[1] + 1;
4917 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4920 size
= *(const WORD
*)pFormat
;
4921 pFormat
+= sizeof(WORD
);
4922 elements
= *(const WORD
*)pFormat
;
4923 pFormat
+= sizeof(WORD
);
4928 size
= *(const DWORD
*)pFormat
;
4929 pFormat
+= sizeof(DWORD
);
4930 elements
= *(const DWORD
*)pFormat
;
4931 pFormat
+= sizeof(DWORD
);
4934 esize
= *(const WORD
*)pFormat
;
4935 pFormat
+= sizeof(WORD
);
4937 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
4939 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4941 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
4942 pStubMsg
->MemorySize
+= size
;
4944 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4946 return pStubMsg
->MemorySize
;
4949 /***********************************************************************
4950 * NdrVaryingArrayFree [RPCRT4.@]
4952 void WINAPI
NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4953 unsigned char *pMemory
,
4954 PFORMAT_STRING pFormat
)
4956 unsigned char alignment
;
4959 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4961 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4962 (pFormat
[0] != RPC_FC_LGVARRAY
))
4964 ERR("invalid format type %x\n", pFormat
[0]);
4965 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4969 alignment
= pFormat
[1] + 1;
4971 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4974 pFormat
+= sizeof(WORD
);
4975 elements
= *(const WORD
*)pFormat
;
4976 pFormat
+= sizeof(WORD
);
4981 pFormat
+= sizeof(DWORD
);
4982 elements
= *(const DWORD
*)pFormat
;
4983 pFormat
+= sizeof(DWORD
);
4986 pFormat
+= sizeof(WORD
);
4988 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4989 if ((pStubMsg
->ActualCount
> elements
) ||
4990 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4992 RpcRaiseException(RPC_S_INVALID_BOUND
);
4996 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4999 static ULONG
get_discriminant(unsigned char fc
, const unsigned char *pMemory
)
5012 return *(const USHORT
*)pMemory
;
5016 return *(const ULONG
*)pMemory
;
5018 FIXME("Unhandled base type: 0x%02x\n", fc
);
5023 static PFORMAT_STRING
get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg
,
5024 unsigned long discriminant
,
5025 PFORMAT_STRING pFormat
)
5027 unsigned short num_arms
, arm
, type
;
5029 num_arms
= *(const SHORT
*)pFormat
& 0x0fff;
5031 for(arm
= 0; arm
< num_arms
; arm
++)
5033 if(discriminant
== *(const ULONG
*)pFormat
)
5041 type
= *(const unsigned short*)pFormat
;
5042 TRACE("type %04x\n", type
);
5043 if(arm
== num_arms
) /* default arm extras */
5047 ERR("no arm for 0x%lx and no default case\n", discriminant
);
5048 RpcRaiseException(RPC_S_INVALID_TAG
);
5053 TRACE("falling back to empty default case for 0x%lx\n", discriminant
);
5060 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
, ULONG discriminant
, PFORMAT_STRING pFormat
)
5062 unsigned short type
;
5066 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5070 type
= *(const unsigned short*)pFormat
;
5071 if((type
& 0xff00) == 0x8000)
5073 unsigned char basetype
= LOBYTE(type
);
5074 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &basetype
);
5078 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5079 NDR_MARSHALL m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
5082 unsigned char *saved_buffer
= NULL
;
5083 int pointer_buffer_mark_set
= 0;
5090 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
5091 saved_buffer
= pStubMsg
->Buffer
;
5092 if (pStubMsg
->PointerBufferMark
)
5094 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5095 pStubMsg
->PointerBufferMark
= NULL
;
5096 pointer_buffer_mark_set
= 1;
5099 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
5101 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char **)pMemory
, desc
);
5102 if (pointer_buffer_mark_set
)
5104 STD_OVERFLOW_CHECK(pStubMsg
);
5105 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5106 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5108 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5109 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
5110 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5112 pStubMsg
->Buffer
= saved_buffer
+ 4;
5116 m(pStubMsg
, pMemory
, desc
);
5119 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5124 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5125 unsigned char **ppMemory
,
5127 PFORMAT_STRING pFormat
,
5128 unsigned char fMustAlloc
)
5130 unsigned short type
;
5134 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5138 type
= *(const unsigned short*)pFormat
;
5139 if((type
& 0xff00) == 0x8000)
5141 unsigned char basetype
= LOBYTE(type
);
5142 return NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &basetype
, FALSE
);
5146 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5147 NDR_UNMARSHALL m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
5150 unsigned char *saved_buffer
= NULL
;
5151 int pointer_buffer_mark_set
= 0;
5158 **(void***)ppMemory
= NULL
;
5159 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5160 saved_buffer
= pStubMsg
->Buffer
;
5161 if (pStubMsg
->PointerBufferMark
)
5163 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5164 pStubMsg
->PointerBufferMark
= NULL
;
5165 pointer_buffer_mark_set
= 1;
5168 pStubMsg
->Buffer
+= 4; /* for pointer ID */
5170 if (saved_buffer
+ 4 > pStubMsg
->BufferEnd
)
5172 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5173 saved_buffer
, pStubMsg
->BufferEnd
);
5174 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5177 PointerUnmarshall(pStubMsg
, saved_buffer
, *(unsigned char ***)ppMemory
, **(unsigned char ***)ppMemory
, desc
, fMustAlloc
);
5178 if (pointer_buffer_mark_set
)
5180 STD_OVERFLOW_CHECK(pStubMsg
);
5181 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5182 pStubMsg
->Buffer
= saved_buffer
+ 4;
5186 m(pStubMsg
, ppMemory
, desc
, fMustAlloc
);
5189 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5194 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg
,
5195 unsigned char *pMemory
,
5197 PFORMAT_STRING pFormat
)
5199 unsigned short type
;
5203 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5207 type
= *(const unsigned short*)pFormat
;
5208 if((type
& 0xff00) == 0x8000)
5210 unsigned char basetype
= LOBYTE(type
);
5211 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &basetype
);
5215 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5216 NDR_BUFFERSIZE m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
5225 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
5226 safe_buffer_length_increment(pStubMsg
, 4); /* for pointer ID */
5227 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5229 int saved_buffer_length
= pStubMsg
->BufferLength
;
5230 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
5231 pStubMsg
->PointerLength
= 0;
5232 if(!pStubMsg
->BufferLength
)
5233 ERR("BufferLength == 0??\n");
5234 PointerBufferSize(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5235 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
5236 pStubMsg
->BufferLength
= saved_buffer_length
;
5240 m(pStubMsg
, pMemory
, desc
);
5243 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
5247 static ULONG
union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg
,
5249 PFORMAT_STRING pFormat
)
5251 unsigned short type
, size
;
5253 size
= *(const unsigned short*)pFormat
;
5254 pStubMsg
->Memory
+= size
;
5257 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5261 type
= *(const unsigned short*)pFormat
;
5262 if((type
& 0xff00) == 0x8000)
5264 return NdrBaseTypeMemorySize(pStubMsg
, pFormat
);
5268 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5269 NDR_MEMORYSIZE m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
5270 unsigned char *saved_buffer
;
5279 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5280 saved_buffer
= pStubMsg
->Buffer
;
5281 safe_buffer_increment(pStubMsg
, 4);
5282 ALIGN_LENGTH(pStubMsg
->MemorySize
, 4);
5283 pStubMsg
->MemorySize
+= 4;
5284 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5285 PointerMemorySize(pStubMsg
, saved_buffer
, pFormat
);
5288 return m(pStubMsg
, desc
);
5291 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5294 TRACE("size %d\n", size
);
5298 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg
,
5299 unsigned char *pMemory
,
5301 PFORMAT_STRING pFormat
)
5303 unsigned short type
;
5307 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5311 type
= *(const unsigned short*)pFormat
;
5312 if((type
& 0xff00) != 0x8000)
5314 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5315 NDR_FREE m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
5324 PointerFree(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5327 m(pStubMsg
, pMemory
, desc
);
5333 /***********************************************************************
5334 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5336 unsigned char * WINAPI
NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5337 unsigned char *pMemory
,
5338 PFORMAT_STRING pFormat
)
5340 unsigned char switch_type
;
5341 unsigned char increment
;
5344 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5347 switch_type
= *pFormat
& 0xf;
5348 increment
= (*pFormat
& 0xf0) >> 4;
5351 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, increment
);
5353 switch_value
= get_discriminant(switch_type
, pMemory
);
5354 TRACE("got switch value 0x%x\n", switch_value
);
5356 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &switch_type
);
5357 pMemory
+= increment
;
5359 return union_arm_marshall(pStubMsg
, pMemory
, switch_value
, pFormat
);
5362 /***********************************************************************
5363 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5365 unsigned char * WINAPI
NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5366 unsigned char **ppMemory
,
5367 PFORMAT_STRING pFormat
,
5368 unsigned char fMustAlloc
)
5370 unsigned char switch_type
;
5371 unsigned char increment
;
5373 unsigned short size
;
5374 unsigned char *pMemoryArm
;
5376 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5379 switch_type
= *pFormat
& 0xf;
5380 increment
= (*pFormat
& 0xf0) >> 4;
5383 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
5384 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
5385 TRACE("got switch value 0x%x\n", switch_value
);
5387 size
= *(const unsigned short*)pFormat
+ increment
;
5388 if(!*ppMemory
|| fMustAlloc
)
5389 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5391 NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &switch_type
, FALSE
);
5392 pMemoryArm
= *ppMemory
+ increment
;
5394 return union_arm_unmarshall(pStubMsg
, &pMemoryArm
, switch_value
, pFormat
, fMustAlloc
);
5397 /***********************************************************************
5398 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5400 void WINAPI
NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5401 unsigned char *pMemory
,
5402 PFORMAT_STRING pFormat
)
5404 unsigned char switch_type
;
5405 unsigned char increment
;
5408 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5411 switch_type
= *pFormat
& 0xf;
5412 increment
= (*pFormat
& 0xf0) >> 4;
5415 ALIGN_LENGTH(pStubMsg
->BufferLength
, increment
);
5416 switch_value
= get_discriminant(switch_type
, pMemory
);
5417 TRACE("got switch value 0x%x\n", switch_value
);
5419 /* Add discriminant size */
5420 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&switch_value
, &switch_type
);
5421 pMemory
+= increment
;
5423 union_arm_buffer_size(pStubMsg
, pMemory
, switch_value
, pFormat
);
5426 /***********************************************************************
5427 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5429 ULONG WINAPI
NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5430 PFORMAT_STRING pFormat
)
5432 unsigned char switch_type
;
5433 unsigned char increment
;
5436 switch_type
= *pFormat
& 0xf;
5437 increment
= (*pFormat
& 0xf0) >> 4;
5440 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
5441 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
5442 TRACE("got switch value 0x%x\n", switch_value
);
5444 pStubMsg
->Memory
+= increment
;
5446 return increment
+ union_arm_memory_size(pStubMsg
, switch_value
, pFormat
+ *(const SHORT
*)pFormat
);
5449 /***********************************************************************
5450 * NdrEncapsulatedUnionFree [RPCRT4.@]
5452 void WINAPI
NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
5453 unsigned char *pMemory
,
5454 PFORMAT_STRING pFormat
)
5456 unsigned char switch_type
;
5457 unsigned char increment
;
5460 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5463 switch_type
= *pFormat
& 0xf;
5464 increment
= (*pFormat
& 0xf0) >> 4;
5467 switch_value
= get_discriminant(switch_type
, pMemory
);
5468 TRACE("got switch value 0x%x\n", switch_value
);
5470 pMemory
+= increment
;
5472 return union_arm_free(pStubMsg
, pMemory
, switch_value
, pFormat
);
5475 /***********************************************************************
5476 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5478 unsigned char * WINAPI
NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5479 unsigned char *pMemory
,
5480 PFORMAT_STRING pFormat
)
5482 unsigned char switch_type
;
5484 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5487 switch_type
= *pFormat
;
5490 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5491 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5492 /* Marshall discriminant */
5493 NdrBaseTypeMarshall(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
5495 return union_arm_marshall(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5498 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg
,
5499 PFORMAT_STRING
*ppFormat
)
5501 long discriminant
= 0;
5511 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5520 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5521 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5529 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
5530 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5535 FIXME("Unhandled base type: 0x%02x\n", **ppFormat
);
5539 if (pStubMsg
->fHasNewCorrDesc
)
5543 return discriminant
;
5546 /**********************************************************************
5547 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5549 unsigned char * WINAPI
NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5550 unsigned char **ppMemory
,
5551 PFORMAT_STRING pFormat
,
5552 unsigned char fMustAlloc
)
5555 unsigned short size
;
5557 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5560 /* Unmarshall discriminant */
5561 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
5562 TRACE("unmarshalled discriminant %lx\n", discriminant
);
5564 pFormat
+= *(const SHORT
*)pFormat
;
5566 size
= *(const unsigned short*)pFormat
;
5568 if(!*ppMemory
|| fMustAlloc
)
5569 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5571 return union_arm_unmarshall(pStubMsg
, ppMemory
, discriminant
, pFormat
, fMustAlloc
);
5574 /***********************************************************************
5575 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5577 void WINAPI
NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5578 unsigned char *pMemory
,
5579 PFORMAT_STRING pFormat
)
5581 unsigned char switch_type
;
5583 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5586 switch_type
= *pFormat
;
5589 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5590 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5591 /* Add discriminant size */
5592 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
5594 union_arm_buffer_size(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5597 /***********************************************************************
5598 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5600 ULONG WINAPI
NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5601 PFORMAT_STRING pFormat
)
5606 /* Unmarshall discriminant */
5607 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
5608 TRACE("unmarshalled discriminant 0x%x\n", discriminant
);
5610 return union_arm_memory_size(pStubMsg
, discriminant
, pFormat
+ *(const SHORT
*)pFormat
);
5613 /***********************************************************************
5614 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5616 void WINAPI
NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
5617 unsigned char *pMemory
,
5618 PFORMAT_STRING pFormat
)
5620 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5624 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5625 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5627 return union_arm_free(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5630 /***********************************************************************
5631 * NdrByteCountPointerMarshall [RPCRT4.@]
5633 unsigned char * WINAPI
NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5634 unsigned char *pMemory
,
5635 PFORMAT_STRING pFormat
)
5641 /***********************************************************************
5642 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5644 unsigned char * WINAPI
NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5645 unsigned char **ppMemory
,
5646 PFORMAT_STRING pFormat
,
5647 unsigned char fMustAlloc
)
5653 /***********************************************************************
5654 * NdrByteCountPointerBufferSize [RPCRT4.@]
5656 void WINAPI
NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5657 unsigned char *pMemory
,
5658 PFORMAT_STRING pFormat
)
5663 /***********************************************************************
5664 * NdrByteCountPointerMemorySize [RPCRT4.@]
5666 ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5667 PFORMAT_STRING pFormat
)
5673 /***********************************************************************
5674 * NdrByteCountPointerFree [RPCRT4.@]
5676 void WINAPI
NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
5677 unsigned char *pMemory
,
5678 PFORMAT_STRING pFormat
)
5683 /***********************************************************************
5684 * NdrXmitOrRepAsMarshall [RPCRT4.@]
5686 unsigned char * WINAPI
NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5687 unsigned char *pMemory
,
5688 PFORMAT_STRING pFormat
)
5694 /***********************************************************************
5695 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
5697 unsigned char * WINAPI
NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5698 unsigned char **ppMemory
,
5699 PFORMAT_STRING pFormat
,
5700 unsigned char fMustAlloc
)
5706 /***********************************************************************
5707 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
5709 void WINAPI
NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5710 unsigned char *pMemory
,
5711 PFORMAT_STRING pFormat
)
5716 /***********************************************************************
5717 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
5719 ULONG WINAPI
NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5720 PFORMAT_STRING pFormat
)
5726 /***********************************************************************
5727 * NdrXmitOrRepAsFree [RPCRT4.@]
5729 void WINAPI
NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg
,
5730 unsigned char *pMemory
,
5731 PFORMAT_STRING pFormat
)
5736 #include "pshpack1.h"
5740 unsigned char flags_type
; /* flags in upper nibble, type in lower nibble */
5744 #include "poppack.h"
5746 /***********************************************************************
5747 * NdrRangeMarshall [internal]
5749 unsigned char *WINAPI
NdrRangeMarshall(
5750 PMIDL_STUB_MESSAGE pStubMsg
,
5751 unsigned char *pMemory
,
5752 PFORMAT_STRING pFormat
)
5754 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5755 unsigned char base_type
;
5757 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5759 if (pRange
->type
!= RPC_FC_RANGE
)
5761 ERR("invalid format type %x\n", pRange
->type
);
5762 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5766 base_type
= pRange
->flags_type
& 0xf;
5768 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &base_type
);
5771 /***********************************************************************
5772 * NdrRangeUnmarshall
5774 unsigned char *WINAPI
NdrRangeUnmarshall(
5775 PMIDL_STUB_MESSAGE pStubMsg
,
5776 unsigned char **ppMemory
,
5777 PFORMAT_STRING pFormat
,
5778 unsigned char fMustAlloc
)
5780 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5781 unsigned char base_type
;
5783 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
5785 if (pRange
->type
!= RPC_FC_RANGE
)
5787 ERR("invalid format type %x\n", pRange
->type
);
5788 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5791 base_type
= pRange
->flags_type
& 0xf;
5793 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5794 base_type
, pRange
->low_value
, pRange
->high_value
);
5796 #define RANGE_UNMARSHALL(type, format_spec) \
5799 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5800 if (fMustAlloc || !*ppMemory) \
5801 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5802 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
5804 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
5805 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
5806 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
5808 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5809 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5811 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5812 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5813 (type)pRange->high_value); \
5814 RpcRaiseException(RPC_S_INVALID_BOUND); \
5817 TRACE("*ppMemory: %p\n", *ppMemory); \
5818 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5819 pStubMsg->Buffer += sizeof(type); \
5826 RANGE_UNMARSHALL(UCHAR
, "%d");
5827 TRACE("value: 0x%02x\n", **ppMemory
);
5831 RANGE_UNMARSHALL(CHAR
, "%u");
5832 TRACE("value: 0x%02x\n", **ppMemory
);
5834 case RPC_FC_WCHAR
: /* FIXME: valid? */
5836 RANGE_UNMARSHALL(USHORT
, "%u");
5837 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5840 RANGE_UNMARSHALL(SHORT
, "%d");
5841 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5844 RANGE_UNMARSHALL(LONG
, "%d");
5845 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5848 RANGE_UNMARSHALL(ULONG
, "%u");
5849 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5853 FIXME("Unhandled enum type\n");
5855 case RPC_FC_ERROR_STATUS_T
: /* FIXME: valid? */
5860 ERR("invalid range base type: 0x%02x\n", base_type
);
5861 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5867 /***********************************************************************
5868 * NdrRangeBufferSize [internal]
5870 void WINAPI
NdrRangeBufferSize(
5871 PMIDL_STUB_MESSAGE pStubMsg
,
5872 unsigned char *pMemory
,
5873 PFORMAT_STRING pFormat
)
5875 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5876 unsigned char base_type
;
5878 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5880 if (pRange
->type
!= RPC_FC_RANGE
)
5882 ERR("invalid format type %x\n", pRange
->type
);
5883 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5885 base_type
= pRange
->flags_type
& 0xf;
5887 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &base_type
);
5890 /***********************************************************************
5891 * NdrRangeMemorySize [internal]
5893 ULONG WINAPI
NdrRangeMemorySize(
5894 PMIDL_STUB_MESSAGE pStubMsg
,
5895 PFORMAT_STRING pFormat
)
5897 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5898 unsigned char base_type
;
5900 if (pRange
->type
!= RPC_FC_RANGE
)
5902 ERR("invalid format type %x\n", pRange
->type
);
5903 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5906 base_type
= pRange
->flags_type
& 0xf;
5908 return NdrBaseTypeMemorySize(pStubMsg
, &base_type
);
5911 /***********************************************************************
5912 * NdrRangeFree [internal]
5914 void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg
,
5915 unsigned char *pMemory
,
5916 PFORMAT_STRING pFormat
)
5918 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5923 /***********************************************************************
5924 * NdrBaseTypeMarshall [internal]
5926 static unsigned char *WINAPI
NdrBaseTypeMarshall(
5927 PMIDL_STUB_MESSAGE pStubMsg
,
5928 unsigned char *pMemory
,
5929 PFORMAT_STRING pFormat
)
5931 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5939 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(UCHAR
));
5940 TRACE("value: 0x%02x\n", *pMemory
);
5945 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(USHORT
));
5946 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(USHORT
));
5947 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
5951 case RPC_FC_ERROR_STATUS_T
:
5953 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(ULONG
));
5954 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONG
));
5955 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
5958 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(float));
5959 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
5962 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(double));
5963 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
5966 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(ULONGLONG
));
5967 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONGLONG
));
5968 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
5971 /* only 16-bits on the wire, so do a sanity check */
5972 if (*(UINT
*)pMemory
> SHRT_MAX
)
5973 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
5974 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(USHORT
));
5975 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5976 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5977 *(USHORT
*)pStubMsg
->Buffer
= *(UINT
*)pMemory
;
5978 pStubMsg
->Buffer
+= sizeof(USHORT
);
5979 TRACE("value: 0x%04x\n", *(UINT
*)pMemory
);
5984 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5987 /* FIXME: what is the correct return value? */
5991 /***********************************************************************
5992 * NdrBaseTypeUnmarshall [internal]
5994 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(
5995 PMIDL_STUB_MESSAGE pStubMsg
,
5996 unsigned char **ppMemory
,
5997 PFORMAT_STRING pFormat
,
5998 unsigned char fMustAlloc
)
6000 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6002 #define BASE_TYPE_UNMARSHALL(type) \
6003 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6004 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6006 *ppMemory = pStubMsg->Buffer; \
6007 TRACE("*ppMemory: %p\n", *ppMemory); \
6012 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6013 TRACE("*ppMemory: %p\n", *ppMemory); \
6014 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
6016 pStubMsg->Buffer += sizeof(type);
6024 BASE_TYPE_UNMARSHALL(UCHAR
);
6025 TRACE("value: 0x%02x\n", **ppMemory
);
6030 BASE_TYPE_UNMARSHALL(USHORT
);
6031 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6035 case RPC_FC_ERROR_STATUS_T
:
6037 BASE_TYPE_UNMARSHALL(ULONG
);
6038 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6041 BASE_TYPE_UNMARSHALL(float);
6042 TRACE("value: %f\n", **(float **)ppMemory
);
6045 BASE_TYPE_UNMARSHALL(double);
6046 TRACE("value: %f\n", **(double **)ppMemory
);
6049 BASE_TYPE_UNMARSHALL(ULONGLONG
);
6050 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG
**)ppMemory
));
6053 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
6054 if (fMustAlloc
|| !*ppMemory
)
6055 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT
));
6056 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > pStubMsg
->BufferEnd
)
6057 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6058 TRACE("*ppMemory: %p\n", *ppMemory
);
6059 /* 16-bits on the wire, but int in memory */
6060 **(UINT
**)ppMemory
= *(USHORT
*)pStubMsg
->Buffer
;
6061 pStubMsg
->Buffer
+= sizeof(USHORT
);
6062 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
6067 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6069 #undef BASE_TYPE_UNMARSHALL
6071 /* FIXME: what is the correct return value? */
6076 /***********************************************************************
6077 * NdrBaseTypeBufferSize [internal]
6079 static void WINAPI
NdrBaseTypeBufferSize(
6080 PMIDL_STUB_MESSAGE pStubMsg
,
6081 unsigned char *pMemory
,
6082 PFORMAT_STRING pFormat
)
6084 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6092 safe_buffer_length_increment(pStubMsg
, sizeof(UCHAR
));
6098 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(USHORT
));
6099 safe_buffer_length_increment(pStubMsg
, sizeof(USHORT
));
6104 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONG
));
6105 safe_buffer_length_increment(pStubMsg
, sizeof(ULONG
));
6108 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(float));
6109 safe_buffer_length_increment(pStubMsg
, sizeof(float));
6112 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(double));
6113 safe_buffer_length_increment(pStubMsg
, sizeof(double));
6116 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONGLONG
));
6117 safe_buffer_length_increment(pStubMsg
, sizeof(ULONGLONG
));
6119 case RPC_FC_ERROR_STATUS_T
:
6120 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(error_status_t
));
6121 safe_buffer_length_increment(pStubMsg
, sizeof(error_status_t
));
6126 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6130 /***********************************************************************
6131 * NdrBaseTypeMemorySize [internal]
6133 static ULONG WINAPI
NdrBaseTypeMemorySize(
6134 PMIDL_STUB_MESSAGE pStubMsg
,
6135 PFORMAT_STRING pFormat
)
6137 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg
, *pFormat
);
6145 safe_buffer_increment(pStubMsg
, sizeof(UCHAR
));
6146 pStubMsg
->MemorySize
+= sizeof(UCHAR
);
6147 return sizeof(UCHAR
);
6151 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6152 pStubMsg
->MemorySize
+= sizeof(USHORT
);
6153 return sizeof(USHORT
);
6157 safe_buffer_increment(pStubMsg
, sizeof(ULONG
));
6158 pStubMsg
->MemorySize
+= sizeof(ULONG
);
6159 return sizeof(ULONG
);
6161 safe_buffer_increment(pStubMsg
, sizeof(float));
6162 pStubMsg
->MemorySize
+= sizeof(float);
6163 return sizeof(float);
6165 safe_buffer_increment(pStubMsg
, sizeof(double));
6166 pStubMsg
->MemorySize
+= sizeof(double);
6167 return sizeof(double);
6169 safe_buffer_increment(pStubMsg
, sizeof(ULONGLONG
));
6170 pStubMsg
->MemorySize
+= sizeof(ULONGLONG
);
6171 return sizeof(ULONGLONG
);
6172 case RPC_FC_ERROR_STATUS_T
:
6173 safe_buffer_increment(pStubMsg
, sizeof(error_status_t
));
6174 pStubMsg
->MemorySize
+= sizeof(error_status_t
);
6175 return sizeof(error_status_t
);
6177 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6178 pStubMsg
->MemorySize
+= sizeof(UINT
);
6179 return sizeof(UINT
);
6181 pStubMsg
->MemorySize
+= sizeof(void *);
6182 return sizeof(void *);
6184 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6189 /***********************************************************************
6190 * NdrBaseTypeFree [internal]
6192 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6193 unsigned char *pMemory
,
6194 PFORMAT_STRING pFormat
)
6196 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6201 /***********************************************************************
6202 * NdrContextHandleBufferSize [internal]
6204 static void WINAPI
NdrContextHandleBufferSize(
6205 PMIDL_STUB_MESSAGE pStubMsg
,
6206 unsigned char *pMemory
,
6207 PFORMAT_STRING pFormat
)
6209 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6211 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6213 ERR("invalid format type %x\n", *pFormat
);
6214 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6216 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
6217 safe_buffer_length_increment(pStubMsg
, cbNDRContext
);
6220 /***********************************************************************
6221 * NdrContextHandleMarshall [internal]
6223 static unsigned char *WINAPI
NdrContextHandleMarshall(
6224 PMIDL_STUB_MESSAGE pStubMsg
,
6225 unsigned char *pMemory
,
6226 PFORMAT_STRING pFormat
)
6228 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6230 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6232 ERR("invalid format type %x\n", *pFormat
);
6233 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6235 TRACE("flags: 0x%02x\n", pFormat
[1]);
6237 if (pFormat
[1] & 0x80)
6238 NdrClientContextMarshall(pStubMsg
, *(NDR_CCONTEXT
**)pMemory
, FALSE
);
6240 NdrClientContextMarshall(pStubMsg
, (NDR_CCONTEXT
*)pMemory
, FALSE
);
6245 /***********************************************************************
6246 * NdrContextHandleUnmarshall [internal]
6248 static unsigned char *WINAPI
NdrContextHandleUnmarshall(
6249 PMIDL_STUB_MESSAGE pStubMsg
,
6250 unsigned char **ppMemory
,
6251 PFORMAT_STRING pFormat
,
6252 unsigned char fMustAlloc
)
6254 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg
,
6255 ppMemory
, pFormat
, fMustAlloc
? "TRUE": "FALSE");
6257 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6259 ERR("invalid format type %x\n", *pFormat
);
6260 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6262 TRACE("flags: 0x%02x\n", pFormat
[1]);
6264 /* [out]-only or [ret] param */
6265 if ((pFormat
[1] & 0x60) == 0x20)
6266 **(NDR_CCONTEXT
**)ppMemory
= NULL
;
6267 NdrClientContextUnmarshall(pStubMsg
, *(NDR_CCONTEXT
**)ppMemory
, pStubMsg
->RpcMsg
->Handle
);
6272 /***********************************************************************
6273 * NdrClientContextMarshall [RPCRT4.@]
6275 void WINAPI
NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6276 NDR_CCONTEXT ContextHandle
,
6279 TRACE("(%p, %p, %d)\n", pStubMsg
, ContextHandle
, fCheck
);
6281 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
6283 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6285 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6286 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6287 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6290 /* FIXME: what does fCheck do? */
6291 NDRCContextMarshall(ContextHandle
,
6294 pStubMsg
->Buffer
+= cbNDRContext
;
6297 /***********************************************************************
6298 * NdrClientContextUnmarshall [RPCRT4.@]
6300 void WINAPI
NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6301 NDR_CCONTEXT
* pContextHandle
,
6302 RPC_BINDING_HANDLE BindHandle
)
6304 TRACE("(%p, %p, %p)\n", pStubMsg
, pContextHandle
, BindHandle
);
6306 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6308 if (pStubMsg
->Buffer
+ cbNDRContext
> pStubMsg
->BufferEnd
)
6309 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6311 NDRCContextUnmarshall(pContextHandle
,
6314 pStubMsg
->RpcMsg
->DataRepresentation
);
6316 pStubMsg
->Buffer
+= cbNDRContext
;
6319 void WINAPI
NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6320 NDR_SCONTEXT ContextHandle
,
6321 NDR_RUNDOWN RundownRoutine
)
6323 TRACE("(%p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
);
6325 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6327 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6329 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6330 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6331 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6334 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
6335 pStubMsg
->Buffer
, RundownRoutine
, NULL
,
6336 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
6337 pStubMsg
->Buffer
+= cbNDRContext
;
6340 NDR_SCONTEXT WINAPI
NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
)
6342 NDR_SCONTEXT ContextHandle
;
6344 TRACE("(%p)\n", pStubMsg
);
6346 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6348 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6350 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6351 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6352 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6355 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
6357 pStubMsg
->RpcMsg
->DataRepresentation
,
6358 NULL
, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
6359 pStubMsg
->Buffer
+= cbNDRContext
;
6361 return ContextHandle
;
6364 void WINAPI
NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg
,
6365 unsigned char* pMemory
,
6366 PFORMAT_STRING pFormat
)
6368 FIXME("(%p, %p, %p): stub\n", pStubMsg
, pMemory
, pFormat
);
6371 NDR_SCONTEXT WINAPI
NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg
,
6372 PFORMAT_STRING pFormat
)
6374 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6375 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6377 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
6379 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
6380 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
6381 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
6382 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
6383 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
6385 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
6386 if_id
= &sif
->InterfaceId
;
6389 return NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
, NULL
,
6390 pStubMsg
->RpcMsg
->DataRepresentation
, if_id
,
6394 void WINAPI
NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6395 NDR_SCONTEXT ContextHandle
,
6396 NDR_RUNDOWN RundownRoutine
,
6397 PFORMAT_STRING pFormat
)
6399 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6400 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6402 TRACE("(%p, %p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
, pFormat
);
6404 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6406 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6408 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6409 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6410 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6413 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
6414 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
6415 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
6416 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
6417 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
6419 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
6420 if_id
= &sif
->InterfaceId
;
6423 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
6424 pStubMsg
->Buffer
, RundownRoutine
, if_id
, flags
);
6425 pStubMsg
->Buffer
+= cbNDRContext
;
6428 NDR_SCONTEXT WINAPI
NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6429 PFORMAT_STRING pFormat
)
6431 NDR_SCONTEXT ContextHandle
;
6432 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6433 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6435 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
6437 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6439 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6441 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6442 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6443 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6446 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
6447 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
6448 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
6449 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
6450 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
6452 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
6453 if_id
= &sif
->InterfaceId
;
6456 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
6458 pStubMsg
->RpcMsg
->DataRepresentation
,
6460 pStubMsg
->Buffer
+= cbNDRContext
;
6462 return ContextHandle
;
6465 /***********************************************************************
6466 * NdrCorrelationInitialize [RPCRT4.@]
6468 * Initializes correlation validity checking.
6471 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6472 * pMemory [I] Pointer to memory to use as a cache.
6473 * CacheSize [I] Size of the memory pointed to by pMemory.
6474 * Flags [I] Reserved. Set to zero.
6479 void WINAPI
NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg
, void *pMemory
, ULONG CacheSize
, ULONG Flags
)
6481 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg
, pMemory
, CacheSize
, Flags
);
6482 pStubMsg
->fHasNewCorrDesc
= TRUE
;
6485 /***********************************************************************
6486 * NdrCorrelationPass [RPCRT4.@]
6488 * Performs correlation validity checking.
6491 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6496 void WINAPI
NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg
)
6498 FIXME("(%p): stub\n", pStubMsg
);
6501 /***********************************************************************
6502 * NdrCorrelationFree [RPCRT4.@]
6504 * Frees any resources used while unmarshalling parameters that need
6505 * correlation validity checking.
6508 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6513 void WINAPI
NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg
)
6515 FIXME("(%p): stub\n", pStubMsg
);