4 * Copyright 2002 Greg Turner
5 * Copyright 2003-2006 CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 * - Byte count pointers
24 * - transmit_as/represent as
25 * - Multi-dimensional arrays
26 * - Conversion functions (NdrConvert)
27 * - Checks for integer addition overflow in user marshall functions
43 #include "wine/unicode.h"
44 #include "wine/rpcfc.h"
46 #include "wine/debug.h"
48 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
51 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
52 (*((UINT32 *)(pchar)) = (uint32))
54 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
55 (*((UINT32 *)(pchar)))
57 /* these would work for i386 too, but less efficient */
58 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
59 (*(pchar) = LOBYTE(LOWORD(uint32)), \
60 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
61 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
62 *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
63 (uint32)) /* allow as r-value */
65 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
67 MAKEWORD(*(pchar), *((pchar)+1)), \
68 MAKEWORD(*((pchar)+2), *((pchar)+3))))
71 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
72 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
73 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
74 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
75 *(pchar) = HIBYTE(HIWORD(uint32)), \
76 (uint32)) /* allow as r-value */
78 #define BIG_ENDIAN_UINT32_READ(pchar) \
80 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
81 MAKEWORD(*((pchar)+1), *(pchar))))
83 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
84 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
85 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
86 # define NDR_LOCAL_UINT32_READ(pchar) \
87 BIG_ENDIAN_UINT32_READ(pchar)
89 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
90 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
91 # define NDR_LOCAL_UINT32_READ(pchar) \
92 LITTLE_ENDIAN_UINT32_READ(pchar)
95 /* _Align must be the desired alignment,
96 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
97 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
98 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
99 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
100 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
101 #define ALIGN_POINTER_CLEAR(_Ptr, _Align) \
103 memset((_Ptr), 0, ((_Align) - (ULONG_PTR)(_Ptr)) & ((_Align) - 1)); \
104 ALIGN_POINTER(_Ptr, _Align); \
107 #define STD_OVERFLOW_CHECK(_Msg) do { \
108 TRACE("buffer=%d/%d\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
109 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
110 ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
113 #define NDR_TABLE_SIZE 128
114 #define NDR_TABLE_MASK 127
116 static unsigned char *WINAPI
NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
117 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
118 static void WINAPI
NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
119 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
120 static ULONG WINAPI
NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
122 static unsigned char *WINAPI
NdrContextHandleMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
123 static void WINAPI
NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
124 static unsigned char *WINAPI
NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
126 const NDR_MARSHALL NdrMarshaller
[NDR_TABLE_SIZE
] = {
128 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
129 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
130 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
131 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
135 NdrPointerMarshall
, NdrPointerMarshall
,
136 NdrPointerMarshall
, NdrPointerMarshall
,
138 NdrSimpleStructMarshall
, NdrSimpleStructMarshall
,
139 NdrConformantStructMarshall
, NdrConformantStructMarshall
,
140 NdrConformantVaryingStructMarshall
,
141 NdrComplexStructMarshall
,
143 NdrConformantArrayMarshall
,
144 NdrConformantVaryingArrayMarshall
,
145 NdrFixedArrayMarshall
, NdrFixedArrayMarshall
,
146 NdrVaryingArrayMarshall
, NdrVaryingArrayMarshall
,
147 NdrComplexArrayMarshall
,
149 NdrConformantStringMarshall
, 0, 0,
150 NdrConformantStringMarshall
,
151 NdrNonConformantStringMarshall
, 0, 0, 0,
153 NdrEncapsulatedUnionMarshall
,
154 NdrNonEncapsulatedUnionMarshall
,
155 NdrByteCountPointerMarshall
,
156 NdrXmitOrRepAsMarshall
, NdrXmitOrRepAsMarshall
,
158 NdrInterfacePointerMarshall
,
160 NdrContextHandleMarshall
,
163 NdrUserMarshalMarshall
,
168 const NDR_UNMARSHALL NdrUnmarshaller
[NDR_TABLE_SIZE
] = {
170 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
171 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
172 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
173 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
175 NdrBaseTypeUnmarshall
,
177 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
178 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
180 NdrSimpleStructUnmarshall
, NdrSimpleStructUnmarshall
,
181 NdrConformantStructUnmarshall
, NdrConformantStructUnmarshall
,
182 NdrConformantVaryingStructUnmarshall
,
183 NdrComplexStructUnmarshall
,
185 NdrConformantArrayUnmarshall
,
186 NdrConformantVaryingArrayUnmarshall
,
187 NdrFixedArrayUnmarshall
, NdrFixedArrayUnmarshall
,
188 NdrVaryingArrayUnmarshall
, NdrVaryingArrayUnmarshall
,
189 NdrComplexArrayUnmarshall
,
191 NdrConformantStringUnmarshall
, 0, 0,
192 NdrConformantStringUnmarshall
,
193 NdrNonConformantStringUnmarshall
, 0, 0, 0,
195 NdrEncapsulatedUnionUnmarshall
,
196 NdrNonEncapsulatedUnionUnmarshall
,
197 NdrByteCountPointerUnmarshall
,
198 NdrXmitOrRepAsUnmarshall
, NdrXmitOrRepAsUnmarshall
,
200 NdrInterfacePointerUnmarshall
,
202 NdrContextHandleUnmarshall
,
205 NdrUserMarshalUnmarshall
,
210 const NDR_BUFFERSIZE NdrBufferSizer
[NDR_TABLE_SIZE
] = {
212 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
213 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
214 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
215 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
217 NdrBaseTypeBufferSize
,
219 NdrPointerBufferSize
, NdrPointerBufferSize
,
220 NdrPointerBufferSize
, NdrPointerBufferSize
,
222 NdrSimpleStructBufferSize
, NdrSimpleStructBufferSize
,
223 NdrConformantStructBufferSize
, NdrConformantStructBufferSize
,
224 NdrConformantVaryingStructBufferSize
,
225 NdrComplexStructBufferSize
,
227 NdrConformantArrayBufferSize
,
228 NdrConformantVaryingArrayBufferSize
,
229 NdrFixedArrayBufferSize
, NdrFixedArrayBufferSize
,
230 NdrVaryingArrayBufferSize
, NdrVaryingArrayBufferSize
,
231 NdrComplexArrayBufferSize
,
233 NdrConformantStringBufferSize
, 0, 0,
234 NdrConformantStringBufferSize
,
235 NdrNonConformantStringBufferSize
, 0, 0, 0,
237 NdrEncapsulatedUnionBufferSize
,
238 NdrNonEncapsulatedUnionBufferSize
,
239 NdrByteCountPointerBufferSize
,
240 NdrXmitOrRepAsBufferSize
, NdrXmitOrRepAsBufferSize
,
242 NdrInterfacePointerBufferSize
,
244 NdrContextHandleBufferSize
,
247 NdrUserMarshalBufferSize
,
252 const NDR_MEMORYSIZE NdrMemorySizer
[NDR_TABLE_SIZE
] = {
254 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
255 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
256 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
257 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
259 NdrBaseTypeMemorySize
,
261 NdrPointerMemorySize
, NdrPointerMemorySize
,
262 NdrPointerMemorySize
, NdrPointerMemorySize
,
264 NdrSimpleStructMemorySize
, NdrSimpleStructMemorySize
,
265 NdrConformantStructMemorySize
, NdrConformantStructMemorySize
,
266 NdrConformantVaryingStructMemorySize
,
267 NdrComplexStructMemorySize
,
269 NdrConformantArrayMemorySize
,
270 NdrConformantVaryingArrayMemorySize
,
271 NdrFixedArrayMemorySize
, NdrFixedArrayMemorySize
,
272 NdrVaryingArrayMemorySize
, NdrVaryingArrayMemorySize
,
273 NdrComplexArrayMemorySize
,
275 NdrConformantStringMemorySize
, 0, 0,
276 NdrConformantStringMemorySize
,
277 NdrNonConformantStringMemorySize
, 0, 0, 0,
279 NdrEncapsulatedUnionMemorySize
,
280 NdrNonEncapsulatedUnionMemorySize
,
281 NdrByteCountPointerMemorySize
,
282 NdrXmitOrRepAsMemorySize
, NdrXmitOrRepAsMemorySize
,
284 NdrInterfacePointerMemorySize
,
289 NdrUserMarshalMemorySize
,
294 const NDR_FREE NdrFreer
[NDR_TABLE_SIZE
] = {
296 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
297 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
298 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
299 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
303 NdrPointerFree
, NdrPointerFree
,
304 NdrPointerFree
, NdrPointerFree
,
306 NdrSimpleStructFree
, NdrSimpleStructFree
,
307 NdrConformantStructFree
, NdrConformantStructFree
,
308 NdrConformantVaryingStructFree
,
309 NdrComplexStructFree
,
311 NdrConformantArrayFree
,
312 NdrConformantVaryingArrayFree
,
313 NdrFixedArrayFree
, NdrFixedArrayFree
,
314 NdrVaryingArrayFree
, NdrVaryingArrayFree
,
320 NdrEncapsulatedUnionFree
,
321 NdrNonEncapsulatedUnionFree
,
323 NdrXmitOrRepAsFree
, NdrXmitOrRepAsFree
,
325 NdrInterfacePointerFree
,
336 typedef struct _NDR_MEMORY_LIST
341 struct _NDR_MEMORY_LIST
*next
;
344 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
346 /***********************************************************************
347 * NdrAllocate [RPCRT4.@]
349 * Allocates a block of memory using pStubMsg->pfnAllocate.
352 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
353 * len [I] Size of memory block to allocate.
356 * The memory block of size len that was allocated.
359 * The memory block is always 8-byte aligned.
360 * If the function is unable to allocate memory an ERROR_OUTOFMEMORY
361 * exception is raised.
363 void * WINAPI
NdrAllocate(MIDL_STUB_MESSAGE
*pStubMsg
, size_t len
)
368 NDR_MEMORY_LIST
*mem_list
;
370 aligned_len
= ALIGNED_LENGTH(len
, 8);
371 adjusted_len
= aligned_len
+ sizeof(NDR_MEMORY_LIST
);
372 /* check for overflow */
373 if (adjusted_len
< len
)
375 ERR("overflow of adjusted_len %d, len %d\n", adjusted_len
, len
);
376 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
379 p
= pStubMsg
->pfnAllocate(adjusted_len
);
380 if (!p
) RpcRaiseException(ERROR_OUTOFMEMORY
);
382 mem_list
= (NDR_MEMORY_LIST
*)((char *)p
+ aligned_len
);
383 mem_list
->magic
= MEML_MAGIC
;
384 mem_list
->size
= aligned_len
;
385 mem_list
->reserved
= 0;
386 mem_list
->next
= pStubMsg
->pMemoryList
;
387 pStubMsg
->pMemoryList
= mem_list
;
393 static void WINAPI
NdrFree(MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *Pointer
)
395 TRACE("(%p, %p)\n", pStubMsg
, Pointer
);
397 pStubMsg
->pfnFree(Pointer
);
400 static inline BOOL
IsConformanceOrVariancePresent(PFORMAT_STRING pFormat
)
402 return (*(const ULONG
*)pFormat
!= -1);
405 static PFORMAT_STRING
ReadConformance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
)
407 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
408 if (pStubMsg
->Buffer
+ 4 > pStubMsg
->BufferEnd
)
409 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
410 pStubMsg
->MaxCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
411 pStubMsg
->Buffer
+= 4;
412 TRACE("unmarshalled conformance is %ld\n", pStubMsg
->MaxCount
);
413 if (pStubMsg
->fHasNewCorrDesc
)
419 static inline PFORMAT_STRING
ReadVariance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
, ULONG MaxValue
)
421 if (pFormat
&& !IsConformanceOrVariancePresent(pFormat
))
423 pStubMsg
->Offset
= 0;
424 pStubMsg
->ActualCount
= pStubMsg
->MaxCount
;
428 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
429 if (pStubMsg
->Buffer
+ 8 > pStubMsg
->BufferEnd
)
430 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
431 pStubMsg
->Offset
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
432 pStubMsg
->Buffer
+= 4;
433 TRACE("offset is %d\n", pStubMsg
->Offset
);
434 pStubMsg
->ActualCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
435 pStubMsg
->Buffer
+= 4;
436 TRACE("variance is %d\n", pStubMsg
->ActualCount
);
438 if ((pStubMsg
->ActualCount
> MaxValue
) ||
439 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> MaxValue
))
441 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
442 pStubMsg
->ActualCount
, pStubMsg
->Offset
, MaxValue
);
443 RpcRaiseException(RPC_S_INVALID_BOUND
);
448 if (pStubMsg
->fHasNewCorrDesc
)
454 /* writes the conformance value to the buffer */
455 static inline void WriteConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
457 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
458 if (pStubMsg
->Buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
459 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
460 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->MaxCount
);
461 pStubMsg
->Buffer
+= 4;
464 /* writes the variance values to the buffer */
465 static inline void WriteVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
467 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
468 if (pStubMsg
->Buffer
+ 8 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
469 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
470 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->Offset
);
471 pStubMsg
->Buffer
+= 4;
472 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->ActualCount
);
473 pStubMsg
->Buffer
+= 4;
476 /* requests buffer space for the conformance value */
477 static inline void SizeConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
479 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
480 if (pStubMsg
->BufferLength
+ 4 < pStubMsg
->BufferLength
)
481 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
482 pStubMsg
->BufferLength
+= 4;
485 /* requests buffer space for the variance values */
486 static inline void SizeVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
488 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
489 if (pStubMsg
->BufferLength
+ 8 < pStubMsg
->BufferLength
)
490 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
491 pStubMsg
->BufferLength
+= 8;
494 PFORMAT_STRING
ComputeConformanceOrVariance(
495 MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *pMemory
,
496 PFORMAT_STRING pFormat
, ULONG_PTR def
, ULONG_PTR
*pCount
)
498 BYTE dtype
= pFormat
[0] & 0xf;
499 short ofs
= *(const short *)&pFormat
[2];
503 if (!IsConformanceOrVariancePresent(pFormat
)) {
504 /* null descriptor */
509 switch (pFormat
[0] & 0xf0) {
510 case RPC_FC_NORMAL_CONFORMANCE
:
511 TRACE("normal conformance, ofs=%d\n", ofs
);
514 case RPC_FC_POINTER_CONFORMANCE
:
515 TRACE("pointer conformance, ofs=%d\n", ofs
);
516 ptr
= pStubMsg
->Memory
;
518 case RPC_FC_TOP_LEVEL_CONFORMANCE
:
519 TRACE("toplevel conformance, ofs=%d\n", ofs
);
520 if (pStubMsg
->StackTop
) {
521 ptr
= pStubMsg
->StackTop
;
524 /* -Os mode, *pCount is already set */
528 case RPC_FC_CONSTANT_CONFORMANCE
:
529 data
= ofs
| ((DWORD
)pFormat
[1] << 16);
530 TRACE("constant conformance, val=%d\n", data
);
533 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE
:
534 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs
);
535 if (pStubMsg
->StackTop
) {
536 ptr
= pStubMsg
->StackTop
;
544 FIXME("unknown conformance type %x\n", pFormat
[0] & 0xf0);
547 switch (pFormat
[1]) {
548 case RPC_FC_DEREFERENCE
:
549 ptr
= *(LPVOID
*)((char *)ptr
+ ofs
);
551 case RPC_FC_CALLBACK
:
553 unsigned char *old_stack_top
= pStubMsg
->StackTop
;
554 pStubMsg
->StackTop
= ptr
;
556 /* ofs is index into StubDesc->apfnExprEval */
557 TRACE("callback conformance into apfnExprEval[%d]\n", ofs
);
558 pStubMsg
->StubDesc
->apfnExprEval
[ofs
](pStubMsg
);
560 pStubMsg
->StackTop
= old_stack_top
;
562 /* the callback function always stores the computed value in MaxCount */
563 *pCount
= pStubMsg
->MaxCount
;
567 ptr
= (char *)ptr
+ ofs
;
580 data
= *(USHORT
*)ptr
;
591 FIXME("unknown conformance data type %x\n", dtype
);
594 TRACE("dereferenced data type %x at %p, got %d\n", dtype
, ptr
, data
);
597 switch (pFormat
[1]) {
598 case RPC_FC_DEREFERENCE
: /* already handled */
615 FIXME("unknown conformance op %d\n", pFormat
[1]);
620 TRACE("resulting conformance is %ld\n", *pCount
);
621 if (pStubMsg
->fHasNewCorrDesc
)
627 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
628 * the result overflows 32-bits */
629 static inline ULONG
safe_multiply(ULONG a
, ULONG b
)
631 ULONGLONG ret
= (ULONGLONG
)a
* b
;
632 if (ret
> 0xffffffff)
634 RpcRaiseException(RPC_S_INVALID_BOUND
);
640 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
642 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
643 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
644 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
645 pStubMsg
->Buffer
+= size
;
648 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
650 if (pStubMsg
->BufferLength
+ size
< pStubMsg
->BufferLength
) /* integer overflow of pStubMsg->BufferSize */
652 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
653 pStubMsg
->BufferLength
, size
);
654 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
656 pStubMsg
->BufferLength
+= size
;
659 /* copies data from the buffer, checking that there is enough data in the buffer
661 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, void *p
, ULONG size
)
663 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
664 (pStubMsg
->Buffer
+ size
> pStubMsg
->BufferEnd
))
666 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
667 pStubMsg
->Buffer
, pStubMsg
->BufferEnd
, size
);
668 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
670 if (p
== pStubMsg
->Buffer
)
671 ERR("pointer is the same as the buffer\n");
672 memcpy(p
, pStubMsg
->Buffer
, size
);
673 pStubMsg
->Buffer
+= size
;
676 /* copies data to the buffer, checking that there is enough space to do so */
677 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, const void *p
, ULONG size
)
679 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
680 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
682 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
683 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
,
685 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
687 memcpy(pStubMsg
->Buffer
, p
, size
);
688 pStubMsg
->Buffer
+= size
;
692 * NdrConformantString:
694 * What MS calls a ConformantString is, in DCE terminology,
695 * a Varying-Conformant String.
697 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
698 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
699 * into unmarshalled string)
700 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
702 * data: CHARTYPE[maxlen]
704 * ], where CHARTYPE is the appropriate character type (specified externally)
708 /***********************************************************************
709 * NdrConformantStringMarshall [RPCRT4.@]
711 unsigned char *WINAPI
NdrConformantStringMarshall(MIDL_STUB_MESSAGE
*pStubMsg
,
712 unsigned char *pszMessage
, PFORMAT_STRING pFormat
)
716 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg
, pszMessage
, pFormat
);
718 if (*pFormat
== RPC_FC_C_CSTRING
) {
719 TRACE("string=%s\n", debugstr_a((char*)pszMessage
));
720 pStubMsg
->ActualCount
= strlen((char*)pszMessage
)+1;
723 else if (*pFormat
== RPC_FC_C_WSTRING
) {
724 TRACE("string=%s\n", debugstr_w((LPWSTR
)pszMessage
));
725 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pszMessage
)+1;
729 ERR("Unhandled string type: %#x\n", *pFormat
);
730 /* FIXME: raise an exception. */
734 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
735 pFormat
= ComputeConformance(pStubMsg
, pszMessage
, pFormat
+ 2, 0);
737 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
738 pStubMsg
->Offset
= 0;
739 WriteConformance(pStubMsg
);
740 WriteVariance(pStubMsg
);
742 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
743 safe_copy_to_buffer(pStubMsg
, pszMessage
, size
); /* the string itself */
746 return NULL
; /* is this always right? */
749 /***********************************************************************
750 * NdrConformantStringBufferSize [RPCRT4.@]
752 void WINAPI
NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
753 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
757 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
759 SizeConformance(pStubMsg
);
760 SizeVariance(pStubMsg
);
762 if (*pFormat
== RPC_FC_C_CSTRING
) {
763 TRACE("string=%s\n", debugstr_a((char*)pMemory
));
764 pStubMsg
->ActualCount
= strlen((char*)pMemory
)+1;
767 else if (*pFormat
== RPC_FC_C_WSTRING
) {
768 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
));
769 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
)+1;
773 ERR("Unhandled string type: %#x\n", *pFormat
);
774 /* FIXME: raise an exception */
778 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
779 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
781 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
783 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
786 /************************************************************************
787 * NdrConformantStringMemorySize [RPCRT4.@]
789 ULONG WINAPI
NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
790 PFORMAT_STRING pFormat
)
792 ULONG bufsize
, memsize
, esize
, i
;
794 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
796 ReadConformance(pStubMsg
, NULL
);
797 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
799 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
801 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
802 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
803 RpcRaiseException(RPC_S_INVALID_BOUND
);
805 if (pStubMsg
->Offset
)
807 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
808 RpcRaiseException(RPC_S_INVALID_BOUND
);
811 if (*pFormat
== RPC_FC_C_CSTRING
) esize
= 1;
812 else if (*pFormat
== RPC_FC_C_WSTRING
) esize
= 2;
814 ERR("Unhandled string type: %#x\n", *pFormat
);
815 /* FIXME: raise an exception */
819 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
820 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
822 /* strings must always have null terminating bytes */
825 ERR("invalid string length of %d\n", pStubMsg
->ActualCount
);
826 RpcRaiseException(RPC_S_INVALID_BOUND
);
829 /* verify the buffer is safe to access */
830 if ((pStubMsg
->Buffer
+ bufsize
< pStubMsg
->Buffer
) ||
831 (pStubMsg
->Buffer
+ bufsize
> pStubMsg
->BufferEnd
))
833 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize
,
834 pStubMsg
->BufferEnd
, pStubMsg
->Buffer
);
835 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
838 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
839 if (pStubMsg
->Buffer
[i
] != 0)
841 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
842 i
, pStubMsg
->Buffer
[i
]);
843 RpcRaiseException(RPC_S_INVALID_BOUND
);
846 safe_buffer_increment(pStubMsg
, bufsize
);
847 pStubMsg
->MemorySize
+= memsize
;
849 return pStubMsg
->MemorySize
;
852 /************************************************************************
853 * NdrConformantStringUnmarshall [RPCRT4.@]
855 unsigned char *WINAPI
NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
856 unsigned char** ppMemory
, PFORMAT_STRING pFormat
, unsigned char fMustAlloc
)
858 ULONG bufsize
, memsize
, esize
, i
;
860 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
861 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
863 assert(pFormat
&& ppMemory
&& pStubMsg
);
865 ReadConformance(pStubMsg
, NULL
);
866 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
868 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
870 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
871 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
872 RpcRaiseException(RPC_S_INVALID_BOUND
);
875 if (pStubMsg
->Offset
)
877 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
878 RpcRaiseException(RPC_S_INVALID_BOUND
);
882 if (*pFormat
== RPC_FC_C_CSTRING
) esize
= 1;
883 else if (*pFormat
== RPC_FC_C_WSTRING
) esize
= 2;
885 ERR("Unhandled string type: %#x\n", *pFormat
);
886 /* FIXME: raise an exception */
890 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
891 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
893 /* strings must always have null terminating bytes */
896 ERR("invalid string length of %d\n", pStubMsg
->ActualCount
);
897 RpcRaiseException(RPC_S_INVALID_BOUND
);
901 /* verify the buffer is safe to access */
902 if ((pStubMsg
->Buffer
+ bufsize
< pStubMsg
->Buffer
) ||
903 (pStubMsg
->Buffer
+ bufsize
> pStubMsg
->BufferEnd
))
905 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize
,
906 pStubMsg
->BufferEnd
, pStubMsg
->Buffer
);
907 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
911 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
912 if (pStubMsg
->Buffer
[i
] != 0)
914 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
915 i
, pStubMsg
->Buffer
[i
]);
916 RpcRaiseException(RPC_S_INVALID_BOUND
);
921 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
924 if (!pStubMsg
->IsClient
&& !*ppMemory
&& (pStubMsg
->MaxCount
== pStubMsg
->ActualCount
))
925 /* if the data in the RPC buffer is big enough, we just point straight
927 *ppMemory
= pStubMsg
->Buffer
;
929 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
932 if (*ppMemory
== pStubMsg
->Buffer
)
933 safe_buffer_increment(pStubMsg
, bufsize
);
935 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
937 if (*pFormat
== RPC_FC_C_CSTRING
) {
938 TRACE("string=%s\n", debugstr_a((char*)*ppMemory
));
940 else if (*pFormat
== RPC_FC_C_WSTRING
) {
941 TRACE("string=%s\n", debugstr_w((LPWSTR
)*ppMemory
));
944 return NULL
; /* FIXME: is this always right? */
947 /***********************************************************************
948 * NdrNonConformantStringMarshall [RPCRT4.@]
950 unsigned char * WINAPI
NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
951 unsigned char *pMemory
,
952 PFORMAT_STRING pFormat
)
954 ULONG esize
, size
, maxsize
;
956 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
958 maxsize
= *(USHORT
*)&pFormat
[2];
960 if (*pFormat
== RPC_FC_CSTRING
)
963 const char *str
= (const char *)pMemory
;
964 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
966 TRACE("string=%s\n", debugstr_an(str
, i
));
967 pStubMsg
->ActualCount
= i
+ 1;
970 else if (*pFormat
== RPC_FC_WSTRING
)
973 const WCHAR
*str
= (const WCHAR
*)pMemory
;
974 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
976 TRACE("string=%s\n", debugstr_wn(str
, i
));
977 pStubMsg
->ActualCount
= i
+ 1;
982 ERR("Unhandled string type: %#x\n", *pFormat
);
983 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
986 pStubMsg
->Offset
= 0;
987 WriteVariance(pStubMsg
);
989 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
990 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
995 /***********************************************************************
996 * NdrNonConformantStringUnmarshall [RPCRT4.@]
998 unsigned char * WINAPI
NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
999 unsigned char **ppMemory
,
1000 PFORMAT_STRING pFormat
,
1001 unsigned char fMustAlloc
)
1003 ULONG bufsize
, memsize
, esize
, i
, maxsize
;
1005 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
1006 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
1008 maxsize
= *(USHORT
*)&pFormat
[2];
1010 ReadVariance(pStubMsg
, NULL
, maxsize
);
1011 if (pStubMsg
->Offset
)
1013 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
1014 RpcRaiseException(RPC_S_INVALID_BOUND
);
1017 if (*pFormat
== RPC_FC_CSTRING
) esize
= 1;
1018 else if (*pFormat
== RPC_FC_WSTRING
) esize
= 2;
1021 ERR("Unhandled string type: %#x\n", *pFormat
);
1022 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1025 memsize
= esize
* maxsize
;
1026 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1028 if (bufsize
< esize
)
1030 ERR("invalid string length of %d\n", pStubMsg
->ActualCount
);
1031 RpcRaiseException(RPC_S_INVALID_BOUND
);
1035 /* verify the buffer is safe to access */
1036 if ((pStubMsg
->Buffer
+ bufsize
< pStubMsg
->Buffer
) ||
1037 (pStubMsg
->Buffer
+ bufsize
> pStubMsg
->BufferEnd
))
1039 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize
,
1040 pStubMsg
->BufferEnd
, pStubMsg
->Buffer
);
1041 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1045 /* strings must always have null terminating bytes */
1046 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
1047 if (pStubMsg
->Buffer
[i
] != 0)
1049 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
1050 i
, pStubMsg
->Buffer
[i
]);
1051 RpcRaiseException(RPC_S_INVALID_BOUND
);
1054 if (fMustAlloc
|| !*ppMemory
)
1055 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
1057 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
1059 if (*pFormat
== RPC_FC_CSTRING
) {
1060 TRACE("string=%s\n", debugstr_an((char*)*ppMemory
, pStubMsg
->ActualCount
));
1062 else if (*pFormat
== RPC_FC_WSTRING
) {
1063 TRACE("string=%s\n", debugstr_wn((LPWSTR
)*ppMemory
, pStubMsg
->ActualCount
));
1069 /***********************************************************************
1070 * NdrNonConformantStringBufferSize [RPCRT4.@]
1072 void WINAPI
NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1073 unsigned char *pMemory
,
1074 PFORMAT_STRING pFormat
)
1076 ULONG esize
, maxsize
;
1078 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
1080 maxsize
= *(USHORT
*)&pFormat
[2];
1082 SizeVariance(pStubMsg
);
1084 if (*pFormat
== RPC_FC_CSTRING
)
1087 const char *str
= (const char *)pMemory
;
1088 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
1090 TRACE("string=%s\n", debugstr_an(str
, i
));
1091 pStubMsg
->ActualCount
= i
+ 1;
1094 else if (*pFormat
== RPC_FC_WSTRING
)
1097 const WCHAR
*str
= (const WCHAR
*)pMemory
;
1098 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
1100 TRACE("string=%s\n", debugstr_wn(str
, i
));
1101 pStubMsg
->ActualCount
= i
+ 1;
1106 ERR("Unhandled string type: %#x\n", *pFormat
);
1107 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1110 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
1113 /***********************************************************************
1114 * NdrNonConformantStringMemorySize [RPCRT4.@]
1116 ULONG WINAPI
NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1117 PFORMAT_STRING pFormat
)
1119 ULONG bufsize
, memsize
, esize
, i
, maxsize
;
1121 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
1123 maxsize
= *(USHORT
*)&pFormat
[2];
1125 ReadVariance(pStubMsg
, NULL
, maxsize
);
1127 if (pStubMsg
->Offset
)
1129 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
1130 RpcRaiseException(RPC_S_INVALID_BOUND
);
1133 if (*pFormat
== RPC_FC_CSTRING
) esize
= 1;
1134 else if (*pFormat
== RPC_FC_WSTRING
) esize
= 2;
1137 ERR("Unhandled string type: %#x\n", *pFormat
);
1138 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1141 memsize
= esize
* maxsize
;
1142 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1144 /* strings must always have null terminating bytes */
1145 if (bufsize
< esize
)
1147 ERR("invalid string length of %d\n", pStubMsg
->ActualCount
);
1148 RpcRaiseException(RPC_S_INVALID_BOUND
);
1151 /* verify the buffer is safe to access */
1152 if ((pStubMsg
->Buffer
+ bufsize
< pStubMsg
->Buffer
) ||
1153 (pStubMsg
->Buffer
+ bufsize
> pStubMsg
->BufferEnd
))
1155 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize
,
1156 pStubMsg
->BufferEnd
, pStubMsg
->Buffer
);
1157 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1160 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
1161 if (pStubMsg
->Buffer
[i
] != 0)
1163 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
1164 i
, pStubMsg
->Buffer
[i
]);
1165 RpcRaiseException(RPC_S_INVALID_BOUND
);
1168 safe_buffer_increment(pStubMsg
, bufsize
);
1169 pStubMsg
->MemorySize
+= memsize
;
1171 return pStubMsg
->MemorySize
;
1174 static inline void dump_pointer_attr(unsigned char attr
)
1176 if (attr
& RPC_FC_P_ALLOCALLNODES
)
1177 TRACE(" RPC_FC_P_ALLOCALLNODES");
1178 if (attr
& RPC_FC_P_DONTFREE
)
1179 TRACE(" RPC_FC_P_DONTFREE");
1180 if (attr
& RPC_FC_P_ONSTACK
)
1181 TRACE(" RPC_FC_P_ONSTACK");
1182 if (attr
& RPC_FC_P_SIMPLEPOINTER
)
1183 TRACE(" RPC_FC_P_SIMPLEPOINTER");
1184 if (attr
& RPC_FC_P_DEREF
)
1185 TRACE(" RPC_FC_P_DEREF");
1189 /***********************************************************************
1190 * PointerMarshall [internal]
1192 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1193 unsigned char *Buffer
,
1194 unsigned char *Pointer
,
1195 PFORMAT_STRING pFormat
)
1197 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1198 PFORMAT_STRING desc
;
1201 int pointer_needs_marshaling
;
1203 TRACE("(%p,%p,%p,%p)\n", pStubMsg
, Buffer
, Pointer
, pFormat
);
1204 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1206 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1207 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1210 case RPC_FC_RP
: /* ref pointer (always non-null) */
1213 ERR("NULL ref pointer is not allowed\n");
1214 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
1216 pointer_needs_marshaling
= 1;
1218 case RPC_FC_UP
: /* unique pointer */
1219 case RPC_FC_OP
: /* object pointer - same as unique here */
1221 pointer_needs_marshaling
= 1;
1223 pointer_needs_marshaling
= 0;
1224 pointer_id
= (ULONG
)Pointer
;
1225 TRACE("writing 0x%08x to buffer\n", pointer_id
);
1226 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
1229 pointer_needs_marshaling
= !NdrFullPointerQueryPointer(
1230 pStubMsg
->FullPtrXlatTables
, Pointer
, 1, &pointer_id
);
1231 TRACE("writing 0x%08x to buffer\n", pointer_id
);
1232 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
1235 FIXME("unhandled ptr type=%02x\n", type
);
1236 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1240 TRACE("calling marshaller for type 0x%x\n", (int)*desc
);
1242 if (pointer_needs_marshaling
) {
1243 if (attr
& RPC_FC_P_DEREF
) {
1244 Pointer
= *(unsigned char**)Pointer
;
1245 TRACE("deref => %p\n", Pointer
);
1247 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
1248 if (m
) m(pStubMsg
, Pointer
, desc
);
1249 else FIXME("no marshaller for data type=%02x\n", *desc
);
1252 STD_OVERFLOW_CHECK(pStubMsg
);
1255 /***********************************************************************
1256 * PointerUnmarshall [internal]
1258 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1259 unsigned char *Buffer
,
1260 unsigned char **pPointer
,
1261 unsigned char *pSrcPointer
,
1262 PFORMAT_STRING pFormat
,
1263 unsigned char fMustAlloc
)
1265 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1266 PFORMAT_STRING desc
;
1268 DWORD pointer_id
= 0;
1269 int pointer_needs_unmarshaling
;
1271 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg
, Buffer
, pPointer
, pSrcPointer
, pFormat
, fMustAlloc
);
1272 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1274 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1275 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1278 case RPC_FC_RP
: /* ref pointer (always non-null) */
1279 pointer_needs_unmarshaling
= 1;
1281 case RPC_FC_UP
: /* unique pointer */
1282 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1283 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1285 pointer_needs_unmarshaling
= 1;
1288 pointer_needs_unmarshaling
= 0;
1291 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
1292 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1293 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1294 if (!fMustAlloc
&& pSrcPointer
)
1296 FIXME("free object pointer %p\n", pSrcPointer
);
1300 pointer_needs_unmarshaling
= 1;
1302 pointer_needs_unmarshaling
= 0;
1305 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1306 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1307 pointer_needs_unmarshaling
= !NdrFullPointerQueryRefId(
1308 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, (void **)pPointer
);
1311 FIXME("unhandled ptr type=%02x\n", type
);
1312 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1316 if (pointer_needs_unmarshaling
) {
1317 unsigned char *base_ptr_val
= *pPointer
;
1318 unsigned char **current_ptr
= pPointer
;
1319 if (pStubMsg
->IsClient
) {
1321 /* if we aren't forcing allocation of memory then try to use the existing
1322 * (source) pointer to unmarshall the data into so that [in,out]
1323 * parameters behave correctly. it doesn't matter if the parameter is
1324 * [out] only since in that case the pointer will be NULL. we force
1325 * allocation when the source pointer is NULL here instead of in the type
1326 * unmarshalling routine for the benefit of the deref code below */
1329 TRACE("setting *pPointer to %p\n", pSrcPointer
);
1330 *pPointer
= base_ptr_val
= pSrcPointer
;
1336 /* the memory in a stub is never initialised, so we have to work out here
1337 * whether we have to initialise it so we can use the optimisation of
1338 * setting the pointer to the buffer, if possible, or set fMustAlloc to
1340 if (attr
& RPC_FC_P_DEREF
) {
1343 base_ptr_val
= NULL
;
1344 *current_ptr
= NULL
;
1348 if (attr
& RPC_FC_P_ALLOCALLNODES
)
1349 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
1351 if (attr
& RPC_FC_P_DEREF
) {
1353 base_ptr_val
= NdrAllocate(pStubMsg
, sizeof(void *));
1354 *pPointer
= base_ptr_val
;
1355 current_ptr
= (unsigned char **)base_ptr_val
;
1357 current_ptr
= *(unsigned char***)current_ptr
;
1358 TRACE("deref => %p\n", current_ptr
);
1359 if (!fMustAlloc
&& !*current_ptr
) fMustAlloc
= TRUE
;
1361 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
1362 if (m
) m(pStubMsg
, current_ptr
, desc
, fMustAlloc
);
1363 else FIXME("no unmarshaller for data type=%02x\n", *desc
);
1365 if (type
== RPC_FC_FP
)
1366 NdrFullPointerInsertRefId(pStubMsg
->FullPtrXlatTables
, pointer_id
,
1370 TRACE("pointer=%p\n", *pPointer
);
1373 /***********************************************************************
1374 * PointerBufferSize [internal]
1376 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1377 unsigned char *Pointer
,
1378 PFORMAT_STRING pFormat
)
1380 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1381 PFORMAT_STRING desc
;
1383 int pointer_needs_sizing
;
1386 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1387 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1389 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1390 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1393 case RPC_FC_RP
: /* ref pointer (always non-null) */
1396 ERR("NULL ref pointer is not allowed\n");
1397 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
1402 /* NULL pointer has no further representation */
1407 pointer_needs_sizing
= !NdrFullPointerQueryPointer(
1408 pStubMsg
->FullPtrXlatTables
, Pointer
, 0, &pointer_id
);
1409 if (!pointer_needs_sizing
)
1413 FIXME("unhandled ptr type=%02x\n", type
);
1414 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1418 if (attr
& RPC_FC_P_DEREF
) {
1419 Pointer
= *(unsigned char**)Pointer
;
1420 TRACE("deref => %p\n", Pointer
);
1423 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
1424 if (m
) m(pStubMsg
, Pointer
, desc
);
1425 else FIXME("no buffersizer for data type=%02x\n", *desc
);
1428 /***********************************************************************
1429 * PointerMemorySize [internal]
1431 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1432 unsigned char *Buffer
,
1433 PFORMAT_STRING pFormat
)
1435 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1436 PFORMAT_STRING desc
;
1438 DWORD pointer_id
= 0;
1439 int pointer_needs_sizing
;
1441 TRACE("(%p,%p,%p)\n", pStubMsg
, Buffer
, pFormat
);
1442 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1444 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1445 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1448 case RPC_FC_RP
: /* ref pointer (always non-null) */
1449 pointer_needs_sizing
= 1;
1451 case RPC_FC_UP
: /* unique pointer */
1452 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
1453 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1454 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1456 pointer_needs_sizing
= 1;
1458 pointer_needs_sizing
= 0;
1463 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1464 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1465 pointer_needs_sizing
= !NdrFullPointerQueryRefId(
1466 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, &pointer
);
1470 FIXME("unhandled ptr type=%02x\n", type
);
1471 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1475 if (attr
& RPC_FC_P_DEREF
) {
1479 if (pointer_needs_sizing
) {
1480 m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
1481 if (m
) m(pStubMsg
, desc
);
1482 else FIXME("no memorysizer for data type=%02x\n", *desc
);
1485 return pStubMsg
->MemorySize
;
1488 /***********************************************************************
1489 * PointerFree [internal]
1491 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1492 unsigned char *Pointer
,
1493 PFORMAT_STRING pFormat
)
1495 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1496 PFORMAT_STRING desc
;
1498 unsigned char *current_pointer
= Pointer
;
1500 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1501 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1502 if (attr
& RPC_FC_P_DONTFREE
) return;
1504 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1505 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1507 if (!Pointer
) return;
1509 if (type
== RPC_FC_FP
) {
1510 int pointer_needs_freeing
= NdrFullPointerFree(
1511 pStubMsg
->FullPtrXlatTables
, Pointer
);
1512 if (!pointer_needs_freeing
)
1516 if (attr
& RPC_FC_P_DEREF
) {
1517 current_pointer
= *(unsigned char**)Pointer
;
1518 TRACE("deref => %p\n", current_pointer
);
1521 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
1522 if (m
) m(pStubMsg
, current_pointer
, desc
);
1524 /* this check stops us from trying to free buffer memory. we don't have to
1525 * worry about clients, since they won't call this function.
1526 * we don't have to check for the buffer being reallocated because
1527 * BufferStart and BufferEnd won't be reset when allocating memory for
1528 * sending the response. we don't have to check for the new buffer here as
1529 * it won't be used a type memory, only for buffer memory */
1530 if (Pointer
>= pStubMsg
->BufferStart
&& Pointer
< pStubMsg
->BufferEnd
)
1533 if (attr
& RPC_FC_P_ONSTACK
) {
1534 TRACE("not freeing stack ptr %p\n", Pointer
);
1537 TRACE("freeing %p\n", Pointer
);
1538 NdrFree(pStubMsg
, Pointer
);
1541 TRACE("not freeing %p\n", Pointer
);
1544 /***********************************************************************
1545 * EmbeddedPointerMarshall
1547 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1548 unsigned char *pMemory
,
1549 PFORMAT_STRING pFormat
)
1551 unsigned char *Mark
= pStubMsg
->BufferMark
;
1552 unsigned rep
, count
, stride
;
1554 unsigned char *saved_buffer
= NULL
;
1556 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1558 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1561 if (pStubMsg
->PointerBufferMark
)
1563 saved_buffer
= pStubMsg
->Buffer
;
1564 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1565 pStubMsg
->PointerBufferMark
= NULL
;
1568 while (pFormat
[0] != RPC_FC_END
) {
1569 switch (pFormat
[0]) {
1571 FIXME("unknown repeat type %d\n", pFormat
[0]);
1572 case RPC_FC_NO_REPEAT
:
1578 case RPC_FC_FIXED_REPEAT
:
1579 rep
= *(const WORD
*)&pFormat
[2];
1580 stride
= *(const WORD
*)&pFormat
[4];
1581 count
= *(const WORD
*)&pFormat
[8];
1584 case RPC_FC_VARIABLE_REPEAT
:
1585 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1586 stride
= *(const WORD
*)&pFormat
[2];
1587 count
= *(const WORD
*)&pFormat
[6];
1591 for (i
= 0; i
< rep
; i
++) {
1592 PFORMAT_STRING info
= pFormat
;
1593 unsigned char *membase
= pMemory
+ (i
* stride
);
1594 unsigned char *bufbase
= Mark
+ (i
* stride
);
1597 for (u
=0; u
<count
; u
++,info
+=8) {
1598 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1599 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1600 unsigned char *saved_memory
= pStubMsg
->Memory
;
1602 pStubMsg
->Memory
= pMemory
;
1603 PointerMarshall(pStubMsg
, bufptr
, *(unsigned char**)memptr
, info
+4);
1604 pStubMsg
->Memory
= saved_memory
;
1607 pFormat
+= 8 * count
;
1612 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1613 pStubMsg
->Buffer
= saved_buffer
;
1616 STD_OVERFLOW_CHECK(pStubMsg
);
1621 /***********************************************************************
1622 * EmbeddedPointerUnmarshall
1624 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1625 unsigned char *pDstMemoryPtrs
,
1626 unsigned char *pSrcMemoryPtrs
,
1627 PFORMAT_STRING pFormat
,
1628 unsigned char fMustAlloc
)
1630 unsigned char *Mark
= pStubMsg
->BufferMark
;
1631 unsigned rep
, count
, stride
;
1633 unsigned char *saved_buffer
= NULL
;
1635 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg
, pDstMemoryPtrs
, pSrcMemoryPtrs
, pFormat
, fMustAlloc
);
1637 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1640 if (pStubMsg
->PointerBufferMark
)
1642 saved_buffer
= pStubMsg
->Buffer
;
1643 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1644 pStubMsg
->PointerBufferMark
= NULL
;
1647 while (pFormat
[0] != RPC_FC_END
) {
1648 TRACE("pFormat[0] = 0x%x\n", pFormat
[0]);
1649 switch (pFormat
[0]) {
1651 FIXME("unknown repeat type %d\n", pFormat
[0]);
1652 case RPC_FC_NO_REPEAT
:
1658 case RPC_FC_FIXED_REPEAT
:
1659 rep
= *(const WORD
*)&pFormat
[2];
1660 stride
= *(const WORD
*)&pFormat
[4];
1661 count
= *(const WORD
*)&pFormat
[8];
1664 case RPC_FC_VARIABLE_REPEAT
:
1665 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1666 stride
= *(const WORD
*)&pFormat
[2];
1667 count
= *(const WORD
*)&pFormat
[6];
1671 for (i
= 0; i
< rep
; i
++) {
1672 PFORMAT_STRING info
= pFormat
;
1673 unsigned char *memdstbase
= pDstMemoryPtrs
+ (i
* stride
);
1674 unsigned char *memsrcbase
= pSrcMemoryPtrs
+ (i
* stride
);
1675 unsigned char *bufbase
= Mark
+ (i
* stride
);
1678 for (u
=0; u
<count
; u
++,info
+=8) {
1679 unsigned char **memdstptr
= (unsigned char **)(memdstbase
+ *(const SHORT
*)&info
[0]);
1680 unsigned char **memsrcptr
= (unsigned char **)(memsrcbase
+ *(const SHORT
*)&info
[0]);
1681 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1682 PointerUnmarshall(pStubMsg
, bufptr
, memdstptr
, *memsrcptr
, info
+4, fMustAlloc
);
1685 pFormat
+= 8 * count
;
1690 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1691 pStubMsg
->Buffer
= saved_buffer
;
1697 /***********************************************************************
1698 * EmbeddedPointerBufferSize
1700 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1701 unsigned char *pMemory
,
1702 PFORMAT_STRING pFormat
)
1704 unsigned rep
, count
, stride
;
1706 ULONG saved_buffer_length
= 0;
1708 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1710 if (pStubMsg
->IgnoreEmbeddedPointers
) return;
1712 if (*pFormat
!= RPC_FC_PP
) return;
1715 if (pStubMsg
->PointerLength
)
1717 saved_buffer_length
= pStubMsg
->BufferLength
;
1718 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
1719 pStubMsg
->PointerLength
= 0;
1722 while (pFormat
[0] != RPC_FC_END
) {
1723 switch (pFormat
[0]) {
1725 FIXME("unknown repeat type %d\n", pFormat
[0]);
1726 case RPC_FC_NO_REPEAT
:
1732 case RPC_FC_FIXED_REPEAT
:
1733 rep
= *(const WORD
*)&pFormat
[2];
1734 stride
= *(const WORD
*)&pFormat
[4];
1735 count
= *(const WORD
*)&pFormat
[8];
1738 case RPC_FC_VARIABLE_REPEAT
:
1739 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1740 stride
= *(const WORD
*)&pFormat
[2];
1741 count
= *(const WORD
*)&pFormat
[6];
1745 for (i
= 0; i
< rep
; i
++) {
1746 PFORMAT_STRING info
= pFormat
;
1747 unsigned char *membase
= pMemory
+ (i
* stride
);
1750 for (u
=0; u
<count
; u
++,info
+=8) {
1751 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1752 unsigned char *saved_memory
= pStubMsg
->Memory
;
1754 pStubMsg
->Memory
= pMemory
;
1755 PointerBufferSize(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1756 pStubMsg
->Memory
= saved_memory
;
1759 pFormat
+= 8 * count
;
1762 if (saved_buffer_length
)
1764 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
1765 pStubMsg
->BufferLength
= saved_buffer_length
;
1769 /***********************************************************************
1770 * EmbeddedPointerMemorySize [internal]
1772 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1773 PFORMAT_STRING pFormat
)
1775 unsigned char *Mark
= pStubMsg
->BufferMark
;
1776 unsigned rep
, count
, stride
;
1778 unsigned char *saved_buffer
= NULL
;
1780 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1782 if (pStubMsg
->IgnoreEmbeddedPointers
) return 0;
1784 if (pStubMsg
->PointerBufferMark
)
1786 saved_buffer
= pStubMsg
->Buffer
;
1787 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1788 pStubMsg
->PointerBufferMark
= NULL
;
1791 if (*pFormat
!= RPC_FC_PP
) return 0;
1794 while (pFormat
[0] != RPC_FC_END
) {
1795 switch (pFormat
[0]) {
1797 FIXME("unknown repeat type %d\n", pFormat
[0]);
1798 case RPC_FC_NO_REPEAT
:
1804 case RPC_FC_FIXED_REPEAT
:
1805 rep
= *(const WORD
*)&pFormat
[2];
1806 stride
= *(const WORD
*)&pFormat
[4];
1807 count
= *(const WORD
*)&pFormat
[8];
1810 case RPC_FC_VARIABLE_REPEAT
:
1811 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1812 stride
= *(const WORD
*)&pFormat
[2];
1813 count
= *(const WORD
*)&pFormat
[6];
1817 for (i
= 0; i
< rep
; i
++) {
1818 PFORMAT_STRING info
= pFormat
;
1819 unsigned char *bufbase
= Mark
+ (i
* stride
);
1821 for (u
=0; u
<count
; u
++,info
+=8) {
1822 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1823 PointerMemorySize(pStubMsg
, bufptr
, info
+4);
1826 pFormat
+= 8 * count
;
1831 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1832 pStubMsg
->Buffer
= saved_buffer
;
1838 /***********************************************************************
1839 * EmbeddedPointerFree [internal]
1841 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1842 unsigned char *pMemory
,
1843 PFORMAT_STRING pFormat
)
1845 unsigned rep
, count
, stride
;
1848 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1849 if (*pFormat
!= RPC_FC_PP
) return;
1852 while (pFormat
[0] != RPC_FC_END
) {
1853 switch (pFormat
[0]) {
1855 FIXME("unknown repeat type %d\n", pFormat
[0]);
1856 case RPC_FC_NO_REPEAT
:
1862 case RPC_FC_FIXED_REPEAT
:
1863 rep
= *(const WORD
*)&pFormat
[2];
1864 stride
= *(const WORD
*)&pFormat
[4];
1865 count
= *(const WORD
*)&pFormat
[8];
1868 case RPC_FC_VARIABLE_REPEAT
:
1869 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1870 stride
= *(const WORD
*)&pFormat
[2];
1871 count
= *(const WORD
*)&pFormat
[6];
1875 for (i
= 0; i
< rep
; i
++) {
1876 PFORMAT_STRING info
= pFormat
;
1877 unsigned char *membase
= pMemory
+ (i
* stride
);
1880 for (u
=0; u
<count
; u
++,info
+=8) {
1881 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1882 unsigned char *saved_memory
= pStubMsg
->Memory
;
1884 pStubMsg
->Memory
= pMemory
;
1885 PointerFree(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1886 pStubMsg
->Memory
= saved_memory
;
1889 pFormat
+= 8 * count
;
1893 /***********************************************************************
1894 * NdrPointerMarshall [RPCRT4.@]
1896 unsigned char * WINAPI
NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1897 unsigned char *pMemory
,
1898 PFORMAT_STRING pFormat
)
1900 unsigned char *Buffer
;
1902 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1904 /* Increment the buffer here instead of in PointerMarshall,
1905 * as that is used by embedded pointers which already handle the incrementing
1906 * the buffer, and shouldn't write any additional pointer data to the wire */
1907 if (*pFormat
!= RPC_FC_RP
)
1909 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
1910 Buffer
= pStubMsg
->Buffer
;
1911 safe_buffer_increment(pStubMsg
, 4);
1914 Buffer
= pStubMsg
->Buffer
;
1916 PointerMarshall(pStubMsg
, Buffer
, pMemory
, pFormat
);
1921 /***********************************************************************
1922 * NdrPointerUnmarshall [RPCRT4.@]
1924 unsigned char * WINAPI
NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1925 unsigned char **ppMemory
,
1926 PFORMAT_STRING pFormat
,
1927 unsigned char fMustAlloc
)
1929 unsigned char *Buffer
;
1931 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1933 /* Increment the buffer here instead of in PointerUnmarshall,
1934 * as that is used by embedded pointers which already handle the incrementing
1935 * the buffer, and shouldn't read any additional pointer data from the
1937 if (*pFormat
!= RPC_FC_RP
)
1939 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1940 Buffer
= pStubMsg
->Buffer
;
1941 safe_buffer_increment(pStubMsg
, 4);
1944 Buffer
= pStubMsg
->Buffer
;
1946 PointerUnmarshall(pStubMsg
, Buffer
, ppMemory
, *ppMemory
, pFormat
, fMustAlloc
);
1951 /***********************************************************************
1952 * NdrPointerBufferSize [RPCRT4.@]
1954 void WINAPI
NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1955 unsigned char *pMemory
,
1956 PFORMAT_STRING pFormat
)
1958 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1960 /* Increment the buffer length here instead of in PointerBufferSize,
1961 * as that is used by embedded pointers which already handle the buffer
1962 * length, and shouldn't write anything more to the wire */
1963 if (*pFormat
!= RPC_FC_RP
)
1965 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
1966 safe_buffer_length_increment(pStubMsg
, 4);
1969 PointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1972 /***********************************************************************
1973 * NdrPointerMemorySize [RPCRT4.@]
1975 ULONG WINAPI
NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1976 PFORMAT_STRING pFormat
)
1978 /* unsigned size = *(LPWORD)(pFormat+2); */
1979 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1980 PointerMemorySize(pStubMsg
, pStubMsg
->Buffer
, pFormat
);
1984 /***********************************************************************
1985 * NdrPointerFree [RPCRT4.@]
1987 void WINAPI
NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1988 unsigned char *pMemory
,
1989 PFORMAT_STRING pFormat
)
1991 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1992 PointerFree(pStubMsg
, pMemory
, pFormat
);
1995 /***********************************************************************
1996 * NdrSimpleTypeMarshall [RPCRT4.@]
1998 void WINAPI
NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1999 unsigned char FormatChar
)
2001 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &FormatChar
);
2004 /***********************************************************************
2005 * NdrSimpleTypeUnmarshall [RPCRT4.@]
2007 * Unmarshall a base type.
2010 * Doesn't check that the buffer is long enough before copying, so the caller
2013 void WINAPI
NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
2014 unsigned char FormatChar
)
2016 #define BASE_TYPE_UNMARSHALL(type) \
2017 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
2018 TRACE("pMemory: %p\n", pMemory); \
2019 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
2020 pStubMsg->Buffer += sizeof(type);
2028 BASE_TYPE_UNMARSHALL(UCHAR
);
2029 TRACE("value: 0x%02x\n", *pMemory
);
2034 BASE_TYPE_UNMARSHALL(USHORT
);
2035 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
2039 case RPC_FC_ERROR_STATUS_T
:
2041 BASE_TYPE_UNMARSHALL(ULONG
);
2042 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
2045 BASE_TYPE_UNMARSHALL(float);
2046 TRACE("value: %f\n", *(float *)pMemory
);
2049 BASE_TYPE_UNMARSHALL(double);
2050 TRACE("value: %f\n", *(double *)pMemory
);
2053 BASE_TYPE_UNMARSHALL(ULONGLONG
);
2054 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
2057 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
2058 TRACE("pMemory: %p\n", pMemory
);
2059 /* 16-bits on the wire, but int in memory */
2060 *(UINT
*)pMemory
= *(USHORT
*)pStubMsg
->Buffer
;
2061 pStubMsg
->Buffer
+= sizeof(USHORT
);
2062 TRACE("value: 0x%08x\n", *(UINT
*)pMemory
);
2067 FIXME("Unhandled base type: 0x%02x\n", FormatChar
);
2069 #undef BASE_TYPE_UNMARSHALL
2072 /***********************************************************************
2073 * NdrSimpleStructMarshall [RPCRT4.@]
2075 unsigned char * WINAPI
NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2076 unsigned char *pMemory
,
2077 PFORMAT_STRING pFormat
)
2079 unsigned size
= *(const WORD
*)(pFormat
+2);
2080 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2082 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pFormat
[1] + 1);
2084 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2085 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
2087 if (pFormat
[0] != RPC_FC_STRUCT
)
2088 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
+4);
2093 /***********************************************************************
2094 * NdrSimpleStructUnmarshall [RPCRT4.@]
2096 unsigned char * WINAPI
NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2097 unsigned char **ppMemory
,
2098 PFORMAT_STRING pFormat
,
2099 unsigned char fMustAlloc
)
2101 unsigned size
= *(const WORD
*)(pFormat
+2);
2102 unsigned char *saved_buffer
;
2103 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2105 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2108 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2111 if (!pStubMsg
->IsClient
&& !*ppMemory
)
2112 /* for servers, we just point straight into the RPC buffer */
2113 *ppMemory
= pStubMsg
->Buffer
;
2116 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2117 safe_buffer_increment(pStubMsg
, size
);
2118 if (pFormat
[0] == RPC_FC_PSTRUCT
)
2119 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
+4, fMustAlloc
);
2121 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
2122 if (*ppMemory
!= saved_buffer
)
2123 memcpy(*ppMemory
, saved_buffer
, size
);
2128 /***********************************************************************
2129 * NdrSimpleStructBufferSize [RPCRT4.@]
2131 void WINAPI
NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2132 unsigned char *pMemory
,
2133 PFORMAT_STRING pFormat
)
2135 unsigned size
= *(const WORD
*)(pFormat
+2);
2136 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2138 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
2140 safe_buffer_length_increment(pStubMsg
, size
);
2141 if (pFormat
[0] != RPC_FC_STRUCT
)
2142 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
+4);
2145 /***********************************************************************
2146 * NdrSimpleStructMemorySize [RPCRT4.@]
2148 ULONG WINAPI
NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2149 PFORMAT_STRING pFormat
)
2151 unsigned short size
= *(const WORD
*)(pFormat
+2);
2153 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2155 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2156 pStubMsg
->MemorySize
+= size
;
2157 safe_buffer_increment(pStubMsg
, size
);
2159 if (pFormat
[0] != RPC_FC_STRUCT
)
2160 EmbeddedPointerMemorySize(pStubMsg
, pFormat
+4);
2161 return pStubMsg
->MemorySize
;
2164 /***********************************************************************
2165 * NdrSimpleStructFree [RPCRT4.@]
2167 void WINAPI
NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
2168 unsigned char *pMemory
,
2169 PFORMAT_STRING pFormat
)
2171 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2172 if (pFormat
[0] != RPC_FC_STRUCT
)
2173 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
+4);
2177 static unsigned long EmbeddedComplexSize(const MIDL_STUB_MESSAGE
*pStubMsg
,
2178 PFORMAT_STRING pFormat
)
2182 case RPC_FC_PSTRUCT
:
2183 case RPC_FC_CSTRUCT
:
2184 case RPC_FC_BOGUS_STRUCT
:
2185 case RPC_FC_SMFARRAY
:
2186 case RPC_FC_SMVARRAY
:
2187 case RPC_FC_CSTRING
:
2188 return *(const WORD
*)&pFormat
[2];
2189 case RPC_FC_USER_MARSHAL
:
2190 return *(const WORD
*)&pFormat
[4];
2191 case RPC_FC_NON_ENCAPSULATED_UNION
:
2193 if (pStubMsg
->fHasNewCorrDesc
)
2198 pFormat
+= *(const SHORT
*)pFormat
;
2199 return *(const SHORT
*)pFormat
;
2201 return sizeof(void *);
2202 case RPC_FC_WSTRING
:
2203 return *(const WORD
*)&pFormat
[2] * 2;
2205 FIXME("unhandled embedded type %02x\n", *pFormat
);
2211 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2212 PFORMAT_STRING pFormat
)
2214 NDR_MEMORYSIZE m
= NdrMemorySizer
[*pFormat
& NDR_TABLE_MASK
];
2218 FIXME("no memorysizer for data type=%02x\n", *pFormat
);
2222 return m(pStubMsg
, pFormat
);
2226 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2227 unsigned char *pMemory
,
2228 PFORMAT_STRING pFormat
,
2229 PFORMAT_STRING pPointer
)
2231 PFORMAT_STRING desc
;
2235 while (*pFormat
!= RPC_FC_END
) {
2241 TRACE("byte=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2242 safe_copy_to_buffer(pStubMsg
, pMemory
, 1);
2248 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2249 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
2253 TRACE("enum16=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2254 if (32767 < *(DWORD
*)pMemory
)
2255 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
2256 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
2262 TRACE("long=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2263 safe_copy_to_buffer(pStubMsg
, pMemory
, 4);
2267 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2268 safe_copy_to_buffer(pStubMsg
, pMemory
, 8);
2271 case RPC_FC_POINTER
:
2273 unsigned char *saved_buffer
;
2274 int pointer_buffer_mark_set
= 0;
2275 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
2276 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
2277 saved_buffer
= pStubMsg
->Buffer
;
2278 if (pStubMsg
->PointerBufferMark
)
2280 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2281 pStubMsg
->PointerBufferMark
= NULL
;
2282 pointer_buffer_mark_set
= 1;
2285 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2286 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char**)pMemory
, pPointer
);
2287 if (pointer_buffer_mark_set
)
2289 STD_OVERFLOW_CHECK(pStubMsg
);
2290 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2291 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
2293 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2294 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
2295 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2297 pStubMsg
->Buffer
= saved_buffer
+ 4;
2303 case RPC_FC_ALIGNM4
:
2304 ALIGN_POINTER(pMemory
, 4);
2306 case RPC_FC_ALIGNM8
:
2307 ALIGN_POINTER(pMemory
, 8);
2309 case RPC_FC_STRUCTPAD1
:
2310 case RPC_FC_STRUCTPAD2
:
2311 case RPC_FC_STRUCTPAD3
:
2312 case RPC_FC_STRUCTPAD4
:
2313 case RPC_FC_STRUCTPAD5
:
2314 case RPC_FC_STRUCTPAD6
:
2315 case RPC_FC_STRUCTPAD7
:
2316 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2318 case RPC_FC_EMBEDDED_COMPLEX
:
2319 pMemory
+= pFormat
[1];
2321 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2322 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2323 TRACE("embedded complex (size=%ld) <= %p\n", size
, pMemory
);
2324 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
2327 /* for some reason interface pointers aren't generated as
2328 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2329 * they still need the derefencing treatment that pointers are
2331 if (*desc
== RPC_FC_IP
)
2332 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2334 m(pStubMsg
, pMemory
, desc
);
2336 else FIXME("no marshaller for embedded type %02x\n", *desc
);
2343 FIXME("unhandled format 0x%02x\n", *pFormat
);
2351 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2352 unsigned char *pMemory
,
2353 PFORMAT_STRING pFormat
,
2354 PFORMAT_STRING pPointer
)
2356 PFORMAT_STRING desc
;
2360 while (*pFormat
!= RPC_FC_END
) {
2366 safe_copy_from_buffer(pStubMsg
, pMemory
, 1);
2367 TRACE("byte=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2373 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
2374 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2378 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
2379 *(DWORD
*)pMemory
&= 0xffff;
2380 TRACE("enum16=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
2381 if (32767 < *(DWORD
*)pMemory
)
2382 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
2388 safe_copy_from_buffer(pStubMsg
, pMemory
, 4);
2389 TRACE("long=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
2393 safe_copy_from_buffer(pStubMsg
, pMemory
, 8);
2394 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2397 case RPC_FC_POINTER
:
2399 unsigned char *saved_buffer
;
2400 int pointer_buffer_mark_set
= 0;
2401 TRACE("pointer => %p\n", pMemory
);
2402 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2403 saved_buffer
= pStubMsg
->Buffer
;
2404 if (pStubMsg
->PointerBufferMark
)
2406 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2407 pStubMsg
->PointerBufferMark
= NULL
;
2408 pointer_buffer_mark_set
= 1;
2411 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2413 PointerUnmarshall(pStubMsg
, saved_buffer
, (unsigned char**)pMemory
, *(unsigned char**)pMemory
, pPointer
, TRUE
);
2414 if (pointer_buffer_mark_set
)
2416 STD_OVERFLOW_CHECK(pStubMsg
);
2417 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2418 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
2420 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2421 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
2422 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2424 pStubMsg
->Buffer
= saved_buffer
+ 4;
2430 case RPC_FC_ALIGNM4
:
2431 ALIGN_POINTER_CLEAR(pMemory
, 4);
2433 case RPC_FC_ALIGNM8
:
2434 ALIGN_POINTER_CLEAR(pMemory
, 8);
2436 case RPC_FC_STRUCTPAD1
:
2437 case RPC_FC_STRUCTPAD2
:
2438 case RPC_FC_STRUCTPAD3
:
2439 case RPC_FC_STRUCTPAD4
:
2440 case RPC_FC_STRUCTPAD5
:
2441 case RPC_FC_STRUCTPAD6
:
2442 case RPC_FC_STRUCTPAD7
:
2443 memset(pMemory
, 0, *pFormat
- RPC_FC_STRUCTPAD1
+ 1);
2444 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2446 case RPC_FC_EMBEDDED_COMPLEX
:
2447 pMemory
+= pFormat
[1];
2449 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2450 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2451 TRACE("embedded complex (size=%ld) => %p\n", size
, pMemory
);
2452 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
2453 memset(pMemory
, 0, size
); /* just in case */
2456 /* for some reason interface pointers aren't generated as
2457 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2458 * they still need the derefencing treatment that pointers are
2460 if (*desc
== RPC_FC_IP
)
2461 m(pStubMsg
, (unsigned char **)pMemory
, desc
, FALSE
);
2463 m(pStubMsg
, &pMemory
, desc
, FALSE
);
2465 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
2472 FIXME("unhandled format %d\n", *pFormat
);
2480 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2481 unsigned char *pMemory
,
2482 PFORMAT_STRING pFormat
,
2483 PFORMAT_STRING pPointer
)
2485 PFORMAT_STRING desc
;
2489 while (*pFormat
!= RPC_FC_END
) {
2495 safe_buffer_length_increment(pStubMsg
, 1);
2501 safe_buffer_length_increment(pStubMsg
, 2);
2505 safe_buffer_length_increment(pStubMsg
, 2);
2511 safe_buffer_length_increment(pStubMsg
, 4);
2515 safe_buffer_length_increment(pStubMsg
, 8);
2518 case RPC_FC_POINTER
:
2519 if (!pStubMsg
->IgnoreEmbeddedPointers
)
2521 int saved_buffer_length
= pStubMsg
->BufferLength
;
2522 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2523 pStubMsg
->PointerLength
= 0;
2524 if(!pStubMsg
->BufferLength
)
2525 ERR("BufferLength == 0??\n");
2526 PointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
2527 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2528 pStubMsg
->BufferLength
= saved_buffer_length
;
2530 safe_buffer_length_increment(pStubMsg
, 4);
2534 case RPC_FC_ALIGNM4
:
2535 ALIGN_POINTER(pMemory
, 4);
2537 case RPC_FC_ALIGNM8
:
2538 ALIGN_POINTER(pMemory
, 8);
2540 case RPC_FC_STRUCTPAD1
:
2541 case RPC_FC_STRUCTPAD2
:
2542 case RPC_FC_STRUCTPAD3
:
2543 case RPC_FC_STRUCTPAD4
:
2544 case RPC_FC_STRUCTPAD5
:
2545 case RPC_FC_STRUCTPAD6
:
2546 case RPC_FC_STRUCTPAD7
:
2547 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2549 case RPC_FC_EMBEDDED_COMPLEX
:
2550 pMemory
+= pFormat
[1];
2552 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2553 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2554 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
2557 /* for some reason interface pointers aren't generated as
2558 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2559 * they still need the derefencing treatment that pointers are
2561 if (*desc
== RPC_FC_IP
)
2562 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2564 m(pStubMsg
, pMemory
, desc
);
2566 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
2573 FIXME("unhandled format 0x%02x\n", *pFormat
);
2581 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
2582 unsigned char *pMemory
,
2583 PFORMAT_STRING pFormat
,
2584 PFORMAT_STRING pPointer
)
2586 PFORMAT_STRING desc
;
2590 while (*pFormat
!= RPC_FC_END
) {
2612 case RPC_FC_POINTER
:
2613 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
2617 case RPC_FC_ALIGNM4
:
2618 ALIGN_POINTER(pMemory
, 4);
2620 case RPC_FC_ALIGNM8
:
2621 ALIGN_POINTER(pMemory
, 8);
2623 case RPC_FC_STRUCTPAD1
:
2624 case RPC_FC_STRUCTPAD2
:
2625 case RPC_FC_STRUCTPAD3
:
2626 case RPC_FC_STRUCTPAD4
:
2627 case RPC_FC_STRUCTPAD5
:
2628 case RPC_FC_STRUCTPAD6
:
2629 case RPC_FC_STRUCTPAD7
:
2630 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2632 case RPC_FC_EMBEDDED_COMPLEX
:
2633 pMemory
+= pFormat
[1];
2635 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2636 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2637 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
2640 /* for some reason interface pointers aren't generated as
2641 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2642 * they still need the derefencing treatment that pointers are
2644 if (*desc
== RPC_FC_IP
)
2645 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2647 m(pStubMsg
, pMemory
, desc
);
2655 FIXME("unhandled format 0x%02x\n", *pFormat
);
2663 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2664 PFORMAT_STRING pFormat
)
2666 PFORMAT_STRING desc
;
2667 unsigned long size
= 0;
2669 while (*pFormat
!= RPC_FC_END
) {
2676 safe_buffer_increment(pStubMsg
, 1);
2682 safe_buffer_increment(pStubMsg
, 2);
2686 safe_buffer_increment(pStubMsg
, 2);
2692 safe_buffer_increment(pStubMsg
, 4);
2696 safe_buffer_increment(pStubMsg
, 8);
2698 case RPC_FC_POINTER
:
2700 safe_buffer_increment(pStubMsg
, 4);
2701 if (!pStubMsg
->IgnoreEmbeddedPointers
)
2702 FIXME("embedded pointers\n");
2704 case RPC_FC_ALIGNM4
:
2705 ALIGN_LENGTH(size
, 4);
2706 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2708 case RPC_FC_ALIGNM8
:
2709 ALIGN_LENGTH(size
, 8);
2710 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
2712 case RPC_FC_STRUCTPAD1
:
2713 case RPC_FC_STRUCTPAD2
:
2714 case RPC_FC_STRUCTPAD3
:
2715 case RPC_FC_STRUCTPAD4
:
2716 case RPC_FC_STRUCTPAD5
:
2717 case RPC_FC_STRUCTPAD6
:
2718 case RPC_FC_STRUCTPAD7
:
2719 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2721 case RPC_FC_EMBEDDED_COMPLEX
:
2724 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2725 size
+= EmbeddedComplexMemorySize(pStubMsg
, desc
);
2731 FIXME("unhandled format 0x%02x\n", *pFormat
);
2739 unsigned long ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg
,
2740 PFORMAT_STRING pFormat
)
2742 PFORMAT_STRING desc
;
2743 unsigned long size
= 0;
2745 while (*pFormat
!= RPC_FC_END
) {
2767 case RPC_FC_POINTER
:
2768 size
+= sizeof(void *);
2770 case RPC_FC_ALIGNM4
:
2771 ALIGN_LENGTH(size
, 4);
2773 case RPC_FC_ALIGNM8
:
2774 ALIGN_LENGTH(size
, 8);
2776 case RPC_FC_STRUCTPAD1
:
2777 case RPC_FC_STRUCTPAD2
:
2778 case RPC_FC_STRUCTPAD3
:
2779 case RPC_FC_STRUCTPAD4
:
2780 case RPC_FC_STRUCTPAD5
:
2781 case RPC_FC_STRUCTPAD6
:
2782 case RPC_FC_STRUCTPAD7
:
2783 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2785 case RPC_FC_EMBEDDED_COMPLEX
:
2788 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2789 size
+= EmbeddedComplexSize(pStubMsg
, desc
);
2795 FIXME("unhandled format 0x%02x\n", *pFormat
);
2803 /***********************************************************************
2804 * NdrComplexStructMarshall [RPCRT4.@]
2806 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2807 unsigned char *pMemory
,
2808 PFORMAT_STRING pFormat
)
2810 PFORMAT_STRING conf_array
= NULL
;
2811 PFORMAT_STRING pointer_desc
= NULL
;
2812 unsigned char *OldMemory
= pStubMsg
->Memory
;
2813 int pointer_buffer_mark_set
= 0;
2815 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2817 if (!pStubMsg
->PointerBufferMark
)
2819 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2820 /* save buffer length */
2821 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2823 /* get the buffer pointer after complex array data, but before
2825 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- pStubMsg
->BufferStart
;
2826 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2827 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
2828 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2830 /* save it for use by embedded pointer code later */
2831 pStubMsg
->PointerBufferMark
= pStubMsg
->BufferStart
+ pStubMsg
->BufferLength
;
2832 TRACE("difference = 0x%x\n", pStubMsg
->PointerBufferMark
- pStubMsg
->Buffer
);
2833 pointer_buffer_mark_set
= 1;
2835 /* restore the original buffer length */
2836 pStubMsg
->BufferLength
= saved_buffer_length
;
2839 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pFormat
[1] + 1);
2842 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2844 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2847 pStubMsg
->Memory
= pMemory
;
2849 ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2852 NdrConformantArrayMarshall(pStubMsg
, pMemory
, conf_array
);
2854 pStubMsg
->Memory
= OldMemory
;
2856 if (pointer_buffer_mark_set
)
2858 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2859 pStubMsg
->PointerBufferMark
= NULL
;
2862 STD_OVERFLOW_CHECK(pStubMsg
);
2867 /***********************************************************************
2868 * NdrComplexStructUnmarshall [RPCRT4.@]
2870 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2871 unsigned char **ppMemory
,
2872 PFORMAT_STRING pFormat
,
2873 unsigned char fMustAlloc
)
2875 unsigned size
= *(const WORD
*)(pFormat
+2);
2876 PFORMAT_STRING conf_array
= NULL
;
2877 PFORMAT_STRING pointer_desc
= NULL
;
2878 unsigned char *pMemory
;
2879 int pointer_buffer_mark_set
= 0;
2881 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2883 if (!pStubMsg
->PointerBufferMark
)
2885 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2886 /* save buffer pointer */
2887 unsigned char *saved_buffer
= pStubMsg
->Buffer
;
2889 /* get the buffer pointer after complex array data, but before
2891 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2892 NdrComplexStructMemorySize(pStubMsg
, pFormat
);
2893 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2895 /* save it for use by embedded pointer code later */
2896 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2897 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->PointerBufferMark
- saved_buffer
));
2898 pointer_buffer_mark_set
= 1;
2900 /* restore the original buffer */
2901 pStubMsg
->Buffer
= saved_buffer
;
2904 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2906 if (fMustAlloc
|| !*ppMemory
)
2908 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2909 memset(*ppMemory
, 0, size
);
2913 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2915 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2918 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
);
2921 NdrConformantArrayUnmarshall(pStubMsg
, &pMemory
, conf_array
, fMustAlloc
);
2923 if (pointer_buffer_mark_set
)
2925 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2926 pStubMsg
->PointerBufferMark
= NULL
;
2932 /***********************************************************************
2933 * NdrComplexStructBufferSize [RPCRT4.@]
2935 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2936 unsigned char *pMemory
,
2937 PFORMAT_STRING pFormat
)
2939 PFORMAT_STRING conf_array
= NULL
;
2940 PFORMAT_STRING pointer_desc
= NULL
;
2941 unsigned char *OldMemory
= pStubMsg
->Memory
;
2942 int pointer_length_set
= 0;
2944 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2946 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
2948 if(!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
2950 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2951 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2953 /* get the buffer length after complex struct data, but before
2955 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2956 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
2957 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2959 /* save it for use by embedded pointer code later */
2960 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2961 pointer_length_set
= 1;
2962 TRACE("difference = 0x%lx\n", pStubMsg
->PointerLength
- saved_buffer_length
);
2964 /* restore the original buffer length */
2965 pStubMsg
->BufferLength
= saved_buffer_length
;
2969 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2971 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2974 pStubMsg
->Memory
= pMemory
;
2976 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2979 NdrConformantArrayBufferSize(pStubMsg
, pMemory
, conf_array
);
2981 pStubMsg
->Memory
= OldMemory
;
2983 if(pointer_length_set
)
2985 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2986 pStubMsg
->PointerLength
= 0;
2991 /***********************************************************************
2992 * NdrComplexStructMemorySize [RPCRT4.@]
2994 ULONG WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2995 PFORMAT_STRING pFormat
)
2997 unsigned size
= *(const WORD
*)(pFormat
+2);
2998 PFORMAT_STRING conf_array
= NULL
;
2999 PFORMAT_STRING pointer_desc
= NULL
;
3001 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3003 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
3006 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
3008 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3011 ComplexStructMemorySize(pStubMsg
, pFormat
);
3014 NdrConformantArrayMemorySize(pStubMsg
, conf_array
);
3019 /***********************************************************************
3020 * NdrComplexStructFree [RPCRT4.@]
3022 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3023 unsigned char *pMemory
,
3024 PFORMAT_STRING pFormat
)
3026 PFORMAT_STRING conf_array
= NULL
;
3027 PFORMAT_STRING pointer_desc
= NULL
;
3028 unsigned char *OldMemory
= pStubMsg
->Memory
;
3030 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3033 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
3035 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3038 pStubMsg
->Memory
= pMemory
;
3040 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3043 NdrConformantArrayFree(pStubMsg
, pMemory
, conf_array
);
3045 pStubMsg
->Memory
= OldMemory
;
3048 /***********************************************************************
3049 * NdrConformantArrayMarshall [RPCRT4.@]
3051 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3052 unsigned char *pMemory
,
3053 PFORMAT_STRING pFormat
)
3055 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
3056 unsigned char alignment
= pFormat
[1] + 1;
3058 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3059 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
3061 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
3063 WriteConformance(pStubMsg
);
3065 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
3067 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3068 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3069 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
3071 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3076 /***********************************************************************
3077 * NdrConformantArrayUnmarshall [RPCRT4.@]
3079 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3080 unsigned char **ppMemory
,
3081 PFORMAT_STRING pFormat
,
3082 unsigned char fMustAlloc
)
3084 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
3085 unsigned char alignment
= pFormat
[1] + 1;
3086 unsigned char *saved_buffer
;
3088 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3089 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
3091 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
3093 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3094 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3097 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3100 if (!pStubMsg
->IsClient
&& !*ppMemory
)
3101 /* for servers, we just point straight into the RPC buffer */
3102 *ppMemory
= pStubMsg
->Buffer
;
3105 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3106 safe_buffer_increment(pStubMsg
, size
);
3107 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
3109 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
3110 if (*ppMemory
!= saved_buffer
)
3111 memcpy(*ppMemory
, saved_buffer
, size
);
3116 /***********************************************************************
3117 * NdrConformantArrayBufferSize [RPCRT4.@]
3119 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3120 unsigned char *pMemory
,
3121 PFORMAT_STRING pFormat
)
3123 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
3124 unsigned char alignment
= pFormat
[1] + 1;
3126 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3127 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
3129 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
3131 SizeConformance(pStubMsg
);
3133 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
3135 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3136 /* conformance value plus array */
3137 safe_buffer_length_increment(pStubMsg
, size
);
3139 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3142 /***********************************************************************
3143 * NdrConformantArrayMemorySize [RPCRT4.@]
3145 ULONG WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3146 PFORMAT_STRING pFormat
)
3148 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
3149 unsigned char alignment
= pFormat
[1] + 1;
3151 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3152 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
3154 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
3155 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3156 pStubMsg
->MemorySize
+= size
;
3158 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3159 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3160 safe_buffer_increment(pStubMsg
, size
);
3162 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
3164 return pStubMsg
->MemorySize
;
3167 /***********************************************************************
3168 * NdrConformantArrayFree [RPCRT4.@]
3170 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3171 unsigned char *pMemory
,
3172 PFORMAT_STRING pFormat
)
3174 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3175 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
3177 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
3179 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
3183 /***********************************************************************
3184 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3186 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
3187 unsigned char* pMemory
,
3188 PFORMAT_STRING pFormat
)
3191 unsigned char alignment
= pFormat
[1] + 1;
3192 DWORD esize
= *(const WORD
*)(pFormat
+2);
3194 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3196 if (pFormat
[0] != RPC_FC_CVARRAY
)
3198 ERR("invalid format type %x\n", pFormat
[0]);
3199 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3203 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
3204 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
3206 WriteConformance(pStubMsg
);
3207 WriteVariance(pStubMsg
);
3209 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
3211 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3213 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3214 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
3216 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3222 /***********************************************************************
3223 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
3225 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
3226 unsigned char** ppMemory
,
3227 PFORMAT_STRING pFormat
,
3228 unsigned char fMustAlloc
)
3230 ULONG bufsize
, memsize
;
3231 unsigned char alignment
= pFormat
[1] + 1;
3232 DWORD esize
= *(const WORD
*)(pFormat
+2);
3233 unsigned char *saved_buffer
;
3236 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3238 if (pFormat
[0] != RPC_FC_CVARRAY
)
3240 ERR("invalid format type %x\n", pFormat
[0]);
3241 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3245 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
3246 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3248 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3250 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3251 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3252 offset
= pStubMsg
->Offset
;
3254 if (!*ppMemory
|| fMustAlloc
)
3255 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
3256 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3257 safe_buffer_increment(pStubMsg
, bufsize
);
3259 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
3261 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
3267 /***********************************************************************
3268 * NdrConformantVaryingArrayFree [RPCRT4.@]
3270 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
3271 unsigned char* pMemory
,
3272 PFORMAT_STRING pFormat
)
3274 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3276 if (pFormat
[0] != RPC_FC_CVARRAY
)
3278 ERR("invalid format type %x\n", pFormat
[0]);
3279 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3283 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
3284 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
3286 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
3290 /***********************************************************************
3291 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
3293 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
3294 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
3296 unsigned char alignment
= pFormat
[1] + 1;
3297 DWORD esize
= *(const WORD
*)(pFormat
+2);
3299 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3301 if (pFormat
[0] != RPC_FC_CVARRAY
)
3303 ERR("invalid format type %x\n", pFormat
[0]);
3304 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3309 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
3310 /* compute length */
3311 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
3313 SizeConformance(pStubMsg
);
3314 SizeVariance(pStubMsg
);
3316 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
3318 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
3320 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3324 /***********************************************************************
3325 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
3327 ULONG WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
3328 PFORMAT_STRING pFormat
)
3330 ULONG bufsize
, memsize
;
3331 unsigned char alignment
= pFormat
[1] + 1;
3332 DWORD esize
= *(const WORD
*)(pFormat
+2);
3334 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
3336 if (pFormat
[0] != RPC_FC_CVARRAY
)
3338 ERR("invalid format type %x\n", pFormat
[0]);
3339 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3340 return pStubMsg
->MemorySize
;
3343 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
3344 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3346 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3348 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3349 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3351 safe_buffer_increment(pStubMsg
, bufsize
);
3352 pStubMsg
->MemorySize
+= memsize
;
3354 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
3356 return pStubMsg
->MemorySize
;
3360 /***********************************************************************
3361 * NdrComplexArrayMarshall [RPCRT4.@]
3363 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3364 unsigned char *pMemory
,
3365 PFORMAT_STRING pFormat
)
3367 ULONG i
, count
, def
;
3368 BOOL variance_present
;
3369 unsigned char alignment
;
3370 int pointer_buffer_mark_set
= 0;
3372 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3374 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3376 ERR("invalid format type %x\n", pFormat
[0]);
3377 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3381 alignment
= pFormat
[1] + 1;
3383 if (!pStubMsg
->PointerBufferMark
)
3385 /* save buffer fields that may be changed by buffer sizer functions
3386 * and that may be needed later on */
3387 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3388 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
3389 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
3390 unsigned long saved_offset
= pStubMsg
->Offset
;
3391 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
3393 /* get the buffer pointer after complex array data, but before
3395 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- pStubMsg
->BufferStart
;
3396 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3397 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
3398 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3400 /* save it for use by embedded pointer code later */
3401 pStubMsg
->PointerBufferMark
= pStubMsg
->BufferStart
+ pStubMsg
->BufferLength
;
3402 TRACE("difference = 0x%x\n", pStubMsg
->Buffer
- pStubMsg
->BufferStart
);
3403 pointer_buffer_mark_set
= 1;
3405 /* restore fields */
3406 pStubMsg
->ActualCount
= saved_actual_count
;
3407 pStubMsg
->Offset
= saved_offset
;
3408 pStubMsg
->MaxCount
= saved_max_count
;
3409 pStubMsg
->BufferLength
= saved_buffer_length
;
3412 def
= *(const WORD
*)&pFormat
[2];
3415 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3416 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3418 variance_present
= IsConformanceOrVariancePresent(pFormat
);
3419 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3420 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3422 WriteConformance(pStubMsg
);
3423 if (variance_present
)
3424 WriteVariance(pStubMsg
);
3426 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
3428 count
= pStubMsg
->ActualCount
;
3429 for (i
= 0; i
< count
; i
++)
3430 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
3432 STD_OVERFLOW_CHECK(pStubMsg
);
3434 if (pointer_buffer_mark_set
)
3436 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3437 pStubMsg
->PointerBufferMark
= NULL
;
3443 /***********************************************************************
3444 * NdrComplexArrayUnmarshall [RPCRT4.@]
3446 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3447 unsigned char **ppMemory
,
3448 PFORMAT_STRING pFormat
,
3449 unsigned char fMustAlloc
)
3451 ULONG i
, count
, size
;
3452 unsigned char alignment
;
3453 unsigned char *pMemory
;
3454 unsigned char *saved_buffer
;
3455 int pointer_buffer_mark_set
= 0;
3456 int saved_ignore_embedded
;
3458 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3460 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3462 ERR("invalid format type %x\n", pFormat
[0]);
3463 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3467 alignment
= pFormat
[1] + 1;
3469 saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3470 /* save buffer pointer */
3471 saved_buffer
= pStubMsg
->Buffer
;
3472 /* get the buffer pointer after complex array data, but before
3474 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3475 pStubMsg
->MemorySize
= 0;
3476 NdrComplexArrayMemorySize(pStubMsg
, pFormat
);
3477 size
= pStubMsg
->MemorySize
;
3478 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3480 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->Buffer
- saved_buffer
));
3481 if (!pStubMsg
->PointerBufferMark
)
3483 /* save it for use by embedded pointer code later */
3484 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3485 pointer_buffer_mark_set
= 1;
3487 /* restore the original buffer */
3488 pStubMsg
->Buffer
= saved_buffer
;
3492 pFormat
= ReadConformance(pStubMsg
, pFormat
);
3493 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3495 if (fMustAlloc
|| !*ppMemory
)
3497 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3498 memset(*ppMemory
, 0, size
);
3501 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3503 pMemory
= *ppMemory
;
3504 count
= pStubMsg
->ActualCount
;
3505 for (i
= 0; i
< count
; i
++)
3506 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
3508 if (pointer_buffer_mark_set
)
3510 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3511 pStubMsg
->PointerBufferMark
= NULL
;
3517 /***********************************************************************
3518 * NdrComplexArrayBufferSize [RPCRT4.@]
3520 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3521 unsigned char *pMemory
,
3522 PFORMAT_STRING pFormat
)
3524 ULONG i
, count
, def
;
3525 unsigned char alignment
;
3526 BOOL variance_present
;
3527 int pointer_length_set
= 0;
3529 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3531 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3533 ERR("invalid format type %x\n", pFormat
[0]);
3534 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3538 alignment
= pFormat
[1] + 1;
3540 if (!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
3542 /* save buffer fields that may be changed by buffer sizer functions
3543 * and that may be needed later on */
3544 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3545 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
3546 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
3547 unsigned long saved_offset
= pStubMsg
->Offset
;
3548 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
3550 /* get the buffer pointer after complex array data, but before
3552 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3553 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
3554 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3556 /* save it for use by embedded pointer code later */
3557 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3558 pointer_length_set
= 1;
3560 /* restore fields */
3561 pStubMsg
->ActualCount
= saved_actual_count
;
3562 pStubMsg
->Offset
= saved_offset
;
3563 pStubMsg
->MaxCount
= saved_max_count
;
3564 pStubMsg
->BufferLength
= saved_buffer_length
;
3566 def
= *(const WORD
*)&pFormat
[2];
3569 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3570 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3571 SizeConformance(pStubMsg
);
3573 variance_present
= IsConformanceOrVariancePresent(pFormat
);
3574 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3575 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3577 if (variance_present
)
3578 SizeVariance(pStubMsg
);
3580 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
3582 count
= pStubMsg
->ActualCount
;
3583 for (i
= 0; i
< count
; i
++)
3584 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
3586 if(pointer_length_set
)
3588 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3589 pStubMsg
->PointerLength
= 0;
3593 /***********************************************************************
3594 * NdrComplexArrayMemorySize [RPCRT4.@]
3596 ULONG WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3597 PFORMAT_STRING pFormat
)
3599 ULONG i
, count
, esize
, SavedMemorySize
, MemorySize
;
3600 unsigned char alignment
;
3602 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3604 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3606 ERR("invalid format type %x\n", pFormat
[0]);
3607 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3611 alignment
= pFormat
[1] + 1;
3615 pFormat
= ReadConformance(pStubMsg
, pFormat
);
3616 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3618 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3620 SavedMemorySize
= pStubMsg
->MemorySize
;
3622 esize
= ComplexStructSize(pStubMsg
, pFormat
);
3624 MemorySize
= safe_multiply(pStubMsg
->MaxCount
, esize
);
3626 count
= pStubMsg
->ActualCount
;
3627 for (i
= 0; i
< count
; i
++)
3628 ComplexStructMemorySize(pStubMsg
, pFormat
);
3630 pStubMsg
->MemorySize
= SavedMemorySize
;
3632 pStubMsg
->MemorySize
+= MemorySize
;
3636 /***********************************************************************
3637 * NdrComplexArrayFree [RPCRT4.@]
3639 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3640 unsigned char *pMemory
,
3641 PFORMAT_STRING pFormat
)
3643 ULONG i
, count
, def
;
3645 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3647 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3649 ERR("invalid format type %x\n", pFormat
[0]);
3650 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3654 def
= *(const WORD
*)&pFormat
[2];
3657 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3658 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3660 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3661 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3663 count
= pStubMsg
->ActualCount
;
3664 for (i
= 0; i
< count
; i
++)
3665 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
3668 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg
,
3669 USER_MARSHAL_CB_TYPE cbtype
, PFORMAT_STRING pFormat
,
3670 USER_MARSHAL_CB
*umcb
)
3672 umcb
->Flags
= MAKELONG(pStubMsg
->dwDestContext
,
3673 pStubMsg
->RpcMsg
->DataRepresentation
);
3674 umcb
->pStubMsg
= pStubMsg
;
3675 umcb
->pReserve
= NULL
;
3676 umcb
->Signature
= USER_MARSHAL_CB_SIGNATURE
;
3677 umcb
->CBType
= cbtype
;
3678 umcb
->pFormat
= pFormat
;
3679 umcb
->pTypeFormat
= NULL
/* FIXME */;
3682 #define USER_MARSHAL_PTR_PREFIX \
3683 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3684 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3686 /***********************************************************************
3687 * NdrUserMarshalMarshall [RPCRT4.@]
3689 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3690 unsigned char *pMemory
,
3691 PFORMAT_STRING pFormat
)
3693 unsigned flags
= pFormat
[1];
3694 unsigned index
= *(const WORD
*)&pFormat
[2];
3695 unsigned char *saved_buffer
= NULL
;
3696 USER_MARSHAL_CB umcb
;
3698 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3699 TRACE("index=%d\n", index
);
3701 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_MARSHALL
, pFormat
, &umcb
);
3703 if (flags
& USER_MARSHAL_POINTER
)
3705 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
3706 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, USER_MARSHAL_PTR_PREFIX
);
3707 pStubMsg
->Buffer
+= 4;
3708 if (pStubMsg
->PointerBufferMark
)
3710 saved_buffer
= pStubMsg
->Buffer
;
3711 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3712 pStubMsg
->PointerBufferMark
= NULL
;
3714 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 8);
3717 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3720 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
3721 &umcb
.Flags
, pStubMsg
->Buffer
, pMemory
);
3725 STD_OVERFLOW_CHECK(pStubMsg
);
3726 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3727 pStubMsg
->Buffer
= saved_buffer
;
3730 STD_OVERFLOW_CHECK(pStubMsg
);
3735 /***********************************************************************
3736 * NdrUserMarshalUnmarshall [RPCRT4.@]
3738 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3739 unsigned char **ppMemory
,
3740 PFORMAT_STRING pFormat
,
3741 unsigned char fMustAlloc
)
3743 unsigned flags
= pFormat
[1];
3744 unsigned index
= *(const WORD
*)&pFormat
[2];
3745 DWORD memsize
= *(const WORD
*)&pFormat
[4];
3746 unsigned char *saved_buffer
= NULL
;
3747 USER_MARSHAL_CB umcb
;
3749 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3750 TRACE("index=%d\n", index
);
3752 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_UNMARSHALL
, pFormat
, &umcb
);
3754 if (flags
& USER_MARSHAL_POINTER
)
3756 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3757 /* skip pointer prefix */
3758 pStubMsg
->Buffer
+= 4;
3759 if (pStubMsg
->PointerBufferMark
)
3761 saved_buffer
= pStubMsg
->Buffer
;
3762 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3763 pStubMsg
->PointerBufferMark
= NULL
;
3765 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3768 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3770 if (fMustAlloc
|| !*ppMemory
)
3771 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
3774 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
3775 &umcb
.Flags
, pStubMsg
->Buffer
, *ppMemory
);
3779 STD_OVERFLOW_CHECK(pStubMsg
);
3780 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3781 pStubMsg
->Buffer
= saved_buffer
;
3787 /***********************************************************************
3788 * NdrUserMarshalBufferSize [RPCRT4.@]
3790 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3791 unsigned char *pMemory
,
3792 PFORMAT_STRING pFormat
)
3794 unsigned flags
= pFormat
[1];
3795 unsigned index
= *(const WORD
*)&pFormat
[2];
3796 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
3797 USER_MARSHAL_CB umcb
;
3798 unsigned long saved_buffer_length
= 0;
3800 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3801 TRACE("index=%d\n", index
);
3803 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_BUFFER_SIZE
, pFormat
, &umcb
);
3805 if (flags
& USER_MARSHAL_POINTER
)
3807 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
3808 /* skip pointer prefix */
3809 safe_buffer_length_increment(pStubMsg
, 4);
3810 if (pStubMsg
->IgnoreEmbeddedPointers
)
3812 if (pStubMsg
->PointerLength
)
3814 saved_buffer_length
= pStubMsg
->BufferLength
;
3815 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3816 pStubMsg
->PointerLength
= 0;
3818 ALIGN_LENGTH(pStubMsg
->BufferLength
, 8);
3821 ALIGN_LENGTH(pStubMsg
->BufferLength
, (flags
& 0xf) + 1);
3824 TRACE("size=%d\n", bufsize
);
3825 safe_buffer_length_increment(pStubMsg
, bufsize
);
3828 pStubMsg
->BufferLength
=
3829 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
3830 &umcb
.Flags
, pStubMsg
->BufferLength
, pMemory
);
3832 if (saved_buffer_length
)
3834 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3835 pStubMsg
->BufferLength
= saved_buffer_length
;
3840 /***********************************************************************
3841 * NdrUserMarshalMemorySize [RPCRT4.@]
3843 ULONG WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3844 PFORMAT_STRING pFormat
)
3846 unsigned flags
= pFormat
[1];
3847 unsigned index
= *(const WORD
*)&pFormat
[2];
3848 DWORD memsize
= *(const WORD
*)&pFormat
[4];
3849 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
3851 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3852 TRACE("index=%d\n", index
);
3854 pStubMsg
->MemorySize
+= memsize
;
3856 if (flags
& USER_MARSHAL_POINTER
)
3858 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3859 /* skip pointer prefix */
3860 pStubMsg
->Buffer
+= 4;
3861 if (pStubMsg
->IgnoreEmbeddedPointers
)
3862 return pStubMsg
->MemorySize
;
3863 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3866 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3869 FIXME("not implemented for varying buffer size\n");
3871 pStubMsg
->Buffer
+= bufsize
;
3873 return pStubMsg
->MemorySize
;
3876 /***********************************************************************
3877 * NdrUserMarshalFree [RPCRT4.@]
3879 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
3880 unsigned char *pMemory
,
3881 PFORMAT_STRING pFormat
)
3883 /* unsigned flags = pFormat[1]; */
3884 unsigned index
= *(const WORD
*)&pFormat
[2];
3885 USER_MARSHAL_CB umcb
;
3887 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3888 TRACE("index=%d\n", index
);
3890 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_FREE
, pFormat
, &umcb
);
3892 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
3893 &umcb
.Flags
, pMemory
);
3896 /***********************************************************************
3897 * NdrClearOutParameters [RPCRT4.@]
3899 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
3900 PFORMAT_STRING pFormat
,
3903 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
3906 /***********************************************************************
3907 * NdrConvert [RPCRT4.@]
3909 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
3911 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
3912 /* FIXME: since this stub doesn't do any converting, the proper behavior
3913 is to raise an exception */
3916 /***********************************************************************
3917 * NdrConvert2 [RPCRT4.@]
3919 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, LONG NumberParams
)
3921 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3922 pStubMsg
, pFormat
, NumberParams
);
3923 /* FIXME: since this stub doesn't do any converting, the proper behavior
3924 is to raise an exception */
3927 #include "pshpack1.h"
3928 typedef struct _NDR_CSTRUCT_FORMAT
3931 unsigned char alignment
;
3932 unsigned short memory_size
;
3933 short offset_to_array_description
;
3934 } NDR_CSTRUCT_FORMAT
, NDR_CVSTRUCT_FORMAT
;
3935 #include "poppack.h"
3937 /***********************************************************************
3938 * NdrConformantStructMarshall [RPCRT4.@]
3940 unsigned char * WINAPI
NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3941 unsigned char *pMemory
,
3942 PFORMAT_STRING pFormat
)
3944 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3945 PFORMAT_STRING pCArrayFormat
;
3946 ULONG esize
, bufsize
;
3948 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
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
);
3958 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3959 pCStructFormat
->offset_to_array_description
;
3960 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3962 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3963 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3966 esize
= *(const WORD
*)(pCArrayFormat
+2);
3968 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
3969 pCArrayFormat
+ 4, 0);
3971 WriteConformance(pStubMsg
);
3973 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
3975 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3977 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3978 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
3980 ERR("integer overflow of memory_size %u with bufsize %u\n",
3981 pCStructFormat
->memory_size
, bufsize
);
3982 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3984 /* copy constant sized part of struct */
3985 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3986 safe_copy_to_buffer(pStubMsg
, pMemory
, pCStructFormat
->memory_size
+ bufsize
);
3988 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3989 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3994 /***********************************************************************
3995 * NdrConformantStructUnmarshall [RPCRT4.@]
3997 unsigned char * WINAPI
NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3998 unsigned char **ppMemory
,
3999 PFORMAT_STRING pFormat
,
4000 unsigned char fMustAlloc
)
4002 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4003 PFORMAT_STRING pCArrayFormat
;
4004 ULONG esize
, bufsize
;
4005 unsigned char *saved_buffer
;
4007 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4009 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4010 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4012 ERR("invalid format type %x\n", pCStructFormat
->type
);
4013 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4016 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4017 pCStructFormat
->offset_to_array_description
;
4018 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4020 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4021 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4024 esize
= *(const WORD
*)(pCArrayFormat
+2);
4026 pCArrayFormat
= ReadConformance(pStubMsg
, pCArrayFormat
+ 4);
4028 ALIGN_POINTER(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4030 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4032 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4033 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4035 ERR("integer overflow of memory_size %u with bufsize %u\n",
4036 pCStructFormat
->memory_size
, bufsize
);
4037 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4042 SIZE_T size
= pCStructFormat
->memory_size
+ bufsize
;
4043 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4047 if (!pStubMsg
->IsClient
&& !*ppMemory
)
4048 /* for servers, we just point straight into the RPC buffer */
4049 *ppMemory
= pStubMsg
->Buffer
;
4052 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4053 safe_buffer_increment(pStubMsg
, pCStructFormat
->memory_size
+ bufsize
);
4054 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4055 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4057 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
4058 if (*ppMemory
!= saved_buffer
)
4059 memcpy(*ppMemory
, saved_buffer
, pCStructFormat
->memory_size
+ bufsize
);
4064 /***********************************************************************
4065 * NdrConformantStructBufferSize [RPCRT4.@]
4067 void WINAPI
NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4068 unsigned char *pMemory
,
4069 PFORMAT_STRING pFormat
)
4071 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4072 PFORMAT_STRING pCArrayFormat
;
4075 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4077 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4078 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4080 ERR("invalid format type %x\n", pCStructFormat
->type
);
4081 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4084 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4085 pCStructFormat
->offset_to_array_description
;
4086 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4088 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4089 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4092 esize
= *(const WORD
*)(pCArrayFormat
+2);
4094 pCArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
, pCArrayFormat
+4, 0);
4095 SizeConformance(pStubMsg
);
4097 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCStructFormat
->alignment
+ 1);
4099 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4101 safe_buffer_length_increment(pStubMsg
, pCStructFormat
->memory_size
);
4102 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
4104 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4105 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4108 /***********************************************************************
4109 * NdrConformantStructMemorySize [RPCRT4.@]
4111 ULONG WINAPI
NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4112 PFORMAT_STRING pFormat
)
4118 /***********************************************************************
4119 * NdrConformantStructFree [RPCRT4.@]
4121 void WINAPI
NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
4122 unsigned char *pMemory
,
4123 PFORMAT_STRING pFormat
)
4125 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4126 PFORMAT_STRING pCArrayFormat
;
4129 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4131 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4132 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4134 ERR("invalid format type %x\n", pCStructFormat
->type
);
4135 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4139 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4140 pCStructFormat
->offset_to_array_description
;
4141 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4143 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4144 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4147 esize
= *(const WORD
*)(pCArrayFormat
+2);
4149 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4150 pCArrayFormat
+ 4, 0);
4152 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4154 /* copy constant sized part of struct */
4155 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4157 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4158 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4161 /***********************************************************************
4162 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4164 unsigned char * WINAPI
NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4165 unsigned char *pMemory
,
4166 PFORMAT_STRING pFormat
)
4168 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4169 PFORMAT_STRING pCVArrayFormat
;
4170 ULONG esize
, bufsize
;
4172 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4174 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4175 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4177 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4178 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4182 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4183 pCVStructFormat
->offset_to_array_description
;
4184 switch (*pCVArrayFormat
)
4186 case RPC_FC_CVARRAY
:
4187 esize
= *(const WORD
*)(pCVArrayFormat
+2);
4189 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4190 pCVArrayFormat
+ 4, 0);
4191 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4194 case RPC_FC_C_CSTRING
:
4195 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
4196 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
4197 esize
= sizeof(char);
4198 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4199 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4200 pCVArrayFormat
+ 2, 0);
4202 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4204 case RPC_FC_C_WSTRING
:
4205 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
4206 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
4207 esize
= sizeof(WCHAR
);
4208 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4209 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4210 pCVArrayFormat
+ 2, 0);
4212 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4215 ERR("invalid array format type %x\n", *pCVArrayFormat
);
4216 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4220 WriteConformance(pStubMsg
);
4222 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4224 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4226 /* write constant sized part */
4227 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4228 safe_copy_to_buffer(pStubMsg
, pMemory
, pCVStructFormat
->memory_size
);
4230 WriteVariance(pStubMsg
);
4232 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4234 /* write array part */
4235 safe_copy_to_buffer(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
, bufsize
);
4237 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4242 /***********************************************************************
4243 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4245 unsigned char * WINAPI
NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4246 unsigned char **ppMemory
,
4247 PFORMAT_STRING pFormat
,
4248 unsigned char fMustAlloc
)
4250 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4251 PFORMAT_STRING pCVArrayFormat
;
4252 ULONG esize
, bufsize
;
4253 unsigned char cvarray_type
;
4255 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4257 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4258 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4260 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4261 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4265 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4266 pCVStructFormat
->offset_to_array_description
;
4267 cvarray_type
= *pCVArrayFormat
;
4268 switch (cvarray_type
)
4270 case RPC_FC_CVARRAY
:
4271 esize
= *(const WORD
*)(pCVArrayFormat
+2);
4272 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 4);
4274 case RPC_FC_C_CSTRING
:
4275 esize
= sizeof(char);
4276 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4277 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
4279 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
4281 case RPC_FC_C_WSTRING
:
4282 esize
= sizeof(WCHAR
);
4283 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4284 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
4286 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
4289 ERR("invalid array format type %x\n", *pCVArrayFormat
);
4290 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4294 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4296 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4298 /* work out how much memory to allocate if we need to do so */
4299 if (!*ppMemory
|| fMustAlloc
)
4301 SIZE_T size
= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->MaxCount
);
4302 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4305 /* copy the constant data */
4306 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4307 safe_copy_from_buffer(pStubMsg
, *ppMemory
, pCVStructFormat
->memory_size
);
4309 pCVArrayFormat
= ReadVariance(pStubMsg
, pCVArrayFormat
, pStubMsg
->MaxCount
);
4311 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4313 if ((cvarray_type
== RPC_FC_C_CSTRING
) ||
4314 (cvarray_type
== RPC_FC_C_WSTRING
))
4317 /* strings must always have null terminating bytes */
4318 if (bufsize
< esize
)
4320 ERR("invalid string length of %d\n", pStubMsg
->ActualCount
);
4321 RpcRaiseException(RPC_S_INVALID_BOUND
);
4324 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
4325 if (pStubMsg
->Buffer
[i
] != 0)
4327 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
4328 i
, pStubMsg
->Buffer
[i
]);
4329 RpcRaiseException(RPC_S_INVALID_BOUND
);
4334 /* copy the array data */
4335 safe_copy_from_buffer(pStubMsg
, *ppMemory
+ pCVStructFormat
->memory_size
, bufsize
);
4337 if (cvarray_type
== RPC_FC_C_CSTRING
)
4338 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory
+ pCVStructFormat
->memory_size
)));
4339 else if (cvarray_type
== RPC_FC_C_WSTRING
)
4340 TRACE("string=%s\n", debugstr_w((WCHAR
*)(*ppMemory
+ pCVStructFormat
->memory_size
)));
4342 EmbeddedPointerUnmarshall(pStubMsg
, *ppMemory
, *ppMemory
, pFormat
, TRUE
/* FIXME */);
4347 /***********************************************************************
4348 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
4350 void WINAPI
NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4351 unsigned char *pMemory
,
4352 PFORMAT_STRING pFormat
)
4354 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4355 PFORMAT_STRING pCVArrayFormat
;
4358 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4360 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4361 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4363 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4364 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4368 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4369 pCVStructFormat
->offset_to_array_description
;
4370 switch (*pCVArrayFormat
)
4372 case RPC_FC_CVARRAY
:
4373 esize
= *(const WORD
*)(pCVArrayFormat
+2);
4375 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4376 pCVArrayFormat
+ 4, 0);
4377 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4380 case RPC_FC_C_CSTRING
:
4381 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
4382 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
4383 esize
= sizeof(char);
4384 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4385 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4386 pCVArrayFormat
+ 2, 0);
4388 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4390 case RPC_FC_C_WSTRING
:
4391 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
4392 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
4393 esize
= sizeof(WCHAR
);
4394 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4395 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4396 pCVArrayFormat
+ 2, 0);
4398 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4401 ERR("invalid array format type %x\n", *pCVArrayFormat
);
4402 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4406 SizeConformance(pStubMsg
);
4408 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCVStructFormat
->alignment
+ 1);
4410 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4412 safe_buffer_length_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4413 SizeVariance(pStubMsg
);
4414 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
4416 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4419 /***********************************************************************
4420 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4422 ULONG WINAPI
NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4423 PFORMAT_STRING pFormat
)
4425 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4426 PFORMAT_STRING pCVArrayFormat
;
4428 unsigned char cvarray_type
;
4430 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4432 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4433 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4435 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4436 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4440 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4441 pCVStructFormat
->offset_to_array_description
;
4442 cvarray_type
= *pCVArrayFormat
;
4443 switch (cvarray_type
)
4445 case RPC_FC_CVARRAY
:
4446 esize
= *(const WORD
*)(pCVArrayFormat
+2);
4447 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 4);
4449 case RPC_FC_C_CSTRING
:
4450 esize
= sizeof(char);
4451 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4452 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
4454 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
4456 case RPC_FC_C_WSTRING
:
4457 esize
= sizeof(WCHAR
);
4458 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4459 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
4461 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
4464 ERR("invalid array format type %x\n", *pCVArrayFormat
);
4465 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4469 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4471 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4473 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4474 pCVArrayFormat
= ReadVariance(pStubMsg
, pCVArrayFormat
, pStubMsg
->MaxCount
);
4475 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
4477 pStubMsg
->MemorySize
+= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->MaxCount
);
4479 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4481 return pCVStructFormat
->memory_size
+ pStubMsg
->MaxCount
* esize
;
4484 /***********************************************************************
4485 * NdrConformantVaryingStructFree [RPCRT4.@]
4487 void WINAPI
NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
4488 unsigned char *pMemory
,
4489 PFORMAT_STRING pFormat
)
4491 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4492 PFORMAT_STRING pCVArrayFormat
;
4495 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4497 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4498 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4500 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4501 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4505 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4506 pCVStructFormat
->offset_to_array_description
;
4507 switch (*pCVArrayFormat
)
4509 case RPC_FC_CVARRAY
:
4510 esize
= *(const WORD
*)(pCVArrayFormat
+2);
4512 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4513 pCVArrayFormat
+ 4, 0);
4514 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4517 case RPC_FC_C_CSTRING
:
4518 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
4519 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
4520 esize
= sizeof(char);
4521 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4522 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4523 pCVArrayFormat
+ 2, 0);
4525 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4527 case RPC_FC_C_WSTRING
:
4528 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
4529 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
4530 esize
= sizeof(WCHAR
);
4531 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4532 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4533 pCVArrayFormat
+ 2, 0);
4535 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4538 ERR("invalid array format type %x\n", *pCVArrayFormat
);
4539 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4543 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4545 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4548 #include "pshpack1.h"
4552 unsigned char alignment
;
4553 unsigned short total_size
;
4554 } NDR_SMFARRAY_FORMAT
;
4559 unsigned char alignment
;
4560 unsigned long total_size
;
4561 } NDR_LGFARRAY_FORMAT
;
4562 #include "poppack.h"
4564 /***********************************************************************
4565 * NdrFixedArrayMarshall [RPCRT4.@]
4567 unsigned char * WINAPI
NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4568 unsigned char *pMemory
,
4569 PFORMAT_STRING pFormat
)
4571 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4572 unsigned long total_size
;
4574 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4576 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4577 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4579 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4580 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4584 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4586 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4588 total_size
= pSmFArrayFormat
->total_size
;
4589 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4593 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4594 total_size
= pLgFArrayFormat
->total_size
;
4595 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4598 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4599 safe_copy_to_buffer(pStubMsg
, pMemory
, total_size
);
4601 pFormat
= EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4606 /***********************************************************************
4607 * NdrFixedArrayUnmarshall [RPCRT4.@]
4609 unsigned char * WINAPI
NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4610 unsigned char **ppMemory
,
4611 PFORMAT_STRING pFormat
,
4612 unsigned char fMustAlloc
)
4614 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4615 unsigned long total_size
;
4616 unsigned char *saved_buffer
;
4618 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4620 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4621 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4623 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4624 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4628 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4630 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4632 total_size
= pSmFArrayFormat
->total_size
;
4633 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4637 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4638 total_size
= pLgFArrayFormat
->total_size
;
4639 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4643 *ppMemory
= NdrAllocate(pStubMsg
, total_size
);
4646 if (!pStubMsg
->IsClient
&& !*ppMemory
)
4647 /* for servers, we just point straight into the RPC buffer */
4648 *ppMemory
= pStubMsg
->Buffer
;
4651 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4652 safe_buffer_increment(pStubMsg
, total_size
);
4653 pFormat
= EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4655 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
4656 if (*ppMemory
!= saved_buffer
)
4657 memcpy(*ppMemory
, saved_buffer
, total_size
);
4662 /***********************************************************************
4663 * NdrFixedArrayBufferSize [RPCRT4.@]
4665 void WINAPI
NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4666 unsigned char *pMemory
,
4667 PFORMAT_STRING pFormat
)
4669 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4670 unsigned long total_size
;
4672 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4674 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4675 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4677 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4678 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4682 ALIGN_LENGTH(pStubMsg
->BufferLength
, pSmFArrayFormat
->alignment
+ 1);
4684 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4686 total_size
= pSmFArrayFormat
->total_size
;
4687 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4691 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4692 total_size
= pLgFArrayFormat
->total_size
;
4693 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4695 safe_buffer_length_increment(pStubMsg
, total_size
);
4697 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4700 /***********************************************************************
4701 * NdrFixedArrayMemorySize [RPCRT4.@]
4703 ULONG WINAPI
NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4704 PFORMAT_STRING pFormat
)
4706 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4709 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4711 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4712 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4714 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4715 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4719 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4721 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4723 total_size
= pSmFArrayFormat
->total_size
;
4724 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4728 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4729 total_size
= pLgFArrayFormat
->total_size
;
4730 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4732 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4733 safe_buffer_increment(pStubMsg
, total_size
);
4734 pStubMsg
->MemorySize
+= total_size
;
4736 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4741 /***********************************************************************
4742 * NdrFixedArrayFree [RPCRT4.@]
4744 void WINAPI
NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4745 unsigned char *pMemory
,
4746 PFORMAT_STRING pFormat
)
4748 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4750 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4752 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4753 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4755 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4756 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4760 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4761 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4764 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4765 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4768 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4771 /***********************************************************************
4772 * NdrVaryingArrayMarshall [RPCRT4.@]
4774 unsigned char * WINAPI
NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4775 unsigned char *pMemory
,
4776 PFORMAT_STRING pFormat
)
4778 unsigned char alignment
;
4779 DWORD elements
, esize
;
4782 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4784 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4785 (pFormat
[0] != RPC_FC_LGVARRAY
))
4787 ERR("invalid format type %x\n", pFormat
[0]);
4788 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4792 alignment
= pFormat
[1] + 1;
4794 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4797 pFormat
+= sizeof(WORD
);
4798 elements
= *(const WORD
*)pFormat
;
4799 pFormat
+= sizeof(WORD
);
4804 pFormat
+= sizeof(DWORD
);
4805 elements
= *(const DWORD
*)pFormat
;
4806 pFormat
+= sizeof(DWORD
);
4809 esize
= *(const WORD
*)pFormat
;
4810 pFormat
+= sizeof(WORD
);
4812 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4813 if ((pStubMsg
->ActualCount
> elements
) ||
4814 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4816 RpcRaiseException(RPC_S_INVALID_BOUND
);
4820 WriteVariance(pStubMsg
);
4822 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
4824 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4825 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4826 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
4828 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4833 /***********************************************************************
4834 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4836 unsigned char * WINAPI
NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4837 unsigned char **ppMemory
,
4838 PFORMAT_STRING pFormat
,
4839 unsigned char fMustAlloc
)
4841 unsigned char alignment
;
4842 DWORD size
, elements
, esize
;
4844 unsigned char *saved_buffer
;
4847 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4849 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4850 (pFormat
[0] != RPC_FC_LGVARRAY
))
4852 ERR("invalid format type %x\n", pFormat
[0]);
4853 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4857 alignment
= pFormat
[1] + 1;
4859 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4862 size
= *(const WORD
*)pFormat
;
4863 pFormat
+= sizeof(WORD
);
4864 elements
= *(const WORD
*)pFormat
;
4865 pFormat
+= sizeof(WORD
);
4870 size
= *(const DWORD
*)pFormat
;
4871 pFormat
+= sizeof(DWORD
);
4872 elements
= *(const DWORD
*)pFormat
;
4873 pFormat
+= sizeof(DWORD
);
4876 esize
= *(const WORD
*)pFormat
;
4877 pFormat
+= sizeof(WORD
);
4879 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
4881 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4883 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4884 offset
= pStubMsg
->Offset
;
4886 if (!*ppMemory
|| fMustAlloc
)
4887 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4888 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4889 safe_buffer_increment(pStubMsg
, bufsize
);
4891 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4893 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
4898 /***********************************************************************
4899 * NdrVaryingArrayBufferSize [RPCRT4.@]
4901 void WINAPI
NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4902 unsigned char *pMemory
,
4903 PFORMAT_STRING pFormat
)
4905 unsigned char alignment
;
4906 DWORD elements
, esize
;
4908 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4910 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4911 (pFormat
[0] != RPC_FC_LGVARRAY
))
4913 ERR("invalid format type %x\n", pFormat
[0]);
4914 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4918 alignment
= pFormat
[1] + 1;
4920 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4923 pFormat
+= sizeof(WORD
);
4924 elements
= *(const WORD
*)pFormat
;
4925 pFormat
+= sizeof(WORD
);
4930 pFormat
+= sizeof(DWORD
);
4931 elements
= *(const DWORD
*)pFormat
;
4932 pFormat
+= sizeof(DWORD
);
4935 esize
= *(const WORD
*)pFormat
;
4936 pFormat
+= sizeof(WORD
);
4938 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4939 if ((pStubMsg
->ActualCount
> elements
) ||
4940 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4942 RpcRaiseException(RPC_S_INVALID_BOUND
);
4946 SizeVariance(pStubMsg
);
4948 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
4950 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
4952 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4955 /***********************************************************************
4956 * NdrVaryingArrayMemorySize [RPCRT4.@]
4958 ULONG WINAPI
NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4959 PFORMAT_STRING pFormat
)
4961 unsigned char alignment
;
4962 DWORD size
, elements
, esize
;
4964 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4966 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4967 (pFormat
[0] != RPC_FC_LGVARRAY
))
4969 ERR("invalid format type %x\n", pFormat
[0]);
4970 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4974 alignment
= pFormat
[1] + 1;
4976 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4979 size
= *(const WORD
*)pFormat
;
4980 pFormat
+= sizeof(WORD
);
4981 elements
= *(const WORD
*)pFormat
;
4982 pFormat
+= sizeof(WORD
);
4987 size
= *(const DWORD
*)pFormat
;
4988 pFormat
+= sizeof(DWORD
);
4989 elements
= *(const DWORD
*)pFormat
;
4990 pFormat
+= sizeof(DWORD
);
4993 esize
= *(const WORD
*)pFormat
;
4994 pFormat
+= sizeof(WORD
);
4996 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
4998 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
5000 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
5001 pStubMsg
->MemorySize
+= size
;
5003 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5005 return pStubMsg
->MemorySize
;
5008 /***********************************************************************
5009 * NdrVaryingArrayFree [RPCRT4.@]
5011 void WINAPI
NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
5012 unsigned char *pMemory
,
5013 PFORMAT_STRING pFormat
)
5015 unsigned char alignment
;
5018 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5020 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5021 (pFormat
[0] != RPC_FC_LGVARRAY
))
5023 ERR("invalid format type %x\n", pFormat
[0]);
5024 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5028 alignment
= pFormat
[1] + 1;
5030 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5033 pFormat
+= sizeof(WORD
);
5034 elements
= *(const WORD
*)pFormat
;
5035 pFormat
+= sizeof(WORD
);
5040 pFormat
+= sizeof(DWORD
);
5041 elements
= *(const DWORD
*)pFormat
;
5042 pFormat
+= sizeof(DWORD
);
5045 pFormat
+= sizeof(WORD
);
5047 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5048 if ((pStubMsg
->ActualCount
> elements
) ||
5049 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5051 RpcRaiseException(RPC_S_INVALID_BOUND
);
5055 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5058 static ULONG
get_discriminant(unsigned char fc
, const unsigned char *pMemory
)
5071 return *(const USHORT
*)pMemory
;
5075 return *(const ULONG
*)pMemory
;
5077 FIXME("Unhandled base type: 0x%02x\n", fc
);
5082 static PFORMAT_STRING
get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg
,
5083 unsigned long discriminant
,
5084 PFORMAT_STRING pFormat
)
5086 unsigned short num_arms
, arm
, type
;
5088 num_arms
= *(const SHORT
*)pFormat
& 0x0fff;
5090 for(arm
= 0; arm
< num_arms
; arm
++)
5092 if(discriminant
== *(const ULONG
*)pFormat
)
5100 type
= *(const unsigned short*)pFormat
;
5101 TRACE("type %04x\n", type
);
5102 if(arm
== num_arms
) /* default arm extras */
5106 ERR("no arm for 0x%lx and no default case\n", discriminant
);
5107 RpcRaiseException(RPC_S_INVALID_TAG
);
5112 TRACE("falling back to empty default case for 0x%lx\n", discriminant
);
5119 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
, ULONG discriminant
, PFORMAT_STRING pFormat
)
5121 unsigned short type
;
5125 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5129 type
= *(const unsigned short*)pFormat
;
5130 if((type
& 0xff00) == 0x8000)
5132 unsigned char basetype
= LOBYTE(type
);
5133 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &basetype
);
5137 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5138 NDR_MARSHALL m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
5141 unsigned char *saved_buffer
= NULL
;
5142 int pointer_buffer_mark_set
= 0;
5149 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
5150 saved_buffer
= pStubMsg
->Buffer
;
5151 if (pStubMsg
->PointerBufferMark
)
5153 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5154 pStubMsg
->PointerBufferMark
= NULL
;
5155 pointer_buffer_mark_set
= 1;
5158 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
5160 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char **)pMemory
, desc
);
5161 if (pointer_buffer_mark_set
)
5163 STD_OVERFLOW_CHECK(pStubMsg
);
5164 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5165 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5167 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5168 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
5169 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5171 pStubMsg
->Buffer
= saved_buffer
+ 4;
5175 m(pStubMsg
, pMemory
, desc
);
5178 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5183 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5184 unsigned char **ppMemory
,
5186 PFORMAT_STRING pFormat
,
5187 unsigned char fMustAlloc
)
5189 unsigned short type
;
5193 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5197 type
= *(const unsigned short*)pFormat
;
5198 if((type
& 0xff00) == 0x8000)
5200 unsigned char basetype
= LOBYTE(type
);
5201 return NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &basetype
, FALSE
);
5205 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5206 NDR_UNMARSHALL m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
5209 unsigned char *saved_buffer
= NULL
;
5210 int pointer_buffer_mark_set
= 0;
5217 **(void***)ppMemory
= NULL
;
5218 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5219 saved_buffer
= pStubMsg
->Buffer
;
5220 if (pStubMsg
->PointerBufferMark
)
5222 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5223 pStubMsg
->PointerBufferMark
= NULL
;
5224 pointer_buffer_mark_set
= 1;
5227 pStubMsg
->Buffer
+= 4; /* for pointer ID */
5229 if (saved_buffer
+ 4 > pStubMsg
->BufferEnd
)
5231 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5232 saved_buffer
, pStubMsg
->BufferEnd
);
5233 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5236 PointerUnmarshall(pStubMsg
, saved_buffer
, *(unsigned char ***)ppMemory
, **(unsigned char ***)ppMemory
, desc
, fMustAlloc
);
5237 if (pointer_buffer_mark_set
)
5239 STD_OVERFLOW_CHECK(pStubMsg
);
5240 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5241 pStubMsg
->Buffer
= saved_buffer
+ 4;
5245 m(pStubMsg
, ppMemory
, desc
, fMustAlloc
);
5248 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5253 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg
,
5254 unsigned char *pMemory
,
5256 PFORMAT_STRING pFormat
)
5258 unsigned short type
;
5262 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5266 type
= *(const unsigned short*)pFormat
;
5267 if((type
& 0xff00) == 0x8000)
5269 unsigned char basetype
= LOBYTE(type
);
5270 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &basetype
);
5274 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5275 NDR_BUFFERSIZE m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
5284 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
5285 safe_buffer_length_increment(pStubMsg
, 4); /* for pointer ID */
5286 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5288 int saved_buffer_length
= pStubMsg
->BufferLength
;
5289 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
5290 pStubMsg
->PointerLength
= 0;
5291 if(!pStubMsg
->BufferLength
)
5292 ERR("BufferLength == 0??\n");
5293 PointerBufferSize(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5294 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
5295 pStubMsg
->BufferLength
= saved_buffer_length
;
5299 m(pStubMsg
, pMemory
, desc
);
5302 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
5306 static ULONG
union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg
,
5308 PFORMAT_STRING pFormat
)
5310 unsigned short type
, size
;
5312 size
= *(const unsigned short*)pFormat
;
5313 pStubMsg
->Memory
+= size
;
5316 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5320 type
= *(const unsigned short*)pFormat
;
5321 if((type
& 0xff00) == 0x8000)
5323 return NdrBaseTypeMemorySize(pStubMsg
, pFormat
);
5327 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5328 NDR_MEMORYSIZE m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
5329 unsigned char *saved_buffer
;
5338 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5339 saved_buffer
= pStubMsg
->Buffer
;
5340 safe_buffer_increment(pStubMsg
, 4);
5341 ALIGN_LENGTH(pStubMsg
->MemorySize
, 4);
5342 pStubMsg
->MemorySize
+= 4;
5343 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5344 PointerMemorySize(pStubMsg
, saved_buffer
, pFormat
);
5347 return m(pStubMsg
, desc
);
5350 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5353 TRACE("size %d\n", size
);
5357 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg
,
5358 unsigned char *pMemory
,
5360 PFORMAT_STRING pFormat
)
5362 unsigned short type
;
5366 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5370 type
= *(const unsigned short*)pFormat
;
5371 if((type
& 0xff00) != 0x8000)
5373 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5374 NDR_FREE m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
5383 PointerFree(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5386 m(pStubMsg
, pMemory
, desc
);
5392 /***********************************************************************
5393 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5395 unsigned char * WINAPI
NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5396 unsigned char *pMemory
,
5397 PFORMAT_STRING pFormat
)
5399 unsigned char switch_type
;
5400 unsigned char increment
;
5403 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5406 switch_type
= *pFormat
& 0xf;
5407 increment
= (*pFormat
& 0xf0) >> 4;
5410 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, increment
);
5412 switch_value
= get_discriminant(switch_type
, pMemory
);
5413 TRACE("got switch value 0x%x\n", switch_value
);
5415 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &switch_type
);
5416 pMemory
+= increment
;
5418 return union_arm_marshall(pStubMsg
, pMemory
, switch_value
, pFormat
);
5421 /***********************************************************************
5422 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5424 unsigned char * WINAPI
NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5425 unsigned char **ppMemory
,
5426 PFORMAT_STRING pFormat
,
5427 unsigned char fMustAlloc
)
5429 unsigned char switch_type
;
5430 unsigned char increment
;
5432 unsigned short size
;
5433 unsigned char *pMemoryArm
;
5435 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5438 switch_type
= *pFormat
& 0xf;
5439 increment
= (*pFormat
& 0xf0) >> 4;
5442 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
5443 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
5444 TRACE("got switch value 0x%x\n", switch_value
);
5446 size
= *(const unsigned short*)pFormat
+ increment
;
5447 if(!*ppMemory
|| fMustAlloc
)
5448 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5450 NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &switch_type
, FALSE
);
5451 pMemoryArm
= *ppMemory
+ increment
;
5453 return union_arm_unmarshall(pStubMsg
, &pMemoryArm
, switch_value
, pFormat
, fMustAlloc
);
5456 /***********************************************************************
5457 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5459 void WINAPI
NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5460 unsigned char *pMemory
,
5461 PFORMAT_STRING pFormat
)
5463 unsigned char switch_type
;
5464 unsigned char increment
;
5467 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5470 switch_type
= *pFormat
& 0xf;
5471 increment
= (*pFormat
& 0xf0) >> 4;
5474 ALIGN_LENGTH(pStubMsg
->BufferLength
, increment
);
5475 switch_value
= get_discriminant(switch_type
, pMemory
);
5476 TRACE("got switch value 0x%x\n", switch_value
);
5478 /* Add discriminant size */
5479 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&switch_value
, &switch_type
);
5480 pMemory
+= increment
;
5482 union_arm_buffer_size(pStubMsg
, pMemory
, switch_value
, pFormat
);
5485 /***********************************************************************
5486 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5488 ULONG WINAPI
NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5489 PFORMAT_STRING pFormat
)
5491 unsigned char switch_type
;
5492 unsigned char increment
;
5495 switch_type
= *pFormat
& 0xf;
5496 increment
= (*pFormat
& 0xf0) >> 4;
5499 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
5500 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
5501 TRACE("got switch value 0x%x\n", switch_value
);
5503 pStubMsg
->Memory
+= increment
;
5505 return increment
+ union_arm_memory_size(pStubMsg
, switch_value
, pFormat
+ *(const SHORT
*)pFormat
);
5508 /***********************************************************************
5509 * NdrEncapsulatedUnionFree [RPCRT4.@]
5511 void WINAPI
NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
5512 unsigned char *pMemory
,
5513 PFORMAT_STRING pFormat
)
5515 unsigned char switch_type
;
5516 unsigned char increment
;
5519 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5522 switch_type
= *pFormat
& 0xf;
5523 increment
= (*pFormat
& 0xf0) >> 4;
5526 switch_value
= get_discriminant(switch_type
, pMemory
);
5527 TRACE("got switch value 0x%x\n", switch_value
);
5529 pMemory
+= increment
;
5531 union_arm_free(pStubMsg
, pMemory
, switch_value
, pFormat
);
5534 /***********************************************************************
5535 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5537 unsigned char * WINAPI
NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5538 unsigned char *pMemory
,
5539 PFORMAT_STRING pFormat
)
5541 unsigned char switch_type
;
5543 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5546 switch_type
= *pFormat
;
5549 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5550 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5551 /* Marshall discriminant */
5552 NdrBaseTypeMarshall(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
5554 return union_arm_marshall(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5557 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg
,
5558 PFORMAT_STRING
*ppFormat
)
5560 long discriminant
= 0;
5570 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5579 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5580 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5588 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
5589 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5594 FIXME("Unhandled base type: 0x%02x\n", **ppFormat
);
5598 if (pStubMsg
->fHasNewCorrDesc
)
5602 return discriminant
;
5605 /**********************************************************************
5606 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5608 unsigned char * WINAPI
NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5609 unsigned char **ppMemory
,
5610 PFORMAT_STRING pFormat
,
5611 unsigned char fMustAlloc
)
5614 unsigned short size
;
5616 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5619 /* Unmarshall discriminant */
5620 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
5621 TRACE("unmarshalled discriminant %lx\n", discriminant
);
5623 pFormat
+= *(const SHORT
*)pFormat
;
5625 size
= *(const unsigned short*)pFormat
;
5627 if(!*ppMemory
|| fMustAlloc
)
5628 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5630 return union_arm_unmarshall(pStubMsg
, ppMemory
, discriminant
, pFormat
, fMustAlloc
);
5633 /***********************************************************************
5634 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5636 void WINAPI
NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5637 unsigned char *pMemory
,
5638 PFORMAT_STRING pFormat
)
5640 unsigned char switch_type
;
5642 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5645 switch_type
= *pFormat
;
5648 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5649 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5650 /* Add discriminant size */
5651 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
5653 union_arm_buffer_size(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5656 /***********************************************************************
5657 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5659 ULONG WINAPI
NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5660 PFORMAT_STRING pFormat
)
5665 /* Unmarshall discriminant */
5666 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
5667 TRACE("unmarshalled discriminant 0x%x\n", discriminant
);
5669 return union_arm_memory_size(pStubMsg
, discriminant
, pFormat
+ *(const SHORT
*)pFormat
);
5672 /***********************************************************************
5673 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5675 void WINAPI
NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
5676 unsigned char *pMemory
,
5677 PFORMAT_STRING pFormat
)
5679 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5683 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5684 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5686 union_arm_free(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5689 /***********************************************************************
5690 * NdrByteCountPointerMarshall [RPCRT4.@]
5692 unsigned char * WINAPI
NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5693 unsigned char *pMemory
,
5694 PFORMAT_STRING pFormat
)
5700 /***********************************************************************
5701 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5703 unsigned char * WINAPI
NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5704 unsigned char **ppMemory
,
5705 PFORMAT_STRING pFormat
,
5706 unsigned char fMustAlloc
)
5712 /***********************************************************************
5713 * NdrByteCountPointerBufferSize [RPCRT4.@]
5715 void WINAPI
NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5716 unsigned char *pMemory
,
5717 PFORMAT_STRING pFormat
)
5722 /***********************************************************************
5723 * NdrByteCountPointerMemorySize [RPCRT4.@]
5725 ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5726 PFORMAT_STRING pFormat
)
5732 /***********************************************************************
5733 * NdrByteCountPointerFree [RPCRT4.@]
5735 void WINAPI
NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
5736 unsigned char *pMemory
,
5737 PFORMAT_STRING pFormat
)
5742 /***********************************************************************
5743 * NdrXmitOrRepAsMarshall [RPCRT4.@]
5745 unsigned char * WINAPI
NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5746 unsigned char *pMemory
,
5747 PFORMAT_STRING pFormat
)
5753 /***********************************************************************
5754 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
5756 unsigned char * WINAPI
NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5757 unsigned char **ppMemory
,
5758 PFORMAT_STRING pFormat
,
5759 unsigned char fMustAlloc
)
5765 /***********************************************************************
5766 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
5768 void WINAPI
NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5769 unsigned char *pMemory
,
5770 PFORMAT_STRING pFormat
)
5775 /***********************************************************************
5776 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
5778 ULONG WINAPI
NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5779 PFORMAT_STRING pFormat
)
5785 /***********************************************************************
5786 * NdrXmitOrRepAsFree [RPCRT4.@]
5788 void WINAPI
NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg
,
5789 unsigned char *pMemory
,
5790 PFORMAT_STRING pFormat
)
5795 #include "pshpack1.h"
5799 unsigned char flags_type
; /* flags in upper nibble, type in lower nibble */
5803 #include "poppack.h"
5805 /***********************************************************************
5806 * NdrRangeMarshall [internal]
5808 unsigned char *WINAPI
NdrRangeMarshall(
5809 PMIDL_STUB_MESSAGE pStubMsg
,
5810 unsigned char *pMemory
,
5811 PFORMAT_STRING pFormat
)
5813 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5814 unsigned char base_type
;
5816 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5818 if (pRange
->type
!= RPC_FC_RANGE
)
5820 ERR("invalid format type %x\n", pRange
->type
);
5821 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5825 base_type
= pRange
->flags_type
& 0xf;
5827 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &base_type
);
5830 /***********************************************************************
5831 * NdrRangeUnmarshall
5833 unsigned char *WINAPI
NdrRangeUnmarshall(
5834 PMIDL_STUB_MESSAGE pStubMsg
,
5835 unsigned char **ppMemory
,
5836 PFORMAT_STRING pFormat
,
5837 unsigned char fMustAlloc
)
5839 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5840 unsigned char base_type
;
5842 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
5844 if (pRange
->type
!= RPC_FC_RANGE
)
5846 ERR("invalid format type %x\n", pRange
->type
);
5847 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5850 base_type
= pRange
->flags_type
& 0xf;
5852 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5853 base_type
, pRange
->low_value
, pRange
->high_value
);
5855 #define RANGE_UNMARSHALL(type, format_spec) \
5858 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5859 if (fMustAlloc || !*ppMemory) \
5860 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5861 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
5863 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
5864 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
5865 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
5867 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5868 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5870 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5871 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5872 (type)pRange->high_value); \
5873 RpcRaiseException(RPC_S_INVALID_BOUND); \
5876 TRACE("*ppMemory: %p\n", *ppMemory); \
5877 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5878 pStubMsg->Buffer += sizeof(type); \
5885 RANGE_UNMARSHALL(UCHAR
, "%d");
5886 TRACE("value: 0x%02x\n", **ppMemory
);
5890 RANGE_UNMARSHALL(CHAR
, "%u");
5891 TRACE("value: 0x%02x\n", **ppMemory
);
5893 case RPC_FC_WCHAR
: /* FIXME: valid? */
5895 RANGE_UNMARSHALL(USHORT
, "%u");
5896 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5899 RANGE_UNMARSHALL(SHORT
, "%d");
5900 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5903 RANGE_UNMARSHALL(LONG
, "%d");
5904 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5907 RANGE_UNMARSHALL(ULONG
, "%u");
5908 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5912 FIXME("Unhandled enum type\n");
5914 case RPC_FC_ERROR_STATUS_T
: /* FIXME: valid? */
5919 ERR("invalid range base type: 0x%02x\n", base_type
);
5920 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5926 /***********************************************************************
5927 * NdrRangeBufferSize [internal]
5929 void WINAPI
NdrRangeBufferSize(
5930 PMIDL_STUB_MESSAGE pStubMsg
,
5931 unsigned char *pMemory
,
5932 PFORMAT_STRING pFormat
)
5934 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5935 unsigned char base_type
;
5937 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5939 if (pRange
->type
!= RPC_FC_RANGE
)
5941 ERR("invalid format type %x\n", pRange
->type
);
5942 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5944 base_type
= pRange
->flags_type
& 0xf;
5946 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &base_type
);
5949 /***********************************************************************
5950 * NdrRangeMemorySize [internal]
5952 ULONG WINAPI
NdrRangeMemorySize(
5953 PMIDL_STUB_MESSAGE pStubMsg
,
5954 PFORMAT_STRING pFormat
)
5956 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5957 unsigned char base_type
;
5959 if (pRange
->type
!= RPC_FC_RANGE
)
5961 ERR("invalid format type %x\n", pRange
->type
);
5962 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5965 base_type
= pRange
->flags_type
& 0xf;
5967 return NdrBaseTypeMemorySize(pStubMsg
, &base_type
);
5970 /***********************************************************************
5971 * NdrRangeFree [internal]
5973 void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg
,
5974 unsigned char *pMemory
,
5975 PFORMAT_STRING pFormat
)
5977 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5982 /***********************************************************************
5983 * NdrBaseTypeMarshall [internal]
5985 static unsigned char *WINAPI
NdrBaseTypeMarshall(
5986 PMIDL_STUB_MESSAGE pStubMsg
,
5987 unsigned char *pMemory
,
5988 PFORMAT_STRING pFormat
)
5990 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5998 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(UCHAR
));
5999 TRACE("value: 0x%02x\n", *pMemory
);
6004 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(USHORT
));
6005 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(USHORT
));
6006 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
6010 case RPC_FC_ERROR_STATUS_T
:
6012 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(ULONG
));
6013 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONG
));
6014 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
6017 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(float));
6018 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
6021 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(double));
6022 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
6025 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(ULONGLONG
));
6026 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONGLONG
));
6027 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
6030 /* only 16-bits on the wire, so do a sanity check */
6031 if (*(UINT
*)pMemory
> SHRT_MAX
)
6032 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
6033 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(USHORT
));
6034 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6035 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6036 *(USHORT
*)pStubMsg
->Buffer
= *(UINT
*)pMemory
;
6037 pStubMsg
->Buffer
+= sizeof(USHORT
);
6038 TRACE("value: 0x%04x\n", *(UINT
*)pMemory
);
6043 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6046 /* FIXME: what is the correct return value? */
6050 /***********************************************************************
6051 * NdrBaseTypeUnmarshall [internal]
6053 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(
6054 PMIDL_STUB_MESSAGE pStubMsg
,
6055 unsigned char **ppMemory
,
6056 PFORMAT_STRING pFormat
,
6057 unsigned char fMustAlloc
)
6059 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6061 #define BASE_TYPE_UNMARSHALL(type) \
6062 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6063 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6065 *ppMemory = pStubMsg->Buffer; \
6066 TRACE("*ppMemory: %p\n", *ppMemory); \
6071 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6072 TRACE("*ppMemory: %p\n", *ppMemory); \
6073 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
6075 safe_buffer_increment(pStubMsg, sizeof(type));
6083 BASE_TYPE_UNMARSHALL(UCHAR
);
6084 TRACE("value: 0x%02x\n", **ppMemory
);
6089 BASE_TYPE_UNMARSHALL(USHORT
);
6090 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6094 case RPC_FC_ERROR_STATUS_T
:
6096 BASE_TYPE_UNMARSHALL(ULONG
);
6097 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6100 BASE_TYPE_UNMARSHALL(float);
6101 TRACE("value: %f\n", **(float **)ppMemory
);
6104 BASE_TYPE_UNMARSHALL(double);
6105 TRACE("value: %f\n", **(double **)ppMemory
);
6108 BASE_TYPE_UNMARSHALL(ULONGLONG
);
6109 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG
**)ppMemory
));
6112 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
6113 if (fMustAlloc
|| !*ppMemory
)
6114 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT
));
6115 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > pStubMsg
->BufferEnd
)
6116 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6117 TRACE("*ppMemory: %p\n", *ppMemory
);
6118 /* 16-bits on the wire, but int in memory */
6119 **(UINT
**)ppMemory
= *(USHORT
*)pStubMsg
->Buffer
;
6120 pStubMsg
->Buffer
+= sizeof(USHORT
);
6121 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
6126 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6128 #undef BASE_TYPE_UNMARSHALL
6130 /* FIXME: what is the correct return value? */
6135 /***********************************************************************
6136 * NdrBaseTypeBufferSize [internal]
6138 static void WINAPI
NdrBaseTypeBufferSize(
6139 PMIDL_STUB_MESSAGE pStubMsg
,
6140 unsigned char *pMemory
,
6141 PFORMAT_STRING pFormat
)
6143 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6151 safe_buffer_length_increment(pStubMsg
, sizeof(UCHAR
));
6157 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(USHORT
));
6158 safe_buffer_length_increment(pStubMsg
, sizeof(USHORT
));
6163 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONG
));
6164 safe_buffer_length_increment(pStubMsg
, sizeof(ULONG
));
6167 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(float));
6168 safe_buffer_length_increment(pStubMsg
, sizeof(float));
6171 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(double));
6172 safe_buffer_length_increment(pStubMsg
, sizeof(double));
6175 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONGLONG
));
6176 safe_buffer_length_increment(pStubMsg
, sizeof(ULONGLONG
));
6178 case RPC_FC_ERROR_STATUS_T
:
6179 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(error_status_t
));
6180 safe_buffer_length_increment(pStubMsg
, sizeof(error_status_t
));
6185 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6189 /***********************************************************************
6190 * NdrBaseTypeMemorySize [internal]
6192 static ULONG WINAPI
NdrBaseTypeMemorySize(
6193 PMIDL_STUB_MESSAGE pStubMsg
,
6194 PFORMAT_STRING pFormat
)
6196 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg
, *pFormat
);
6204 safe_buffer_increment(pStubMsg
, sizeof(UCHAR
));
6205 pStubMsg
->MemorySize
+= sizeof(UCHAR
);
6206 return sizeof(UCHAR
);
6210 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6211 pStubMsg
->MemorySize
+= sizeof(USHORT
);
6212 return sizeof(USHORT
);
6216 safe_buffer_increment(pStubMsg
, sizeof(ULONG
));
6217 pStubMsg
->MemorySize
+= sizeof(ULONG
);
6218 return sizeof(ULONG
);
6220 safe_buffer_increment(pStubMsg
, sizeof(float));
6221 pStubMsg
->MemorySize
+= sizeof(float);
6222 return sizeof(float);
6224 safe_buffer_increment(pStubMsg
, sizeof(double));
6225 pStubMsg
->MemorySize
+= sizeof(double);
6226 return sizeof(double);
6228 safe_buffer_increment(pStubMsg
, sizeof(ULONGLONG
));
6229 pStubMsg
->MemorySize
+= sizeof(ULONGLONG
);
6230 return sizeof(ULONGLONG
);
6231 case RPC_FC_ERROR_STATUS_T
:
6232 safe_buffer_increment(pStubMsg
, sizeof(error_status_t
));
6233 pStubMsg
->MemorySize
+= sizeof(error_status_t
);
6234 return sizeof(error_status_t
);
6236 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6237 pStubMsg
->MemorySize
+= sizeof(UINT
);
6238 return sizeof(UINT
);
6240 pStubMsg
->MemorySize
+= sizeof(void *);
6241 return sizeof(void *);
6243 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6248 /***********************************************************************
6249 * NdrBaseTypeFree [internal]
6251 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6252 unsigned char *pMemory
,
6253 PFORMAT_STRING pFormat
)
6255 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6260 /***********************************************************************
6261 * NdrContextHandleBufferSize [internal]
6263 static void WINAPI
NdrContextHandleBufferSize(
6264 PMIDL_STUB_MESSAGE pStubMsg
,
6265 unsigned char *pMemory
,
6266 PFORMAT_STRING pFormat
)
6268 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6270 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6272 ERR("invalid format type %x\n", *pFormat
);
6273 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6275 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
6276 safe_buffer_length_increment(pStubMsg
, cbNDRContext
);
6279 /***********************************************************************
6280 * NdrContextHandleMarshall [internal]
6282 static unsigned char *WINAPI
NdrContextHandleMarshall(
6283 PMIDL_STUB_MESSAGE pStubMsg
,
6284 unsigned char *pMemory
,
6285 PFORMAT_STRING pFormat
)
6287 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6289 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6291 ERR("invalid format type %x\n", *pFormat
);
6292 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6294 TRACE("flags: 0x%02x\n", pFormat
[1]);
6296 if (pFormat
[1] & 0x80)
6297 NdrClientContextMarshall(pStubMsg
, *(NDR_CCONTEXT
**)pMemory
, FALSE
);
6299 NdrClientContextMarshall(pStubMsg
, (NDR_CCONTEXT
*)pMemory
, FALSE
);
6304 /***********************************************************************
6305 * NdrContextHandleUnmarshall [internal]
6307 static unsigned char *WINAPI
NdrContextHandleUnmarshall(
6308 PMIDL_STUB_MESSAGE pStubMsg
,
6309 unsigned char **ppMemory
,
6310 PFORMAT_STRING pFormat
,
6311 unsigned char fMustAlloc
)
6313 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg
,
6314 ppMemory
, pFormat
, fMustAlloc
? "TRUE": "FALSE");
6316 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6318 ERR("invalid format type %x\n", *pFormat
);
6319 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6321 TRACE("flags: 0x%02x\n", pFormat
[1]);
6323 /* [out]-only or [ret] param */
6324 if ((pFormat
[1] & 0x60) == 0x20)
6325 **(NDR_CCONTEXT
**)ppMemory
= NULL
;
6326 NdrClientContextUnmarshall(pStubMsg
, *(NDR_CCONTEXT
**)ppMemory
, pStubMsg
->RpcMsg
->Handle
);
6331 /***********************************************************************
6332 * NdrClientContextMarshall [RPCRT4.@]
6334 void WINAPI
NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6335 NDR_CCONTEXT ContextHandle
,
6338 TRACE("(%p, %p, %d)\n", pStubMsg
, ContextHandle
, fCheck
);
6340 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
6342 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6344 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6345 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6346 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6349 /* FIXME: what does fCheck do? */
6350 NDRCContextMarshall(ContextHandle
,
6353 pStubMsg
->Buffer
+= cbNDRContext
;
6356 /***********************************************************************
6357 * NdrClientContextUnmarshall [RPCRT4.@]
6359 void WINAPI
NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6360 NDR_CCONTEXT
* pContextHandle
,
6361 RPC_BINDING_HANDLE BindHandle
)
6363 TRACE("(%p, %p, %p)\n", pStubMsg
, pContextHandle
, BindHandle
);
6365 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6367 if (pStubMsg
->Buffer
+ cbNDRContext
> pStubMsg
->BufferEnd
)
6368 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6370 NDRCContextUnmarshall(pContextHandle
,
6373 pStubMsg
->RpcMsg
->DataRepresentation
);
6375 pStubMsg
->Buffer
+= cbNDRContext
;
6378 void WINAPI
NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6379 NDR_SCONTEXT ContextHandle
,
6380 NDR_RUNDOWN RundownRoutine
)
6382 TRACE("(%p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
);
6384 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6386 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6388 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6389 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6390 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6393 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
6394 pStubMsg
->Buffer
, RundownRoutine
, NULL
,
6395 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
6396 pStubMsg
->Buffer
+= cbNDRContext
;
6399 NDR_SCONTEXT WINAPI
NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
)
6401 NDR_SCONTEXT ContextHandle
;
6403 TRACE("(%p)\n", pStubMsg
);
6405 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6407 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6409 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6410 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6411 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6414 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
6416 pStubMsg
->RpcMsg
->DataRepresentation
,
6417 NULL
, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
6418 pStubMsg
->Buffer
+= cbNDRContext
;
6420 return ContextHandle
;
6423 void WINAPI
NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg
,
6424 unsigned char* pMemory
,
6425 PFORMAT_STRING pFormat
)
6427 FIXME("(%p, %p, %p): stub\n", pStubMsg
, pMemory
, pFormat
);
6430 NDR_SCONTEXT WINAPI
NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg
,
6431 PFORMAT_STRING pFormat
)
6433 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6434 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6436 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
6438 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
6439 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
6440 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
6441 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
6442 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
6444 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
6445 if_id
= &sif
->InterfaceId
;
6448 return NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
, NULL
,
6449 pStubMsg
->RpcMsg
->DataRepresentation
, if_id
,
6453 void WINAPI
NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6454 NDR_SCONTEXT ContextHandle
,
6455 NDR_RUNDOWN RundownRoutine
,
6456 PFORMAT_STRING pFormat
)
6458 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6459 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6461 TRACE("(%p, %p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
, pFormat
);
6463 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6465 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6467 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6468 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6469 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6472 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
6473 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
6474 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
6475 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
6476 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
6478 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
6479 if_id
= &sif
->InterfaceId
;
6482 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
6483 pStubMsg
->Buffer
, RundownRoutine
, if_id
, flags
);
6484 pStubMsg
->Buffer
+= cbNDRContext
;
6487 NDR_SCONTEXT WINAPI
NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6488 PFORMAT_STRING pFormat
)
6490 NDR_SCONTEXT ContextHandle
;
6491 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6492 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6494 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
6496 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6498 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6500 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6501 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6502 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6505 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
6506 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
6507 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
6508 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
6509 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
6511 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
6512 if_id
= &sif
->InterfaceId
;
6515 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
6517 pStubMsg
->RpcMsg
->DataRepresentation
,
6519 pStubMsg
->Buffer
+= cbNDRContext
;
6521 return ContextHandle
;
6524 /***********************************************************************
6525 * NdrCorrelationInitialize [RPCRT4.@]
6527 * Initializes correlation validity checking.
6530 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6531 * pMemory [I] Pointer to memory to use as a cache.
6532 * CacheSize [I] Size of the memory pointed to by pMemory.
6533 * Flags [I] Reserved. Set to zero.
6538 void WINAPI
NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg
, void *pMemory
, ULONG CacheSize
, ULONG Flags
)
6540 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg
, pMemory
, CacheSize
, Flags
);
6541 pStubMsg
->fHasNewCorrDesc
= TRUE
;
6544 /***********************************************************************
6545 * NdrCorrelationPass [RPCRT4.@]
6547 * Performs correlation validity checking.
6550 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6555 void WINAPI
NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg
)
6557 FIXME("(%p): stub\n", pStubMsg
);
6560 /***********************************************************************
6561 * NdrCorrelationFree [RPCRT4.@]
6563 * Frees any resources used while unmarshalling parameters that need
6564 * correlation validity checking.
6567 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6572 void WINAPI
NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg
)
6574 FIXME("(%p): stub\n", pStubMsg
);