4 * Copyright 2002 Greg Turner
5 * Copyright 2003-2006 CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 * - Byte count pointers
24 * - transmit_as/represent as
25 * - Multi-dimensional arrays
26 * - Conversion functions (NdrConvert)
27 * - Checks for integer addition overflow in base type and user marshall functions
43 #include "wine/unicode.h"
44 #include "wine/rpcfc.h"
46 #include "wine/debug.h"
48 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
51 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
52 (*((UINT32 *)(pchar)) = (uint32))
54 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
55 (*((UINT32 *)(pchar)))
57 /* these would work for i386 too, but less efficient */
58 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
59 (*(pchar) = LOBYTE(LOWORD(uint32)), \
60 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
61 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
62 *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
63 (uint32)) /* allow as r-value */
65 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
67 MAKEWORD(*(pchar), *((pchar)+1)), \
68 MAKEWORD(*((pchar)+2), *((pchar)+3))))
71 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
72 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
73 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
74 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
75 *(pchar) = HIBYTE(HIWORD(uint32)), \
76 (uint32)) /* allow as r-value */
78 #define BIG_ENDIAN_UINT32_READ(pchar) \
80 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
81 MAKEWORD(*((pchar)+1), *(pchar))))
83 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
84 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
85 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
86 # define NDR_LOCAL_UINT32_READ(pchar) \
87 BIG_ENDIAN_UINT32_READ(pchar)
89 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
90 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
91 # define NDR_LOCAL_UINT32_READ(pchar) \
92 LITTLE_ENDIAN_UINT32_READ(pchar)
95 /* _Align must be the desired alignment,
96 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
97 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
98 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
99 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
100 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
101 #define ALIGN_POINTER_CLEAR(_Ptr, _Align) \
103 memset((_Ptr), 0, ((_Align) - (ULONG_PTR)(_Ptr)) & ((_Align) - 1)); \
104 ALIGN_POINTER(_Ptr, _Align); \
107 #define STD_OVERFLOW_CHECK(_Msg) do { \
108 TRACE("buffer=%d/%d\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
109 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
110 ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
113 #define NDR_TABLE_SIZE 128
114 #define NDR_TABLE_MASK 127
116 static unsigned char *WINAPI
NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
117 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
118 static void WINAPI
NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
119 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
120 static ULONG WINAPI
NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
122 static unsigned char *WINAPI
NdrContextHandleMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
123 static void WINAPI
NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
124 static unsigned char *WINAPI
NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
126 const NDR_MARSHALL NdrMarshaller
[NDR_TABLE_SIZE
] = {
128 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
129 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
130 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
131 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
135 NdrPointerMarshall
, NdrPointerMarshall
,
136 NdrPointerMarshall
, NdrPointerMarshall
,
138 NdrSimpleStructMarshall
, NdrSimpleStructMarshall
,
139 NdrConformantStructMarshall
, NdrConformantStructMarshall
,
140 NdrConformantVaryingStructMarshall
,
141 NdrComplexStructMarshall
,
143 NdrConformantArrayMarshall
,
144 NdrConformantVaryingArrayMarshall
,
145 NdrFixedArrayMarshall
, NdrFixedArrayMarshall
,
146 NdrVaryingArrayMarshall
, NdrVaryingArrayMarshall
,
147 NdrComplexArrayMarshall
,
149 NdrConformantStringMarshall
, 0, 0,
150 NdrConformantStringMarshall
,
151 NdrNonConformantStringMarshall
, 0, 0, 0,
153 NdrEncapsulatedUnionMarshall
,
154 NdrNonEncapsulatedUnionMarshall
,
155 NdrByteCountPointerMarshall
,
156 NdrXmitOrRepAsMarshall
, NdrXmitOrRepAsMarshall
,
158 NdrInterfacePointerMarshall
,
160 NdrContextHandleMarshall
,
163 NdrUserMarshalMarshall
,
168 const NDR_UNMARSHALL NdrUnmarshaller
[NDR_TABLE_SIZE
] = {
170 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
171 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
172 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
173 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
175 NdrBaseTypeUnmarshall
,
177 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
178 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
180 NdrSimpleStructUnmarshall
, NdrSimpleStructUnmarshall
,
181 NdrConformantStructUnmarshall
, NdrConformantStructUnmarshall
,
182 NdrConformantVaryingStructUnmarshall
,
183 NdrComplexStructUnmarshall
,
185 NdrConformantArrayUnmarshall
,
186 NdrConformantVaryingArrayUnmarshall
,
187 NdrFixedArrayUnmarshall
, NdrFixedArrayUnmarshall
,
188 NdrVaryingArrayUnmarshall
, NdrVaryingArrayUnmarshall
,
189 NdrComplexArrayUnmarshall
,
191 NdrConformantStringUnmarshall
, 0, 0,
192 NdrConformantStringUnmarshall
,
193 NdrNonConformantStringUnmarshall
, 0, 0, 0,
195 NdrEncapsulatedUnionUnmarshall
,
196 NdrNonEncapsulatedUnionUnmarshall
,
197 NdrByteCountPointerUnmarshall
,
198 NdrXmitOrRepAsUnmarshall
, NdrXmitOrRepAsUnmarshall
,
200 NdrInterfacePointerUnmarshall
,
202 NdrContextHandleUnmarshall
,
205 NdrUserMarshalUnmarshall
,
210 const NDR_BUFFERSIZE NdrBufferSizer
[NDR_TABLE_SIZE
] = {
212 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
213 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
214 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
215 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
217 NdrBaseTypeBufferSize
,
219 NdrPointerBufferSize
, NdrPointerBufferSize
,
220 NdrPointerBufferSize
, NdrPointerBufferSize
,
222 NdrSimpleStructBufferSize
, NdrSimpleStructBufferSize
,
223 NdrConformantStructBufferSize
, NdrConformantStructBufferSize
,
224 NdrConformantVaryingStructBufferSize
,
225 NdrComplexStructBufferSize
,
227 NdrConformantArrayBufferSize
,
228 NdrConformantVaryingArrayBufferSize
,
229 NdrFixedArrayBufferSize
, NdrFixedArrayBufferSize
,
230 NdrVaryingArrayBufferSize
, NdrVaryingArrayBufferSize
,
231 NdrComplexArrayBufferSize
,
233 NdrConformantStringBufferSize
, 0, 0,
234 NdrConformantStringBufferSize
,
235 NdrNonConformantStringBufferSize
, 0, 0, 0,
237 NdrEncapsulatedUnionBufferSize
,
238 NdrNonEncapsulatedUnionBufferSize
,
239 NdrByteCountPointerBufferSize
,
240 NdrXmitOrRepAsBufferSize
, NdrXmitOrRepAsBufferSize
,
242 NdrInterfacePointerBufferSize
,
244 NdrContextHandleBufferSize
,
247 NdrUserMarshalBufferSize
,
252 const NDR_MEMORYSIZE NdrMemorySizer
[NDR_TABLE_SIZE
] = {
254 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
255 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
256 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
257 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
259 NdrBaseTypeMemorySize
,
261 NdrPointerMemorySize
, NdrPointerMemorySize
,
262 NdrPointerMemorySize
, NdrPointerMemorySize
,
264 NdrSimpleStructMemorySize
, NdrSimpleStructMemorySize
,
265 NdrConformantStructMemorySize
, NdrConformantStructMemorySize
,
266 NdrConformantVaryingStructMemorySize
,
267 NdrComplexStructMemorySize
,
269 NdrConformantArrayMemorySize
,
270 NdrConformantVaryingArrayMemorySize
,
271 NdrFixedArrayMemorySize
, NdrFixedArrayMemorySize
,
272 NdrVaryingArrayMemorySize
, NdrVaryingArrayMemorySize
,
273 NdrComplexArrayMemorySize
,
275 NdrConformantStringMemorySize
, 0, 0,
276 NdrConformantStringMemorySize
,
277 NdrNonConformantStringMemorySize
, 0, 0, 0,
279 NdrEncapsulatedUnionMemorySize
,
280 NdrNonEncapsulatedUnionMemorySize
,
281 NdrByteCountPointerMemorySize
,
282 NdrXmitOrRepAsMemorySize
, NdrXmitOrRepAsMemorySize
,
284 NdrInterfacePointerMemorySize
,
289 NdrUserMarshalMemorySize
,
294 const NDR_FREE NdrFreer
[NDR_TABLE_SIZE
] = {
296 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
297 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
298 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
299 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
303 NdrPointerFree
, NdrPointerFree
,
304 NdrPointerFree
, NdrPointerFree
,
306 NdrSimpleStructFree
, NdrSimpleStructFree
,
307 NdrConformantStructFree
, NdrConformantStructFree
,
308 NdrConformantVaryingStructFree
,
309 NdrComplexStructFree
,
311 NdrConformantArrayFree
,
312 NdrConformantVaryingArrayFree
,
313 NdrFixedArrayFree
, NdrFixedArrayFree
,
314 NdrVaryingArrayFree
, NdrVaryingArrayFree
,
320 NdrEncapsulatedUnionFree
,
321 NdrNonEncapsulatedUnionFree
,
323 NdrXmitOrRepAsFree
, NdrXmitOrRepAsFree
,
325 NdrInterfacePointerFree
,
336 typedef struct _NDR_MEMORY_LIST
341 struct _NDR_MEMORY_LIST
*next
;
344 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
346 /***********************************************************************
347 * NdrAllocate [RPCRT4.@]
349 * Allocates a block of memory using pStubMsg->pfnAllocate.
352 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
353 * len [I] Size of memory block to allocate.
356 * The memory block of size len that was allocated.
359 * The memory block is always 8-byte aligned.
360 * If the function is unable to allocate memory an ERROR_OUTOFMEMORY
361 * exception is raised.
363 void * WINAPI
NdrAllocate(MIDL_STUB_MESSAGE
*pStubMsg
, size_t len
)
368 NDR_MEMORY_LIST
*mem_list
;
370 aligned_len
= ALIGNED_LENGTH(len
, 8);
371 adjusted_len
= aligned_len
+ sizeof(NDR_MEMORY_LIST
);
372 /* check for overflow */
373 if (adjusted_len
< len
)
375 ERR("overflow of adjusted_len %d, len %d\n", adjusted_len
, len
);
376 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
379 p
= pStubMsg
->pfnAllocate(adjusted_len
);
380 if (!p
) RpcRaiseException(ERROR_OUTOFMEMORY
);
382 mem_list
= (NDR_MEMORY_LIST
*)((char *)p
+ aligned_len
);
383 mem_list
->magic
= MEML_MAGIC
;
384 mem_list
->size
= aligned_len
;
385 mem_list
->reserved
= 0;
386 mem_list
->next
= pStubMsg
->pMemoryList
;
387 pStubMsg
->pMemoryList
= mem_list
;
393 static void WINAPI
NdrFree(MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *Pointer
)
395 TRACE("(%p, %p)\n", pStubMsg
, Pointer
);
397 pStubMsg
->pfnFree(Pointer
);
400 static inline BOOL
IsConformanceOrVariancePresent(PFORMAT_STRING pFormat
)
402 return (*(const ULONG
*)pFormat
!= -1);
405 static PFORMAT_STRING
ReadConformance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
)
407 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
408 if (pStubMsg
->Buffer
+ 4 > pStubMsg
->BufferEnd
)
409 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
410 pStubMsg
->MaxCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
411 pStubMsg
->Buffer
+= 4;
412 TRACE("unmarshalled conformance is %ld\n", pStubMsg
->MaxCount
);
413 if (pStubMsg
->fHasNewCorrDesc
)
419 static inline PFORMAT_STRING
ReadVariance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
, ULONG MaxValue
)
421 if (pFormat
&& !IsConformanceOrVariancePresent(pFormat
))
423 pStubMsg
->Offset
= 0;
424 pStubMsg
->ActualCount
= pStubMsg
->MaxCount
;
428 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
429 if (pStubMsg
->Buffer
+ 8 > pStubMsg
->BufferEnd
)
430 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
431 pStubMsg
->Offset
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
432 pStubMsg
->Buffer
+= 4;
433 TRACE("offset is %d\n", pStubMsg
->Offset
);
434 pStubMsg
->ActualCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
435 pStubMsg
->Buffer
+= 4;
436 TRACE("variance is %d\n", pStubMsg
->ActualCount
);
438 if ((pStubMsg
->ActualCount
> MaxValue
) ||
439 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> MaxValue
))
441 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
442 pStubMsg
->ActualCount
, pStubMsg
->Offset
, MaxValue
);
443 RpcRaiseException(RPC_S_INVALID_BOUND
);
448 if (pStubMsg
->fHasNewCorrDesc
)
454 /* writes the conformance value to the buffer */
455 static inline void WriteConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
457 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
458 if (pStubMsg
->Buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
459 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
460 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->MaxCount
);
461 pStubMsg
->Buffer
+= 4;
464 /* writes the variance values to the buffer */
465 static inline void WriteVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
467 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
468 if (pStubMsg
->Buffer
+ 8 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
469 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
470 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->Offset
);
471 pStubMsg
->Buffer
+= 4;
472 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->ActualCount
);
473 pStubMsg
->Buffer
+= 4;
476 /* requests buffer space for the conformance value */
477 static inline void SizeConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
479 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
480 if (pStubMsg
->BufferLength
+ 4 < pStubMsg
->BufferLength
)
481 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
482 pStubMsg
->BufferLength
+= 4;
485 /* requests buffer space for the variance values */
486 static inline void SizeVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
488 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
489 if (pStubMsg
->BufferLength
+ 8 < pStubMsg
->BufferLength
)
490 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
491 pStubMsg
->BufferLength
+= 8;
494 PFORMAT_STRING
ComputeConformanceOrVariance(
495 MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *pMemory
,
496 PFORMAT_STRING pFormat
, ULONG_PTR def
, ULONG_PTR
*pCount
)
498 BYTE dtype
= pFormat
[0] & 0xf;
499 short ofs
= *(const short *)&pFormat
[2];
503 if (!IsConformanceOrVariancePresent(pFormat
)) {
504 /* null descriptor */
509 switch (pFormat
[0] & 0xf0) {
510 case RPC_FC_NORMAL_CONFORMANCE
:
511 TRACE("normal conformance, ofs=%d\n", ofs
);
514 case RPC_FC_POINTER_CONFORMANCE
:
515 TRACE("pointer conformance, ofs=%d\n", ofs
);
516 ptr
= pStubMsg
->Memory
;
518 case RPC_FC_TOP_LEVEL_CONFORMANCE
:
519 TRACE("toplevel conformance, ofs=%d\n", ofs
);
520 if (pStubMsg
->StackTop
) {
521 ptr
= pStubMsg
->StackTop
;
524 /* -Os mode, *pCount is already set */
528 case RPC_FC_CONSTANT_CONFORMANCE
:
529 data
= ofs
| ((DWORD
)pFormat
[1] << 16);
530 TRACE("constant conformance, val=%d\n", data
);
533 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE
:
534 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs
);
535 if (pStubMsg
->StackTop
) {
536 ptr
= pStubMsg
->StackTop
;
544 FIXME("unknown conformance type %x\n", pFormat
[0] & 0xf0);
547 switch (pFormat
[1]) {
548 case RPC_FC_DEREFERENCE
:
549 ptr
= *(LPVOID
*)((char *)ptr
+ ofs
);
551 case RPC_FC_CALLBACK
:
553 unsigned char *old_stack_top
= pStubMsg
->StackTop
;
554 pStubMsg
->StackTop
= ptr
;
556 /* ofs is index into StubDesc->apfnExprEval */
557 TRACE("callback conformance into apfnExprEval[%d]\n", ofs
);
558 pStubMsg
->StubDesc
->apfnExprEval
[ofs
](pStubMsg
);
560 pStubMsg
->StackTop
= old_stack_top
;
562 /* the callback function always stores the computed value in MaxCount */
563 *pCount
= pStubMsg
->MaxCount
;
567 ptr
= (char *)ptr
+ ofs
;
580 data
= *(USHORT
*)ptr
;
591 FIXME("unknown conformance data type %x\n", dtype
);
594 TRACE("dereferenced data type %x at %p, got %d\n", dtype
, ptr
, data
);
597 switch (pFormat
[1]) {
598 case RPC_FC_DEREFERENCE
: /* already handled */
615 FIXME("unknown conformance op %d\n", pFormat
[1]);
620 TRACE("resulting conformance is %ld\n", *pCount
);
621 if (pStubMsg
->fHasNewCorrDesc
)
627 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
628 * the result overflows 32-bits */
629 static inline ULONG
safe_multiply(ULONG a
, ULONG b
)
631 ULONGLONG ret
= (ULONGLONG
)a
* b
;
632 if (ret
> 0xffffffff)
634 RpcRaiseException(RPC_S_INVALID_BOUND
);
640 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
642 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
643 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
644 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
645 pStubMsg
->Buffer
+= size
;
648 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
650 if (pStubMsg
->BufferLength
+ size
< pStubMsg
->BufferLength
) /* integer overflow of pStubMsg->BufferSize */
652 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
653 pStubMsg
->BufferLength
, size
);
654 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
656 pStubMsg
->BufferLength
+= size
;
659 /* copies data from the buffer, checking that there is enough data in the buffer
661 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, void *p
, ULONG size
)
663 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
664 (pStubMsg
->Buffer
+ size
> pStubMsg
->BufferEnd
))
666 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
667 pStubMsg
->Buffer
, pStubMsg
->BufferEnd
, size
);
668 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
670 if (p
== pStubMsg
->Buffer
)
671 ERR("pointer is the same as the buffer\n");
672 memcpy(p
, pStubMsg
->Buffer
, size
);
673 pStubMsg
->Buffer
+= size
;
676 /* copies data to the buffer, checking that there is enough space to do so */
677 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, const void *p
, ULONG size
)
679 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
680 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
682 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
683 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
,
685 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
687 memcpy(pStubMsg
->Buffer
, p
, size
);
688 pStubMsg
->Buffer
+= size
;
692 * NdrConformantString:
694 * What MS calls a ConformantString is, in DCE terminology,
695 * a Varying-Conformant String.
697 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
698 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
699 * into unmarshalled string)
700 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
702 * data: CHARTYPE[maxlen]
704 * ], where CHARTYPE is the appropriate character type (specified externally)
708 /***********************************************************************
709 * NdrConformantStringMarshall [RPCRT4.@]
711 unsigned char *WINAPI
NdrConformantStringMarshall(MIDL_STUB_MESSAGE
*pStubMsg
,
712 unsigned char *pszMessage
, PFORMAT_STRING pFormat
)
716 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg
, pszMessage
, pFormat
);
718 if (*pFormat
== RPC_FC_C_CSTRING
) {
719 TRACE("string=%s\n", debugstr_a((char*)pszMessage
));
720 pStubMsg
->ActualCount
= strlen((char*)pszMessage
)+1;
723 else if (*pFormat
== RPC_FC_C_WSTRING
) {
724 TRACE("string=%s\n", debugstr_w((LPWSTR
)pszMessage
));
725 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pszMessage
)+1;
729 ERR("Unhandled string type: %#x\n", *pFormat
);
730 /* FIXME: raise an exception. */
734 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
735 pFormat
= ComputeConformance(pStubMsg
, pszMessage
, pFormat
+ 2, 0);
737 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
738 pStubMsg
->Offset
= 0;
739 WriteConformance(pStubMsg
);
740 WriteVariance(pStubMsg
);
742 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
743 safe_copy_to_buffer(pStubMsg
, pszMessage
, size
); /* the string itself */
746 return NULL
; /* is this always right? */
749 /***********************************************************************
750 * NdrConformantStringBufferSize [RPCRT4.@]
752 void WINAPI
NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
753 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
757 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
759 SizeConformance(pStubMsg
);
760 SizeVariance(pStubMsg
);
762 if (*pFormat
== RPC_FC_C_CSTRING
) {
763 TRACE("string=%s\n", debugstr_a((char*)pMemory
));
764 pStubMsg
->ActualCount
= strlen((char*)pMemory
)+1;
767 else if (*pFormat
== RPC_FC_C_WSTRING
) {
768 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
));
769 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
)+1;
773 ERR("Unhandled string type: %#x\n", *pFormat
);
774 /* FIXME: raise an exception */
778 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
779 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
781 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
783 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
786 /************************************************************************
787 * NdrConformantStringMemorySize [RPCRT4.@]
789 ULONG WINAPI
NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
790 PFORMAT_STRING pFormat
)
792 ULONG bufsize
, memsize
, esize
, i
;
794 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
796 ReadConformance(pStubMsg
, NULL
);
797 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
799 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
801 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
802 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
803 RpcRaiseException(RPC_S_INVALID_BOUND
);
805 if (pStubMsg
->Offset
)
807 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
808 RpcRaiseException(RPC_S_INVALID_BOUND
);
811 if (*pFormat
== RPC_FC_C_CSTRING
) esize
= 1;
812 else if (*pFormat
== RPC_FC_C_WSTRING
) esize
= 2;
814 ERR("Unhandled string type: %#x\n", *pFormat
);
815 /* FIXME: raise an exception */
819 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
820 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
822 /* strings must always have null terminating bytes */
825 ERR("invalid string length of %d\n", pStubMsg
->ActualCount
);
826 RpcRaiseException(RPC_S_INVALID_BOUND
);
829 /* verify the buffer is safe to access */
830 if ((pStubMsg
->Buffer
+ bufsize
< pStubMsg
->Buffer
) ||
831 (pStubMsg
->Buffer
+ bufsize
> pStubMsg
->BufferEnd
))
833 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize
,
834 pStubMsg
->BufferEnd
, pStubMsg
->Buffer
);
835 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
838 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
839 if (pStubMsg
->Buffer
[i
] != 0)
841 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
842 i
, pStubMsg
->Buffer
[i
]);
843 RpcRaiseException(RPC_S_INVALID_BOUND
);
846 safe_buffer_increment(pStubMsg
, bufsize
);
847 pStubMsg
->MemorySize
+= memsize
;
849 return pStubMsg
->MemorySize
;
852 /************************************************************************
853 * NdrConformantStringUnmarshall [RPCRT4.@]
855 unsigned char *WINAPI
NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
856 unsigned char** ppMemory
, PFORMAT_STRING pFormat
, unsigned char fMustAlloc
)
858 ULONG bufsize
, memsize
, esize
, i
;
860 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
861 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
863 assert(pFormat
&& ppMemory
&& pStubMsg
);
865 ReadConformance(pStubMsg
, NULL
);
866 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
868 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
870 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
871 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
872 RpcRaiseException(RPC_S_INVALID_BOUND
);
875 if (pStubMsg
->Offset
)
877 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
878 RpcRaiseException(RPC_S_INVALID_BOUND
);
882 if (*pFormat
== RPC_FC_C_CSTRING
) esize
= 1;
883 else if (*pFormat
== RPC_FC_C_WSTRING
) esize
= 2;
885 ERR("Unhandled string type: %#x\n", *pFormat
);
886 /* FIXME: raise an exception */
890 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
891 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
893 /* strings must always have null terminating bytes */
896 ERR("invalid string length of %d\n", pStubMsg
->ActualCount
);
897 RpcRaiseException(RPC_S_INVALID_BOUND
);
901 /* verify the buffer is safe to access */
902 if ((pStubMsg
->Buffer
+ bufsize
< pStubMsg
->Buffer
) ||
903 (pStubMsg
->Buffer
+ bufsize
> pStubMsg
->BufferEnd
))
905 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize
,
906 pStubMsg
->BufferEnd
, pStubMsg
->Buffer
);
907 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
911 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
912 if (pStubMsg
->Buffer
[i
] != 0)
914 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
915 i
, pStubMsg
->Buffer
[i
]);
916 RpcRaiseException(RPC_S_INVALID_BOUND
);
921 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
924 if (!pStubMsg
->IsClient
&& !*ppMemory
&& (pStubMsg
->MaxCount
== pStubMsg
->ActualCount
))
925 /* if the data in the RPC buffer is big enough, we just point straight
927 *ppMemory
= pStubMsg
->Buffer
;
929 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
932 if (*ppMemory
== pStubMsg
->Buffer
)
933 safe_buffer_increment(pStubMsg
, bufsize
);
935 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
937 if (*pFormat
== RPC_FC_C_CSTRING
) {
938 TRACE("string=%s\n", debugstr_a((char*)*ppMemory
));
940 else if (*pFormat
== RPC_FC_C_WSTRING
) {
941 TRACE("string=%s\n", debugstr_w((LPWSTR
)*ppMemory
));
944 return NULL
; /* FIXME: is this always right? */
947 /***********************************************************************
948 * NdrNonConformantStringMarshall [RPCRT4.@]
950 unsigned char * WINAPI
NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
951 unsigned char *pMemory
,
952 PFORMAT_STRING pFormat
)
954 ULONG esize
, size
, maxsize
;
956 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
958 maxsize
= *(USHORT
*)&pFormat
[2];
960 if (*pFormat
== RPC_FC_CSTRING
)
963 const char *str
= (const char *)pMemory
;
964 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
966 TRACE("string=%s\n", debugstr_an(str
, i
));
967 pStubMsg
->ActualCount
= i
+ 1;
970 else if (*pFormat
== RPC_FC_WSTRING
)
973 const WCHAR
*str
= (const WCHAR
*)pMemory
;
974 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
976 TRACE("string=%s\n", debugstr_wn(str
, i
));
977 pStubMsg
->ActualCount
= i
+ 1;
982 ERR("Unhandled string type: %#x\n", *pFormat
);
983 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
986 pStubMsg
->Offset
= 0;
987 WriteVariance(pStubMsg
);
989 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
990 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
995 /***********************************************************************
996 * NdrNonConformantStringUnmarshall [RPCRT4.@]
998 unsigned char * WINAPI
NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
999 unsigned char **ppMemory
,
1000 PFORMAT_STRING pFormat
,
1001 unsigned char fMustAlloc
)
1003 ULONG bufsize
, memsize
, esize
, i
, maxsize
;
1005 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
1006 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
1008 maxsize
= *(USHORT
*)&pFormat
[2];
1010 ReadVariance(pStubMsg
, NULL
, maxsize
);
1011 if (pStubMsg
->Offset
)
1013 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
1014 RpcRaiseException(RPC_S_INVALID_BOUND
);
1017 if (*pFormat
== RPC_FC_CSTRING
) esize
= 1;
1018 else if (*pFormat
== RPC_FC_WSTRING
) esize
= 2;
1021 ERR("Unhandled string type: %#x\n", *pFormat
);
1022 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1025 memsize
= esize
* maxsize
;
1026 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1028 if (bufsize
< esize
)
1030 ERR("invalid string length of %d\n", pStubMsg
->ActualCount
);
1031 RpcRaiseException(RPC_S_INVALID_BOUND
);
1035 /* verify the buffer is safe to access */
1036 if ((pStubMsg
->Buffer
+ bufsize
< pStubMsg
->Buffer
) ||
1037 (pStubMsg
->Buffer
+ bufsize
> pStubMsg
->BufferEnd
))
1039 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize
,
1040 pStubMsg
->BufferEnd
, pStubMsg
->Buffer
);
1041 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1045 /* strings must always have null terminating bytes */
1046 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
1047 if (pStubMsg
->Buffer
[i
] != 0)
1049 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
1050 i
, pStubMsg
->Buffer
[i
]);
1051 RpcRaiseException(RPC_S_INVALID_BOUND
);
1054 if (fMustAlloc
|| !*ppMemory
)
1055 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
1057 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
1059 if (*pFormat
== RPC_FC_CSTRING
) {
1060 TRACE("string=%s\n", debugstr_an((char*)*ppMemory
, pStubMsg
->ActualCount
));
1062 else if (*pFormat
== RPC_FC_WSTRING
) {
1063 TRACE("string=%s\n", debugstr_wn((LPWSTR
)*ppMemory
, pStubMsg
->ActualCount
));
1069 /***********************************************************************
1070 * NdrNonConformantStringBufferSize [RPCRT4.@]
1072 void WINAPI
NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1073 unsigned char *pMemory
,
1074 PFORMAT_STRING pFormat
)
1076 ULONG esize
, maxsize
;
1078 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
1080 maxsize
= *(USHORT
*)&pFormat
[2];
1082 SizeVariance(pStubMsg
);
1084 if (*pFormat
== RPC_FC_CSTRING
)
1087 const char *str
= (const char *)pMemory
;
1088 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
1090 TRACE("string=%s\n", debugstr_an(str
, i
));
1091 pStubMsg
->ActualCount
= i
+ 1;
1094 else if (*pFormat
== RPC_FC_WSTRING
)
1097 const WCHAR
*str
= (const WCHAR
*)pMemory
;
1098 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
1100 TRACE("string=%s\n", debugstr_wn(str
, i
));
1101 pStubMsg
->ActualCount
= i
+ 1;
1106 ERR("Unhandled string type: %#x\n", *pFormat
);
1107 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1110 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
1113 /***********************************************************************
1114 * NdrNonConformantStringMemorySize [RPCRT4.@]
1116 ULONG WINAPI
NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1117 PFORMAT_STRING pFormat
)
1119 ULONG bufsize
, memsize
, esize
, i
, maxsize
;
1121 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
1123 maxsize
= *(USHORT
*)&pFormat
[2];
1125 ReadVariance(pStubMsg
, NULL
, maxsize
);
1127 if (pStubMsg
->Offset
)
1129 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
1130 RpcRaiseException(RPC_S_INVALID_BOUND
);
1133 if (*pFormat
== RPC_FC_CSTRING
) esize
= 1;
1134 else if (*pFormat
== RPC_FC_WSTRING
) esize
= 2;
1137 ERR("Unhandled string type: %#x\n", *pFormat
);
1138 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1141 memsize
= esize
* maxsize
;
1142 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1144 /* strings must always have null terminating bytes */
1145 if (bufsize
< esize
)
1147 ERR("invalid string length of %d\n", pStubMsg
->ActualCount
);
1148 RpcRaiseException(RPC_S_INVALID_BOUND
);
1151 /* verify the buffer is safe to access */
1152 if ((pStubMsg
->Buffer
+ bufsize
< pStubMsg
->Buffer
) ||
1153 (pStubMsg
->Buffer
+ bufsize
> pStubMsg
->BufferEnd
))
1155 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize
,
1156 pStubMsg
->BufferEnd
, pStubMsg
->Buffer
);
1157 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1160 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
1161 if (pStubMsg
->Buffer
[i
] != 0)
1163 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
1164 i
, pStubMsg
->Buffer
[i
]);
1165 RpcRaiseException(RPC_S_INVALID_BOUND
);
1168 safe_buffer_increment(pStubMsg
, bufsize
);
1169 pStubMsg
->MemorySize
+= memsize
;
1171 return pStubMsg
->MemorySize
;
1174 static inline void dump_pointer_attr(unsigned char attr
)
1176 if (attr
& RPC_FC_P_ALLOCALLNODES
)
1177 TRACE(" RPC_FC_P_ALLOCALLNODES");
1178 if (attr
& RPC_FC_P_DONTFREE
)
1179 TRACE(" RPC_FC_P_DONTFREE");
1180 if (attr
& RPC_FC_P_ONSTACK
)
1181 TRACE(" RPC_FC_P_ONSTACK");
1182 if (attr
& RPC_FC_P_SIMPLEPOINTER
)
1183 TRACE(" RPC_FC_P_SIMPLEPOINTER");
1184 if (attr
& RPC_FC_P_DEREF
)
1185 TRACE(" RPC_FC_P_DEREF");
1189 /***********************************************************************
1190 * PointerMarshall [internal]
1192 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1193 unsigned char *Buffer
,
1194 unsigned char *Pointer
,
1195 PFORMAT_STRING pFormat
)
1197 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1198 PFORMAT_STRING desc
;
1201 int pointer_needs_marshaling
;
1203 TRACE("(%p,%p,%p,%p)\n", pStubMsg
, Buffer
, Pointer
, pFormat
);
1204 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1206 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1207 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1210 case RPC_FC_RP
: /* ref pointer (always non-null) */
1213 ERR("NULL ref pointer is not allowed\n");
1214 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
1216 pointer_needs_marshaling
= 1;
1218 case RPC_FC_UP
: /* unique pointer */
1219 case RPC_FC_OP
: /* object pointer - same as unique here */
1221 pointer_needs_marshaling
= 1;
1223 pointer_needs_marshaling
= 0;
1224 pointer_id
= (ULONG
)Pointer
;
1225 TRACE("writing 0x%08x to buffer\n", pointer_id
);
1226 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
1229 pointer_needs_marshaling
= !NdrFullPointerQueryPointer(
1230 pStubMsg
->FullPtrXlatTables
, Pointer
, 1, &pointer_id
);
1231 TRACE("writing 0x%08x to buffer\n", pointer_id
);
1232 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
1235 FIXME("unhandled ptr type=%02x\n", type
);
1236 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1240 TRACE("calling marshaller for type 0x%x\n", (int)*desc
);
1242 if (pointer_needs_marshaling
) {
1243 if (attr
& RPC_FC_P_DEREF
) {
1244 Pointer
= *(unsigned char**)Pointer
;
1245 TRACE("deref => %p\n", Pointer
);
1247 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
1248 if (m
) m(pStubMsg
, Pointer
, desc
);
1249 else FIXME("no marshaller for data type=%02x\n", *desc
);
1252 STD_OVERFLOW_CHECK(pStubMsg
);
1255 /***********************************************************************
1256 * PointerUnmarshall [internal]
1258 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1259 unsigned char *Buffer
,
1260 unsigned char **pPointer
,
1261 unsigned char *pSrcPointer
,
1262 PFORMAT_STRING pFormat
,
1263 unsigned char fMustAlloc
)
1265 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1266 PFORMAT_STRING desc
;
1268 DWORD pointer_id
= 0;
1269 int pointer_needs_unmarshaling
;
1271 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg
, Buffer
, pPointer
, pSrcPointer
, pFormat
, fMustAlloc
);
1272 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1274 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1275 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1278 case RPC_FC_RP
: /* ref pointer (always non-null) */
1279 pointer_needs_unmarshaling
= 1;
1281 case RPC_FC_UP
: /* unique pointer */
1282 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1283 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1285 pointer_needs_unmarshaling
= 1;
1288 pointer_needs_unmarshaling
= 0;
1291 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
1292 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1293 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1294 if (!fMustAlloc
&& pSrcPointer
)
1296 FIXME("free object pointer %p\n", pSrcPointer
);
1300 pointer_needs_unmarshaling
= 1;
1302 pointer_needs_unmarshaling
= 0;
1305 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1306 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1307 pointer_needs_unmarshaling
= !NdrFullPointerQueryRefId(
1308 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, (void **)pPointer
);
1311 FIXME("unhandled ptr type=%02x\n", type
);
1312 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1316 if (pointer_needs_unmarshaling
) {
1317 unsigned char *base_ptr_val
= *pPointer
;
1318 unsigned char **current_ptr
= pPointer
;
1319 if (pStubMsg
->IsClient
) {
1321 /* if we aren't forcing allocation of memory then try to use the existing
1322 * (source) pointer to unmarshall the data into so that [in,out]
1323 * parameters behave correctly. it doesn't matter if the parameter is
1324 * [out] only since in that case the pointer will be NULL. we force
1325 * allocation when the source pointer is NULL here instead of in the type
1326 * unmarshalling routine for the benefit of the deref code below */
1329 TRACE("setting *pPointer to %p\n", pSrcPointer
);
1330 *pPointer
= base_ptr_val
= pSrcPointer
;
1336 /* the memory in a stub is never initialised, so we have to work out here
1337 * whether we have to initialise it so we can use the optimisation of
1338 * setting the pointer to the buffer, if possible, or set fMustAlloc to
1340 if (attr
& RPC_FC_P_DEREF
) {
1343 base_ptr_val
= NULL
;
1344 *current_ptr
= NULL
;
1348 if (attr
& RPC_FC_P_ALLOCALLNODES
)
1349 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
1351 if (attr
& RPC_FC_P_DEREF
) {
1353 base_ptr_val
= NdrAllocate(pStubMsg
, sizeof(void *));
1354 *pPointer
= base_ptr_val
;
1355 current_ptr
= (unsigned char **)base_ptr_val
;
1357 current_ptr
= *(unsigned char***)current_ptr
;
1358 TRACE("deref => %p\n", current_ptr
);
1359 if (!fMustAlloc
&& !*current_ptr
) fMustAlloc
= TRUE
;
1361 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
1362 if (m
) m(pStubMsg
, current_ptr
, desc
, fMustAlloc
);
1363 else FIXME("no unmarshaller for data type=%02x\n", *desc
);
1365 if (type
== RPC_FC_FP
)
1366 NdrFullPointerInsertRefId(pStubMsg
->FullPtrXlatTables
, pointer_id
,
1370 TRACE("pointer=%p\n", *pPointer
);
1373 /***********************************************************************
1374 * PointerBufferSize [internal]
1376 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1377 unsigned char *Pointer
,
1378 PFORMAT_STRING pFormat
)
1380 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1381 PFORMAT_STRING desc
;
1383 int pointer_needs_sizing
;
1386 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1387 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1389 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1390 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1393 case RPC_FC_RP
: /* ref pointer (always non-null) */
1396 ERR("NULL ref pointer is not allowed\n");
1397 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
1402 /* NULL pointer has no further representation */
1407 pointer_needs_sizing
= !NdrFullPointerQueryPointer(
1408 pStubMsg
->FullPtrXlatTables
, Pointer
, 0, &pointer_id
);
1409 if (!pointer_needs_sizing
)
1413 FIXME("unhandled ptr type=%02x\n", type
);
1414 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1418 if (attr
& RPC_FC_P_DEREF
) {
1419 Pointer
= *(unsigned char**)Pointer
;
1420 TRACE("deref => %p\n", Pointer
);
1423 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
1424 if (m
) m(pStubMsg
, Pointer
, desc
);
1425 else FIXME("no buffersizer for data type=%02x\n", *desc
);
1428 /***********************************************************************
1429 * PointerMemorySize [internal]
1431 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1432 unsigned char *Buffer
,
1433 PFORMAT_STRING pFormat
)
1435 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1436 PFORMAT_STRING desc
;
1438 DWORD pointer_id
= 0;
1439 int pointer_needs_sizing
;
1441 TRACE("(%p,%p,%p)\n", pStubMsg
, Buffer
, pFormat
);
1442 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1444 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1445 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1448 case RPC_FC_RP
: /* ref pointer (always non-null) */
1449 pointer_needs_sizing
= 1;
1451 case RPC_FC_UP
: /* unique pointer */
1452 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
1453 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1454 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1456 pointer_needs_sizing
= 1;
1458 pointer_needs_sizing
= 0;
1463 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1464 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1465 pointer_needs_sizing
= !NdrFullPointerQueryRefId(
1466 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, &pointer
);
1470 FIXME("unhandled ptr type=%02x\n", type
);
1471 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1475 if (attr
& RPC_FC_P_DEREF
) {
1479 if (pointer_needs_sizing
) {
1480 m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
1481 if (m
) m(pStubMsg
, desc
);
1482 else FIXME("no memorysizer for data type=%02x\n", *desc
);
1485 return pStubMsg
->MemorySize
;
1488 /***********************************************************************
1489 * PointerFree [internal]
1491 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1492 unsigned char *Pointer
,
1493 PFORMAT_STRING pFormat
)
1495 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1496 PFORMAT_STRING desc
;
1498 unsigned char *current_pointer
= Pointer
;
1500 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1501 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1502 if (attr
& RPC_FC_P_DONTFREE
) return;
1504 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1505 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1507 if (!Pointer
) return;
1509 if (type
== RPC_FC_FP
) {
1510 int pointer_needs_freeing
= NdrFullPointerFree(
1511 pStubMsg
->FullPtrXlatTables
, Pointer
);
1512 if (!pointer_needs_freeing
)
1516 if (attr
& RPC_FC_P_DEREF
) {
1517 current_pointer
= *(unsigned char**)Pointer
;
1518 TRACE("deref => %p\n", current_pointer
);
1521 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
1522 if (m
) m(pStubMsg
, current_pointer
, desc
);
1524 /* this check stops us from trying to free buffer memory. we don't have to
1525 * worry about clients, since they won't call this function.
1526 * we don't have to check for the buffer being reallocated because
1527 * BufferStart and BufferEnd won't be reset when allocating memory for
1528 * sending the response. we don't have to check for the new buffer here as
1529 * it won't be used a type memory, only for buffer memory */
1530 if (Pointer
>= (unsigned char *)pStubMsg
->BufferStart
&&
1531 Pointer
< (unsigned char *)pStubMsg
->BufferEnd
)
1534 if (attr
& RPC_FC_P_ONSTACK
) {
1535 TRACE("not freeing stack ptr %p\n", Pointer
);
1538 TRACE("freeing %p\n", Pointer
);
1539 NdrFree(pStubMsg
, Pointer
);
1542 TRACE("not freeing %p\n", Pointer
);
1545 /***********************************************************************
1546 * EmbeddedPointerMarshall
1548 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1549 unsigned char *pMemory
,
1550 PFORMAT_STRING pFormat
)
1552 unsigned char *Mark
= pStubMsg
->BufferMark
;
1553 unsigned rep
, count
, stride
;
1555 unsigned char *saved_buffer
= NULL
;
1557 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1559 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1562 if (pStubMsg
->PointerBufferMark
)
1564 saved_buffer
= pStubMsg
->Buffer
;
1565 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1566 pStubMsg
->PointerBufferMark
= NULL
;
1569 while (pFormat
[0] != RPC_FC_END
) {
1570 switch (pFormat
[0]) {
1572 FIXME("unknown repeat type %d\n", pFormat
[0]);
1573 case RPC_FC_NO_REPEAT
:
1579 case RPC_FC_FIXED_REPEAT
:
1580 rep
= *(const WORD
*)&pFormat
[2];
1581 stride
= *(const WORD
*)&pFormat
[4];
1582 count
= *(const WORD
*)&pFormat
[8];
1585 case RPC_FC_VARIABLE_REPEAT
:
1586 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1587 stride
= *(const WORD
*)&pFormat
[2];
1588 count
= *(const WORD
*)&pFormat
[6];
1592 for (i
= 0; i
< rep
; i
++) {
1593 PFORMAT_STRING info
= pFormat
;
1594 unsigned char *membase
= pMemory
+ (i
* stride
);
1595 unsigned char *bufbase
= Mark
+ (i
* stride
);
1598 for (u
=0; u
<count
; u
++,info
+=8) {
1599 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1600 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1601 unsigned char *saved_memory
= pStubMsg
->Memory
;
1603 pStubMsg
->Memory
= pMemory
;
1604 PointerMarshall(pStubMsg
, bufptr
, *(unsigned char**)memptr
, info
+4);
1605 pStubMsg
->Memory
= saved_memory
;
1608 pFormat
+= 8 * count
;
1613 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1614 pStubMsg
->Buffer
= saved_buffer
;
1617 STD_OVERFLOW_CHECK(pStubMsg
);
1622 /***********************************************************************
1623 * EmbeddedPointerUnmarshall
1625 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1626 unsigned char *pDstMemoryPtrs
,
1627 unsigned char *pSrcMemoryPtrs
,
1628 PFORMAT_STRING pFormat
,
1629 unsigned char fMustAlloc
)
1631 unsigned char *Mark
= pStubMsg
->BufferMark
;
1632 unsigned rep
, count
, stride
;
1634 unsigned char *saved_buffer
= NULL
;
1636 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg
, pDstMemoryPtrs
, pSrcMemoryPtrs
, pFormat
, fMustAlloc
);
1638 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1641 if (pStubMsg
->PointerBufferMark
)
1643 saved_buffer
= pStubMsg
->Buffer
;
1644 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1645 pStubMsg
->PointerBufferMark
= NULL
;
1648 while (pFormat
[0] != RPC_FC_END
) {
1649 TRACE("pFormat[0] = 0x%x\n", pFormat
[0]);
1650 switch (pFormat
[0]) {
1652 FIXME("unknown repeat type %d\n", pFormat
[0]);
1653 case RPC_FC_NO_REPEAT
:
1659 case RPC_FC_FIXED_REPEAT
:
1660 rep
= *(const WORD
*)&pFormat
[2];
1661 stride
= *(const WORD
*)&pFormat
[4];
1662 count
= *(const WORD
*)&pFormat
[8];
1665 case RPC_FC_VARIABLE_REPEAT
:
1666 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1667 stride
= *(const WORD
*)&pFormat
[2];
1668 count
= *(const WORD
*)&pFormat
[6];
1672 for (i
= 0; i
< rep
; i
++) {
1673 PFORMAT_STRING info
= pFormat
;
1674 unsigned char *memdstbase
= pDstMemoryPtrs
+ (i
* stride
);
1675 unsigned char *memsrcbase
= pSrcMemoryPtrs
+ (i
* stride
);
1676 unsigned char *bufbase
= Mark
+ (i
* stride
);
1679 for (u
=0; u
<count
; u
++,info
+=8) {
1680 unsigned char **memdstptr
= (unsigned char **)(memdstbase
+ *(const SHORT
*)&info
[0]);
1681 unsigned char **memsrcptr
= (unsigned char **)(memsrcbase
+ *(const SHORT
*)&info
[0]);
1682 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1683 PointerUnmarshall(pStubMsg
, bufptr
, memdstptr
, *memsrcptr
, info
+4, fMustAlloc
);
1686 pFormat
+= 8 * count
;
1691 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1692 pStubMsg
->Buffer
= saved_buffer
;
1698 /***********************************************************************
1699 * EmbeddedPointerBufferSize
1701 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1702 unsigned char *pMemory
,
1703 PFORMAT_STRING pFormat
)
1705 unsigned rep
, count
, stride
;
1707 ULONG saved_buffer_length
= 0;
1709 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1711 if (pStubMsg
->IgnoreEmbeddedPointers
) return;
1713 if (*pFormat
!= RPC_FC_PP
) return;
1716 if (pStubMsg
->PointerLength
)
1718 saved_buffer_length
= pStubMsg
->BufferLength
;
1719 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
1720 pStubMsg
->PointerLength
= 0;
1723 while (pFormat
[0] != RPC_FC_END
) {
1724 switch (pFormat
[0]) {
1726 FIXME("unknown repeat type %d\n", pFormat
[0]);
1727 case RPC_FC_NO_REPEAT
:
1733 case RPC_FC_FIXED_REPEAT
:
1734 rep
= *(const WORD
*)&pFormat
[2];
1735 stride
= *(const WORD
*)&pFormat
[4];
1736 count
= *(const WORD
*)&pFormat
[8];
1739 case RPC_FC_VARIABLE_REPEAT
:
1740 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1741 stride
= *(const WORD
*)&pFormat
[2];
1742 count
= *(const WORD
*)&pFormat
[6];
1746 for (i
= 0; i
< rep
; i
++) {
1747 PFORMAT_STRING info
= pFormat
;
1748 unsigned char *membase
= pMemory
+ (i
* stride
);
1751 for (u
=0; u
<count
; u
++,info
+=8) {
1752 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1753 unsigned char *saved_memory
= pStubMsg
->Memory
;
1755 pStubMsg
->Memory
= pMemory
;
1756 PointerBufferSize(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1757 pStubMsg
->Memory
= saved_memory
;
1760 pFormat
+= 8 * count
;
1763 if (saved_buffer_length
)
1765 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
1766 pStubMsg
->BufferLength
= saved_buffer_length
;
1770 /***********************************************************************
1771 * EmbeddedPointerMemorySize [internal]
1773 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1774 PFORMAT_STRING pFormat
)
1776 unsigned char *Mark
= pStubMsg
->BufferMark
;
1777 unsigned rep
, count
, stride
;
1779 unsigned char *saved_buffer
= NULL
;
1781 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1783 if (pStubMsg
->IgnoreEmbeddedPointers
) return 0;
1785 if (pStubMsg
->PointerBufferMark
)
1787 saved_buffer
= pStubMsg
->Buffer
;
1788 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1789 pStubMsg
->PointerBufferMark
= NULL
;
1792 if (*pFormat
!= RPC_FC_PP
) return 0;
1795 while (pFormat
[0] != RPC_FC_END
) {
1796 switch (pFormat
[0]) {
1798 FIXME("unknown repeat type %d\n", pFormat
[0]);
1799 case RPC_FC_NO_REPEAT
:
1805 case RPC_FC_FIXED_REPEAT
:
1806 rep
= *(const WORD
*)&pFormat
[2];
1807 stride
= *(const WORD
*)&pFormat
[4];
1808 count
= *(const WORD
*)&pFormat
[8];
1811 case RPC_FC_VARIABLE_REPEAT
:
1812 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1813 stride
= *(const WORD
*)&pFormat
[2];
1814 count
= *(const WORD
*)&pFormat
[6];
1818 for (i
= 0; i
< rep
; i
++) {
1819 PFORMAT_STRING info
= pFormat
;
1820 unsigned char *bufbase
= Mark
+ (i
* stride
);
1822 for (u
=0; u
<count
; u
++,info
+=8) {
1823 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1824 PointerMemorySize(pStubMsg
, bufptr
, info
+4);
1827 pFormat
+= 8 * count
;
1832 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1833 pStubMsg
->Buffer
= saved_buffer
;
1839 /***********************************************************************
1840 * EmbeddedPointerFree [internal]
1842 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1843 unsigned char *pMemory
,
1844 PFORMAT_STRING pFormat
)
1846 unsigned rep
, count
, stride
;
1849 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1850 if (*pFormat
!= RPC_FC_PP
) return;
1853 while (pFormat
[0] != RPC_FC_END
) {
1854 switch (pFormat
[0]) {
1856 FIXME("unknown repeat type %d\n", pFormat
[0]);
1857 case RPC_FC_NO_REPEAT
:
1863 case RPC_FC_FIXED_REPEAT
:
1864 rep
= *(const WORD
*)&pFormat
[2];
1865 stride
= *(const WORD
*)&pFormat
[4];
1866 count
= *(const WORD
*)&pFormat
[8];
1869 case RPC_FC_VARIABLE_REPEAT
:
1870 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1871 stride
= *(const WORD
*)&pFormat
[2];
1872 count
= *(const WORD
*)&pFormat
[6];
1876 for (i
= 0; i
< rep
; i
++) {
1877 PFORMAT_STRING info
= pFormat
;
1878 unsigned char *membase
= pMemory
+ (i
* stride
);
1881 for (u
=0; u
<count
; u
++,info
+=8) {
1882 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1883 unsigned char *saved_memory
= pStubMsg
->Memory
;
1885 pStubMsg
->Memory
= pMemory
;
1886 PointerFree(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1887 pStubMsg
->Memory
= saved_memory
;
1890 pFormat
+= 8 * count
;
1894 /***********************************************************************
1895 * NdrPointerMarshall [RPCRT4.@]
1897 unsigned char * WINAPI
NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1898 unsigned char *pMemory
,
1899 PFORMAT_STRING pFormat
)
1901 unsigned char *Buffer
;
1903 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1905 /* incremement the buffer here instead of in PointerMarshall,
1906 * as that is used by embedded pointers which already handle the incrementing
1907 * the buffer, and shouldn't write any additional pointer data to the wire */
1908 if (*pFormat
!= RPC_FC_RP
)
1910 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
1911 Buffer
= pStubMsg
->Buffer
;
1912 safe_buffer_increment(pStubMsg
, 4);
1915 Buffer
= pStubMsg
->Buffer
;
1917 PointerMarshall(pStubMsg
, Buffer
, pMemory
, pFormat
);
1922 /***********************************************************************
1923 * NdrPointerUnmarshall [RPCRT4.@]
1925 unsigned char * WINAPI
NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1926 unsigned char **ppMemory
,
1927 PFORMAT_STRING pFormat
,
1928 unsigned char fMustAlloc
)
1930 unsigned char *Buffer
;
1932 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1934 /* incremement the buffer here instead of in PointerUnmarshall,
1935 * as that is used by embedded pointers which already handle the incrementing
1936 * the buffer, and shouldn't read any additional pointer data from the
1938 if (*pFormat
!= RPC_FC_RP
)
1940 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1941 Buffer
= pStubMsg
->Buffer
;
1942 safe_buffer_increment(pStubMsg
, 4);
1945 Buffer
= pStubMsg
->Buffer
;
1947 PointerUnmarshall(pStubMsg
, Buffer
, ppMemory
, *ppMemory
, pFormat
, fMustAlloc
);
1952 /***********************************************************************
1953 * NdrPointerBufferSize [RPCRT4.@]
1955 void WINAPI
NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1956 unsigned char *pMemory
,
1957 PFORMAT_STRING pFormat
)
1959 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1961 /* incremement the buffer length here instead of in PointerBufferSize,
1962 * as that is used by embedded pointers which already handle the buffer
1963 * length, and shouldn't write anything more to the wire */
1964 if (*pFormat
!= RPC_FC_RP
)
1966 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
1967 safe_buffer_length_increment(pStubMsg
, 4);
1970 PointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1973 /***********************************************************************
1974 * NdrPointerMemorySize [RPCRT4.@]
1976 ULONG WINAPI
NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1977 PFORMAT_STRING pFormat
)
1979 /* unsigned size = *(LPWORD)(pFormat+2); */
1980 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1981 PointerMemorySize(pStubMsg
, pStubMsg
->Buffer
, pFormat
);
1985 /***********************************************************************
1986 * NdrPointerFree [RPCRT4.@]
1988 void WINAPI
NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1989 unsigned char *pMemory
,
1990 PFORMAT_STRING pFormat
)
1992 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1993 PointerFree(pStubMsg
, pMemory
, pFormat
);
1996 /***********************************************************************
1997 * NdrSimpleTypeMarshall [RPCRT4.@]
1999 void WINAPI
NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
2000 unsigned char FormatChar
)
2002 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &FormatChar
);
2005 /***********************************************************************
2006 * NdrSimpleTypeUnmarshall [RPCRT4.@]
2008 void WINAPI
NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
2009 unsigned char FormatChar
)
2011 NdrBaseTypeUnmarshall(pStubMsg
, &pMemory
, &FormatChar
, 0);
2014 /***********************************************************************
2015 * NdrSimpleStructMarshall [RPCRT4.@]
2017 unsigned char * WINAPI
NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2018 unsigned char *pMemory
,
2019 PFORMAT_STRING pFormat
)
2021 unsigned size
= *(const WORD
*)(pFormat
+2);
2022 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2024 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pFormat
[1] + 1);
2026 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2027 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
2029 if (pFormat
[0] != RPC_FC_STRUCT
)
2030 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
+4);
2035 /***********************************************************************
2036 * NdrSimpleStructUnmarshall [RPCRT4.@]
2038 unsigned char * WINAPI
NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2039 unsigned char **ppMemory
,
2040 PFORMAT_STRING pFormat
,
2041 unsigned char fMustAlloc
)
2043 unsigned size
= *(const WORD
*)(pFormat
+2);
2044 unsigned char *saved_buffer
;
2045 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2047 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2050 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2053 if (!pStubMsg
->IsClient
&& !*ppMemory
)
2054 /* for servers, we just point straight into the RPC buffer */
2055 *ppMemory
= pStubMsg
->Buffer
;
2058 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2059 safe_buffer_increment(pStubMsg
, size
);
2060 if (pFormat
[0] == RPC_FC_PSTRUCT
)
2061 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
+4, fMustAlloc
);
2063 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
2064 if (*ppMemory
!= saved_buffer
)
2065 memcpy(*ppMemory
, saved_buffer
, size
);
2070 /***********************************************************************
2071 * NdrSimpleStructBufferSize [RPCRT4.@]
2073 void WINAPI
NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2074 unsigned char *pMemory
,
2075 PFORMAT_STRING pFormat
)
2077 unsigned size
= *(const WORD
*)(pFormat
+2);
2078 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2080 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
2082 safe_buffer_length_increment(pStubMsg
, size
);
2083 if (pFormat
[0] != RPC_FC_STRUCT
)
2084 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
+4);
2087 /***********************************************************************
2088 * NdrSimpleStructMemorySize [RPCRT4.@]
2090 ULONG WINAPI
NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2091 PFORMAT_STRING pFormat
)
2093 unsigned short size
= *(const WORD
*)(pFormat
+2);
2095 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2097 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2098 pStubMsg
->MemorySize
+= size
;
2099 safe_buffer_increment(pStubMsg
, size
);
2101 if (pFormat
[0] != RPC_FC_STRUCT
)
2102 EmbeddedPointerMemorySize(pStubMsg
, pFormat
+4);
2103 return pStubMsg
->MemorySize
;
2106 /***********************************************************************
2107 * NdrSimpleStructFree [RPCRT4.@]
2109 void WINAPI
NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
2110 unsigned char *pMemory
,
2111 PFORMAT_STRING pFormat
)
2113 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2114 if (pFormat
[0] != RPC_FC_STRUCT
)
2115 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
+4);
2119 static unsigned long EmbeddedComplexSize(const MIDL_STUB_MESSAGE
*pStubMsg
,
2120 PFORMAT_STRING pFormat
)
2124 case RPC_FC_PSTRUCT
:
2125 case RPC_FC_CSTRUCT
:
2126 case RPC_FC_BOGUS_STRUCT
:
2127 case RPC_FC_SMFARRAY
:
2128 case RPC_FC_SMVARRAY
:
2129 return *(const WORD
*)&pFormat
[2];
2130 case RPC_FC_USER_MARSHAL
:
2131 return *(const WORD
*)&pFormat
[4];
2132 case RPC_FC_NON_ENCAPSULATED_UNION
:
2134 if (pStubMsg
->fHasNewCorrDesc
)
2139 pFormat
+= *(const SHORT
*)pFormat
;
2140 return *(const SHORT
*)pFormat
;
2142 return sizeof(void *);
2144 FIXME("unhandled embedded type %02x\n", *pFormat
);
2150 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2151 PFORMAT_STRING pFormat
)
2153 NDR_MEMORYSIZE m
= NdrMemorySizer
[*pFormat
& NDR_TABLE_MASK
];
2157 FIXME("no memorysizer for data type=%02x\n", *pFormat
);
2161 return m(pStubMsg
, pFormat
);
2165 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2166 unsigned char *pMemory
,
2167 PFORMAT_STRING pFormat
,
2168 PFORMAT_STRING pPointer
)
2170 PFORMAT_STRING desc
;
2174 while (*pFormat
!= RPC_FC_END
) {
2180 TRACE("byte=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2181 safe_copy_to_buffer(pStubMsg
, pMemory
, 1);
2187 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2188 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
2194 TRACE("long=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2195 safe_copy_to_buffer(pStubMsg
, pMemory
, 4);
2199 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2200 safe_copy_to_buffer(pStubMsg
, pMemory
, 8);
2203 case RPC_FC_POINTER
:
2205 unsigned char *saved_buffer
;
2206 int pointer_buffer_mark_set
= 0;
2207 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
2208 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
2209 saved_buffer
= pStubMsg
->Buffer
;
2210 if (pStubMsg
->PointerBufferMark
)
2212 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2213 pStubMsg
->PointerBufferMark
= NULL
;
2214 pointer_buffer_mark_set
= 1;
2217 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2218 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char**)pMemory
, pPointer
);
2219 if (pointer_buffer_mark_set
)
2221 STD_OVERFLOW_CHECK(pStubMsg
);
2222 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2223 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
2225 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2226 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
2227 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2229 pStubMsg
->Buffer
= saved_buffer
+ 4;
2235 case RPC_FC_ALIGNM4
:
2236 ALIGN_POINTER(pMemory
, 4);
2238 case RPC_FC_ALIGNM8
:
2239 ALIGN_POINTER(pMemory
, 8);
2241 case RPC_FC_STRUCTPAD1
:
2242 case RPC_FC_STRUCTPAD2
:
2243 case RPC_FC_STRUCTPAD3
:
2244 case RPC_FC_STRUCTPAD4
:
2245 case RPC_FC_STRUCTPAD5
:
2246 case RPC_FC_STRUCTPAD6
:
2247 case RPC_FC_STRUCTPAD7
:
2248 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2250 case RPC_FC_EMBEDDED_COMPLEX
:
2251 pMemory
+= pFormat
[1];
2253 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2254 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2255 TRACE("embedded complex (size=%ld) <= %p\n", size
, pMemory
);
2256 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
2259 /* for some reason interface pointers aren't generated as
2260 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2261 * they still need the derefencing treatment that pointers are
2263 if (*desc
== RPC_FC_IP
)
2264 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2266 m(pStubMsg
, pMemory
, desc
);
2268 else FIXME("no marshaller for embedded type %02x\n", *desc
);
2275 FIXME("unhandled format 0x%02x\n", *pFormat
);
2283 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2284 unsigned char *pMemory
,
2285 PFORMAT_STRING pFormat
,
2286 PFORMAT_STRING pPointer
)
2288 PFORMAT_STRING desc
;
2292 while (*pFormat
!= RPC_FC_END
) {
2298 safe_copy_from_buffer(pStubMsg
, pMemory
, 1);
2299 TRACE("byte=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2305 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
2306 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2312 safe_copy_from_buffer(pStubMsg
, pMemory
, 4);
2313 TRACE("long=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
2317 safe_copy_from_buffer(pStubMsg
, pMemory
, 8);
2318 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2321 case RPC_FC_POINTER
:
2323 unsigned char *saved_buffer
;
2324 int pointer_buffer_mark_set
= 0;
2325 TRACE("pointer => %p\n", pMemory
);
2326 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2327 saved_buffer
= pStubMsg
->Buffer
;
2328 if (pStubMsg
->PointerBufferMark
)
2330 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2331 pStubMsg
->PointerBufferMark
= NULL
;
2332 pointer_buffer_mark_set
= 1;
2335 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2337 PointerUnmarshall(pStubMsg
, saved_buffer
, (unsigned char**)pMemory
, *(unsigned char**)pMemory
, pPointer
, TRUE
);
2338 if (pointer_buffer_mark_set
)
2340 STD_OVERFLOW_CHECK(pStubMsg
);
2341 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2342 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
2344 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2345 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
2346 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2348 pStubMsg
->Buffer
= saved_buffer
+ 4;
2354 case RPC_FC_ALIGNM4
:
2355 ALIGN_POINTER_CLEAR(pMemory
, 4);
2357 case RPC_FC_ALIGNM8
:
2358 ALIGN_POINTER_CLEAR(pMemory
, 8);
2360 case RPC_FC_STRUCTPAD1
:
2361 case RPC_FC_STRUCTPAD2
:
2362 case RPC_FC_STRUCTPAD3
:
2363 case RPC_FC_STRUCTPAD4
:
2364 case RPC_FC_STRUCTPAD5
:
2365 case RPC_FC_STRUCTPAD6
:
2366 case RPC_FC_STRUCTPAD7
:
2367 memset(pMemory
, 0, *pFormat
- RPC_FC_STRUCTPAD1
+ 1);
2368 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2370 case RPC_FC_EMBEDDED_COMPLEX
:
2371 pMemory
+= pFormat
[1];
2373 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2374 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2375 TRACE("embedded complex (size=%ld) => %p\n", size
, pMemory
);
2376 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
2377 memset(pMemory
, 0, size
); /* just in case */
2380 /* for some reason interface pointers aren't generated as
2381 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2382 * they still need the derefencing treatment that pointers are
2384 if (*desc
== RPC_FC_IP
)
2385 m(pStubMsg
, (unsigned char **)pMemory
, desc
, FALSE
);
2387 m(pStubMsg
, &pMemory
, desc
, FALSE
);
2389 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
2396 FIXME("unhandled format %d\n", *pFormat
);
2404 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2405 unsigned char *pMemory
,
2406 PFORMAT_STRING pFormat
,
2407 PFORMAT_STRING pPointer
)
2409 PFORMAT_STRING desc
;
2413 while (*pFormat
!= RPC_FC_END
) {
2419 safe_buffer_length_increment(pStubMsg
, 1);
2425 safe_buffer_length_increment(pStubMsg
, 2);
2431 safe_buffer_length_increment(pStubMsg
, 4);
2435 safe_buffer_length_increment(pStubMsg
, 8);
2438 case RPC_FC_POINTER
:
2439 if (!pStubMsg
->IgnoreEmbeddedPointers
)
2441 int saved_buffer_length
= pStubMsg
->BufferLength
;
2442 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2443 pStubMsg
->PointerLength
= 0;
2444 if(!pStubMsg
->BufferLength
)
2445 ERR("BufferLength == 0??\n");
2446 PointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
2447 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2448 pStubMsg
->BufferLength
= saved_buffer_length
;
2450 safe_buffer_length_increment(pStubMsg
, 4);
2454 case RPC_FC_ALIGNM4
:
2455 ALIGN_POINTER(pMemory
, 4);
2457 case RPC_FC_ALIGNM8
:
2458 ALIGN_POINTER(pMemory
, 8);
2460 case RPC_FC_STRUCTPAD1
:
2461 case RPC_FC_STRUCTPAD2
:
2462 case RPC_FC_STRUCTPAD3
:
2463 case RPC_FC_STRUCTPAD4
:
2464 case RPC_FC_STRUCTPAD5
:
2465 case RPC_FC_STRUCTPAD6
:
2466 case RPC_FC_STRUCTPAD7
:
2467 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2469 case RPC_FC_EMBEDDED_COMPLEX
:
2470 pMemory
+= pFormat
[1];
2472 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2473 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2474 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
2477 /* for some reason interface pointers aren't generated as
2478 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2479 * they still need the derefencing treatment that pointers are
2481 if (*desc
== RPC_FC_IP
)
2482 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2484 m(pStubMsg
, pMemory
, desc
);
2486 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
2493 FIXME("unhandled format 0x%02x\n", *pFormat
);
2501 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
2502 unsigned char *pMemory
,
2503 PFORMAT_STRING pFormat
,
2504 PFORMAT_STRING pPointer
)
2506 PFORMAT_STRING desc
;
2510 while (*pFormat
!= RPC_FC_END
) {
2531 case RPC_FC_POINTER
:
2532 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
2536 case RPC_FC_ALIGNM4
:
2537 ALIGN_POINTER(pMemory
, 4);
2539 case RPC_FC_ALIGNM8
:
2540 ALIGN_POINTER(pMemory
, 8);
2542 case RPC_FC_STRUCTPAD1
:
2543 case RPC_FC_STRUCTPAD2
:
2544 case RPC_FC_STRUCTPAD3
:
2545 case RPC_FC_STRUCTPAD4
:
2546 case RPC_FC_STRUCTPAD5
:
2547 case RPC_FC_STRUCTPAD6
:
2548 case RPC_FC_STRUCTPAD7
:
2549 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2551 case RPC_FC_EMBEDDED_COMPLEX
:
2552 pMemory
+= pFormat
[1];
2554 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2555 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2556 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
2559 /* for some reason interface pointers aren't generated as
2560 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2561 * they still need the derefencing treatment that pointers are
2563 if (*desc
== RPC_FC_IP
)
2564 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2566 m(pStubMsg
, pMemory
, desc
);
2568 else FIXME("no freer for embedded type %02x\n", *desc
);
2575 FIXME("unhandled format 0x%02x\n", *pFormat
);
2583 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2584 PFORMAT_STRING pFormat
)
2586 PFORMAT_STRING desc
;
2587 unsigned long size
= 0;
2589 while (*pFormat
!= RPC_FC_END
) {
2596 safe_buffer_increment(pStubMsg
, 1);
2602 safe_buffer_increment(pStubMsg
, 2);
2608 safe_buffer_increment(pStubMsg
, 4);
2612 safe_buffer_increment(pStubMsg
, 8);
2614 case RPC_FC_POINTER
:
2616 safe_buffer_increment(pStubMsg
, 4);
2617 if (!pStubMsg
->IgnoreEmbeddedPointers
)
2618 FIXME("embedded pointers\n");
2620 case RPC_FC_ALIGNM4
:
2621 ALIGN_LENGTH(size
, 4);
2622 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2624 case RPC_FC_ALIGNM8
:
2625 ALIGN_LENGTH(size
, 8);
2626 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
2628 case RPC_FC_STRUCTPAD1
:
2629 case RPC_FC_STRUCTPAD2
:
2630 case RPC_FC_STRUCTPAD3
:
2631 case RPC_FC_STRUCTPAD4
:
2632 case RPC_FC_STRUCTPAD5
:
2633 case RPC_FC_STRUCTPAD6
:
2634 case RPC_FC_STRUCTPAD7
:
2635 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2637 case RPC_FC_EMBEDDED_COMPLEX
:
2640 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2641 size
+= EmbeddedComplexMemorySize(pStubMsg
, desc
);
2647 FIXME("unhandled format 0x%02x\n", *pFormat
);
2655 /***********************************************************************
2656 * NdrComplexStructMarshall [RPCRT4.@]
2658 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2659 unsigned char *pMemory
,
2660 PFORMAT_STRING pFormat
)
2662 PFORMAT_STRING conf_array
= NULL
;
2663 PFORMAT_STRING pointer_desc
= NULL
;
2664 unsigned char *OldMemory
= pStubMsg
->Memory
;
2665 int pointer_buffer_mark_set
= 0;
2667 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2669 if (!pStubMsg
->PointerBufferMark
)
2671 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2672 /* save buffer length */
2673 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2675 /* get the buffer pointer after complex array data, but before
2677 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- pStubMsg
->BufferStart
;
2678 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2679 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
2680 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2682 /* save it for use by embedded pointer code later */
2683 pStubMsg
->PointerBufferMark
= pStubMsg
->BufferStart
+ pStubMsg
->BufferLength
;
2684 TRACE("difference = 0x%x\n", pStubMsg
->PointerBufferMark
- pStubMsg
->Buffer
);
2685 pointer_buffer_mark_set
= 1;
2687 /* restore the original buffer length */
2688 pStubMsg
->BufferLength
= saved_buffer_length
;
2691 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pFormat
[1] + 1);
2694 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2696 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2699 pStubMsg
->Memory
= pMemory
;
2701 ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2704 NdrConformantArrayMarshall(pStubMsg
, pMemory
, conf_array
);
2706 pStubMsg
->Memory
= OldMemory
;
2708 if (pointer_buffer_mark_set
)
2710 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2711 pStubMsg
->PointerBufferMark
= NULL
;
2714 STD_OVERFLOW_CHECK(pStubMsg
);
2719 /***********************************************************************
2720 * NdrComplexStructUnmarshall [RPCRT4.@]
2722 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2723 unsigned char **ppMemory
,
2724 PFORMAT_STRING pFormat
,
2725 unsigned char fMustAlloc
)
2727 unsigned size
= *(const WORD
*)(pFormat
+2);
2728 PFORMAT_STRING conf_array
= NULL
;
2729 PFORMAT_STRING pointer_desc
= NULL
;
2730 unsigned char *pMemory
;
2731 int pointer_buffer_mark_set
= 0;
2733 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2735 if (!pStubMsg
->PointerBufferMark
)
2737 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2738 /* save buffer pointer */
2739 unsigned char *saved_buffer
= pStubMsg
->Buffer
;
2741 /* get the buffer pointer after complex array data, but before
2743 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2744 NdrComplexStructMemorySize(pStubMsg
, pFormat
);
2745 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2747 /* save it for use by embedded pointer code later */
2748 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2749 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->PointerBufferMark
- saved_buffer
));
2750 pointer_buffer_mark_set
= 1;
2752 /* restore the original buffer */
2753 pStubMsg
->Buffer
= saved_buffer
;
2756 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2758 if (fMustAlloc
|| !*ppMemory
)
2760 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2761 memset(*ppMemory
, 0, size
);
2765 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2767 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2770 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
);
2773 NdrConformantArrayUnmarshall(pStubMsg
, &pMemory
, conf_array
, fMustAlloc
);
2775 if (pointer_buffer_mark_set
)
2777 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2778 pStubMsg
->PointerBufferMark
= NULL
;
2784 /***********************************************************************
2785 * NdrComplexStructBufferSize [RPCRT4.@]
2787 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2788 unsigned char *pMemory
,
2789 PFORMAT_STRING pFormat
)
2791 PFORMAT_STRING conf_array
= NULL
;
2792 PFORMAT_STRING pointer_desc
= NULL
;
2793 unsigned char *OldMemory
= pStubMsg
->Memory
;
2794 int pointer_length_set
= 0;
2796 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2798 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
2800 if(!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
2802 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2803 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2805 /* get the buffer length after complex struct data, but before
2807 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2808 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
2809 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2811 /* save it for use by embedded pointer code later */
2812 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2813 pointer_length_set
= 1;
2814 TRACE("difference = 0x%lx\n", pStubMsg
->PointerLength
- saved_buffer_length
);
2816 /* restore the original buffer length */
2817 pStubMsg
->BufferLength
= saved_buffer_length
;
2821 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2823 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2826 pStubMsg
->Memory
= pMemory
;
2828 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2831 NdrConformantArrayBufferSize(pStubMsg
, pMemory
, conf_array
);
2833 pStubMsg
->Memory
= OldMemory
;
2835 if(pointer_length_set
)
2837 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2838 pStubMsg
->PointerLength
= 0;
2843 /***********************************************************************
2844 * NdrComplexStructMemorySize [RPCRT4.@]
2846 ULONG WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2847 PFORMAT_STRING pFormat
)
2849 unsigned size
= *(const WORD
*)(pFormat
+2);
2850 PFORMAT_STRING conf_array
= NULL
;
2851 PFORMAT_STRING pointer_desc
= NULL
;
2853 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2855 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2858 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2860 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2863 ComplexStructMemorySize(pStubMsg
, pFormat
);
2866 NdrConformantArrayMemorySize(pStubMsg
, conf_array
);
2871 /***********************************************************************
2872 * NdrComplexStructFree [RPCRT4.@]
2874 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
2875 unsigned char *pMemory
,
2876 PFORMAT_STRING pFormat
)
2878 PFORMAT_STRING conf_array
= NULL
;
2879 PFORMAT_STRING pointer_desc
= NULL
;
2880 unsigned char *OldMemory
= pStubMsg
->Memory
;
2882 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2885 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2887 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2890 pStubMsg
->Memory
= pMemory
;
2892 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2895 NdrConformantArrayFree(pStubMsg
, pMemory
, conf_array
);
2897 pStubMsg
->Memory
= OldMemory
;
2900 /***********************************************************************
2901 * NdrConformantArrayMarshall [RPCRT4.@]
2903 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2904 unsigned char *pMemory
,
2905 PFORMAT_STRING pFormat
)
2907 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
2908 unsigned char alignment
= pFormat
[1] + 1;
2910 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2911 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2913 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2915 WriteConformance(pStubMsg
);
2917 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
2919 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2920 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2921 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
2923 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2928 /***********************************************************************
2929 * NdrConformantArrayUnmarshall [RPCRT4.@]
2931 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2932 unsigned char **ppMemory
,
2933 PFORMAT_STRING pFormat
,
2934 unsigned char fMustAlloc
)
2936 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
2937 unsigned char alignment
= pFormat
[1] + 1;
2938 unsigned char *saved_buffer
;
2940 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2941 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2943 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2945 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2946 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2949 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2952 if (!pStubMsg
->IsClient
&& !*ppMemory
)
2953 /* for servers, we just point straight into the RPC buffer */
2954 *ppMemory
= pStubMsg
->Buffer
;
2957 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2958 safe_buffer_increment(pStubMsg
, size
);
2959 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
2961 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
2962 if (*ppMemory
!= saved_buffer
)
2963 memcpy(*ppMemory
, saved_buffer
, size
);
2968 /***********************************************************************
2969 * NdrConformantArrayBufferSize [RPCRT4.@]
2971 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2972 unsigned char *pMemory
,
2973 PFORMAT_STRING pFormat
)
2975 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
2976 unsigned char alignment
= pFormat
[1] + 1;
2978 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2979 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2981 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2983 SizeConformance(pStubMsg
);
2985 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
2987 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2988 /* conformance value plus array */
2989 safe_buffer_length_increment(pStubMsg
, size
);
2991 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
2994 /***********************************************************************
2995 * NdrConformantArrayMemorySize [RPCRT4.@]
2997 ULONG WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2998 PFORMAT_STRING pFormat
)
3000 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
3001 unsigned char alignment
= pFormat
[1] + 1;
3003 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3004 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
3006 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
3007 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3008 pStubMsg
->MemorySize
+= size
;
3010 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3011 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3012 safe_buffer_increment(pStubMsg
, size
);
3014 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
3016 return pStubMsg
->MemorySize
;
3019 /***********************************************************************
3020 * NdrConformantArrayFree [RPCRT4.@]
3022 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3023 unsigned char *pMemory
,
3024 PFORMAT_STRING pFormat
)
3026 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3027 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
3029 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
3031 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
3035 /***********************************************************************
3036 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3038 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
3039 unsigned char* pMemory
,
3040 PFORMAT_STRING pFormat
)
3043 unsigned char alignment
= pFormat
[1] + 1;
3044 DWORD esize
= *(const WORD
*)(pFormat
+2);
3046 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3048 if (pFormat
[0] != RPC_FC_CVARRAY
)
3050 ERR("invalid format type %x\n", pFormat
[0]);
3051 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3055 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
3056 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
3058 WriteConformance(pStubMsg
);
3059 WriteVariance(pStubMsg
);
3061 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
3063 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3065 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3066 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
3068 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3074 /***********************************************************************
3075 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
3077 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
3078 unsigned char** ppMemory
,
3079 PFORMAT_STRING pFormat
,
3080 unsigned char fMustAlloc
)
3082 ULONG bufsize
, memsize
;
3083 unsigned char alignment
= pFormat
[1] + 1;
3084 DWORD esize
= *(const WORD
*)(pFormat
+2);
3085 unsigned char *saved_buffer
;
3088 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3090 if (pFormat
[0] != RPC_FC_CVARRAY
)
3092 ERR("invalid format type %x\n", pFormat
[0]);
3093 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3097 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
3098 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3100 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3102 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3103 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3104 offset
= pStubMsg
->Offset
;
3106 if (!*ppMemory
|| fMustAlloc
)
3107 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
3108 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3109 safe_buffer_increment(pStubMsg
, bufsize
);
3111 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
3113 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
3119 /***********************************************************************
3120 * NdrConformantVaryingArrayFree [RPCRT4.@]
3122 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
3123 unsigned char* pMemory
,
3124 PFORMAT_STRING pFormat
)
3126 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3128 if (pFormat
[0] != RPC_FC_CVARRAY
)
3130 ERR("invalid format type %x\n", pFormat
[0]);
3131 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3135 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
3136 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
3138 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
3142 /***********************************************************************
3143 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
3145 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
3146 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
3148 unsigned char alignment
= pFormat
[1] + 1;
3149 DWORD esize
= *(const WORD
*)(pFormat
+2);
3151 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3153 if (pFormat
[0] != RPC_FC_CVARRAY
)
3155 ERR("invalid format type %x\n", pFormat
[0]);
3156 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3161 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
3162 /* compute length */
3163 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
3165 SizeConformance(pStubMsg
);
3166 SizeVariance(pStubMsg
);
3168 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
3170 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
3172 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3176 /***********************************************************************
3177 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
3179 ULONG WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
3180 PFORMAT_STRING pFormat
)
3182 ULONG bufsize
, memsize
;
3183 unsigned char alignment
= pFormat
[1] + 1;
3184 DWORD esize
= *(const WORD
*)(pFormat
+2);
3186 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
3188 if (pFormat
[0] != RPC_FC_CVARRAY
)
3190 ERR("invalid format type %x\n", pFormat
[0]);
3191 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3192 return pStubMsg
->MemorySize
;
3195 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
3196 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3198 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3200 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3201 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3203 safe_buffer_increment(pStubMsg
, bufsize
);
3204 pStubMsg
->MemorySize
+= memsize
;
3206 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
3208 return pStubMsg
->MemorySize
;
3212 /***********************************************************************
3213 * NdrComplexArrayMarshall [RPCRT4.@]
3215 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3216 unsigned char *pMemory
,
3217 PFORMAT_STRING pFormat
)
3219 ULONG i
, count
, def
;
3220 BOOL variance_present
;
3221 unsigned char alignment
;
3222 int pointer_buffer_mark_set
= 0;
3224 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3226 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3228 ERR("invalid format type %x\n", pFormat
[0]);
3229 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3233 alignment
= pFormat
[1] + 1;
3235 if (!pStubMsg
->PointerBufferMark
)
3237 /* save buffer fields that may be changed by buffer sizer functions
3238 * and that may be needed later on */
3239 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3240 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
3241 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
3242 unsigned long saved_offset
= pStubMsg
->Offset
;
3243 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
3245 /* get the buffer pointer after complex array data, but before
3247 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- pStubMsg
->BufferStart
;
3248 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3249 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
3250 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3252 /* save it for use by embedded pointer code later */
3253 pStubMsg
->PointerBufferMark
= pStubMsg
->BufferStart
+ pStubMsg
->BufferLength
;
3254 TRACE("difference = 0x%x\n", pStubMsg
->Buffer
- pStubMsg
->BufferStart
);
3255 pointer_buffer_mark_set
= 1;
3257 /* restore fields */
3258 pStubMsg
->ActualCount
= saved_actual_count
;
3259 pStubMsg
->Offset
= saved_offset
;
3260 pStubMsg
->MaxCount
= saved_max_count
;
3261 pStubMsg
->BufferLength
= saved_buffer_length
;
3264 def
= *(const WORD
*)&pFormat
[2];
3267 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3268 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3270 variance_present
= IsConformanceOrVariancePresent(pFormat
);
3271 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3272 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3274 WriteConformance(pStubMsg
);
3275 if (variance_present
)
3276 WriteVariance(pStubMsg
);
3278 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
3280 count
= pStubMsg
->ActualCount
;
3281 for (i
= 0; i
< count
; i
++)
3282 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
3284 STD_OVERFLOW_CHECK(pStubMsg
);
3286 if (pointer_buffer_mark_set
)
3288 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3289 pStubMsg
->PointerBufferMark
= NULL
;
3295 /***********************************************************************
3296 * NdrComplexArrayUnmarshall [RPCRT4.@]
3298 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3299 unsigned char **ppMemory
,
3300 PFORMAT_STRING pFormat
,
3301 unsigned char fMustAlloc
)
3303 ULONG i
, count
, size
;
3304 unsigned char alignment
;
3305 unsigned char *pMemory
;
3306 unsigned char *saved_buffer
;
3307 int pointer_buffer_mark_set
= 0;
3308 int saved_ignore_embedded
;
3310 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3312 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3314 ERR("invalid format type %x\n", pFormat
[0]);
3315 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3319 alignment
= pFormat
[1] + 1;
3321 saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3322 /* save buffer pointer */
3323 saved_buffer
= pStubMsg
->Buffer
;
3324 /* get the buffer pointer after complex array data, but before
3326 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3327 pStubMsg
->MemorySize
= 0;
3328 NdrComplexArrayMemorySize(pStubMsg
, pFormat
);
3329 size
= pStubMsg
->MemorySize
;
3330 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3332 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->Buffer
- saved_buffer
));
3333 if (!pStubMsg
->PointerBufferMark
)
3335 /* save it for use by embedded pointer code later */
3336 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3337 pointer_buffer_mark_set
= 1;
3339 /* restore the original buffer */
3340 pStubMsg
->Buffer
= saved_buffer
;
3344 pFormat
= ReadConformance(pStubMsg
, pFormat
);
3345 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3347 if (fMustAlloc
|| !*ppMemory
)
3349 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3350 memset(*ppMemory
, 0, size
);
3353 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3355 pMemory
= *ppMemory
;
3356 count
= pStubMsg
->ActualCount
;
3357 for (i
= 0; i
< count
; i
++)
3358 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
3360 if (pointer_buffer_mark_set
)
3362 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3363 pStubMsg
->PointerBufferMark
= NULL
;
3369 /***********************************************************************
3370 * NdrComplexArrayBufferSize [RPCRT4.@]
3372 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3373 unsigned char *pMemory
,
3374 PFORMAT_STRING pFormat
)
3376 ULONG i
, count
, def
;
3377 unsigned char alignment
;
3378 BOOL variance_present
;
3379 int pointer_length_set
= 0;
3381 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3383 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3385 ERR("invalid format type %x\n", pFormat
[0]);
3386 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3390 alignment
= pFormat
[1] + 1;
3392 if (!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
3394 /* save buffer fields that may be changed by buffer sizer functions
3395 * and that may be needed later on */
3396 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3397 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
3398 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
3399 unsigned long saved_offset
= pStubMsg
->Offset
;
3400 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
3402 /* get the buffer pointer after complex array data, but before
3404 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3405 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
3406 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3408 /* save it for use by embedded pointer code later */
3409 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3410 pointer_length_set
= 1;
3412 /* restore fields */
3413 pStubMsg
->ActualCount
= saved_actual_count
;
3414 pStubMsg
->Offset
= saved_offset
;
3415 pStubMsg
->MaxCount
= saved_max_count
;
3416 pStubMsg
->BufferLength
= saved_buffer_length
;
3418 def
= *(const WORD
*)&pFormat
[2];
3421 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3422 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3423 SizeConformance(pStubMsg
);
3425 variance_present
= IsConformanceOrVariancePresent(pFormat
);
3426 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3427 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3429 if (variance_present
)
3430 SizeVariance(pStubMsg
);
3432 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
3434 count
= pStubMsg
->ActualCount
;
3435 for (i
= 0; i
< count
; i
++)
3436 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
3438 if(pointer_length_set
)
3440 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3441 pStubMsg
->PointerLength
= 0;
3445 /***********************************************************************
3446 * NdrComplexArrayMemorySize [RPCRT4.@]
3448 ULONG WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3449 PFORMAT_STRING pFormat
)
3451 ULONG i
, count
, esize
, SavedMemorySize
, MemorySize
;
3452 unsigned char alignment
;
3453 unsigned char *Buffer
;
3455 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3457 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3459 ERR("invalid format type %x\n", pFormat
[0]);
3460 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3464 alignment
= pFormat
[1] + 1;
3468 pFormat
= ReadConformance(pStubMsg
, pFormat
);
3469 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3471 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3473 SavedMemorySize
= pStubMsg
->MemorySize
;
3475 Buffer
= pStubMsg
->Buffer
;
3476 pStubMsg
->MemorySize
= 0;
3477 esize
= ComplexStructMemorySize(pStubMsg
, pFormat
);
3478 pStubMsg
->Buffer
= Buffer
;
3480 MemorySize
= safe_multiply(pStubMsg
->MaxCount
, esize
);
3482 count
= pStubMsg
->ActualCount
;
3483 for (i
= 0; i
< count
; i
++)
3484 ComplexStructMemorySize(pStubMsg
, pFormat
);
3486 pStubMsg
->MemorySize
= SavedMemorySize
;
3488 pStubMsg
->MemorySize
+= MemorySize
;
3492 /***********************************************************************
3493 * NdrComplexArrayFree [RPCRT4.@]
3495 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3496 unsigned char *pMemory
,
3497 PFORMAT_STRING pFormat
)
3499 ULONG i
, count
, def
;
3501 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3503 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3505 ERR("invalid format type %x\n", pFormat
[0]);
3506 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3510 def
= *(const WORD
*)&pFormat
[2];
3513 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3514 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3516 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3517 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3519 count
= pStubMsg
->ActualCount
;
3520 for (i
= 0; i
< count
; i
++)
3521 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
3524 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg
,
3525 USER_MARSHAL_CB_TYPE cbtype
, PFORMAT_STRING pFormat
,
3526 USER_MARSHAL_CB
*umcb
)
3528 umcb
->Flags
= MAKELONG(pStubMsg
->dwDestContext
,
3529 pStubMsg
->RpcMsg
->DataRepresentation
);
3530 umcb
->pStubMsg
= pStubMsg
;
3531 umcb
->pReserve
= NULL
;
3532 umcb
->Signature
= USER_MARSHAL_CB_SIGNATURE
;
3533 umcb
->CBType
= cbtype
;
3534 umcb
->pFormat
= pFormat
;
3535 umcb
->pTypeFormat
= NULL
/* FIXME */;
3538 #define USER_MARSHAL_PTR_PREFIX \
3539 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3540 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3542 /***********************************************************************
3543 * NdrUserMarshalMarshall [RPCRT4.@]
3545 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3546 unsigned char *pMemory
,
3547 PFORMAT_STRING pFormat
)
3549 unsigned flags
= pFormat
[1];
3550 unsigned index
= *(const WORD
*)&pFormat
[2];
3551 unsigned char *saved_buffer
= NULL
;
3552 USER_MARSHAL_CB umcb
;
3554 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3555 TRACE("index=%d\n", index
);
3557 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_MARSHALL
, pFormat
, &umcb
);
3559 if (flags
& USER_MARSHAL_POINTER
)
3561 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
3562 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, USER_MARSHAL_PTR_PREFIX
);
3563 pStubMsg
->Buffer
+= 4;
3564 if (pStubMsg
->PointerBufferMark
)
3566 saved_buffer
= pStubMsg
->Buffer
;
3567 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3568 pStubMsg
->PointerBufferMark
= NULL
;
3570 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 8);
3573 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3576 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
3577 &umcb
.Flags
, pStubMsg
->Buffer
, pMemory
);
3581 STD_OVERFLOW_CHECK(pStubMsg
);
3582 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3583 pStubMsg
->Buffer
= saved_buffer
;
3586 STD_OVERFLOW_CHECK(pStubMsg
);
3591 /***********************************************************************
3592 * NdrUserMarshalUnmarshall [RPCRT4.@]
3594 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3595 unsigned char **ppMemory
,
3596 PFORMAT_STRING pFormat
,
3597 unsigned char fMustAlloc
)
3599 unsigned flags
= pFormat
[1];
3600 unsigned index
= *(const WORD
*)&pFormat
[2];
3601 DWORD memsize
= *(const WORD
*)&pFormat
[4];
3602 unsigned char *saved_buffer
= NULL
;
3603 USER_MARSHAL_CB umcb
;
3605 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3606 TRACE("index=%d\n", index
);
3608 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_UNMARSHALL
, pFormat
, &umcb
);
3610 if (flags
& USER_MARSHAL_POINTER
)
3612 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3613 /* skip pointer prefix */
3614 pStubMsg
->Buffer
+= 4;
3615 if (pStubMsg
->PointerBufferMark
)
3617 saved_buffer
= pStubMsg
->Buffer
;
3618 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3619 pStubMsg
->PointerBufferMark
= NULL
;
3621 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3624 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3626 if (fMustAlloc
|| !*ppMemory
)
3627 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
3630 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
3631 &umcb
.Flags
, pStubMsg
->Buffer
, *ppMemory
);
3635 STD_OVERFLOW_CHECK(pStubMsg
);
3636 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3637 pStubMsg
->Buffer
= saved_buffer
;
3643 /***********************************************************************
3644 * NdrUserMarshalBufferSize [RPCRT4.@]
3646 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3647 unsigned char *pMemory
,
3648 PFORMAT_STRING pFormat
)
3650 unsigned flags
= pFormat
[1];
3651 unsigned index
= *(const WORD
*)&pFormat
[2];
3652 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
3653 USER_MARSHAL_CB umcb
;
3654 unsigned long saved_buffer_length
= 0;
3656 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3657 TRACE("index=%d\n", index
);
3659 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_BUFFER_SIZE
, pFormat
, &umcb
);
3661 if (flags
& USER_MARSHAL_POINTER
)
3663 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
3664 /* skip pointer prefix */
3665 safe_buffer_length_increment(pStubMsg
, 4);
3666 if (pStubMsg
->IgnoreEmbeddedPointers
)
3668 if (pStubMsg
->PointerLength
)
3670 saved_buffer_length
= pStubMsg
->BufferLength
;
3671 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3672 pStubMsg
->PointerLength
= 0;
3674 ALIGN_LENGTH(pStubMsg
->BufferLength
, 8);
3677 ALIGN_LENGTH(pStubMsg
->BufferLength
, (flags
& 0xf) + 1);
3680 TRACE("size=%d\n", bufsize
);
3681 safe_buffer_length_increment(pStubMsg
, bufsize
);
3684 pStubMsg
->BufferLength
=
3685 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
3686 &umcb
.Flags
, pStubMsg
->BufferLength
, pMemory
);
3688 if (saved_buffer_length
)
3690 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3691 pStubMsg
->BufferLength
= saved_buffer_length
;
3696 /***********************************************************************
3697 * NdrUserMarshalMemorySize [RPCRT4.@]
3699 ULONG WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3700 PFORMAT_STRING pFormat
)
3702 unsigned flags
= pFormat
[1];
3703 unsigned index
= *(const WORD
*)&pFormat
[2];
3704 DWORD memsize
= *(const WORD
*)&pFormat
[4];
3705 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
3707 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3708 TRACE("index=%d\n", index
);
3710 pStubMsg
->MemorySize
+= memsize
;
3712 if (flags
& USER_MARSHAL_POINTER
)
3714 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3715 /* skip pointer prefix */
3716 pStubMsg
->Buffer
+= 4;
3717 if (pStubMsg
->IgnoreEmbeddedPointers
)
3718 return pStubMsg
->MemorySize
;
3719 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3722 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3725 FIXME("not implemented for varying buffer size\n");
3727 pStubMsg
->Buffer
+= bufsize
;
3729 return pStubMsg
->MemorySize
;
3732 /***********************************************************************
3733 * NdrUserMarshalFree [RPCRT4.@]
3735 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
3736 unsigned char *pMemory
,
3737 PFORMAT_STRING pFormat
)
3739 /* unsigned flags = pFormat[1]; */
3740 unsigned index
= *(const WORD
*)&pFormat
[2];
3741 USER_MARSHAL_CB umcb
;
3743 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3744 TRACE("index=%d\n", index
);
3746 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_FREE
, pFormat
, &umcb
);
3748 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
3749 &umcb
.Flags
, pMemory
);
3752 /***********************************************************************
3753 * NdrClearOutParameters [RPCRT4.@]
3755 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
3756 PFORMAT_STRING pFormat
,
3759 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
3762 /***********************************************************************
3763 * NdrConvert [RPCRT4.@]
3765 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
3767 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
3768 /* FIXME: since this stub doesn't do any converting, the proper behavior
3769 is to raise an exception */
3772 /***********************************************************************
3773 * NdrConvert2 [RPCRT4.@]
3775 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, LONG NumberParams
)
3777 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3778 pStubMsg
, pFormat
, NumberParams
);
3779 /* FIXME: since this stub doesn't do any converting, the proper behavior
3780 is to raise an exception */
3783 #include "pshpack1.h"
3784 typedef struct _NDR_CSTRUCT_FORMAT
3787 unsigned char alignment
;
3788 unsigned short memory_size
;
3789 short offset_to_array_description
;
3790 } NDR_CSTRUCT_FORMAT
, NDR_CVSTRUCT_FORMAT
;
3791 #include "poppack.h"
3793 /***********************************************************************
3794 * NdrConformantStructMarshall [RPCRT4.@]
3796 unsigned char * WINAPI
NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3797 unsigned char *pMemory
,
3798 PFORMAT_STRING pFormat
)
3800 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3801 PFORMAT_STRING pCArrayFormat
;
3802 ULONG esize
, bufsize
;
3804 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3806 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3807 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3809 ERR("invalid format type %x\n", pCStructFormat
->type
);
3810 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3814 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3815 pCStructFormat
->offset_to_array_description
;
3816 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3818 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3819 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3822 esize
= *(const WORD
*)(pCArrayFormat
+2);
3824 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
3825 pCArrayFormat
+ 4, 0);
3827 WriteConformance(pStubMsg
);
3829 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
3831 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3833 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3834 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
3836 ERR("integer overflow of memory_size %u with bufsize %u\n",
3837 pCStructFormat
->memory_size
, bufsize
);
3838 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3840 /* copy constant sized part of struct */
3841 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3842 safe_copy_to_buffer(pStubMsg
, pMemory
, pCStructFormat
->memory_size
+ bufsize
);
3844 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3845 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3850 /***********************************************************************
3851 * NdrConformantStructUnmarshall [RPCRT4.@]
3853 unsigned char * WINAPI
NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3854 unsigned char **ppMemory
,
3855 PFORMAT_STRING pFormat
,
3856 unsigned char fMustAlloc
)
3858 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3859 PFORMAT_STRING pCArrayFormat
;
3860 ULONG esize
, bufsize
;
3861 unsigned char *saved_buffer
;
3863 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3865 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3866 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3868 ERR("invalid format type %x\n", pCStructFormat
->type
);
3869 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3872 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3873 pCStructFormat
->offset_to_array_description
;
3874 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3876 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3877 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3880 esize
= *(const WORD
*)(pCArrayFormat
+2);
3882 pCArrayFormat
= ReadConformance(pStubMsg
, pCArrayFormat
+ 4);
3884 ALIGN_POINTER(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
3886 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3888 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3889 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
3891 ERR("integer overflow of memory_size %u with bufsize %u\n",
3892 pCStructFormat
->memory_size
, bufsize
);
3893 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3898 SIZE_T size
= pCStructFormat
->memory_size
+ bufsize
;
3899 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3903 if (!pStubMsg
->IsClient
&& !*ppMemory
)
3904 /* for servers, we just point straight into the RPC buffer */
3905 *ppMemory
= pStubMsg
->Buffer
;
3908 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3909 safe_buffer_increment(pStubMsg
, pCStructFormat
->memory_size
+ bufsize
);
3910 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3911 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
3913 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
3914 if (*ppMemory
!= saved_buffer
)
3915 memcpy(*ppMemory
, saved_buffer
, pCStructFormat
->memory_size
+ bufsize
);
3920 /***********************************************************************
3921 * NdrConformantStructBufferSize [RPCRT4.@]
3923 void WINAPI
NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3924 unsigned char *pMemory
,
3925 PFORMAT_STRING pFormat
)
3927 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3928 PFORMAT_STRING pCArrayFormat
;
3931 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3933 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3934 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3936 ERR("invalid format type %x\n", pCStructFormat
->type
);
3937 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3940 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3941 pCStructFormat
->offset_to_array_description
;
3942 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3944 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3945 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3948 esize
= *(const WORD
*)(pCArrayFormat
+2);
3950 pCArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
, pCArrayFormat
+4, 0);
3951 SizeConformance(pStubMsg
);
3953 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCStructFormat
->alignment
+ 1);
3955 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3957 safe_buffer_length_increment(pStubMsg
, pCStructFormat
->memory_size
);
3958 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
3960 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3961 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3964 /***********************************************************************
3965 * NdrConformantStructMemorySize [RPCRT4.@]
3967 ULONG WINAPI
NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3968 PFORMAT_STRING pFormat
)
3974 /***********************************************************************
3975 * NdrConformantStructFree [RPCRT4.@]
3977 void WINAPI
NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3978 unsigned char *pMemory
,
3979 PFORMAT_STRING pFormat
)
3981 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3982 PFORMAT_STRING pCArrayFormat
;
3985 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3987 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3988 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3990 ERR("invalid format type %x\n", pCStructFormat
->type
);
3991 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3995 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3996 pCStructFormat
->offset_to_array_description
;
3997 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3999 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4000 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4003 esize
= *(const WORD
*)(pCArrayFormat
+2);
4005 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4006 pCArrayFormat
+ 4, 0);
4008 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4010 /* copy constant sized part of struct */
4011 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4013 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4014 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4017 /***********************************************************************
4018 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4020 unsigned char * WINAPI
NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4021 unsigned char *pMemory
,
4022 PFORMAT_STRING pFormat
)
4024 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4025 PFORMAT_STRING pCVArrayFormat
;
4026 ULONG esize
, bufsize
;
4028 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4030 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4031 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4033 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4034 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4038 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4039 pCVStructFormat
->offset_to_array_description
;
4040 switch (*pCVArrayFormat
)
4042 case RPC_FC_CVARRAY
:
4043 esize
= *(const WORD
*)(pCVArrayFormat
+2);
4045 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4046 pCVArrayFormat
+ 4, 0);
4047 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4050 case RPC_FC_C_CSTRING
:
4051 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
4052 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
4053 esize
= sizeof(char);
4054 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4055 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4056 pCVArrayFormat
+ 2, 0);
4058 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4060 case RPC_FC_C_WSTRING
:
4061 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
4062 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
4063 esize
= sizeof(WCHAR
);
4064 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4065 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4066 pCVArrayFormat
+ 2, 0);
4068 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4071 ERR("invalid array format type %x\n", *pCVArrayFormat
);
4072 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4076 WriteConformance(pStubMsg
);
4078 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4080 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4082 /* write constant sized part */
4083 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4084 safe_copy_to_buffer(pStubMsg
, pMemory
, pCVStructFormat
->memory_size
);
4086 WriteVariance(pStubMsg
);
4088 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4090 /* write array part */
4091 safe_copy_to_buffer(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
, bufsize
);
4093 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4098 /***********************************************************************
4099 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4101 unsigned char * WINAPI
NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4102 unsigned char **ppMemory
,
4103 PFORMAT_STRING pFormat
,
4104 unsigned char fMustAlloc
)
4106 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4107 PFORMAT_STRING pCVArrayFormat
;
4108 ULONG esize
, bufsize
;
4109 unsigned char cvarray_type
;
4111 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4113 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4114 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4116 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4117 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4121 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4122 pCVStructFormat
->offset_to_array_description
;
4123 cvarray_type
= *pCVArrayFormat
;
4124 switch (cvarray_type
)
4126 case RPC_FC_CVARRAY
:
4127 esize
= *(const WORD
*)(pCVArrayFormat
+2);
4128 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 4);
4130 case RPC_FC_C_CSTRING
:
4131 esize
= sizeof(char);
4132 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4133 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
4135 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
4137 case RPC_FC_C_WSTRING
:
4138 esize
= sizeof(WCHAR
);
4139 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4140 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
4142 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
4145 ERR("invalid array format type %x\n", *pCVArrayFormat
);
4146 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4150 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4152 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4154 /* work out how much memory to allocate if we need to do so */
4155 if (!*ppMemory
|| fMustAlloc
)
4157 SIZE_T size
= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->MaxCount
);
4158 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4161 /* copy the constant data */
4162 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4163 safe_copy_from_buffer(pStubMsg
, *ppMemory
, pCVStructFormat
->memory_size
);
4165 pCVArrayFormat
= ReadVariance(pStubMsg
, pCVArrayFormat
, pStubMsg
->MaxCount
);
4167 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4169 if ((cvarray_type
== RPC_FC_C_CSTRING
) ||
4170 (cvarray_type
== RPC_FC_C_WSTRING
))
4173 /* strings must always have null terminating bytes */
4174 if (bufsize
< esize
)
4176 ERR("invalid string length of %d\n", pStubMsg
->ActualCount
);
4177 RpcRaiseException(RPC_S_INVALID_BOUND
);
4180 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
4181 if (pStubMsg
->Buffer
[i
] != 0)
4183 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
4184 i
, pStubMsg
->Buffer
[i
]);
4185 RpcRaiseException(RPC_S_INVALID_BOUND
);
4190 /* copy the array data */
4191 safe_copy_from_buffer(pStubMsg
, *ppMemory
+ pCVStructFormat
->memory_size
, bufsize
);
4193 if (cvarray_type
== RPC_FC_C_CSTRING
)
4194 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory
+ pCVStructFormat
->memory_size
)));
4195 else if (cvarray_type
== RPC_FC_C_WSTRING
)
4196 TRACE("string=%s\n", debugstr_w((WCHAR
*)(*ppMemory
+ pCVStructFormat
->memory_size
)));
4198 EmbeddedPointerUnmarshall(pStubMsg
, *ppMemory
, *ppMemory
, pFormat
, TRUE
/* FIXME */);
4203 /***********************************************************************
4204 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
4206 void WINAPI
NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4207 unsigned char *pMemory
,
4208 PFORMAT_STRING pFormat
)
4210 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4211 PFORMAT_STRING pCVArrayFormat
;
4214 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4216 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4217 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4219 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4220 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4224 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4225 pCVStructFormat
->offset_to_array_description
;
4226 switch (*pCVArrayFormat
)
4228 case RPC_FC_CVARRAY
:
4229 esize
= *(const WORD
*)(pCVArrayFormat
+2);
4231 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4232 pCVArrayFormat
+ 4, 0);
4233 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4236 case RPC_FC_C_CSTRING
:
4237 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
4238 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
4239 esize
= sizeof(char);
4240 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4241 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4242 pCVArrayFormat
+ 2, 0);
4244 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4246 case RPC_FC_C_WSTRING
:
4247 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
4248 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
4249 esize
= sizeof(WCHAR
);
4250 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4251 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4252 pCVArrayFormat
+ 2, 0);
4254 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4257 ERR("invalid array format type %x\n", *pCVArrayFormat
);
4258 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4262 SizeConformance(pStubMsg
);
4264 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCVStructFormat
->alignment
+ 1);
4266 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4268 safe_buffer_length_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4269 SizeVariance(pStubMsg
);
4270 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
4272 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4275 /***********************************************************************
4276 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4278 ULONG WINAPI
NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4279 PFORMAT_STRING pFormat
)
4281 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4282 PFORMAT_STRING pCVArrayFormat
;
4284 unsigned char cvarray_type
;
4286 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4288 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4289 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4291 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4292 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4296 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4297 pCVStructFormat
->offset_to_array_description
;
4298 cvarray_type
= *pCVArrayFormat
;
4299 switch (cvarray_type
)
4301 case RPC_FC_CVARRAY
:
4302 esize
= *(const WORD
*)(pCVArrayFormat
+2);
4303 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 4);
4305 case RPC_FC_C_CSTRING
:
4306 esize
= sizeof(char);
4307 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4308 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
4310 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
4312 case RPC_FC_C_WSTRING
:
4313 esize
= sizeof(WCHAR
);
4314 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4315 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
4317 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
4320 ERR("invalid array format type %x\n", *pCVArrayFormat
);
4321 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4325 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4327 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4329 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4330 pCVArrayFormat
= ReadVariance(pStubMsg
, pCVArrayFormat
, pStubMsg
->MaxCount
);
4331 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
4333 pStubMsg
->MemorySize
+= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->MaxCount
);
4335 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4337 return pCVStructFormat
->memory_size
+ pStubMsg
->MaxCount
* esize
;
4340 /***********************************************************************
4341 * NdrConformantVaryingStructFree [RPCRT4.@]
4343 void WINAPI
NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
4344 unsigned char *pMemory
,
4345 PFORMAT_STRING pFormat
)
4347 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4348 PFORMAT_STRING pCVArrayFormat
;
4351 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4353 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4354 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4356 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4357 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4361 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4362 pCVStructFormat
->offset_to_array_description
;
4363 switch (*pCVArrayFormat
)
4365 case RPC_FC_CVARRAY
:
4366 esize
= *(const WORD
*)(pCVArrayFormat
+2);
4368 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4369 pCVArrayFormat
+ 4, 0);
4370 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4373 case RPC_FC_C_CSTRING
:
4374 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
4375 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
4376 esize
= sizeof(char);
4377 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4378 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4379 pCVArrayFormat
+ 2, 0);
4381 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4383 case RPC_FC_C_WSTRING
:
4384 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
4385 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
4386 esize
= sizeof(WCHAR
);
4387 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4388 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4389 pCVArrayFormat
+ 2, 0);
4391 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4394 ERR("invalid array format type %x\n", *pCVArrayFormat
);
4395 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4399 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4401 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4404 #include "pshpack1.h"
4408 unsigned char alignment
;
4409 unsigned short total_size
;
4410 } NDR_SMFARRAY_FORMAT
;
4415 unsigned char alignment
;
4416 unsigned long total_size
;
4417 } NDR_LGFARRAY_FORMAT
;
4418 #include "poppack.h"
4420 /***********************************************************************
4421 * NdrFixedArrayMarshall [RPCRT4.@]
4423 unsigned char * WINAPI
NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4424 unsigned char *pMemory
,
4425 PFORMAT_STRING pFormat
)
4427 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4428 unsigned long total_size
;
4430 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4432 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4433 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4435 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4436 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4440 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4442 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4444 total_size
= pSmFArrayFormat
->total_size
;
4445 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4449 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4450 total_size
= pLgFArrayFormat
->total_size
;
4451 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4454 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4455 safe_copy_to_buffer(pStubMsg
, pMemory
, total_size
);
4457 pFormat
= EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4462 /***********************************************************************
4463 * NdrFixedArrayUnmarshall [RPCRT4.@]
4465 unsigned char * WINAPI
NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4466 unsigned char **ppMemory
,
4467 PFORMAT_STRING pFormat
,
4468 unsigned char fMustAlloc
)
4470 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4471 unsigned long total_size
;
4472 unsigned char *saved_buffer
;
4474 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4476 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4477 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4479 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4480 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4484 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4486 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4488 total_size
= pSmFArrayFormat
->total_size
;
4489 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4493 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4494 total_size
= pLgFArrayFormat
->total_size
;
4495 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4499 *ppMemory
= NdrAllocate(pStubMsg
, total_size
);
4502 if (!pStubMsg
->IsClient
&& !*ppMemory
)
4503 /* for servers, we just point straight into the RPC buffer */
4504 *ppMemory
= pStubMsg
->Buffer
;
4507 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4508 safe_buffer_increment(pStubMsg
, total_size
);
4509 pFormat
= EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4511 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
4512 if (*ppMemory
!= saved_buffer
)
4513 memcpy(*ppMemory
, saved_buffer
, total_size
);
4518 /***********************************************************************
4519 * NdrFixedArrayBufferSize [RPCRT4.@]
4521 void WINAPI
NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4522 unsigned char *pMemory
,
4523 PFORMAT_STRING pFormat
)
4525 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4526 unsigned long total_size
;
4528 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4530 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4531 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4533 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4534 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4538 ALIGN_LENGTH(pStubMsg
->BufferLength
, pSmFArrayFormat
->alignment
+ 1);
4540 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4542 total_size
= pSmFArrayFormat
->total_size
;
4543 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4547 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4548 total_size
= pLgFArrayFormat
->total_size
;
4549 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4551 safe_buffer_length_increment(pStubMsg
, total_size
);
4553 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4556 /***********************************************************************
4557 * NdrFixedArrayMemorySize [RPCRT4.@]
4559 ULONG WINAPI
NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4560 PFORMAT_STRING pFormat
)
4562 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4565 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4567 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4568 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4570 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4571 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4575 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4577 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4579 total_size
= pSmFArrayFormat
->total_size
;
4580 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4584 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4585 total_size
= pLgFArrayFormat
->total_size
;
4586 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4588 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4589 safe_buffer_increment(pStubMsg
, total_size
);
4590 pStubMsg
->MemorySize
+= total_size
;
4592 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4597 /***********************************************************************
4598 * NdrFixedArrayFree [RPCRT4.@]
4600 void WINAPI
NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4601 unsigned char *pMemory
,
4602 PFORMAT_STRING pFormat
)
4604 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4606 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4608 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4609 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4611 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4612 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4616 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4617 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4620 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4621 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4624 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4627 /***********************************************************************
4628 * NdrVaryingArrayMarshall [RPCRT4.@]
4630 unsigned char * WINAPI
NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4631 unsigned char *pMemory
,
4632 PFORMAT_STRING pFormat
)
4634 unsigned char alignment
;
4635 DWORD elements
, esize
;
4638 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4640 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4641 (pFormat
[0] != RPC_FC_LGVARRAY
))
4643 ERR("invalid format type %x\n", pFormat
[0]);
4644 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4648 alignment
= pFormat
[1] + 1;
4650 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4653 pFormat
+= sizeof(WORD
);
4654 elements
= *(const WORD
*)pFormat
;
4655 pFormat
+= sizeof(WORD
);
4660 pFormat
+= sizeof(DWORD
);
4661 elements
= *(const DWORD
*)pFormat
;
4662 pFormat
+= sizeof(DWORD
);
4665 esize
= *(const WORD
*)pFormat
;
4666 pFormat
+= sizeof(WORD
);
4668 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4669 if ((pStubMsg
->ActualCount
> elements
) ||
4670 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4672 RpcRaiseException(RPC_S_INVALID_BOUND
);
4676 WriteVariance(pStubMsg
);
4678 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
4680 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4681 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4682 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
4684 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4689 /***********************************************************************
4690 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4692 unsigned char * WINAPI
NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4693 unsigned char **ppMemory
,
4694 PFORMAT_STRING pFormat
,
4695 unsigned char fMustAlloc
)
4697 unsigned char alignment
;
4698 DWORD size
, elements
, esize
;
4700 unsigned char *saved_buffer
;
4703 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4705 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4706 (pFormat
[0] != RPC_FC_LGVARRAY
))
4708 ERR("invalid format type %x\n", pFormat
[0]);
4709 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4713 alignment
= pFormat
[1] + 1;
4715 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4718 size
= *(const WORD
*)pFormat
;
4719 pFormat
+= sizeof(WORD
);
4720 elements
= *(const WORD
*)pFormat
;
4721 pFormat
+= sizeof(WORD
);
4726 size
= *(const DWORD
*)pFormat
;
4727 pFormat
+= sizeof(DWORD
);
4728 elements
= *(const DWORD
*)pFormat
;
4729 pFormat
+= sizeof(DWORD
);
4732 esize
= *(const WORD
*)pFormat
;
4733 pFormat
+= sizeof(WORD
);
4735 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
4737 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4739 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4740 offset
= pStubMsg
->Offset
;
4742 if (!*ppMemory
|| fMustAlloc
)
4743 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4744 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4745 safe_buffer_increment(pStubMsg
, bufsize
);
4747 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4749 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
4754 /***********************************************************************
4755 * NdrVaryingArrayBufferSize [RPCRT4.@]
4757 void WINAPI
NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4758 unsigned char *pMemory
,
4759 PFORMAT_STRING pFormat
)
4761 unsigned char alignment
;
4762 DWORD elements
, esize
;
4764 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4766 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4767 (pFormat
[0] != RPC_FC_LGVARRAY
))
4769 ERR("invalid format type %x\n", pFormat
[0]);
4770 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4774 alignment
= pFormat
[1] + 1;
4776 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4779 pFormat
+= sizeof(WORD
);
4780 elements
= *(const WORD
*)pFormat
;
4781 pFormat
+= sizeof(WORD
);
4786 pFormat
+= sizeof(DWORD
);
4787 elements
= *(const DWORD
*)pFormat
;
4788 pFormat
+= sizeof(DWORD
);
4791 esize
= *(const WORD
*)pFormat
;
4792 pFormat
+= sizeof(WORD
);
4794 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4795 if ((pStubMsg
->ActualCount
> elements
) ||
4796 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4798 RpcRaiseException(RPC_S_INVALID_BOUND
);
4802 SizeVariance(pStubMsg
);
4804 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
4806 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
4808 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4811 /***********************************************************************
4812 * NdrVaryingArrayMemorySize [RPCRT4.@]
4814 ULONG WINAPI
NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4815 PFORMAT_STRING pFormat
)
4817 unsigned char alignment
;
4818 DWORD size
, elements
, esize
;
4820 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4822 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4823 (pFormat
[0] != RPC_FC_LGVARRAY
))
4825 ERR("invalid format type %x\n", pFormat
[0]);
4826 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4830 alignment
= pFormat
[1] + 1;
4832 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4835 size
= *(const WORD
*)pFormat
;
4836 pFormat
+= sizeof(WORD
);
4837 elements
= *(const WORD
*)pFormat
;
4838 pFormat
+= sizeof(WORD
);
4843 size
= *(const DWORD
*)pFormat
;
4844 pFormat
+= sizeof(DWORD
);
4845 elements
= *(const DWORD
*)pFormat
;
4846 pFormat
+= sizeof(DWORD
);
4849 esize
= *(const WORD
*)pFormat
;
4850 pFormat
+= sizeof(WORD
);
4852 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
4854 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4856 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
4857 pStubMsg
->MemorySize
+= size
;
4859 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4861 return pStubMsg
->MemorySize
;
4864 /***********************************************************************
4865 * NdrVaryingArrayFree [RPCRT4.@]
4867 void WINAPI
NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4868 unsigned char *pMemory
,
4869 PFORMAT_STRING pFormat
)
4871 unsigned char alignment
;
4874 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4876 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4877 (pFormat
[0] != RPC_FC_LGVARRAY
))
4879 ERR("invalid format type %x\n", pFormat
[0]);
4880 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4884 alignment
= pFormat
[1] + 1;
4886 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4889 pFormat
+= sizeof(WORD
);
4890 elements
= *(const WORD
*)pFormat
;
4891 pFormat
+= sizeof(WORD
);
4896 pFormat
+= sizeof(DWORD
);
4897 elements
= *(const DWORD
*)pFormat
;
4898 pFormat
+= sizeof(DWORD
);
4901 pFormat
+= sizeof(WORD
);
4903 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4904 if ((pStubMsg
->ActualCount
> elements
) ||
4905 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4907 RpcRaiseException(RPC_S_INVALID_BOUND
);
4911 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4914 static ULONG
get_discriminant(unsigned char fc
, const unsigned char *pMemory
)
4922 return *(const UCHAR
*)pMemory
;
4927 return *(const USHORT
*)pMemory
;
4931 return *(const ULONG
*)pMemory
;
4933 FIXME("Unhandled base type: 0x%02x\n", fc
);
4938 static PFORMAT_STRING
get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg
,
4939 unsigned long discriminant
,
4940 PFORMAT_STRING pFormat
)
4942 unsigned short num_arms
, arm
, type
;
4944 num_arms
= *(const SHORT
*)pFormat
& 0x0fff;
4946 for(arm
= 0; arm
< num_arms
; arm
++)
4948 if(discriminant
== *(const ULONG
*)pFormat
)
4956 type
= *(const unsigned short*)pFormat
;
4957 TRACE("type %04x\n", type
);
4958 if(arm
== num_arms
) /* default arm extras */
4962 ERR("no arm for 0x%lx and no default case\n", discriminant
);
4963 RpcRaiseException(RPC_S_INVALID_TAG
);
4968 TRACE("falling back to empty default case for 0x%lx\n", discriminant
);
4975 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
, ULONG discriminant
, PFORMAT_STRING pFormat
)
4977 unsigned short type
;
4981 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4985 type
= *(const unsigned short*)pFormat
;
4986 if((type
& 0xff00) == 0x8000)
4988 unsigned char basetype
= LOBYTE(type
);
4989 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &basetype
);
4993 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4994 NDR_MARSHALL m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
4997 unsigned char *saved_buffer
= NULL
;
4998 int pointer_buffer_mark_set
= 0;
5005 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
5006 saved_buffer
= pStubMsg
->Buffer
;
5007 if (pStubMsg
->PointerBufferMark
)
5009 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5010 pStubMsg
->PointerBufferMark
= NULL
;
5011 pointer_buffer_mark_set
= 1;
5014 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
5016 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char **)pMemory
, desc
);
5017 if (pointer_buffer_mark_set
)
5019 STD_OVERFLOW_CHECK(pStubMsg
);
5020 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5021 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5023 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5024 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
5025 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5027 pStubMsg
->Buffer
= saved_buffer
+ 4;
5031 m(pStubMsg
, pMemory
, desc
);
5034 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5039 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5040 unsigned char **ppMemory
,
5042 PFORMAT_STRING pFormat
,
5043 unsigned char fMustAlloc
)
5045 unsigned short type
;
5049 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5053 type
= *(const unsigned short*)pFormat
;
5054 if((type
& 0xff00) == 0x8000)
5056 unsigned char basetype
= LOBYTE(type
);
5057 return NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &basetype
, FALSE
);
5061 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5062 NDR_UNMARSHALL m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
5065 unsigned char *saved_buffer
= NULL
;
5066 int pointer_buffer_mark_set
= 0;
5073 **(void***)ppMemory
= NULL
;
5074 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5075 saved_buffer
= pStubMsg
->Buffer
;
5076 if (pStubMsg
->PointerBufferMark
)
5078 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5079 pStubMsg
->PointerBufferMark
= NULL
;
5080 pointer_buffer_mark_set
= 1;
5083 pStubMsg
->Buffer
+= 4; /* for pointer ID */
5085 if (saved_buffer
+ 4 > pStubMsg
->BufferEnd
)
5087 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5088 saved_buffer
, pStubMsg
->BufferEnd
);
5089 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5092 PointerUnmarshall(pStubMsg
, saved_buffer
, *(unsigned char ***)ppMemory
, **(unsigned char ***)ppMemory
, desc
, fMustAlloc
);
5093 if (pointer_buffer_mark_set
)
5095 STD_OVERFLOW_CHECK(pStubMsg
);
5096 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5097 pStubMsg
->Buffer
= saved_buffer
+ 4;
5101 m(pStubMsg
, ppMemory
, desc
, fMustAlloc
);
5104 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5109 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg
,
5110 unsigned char *pMemory
,
5112 PFORMAT_STRING pFormat
)
5114 unsigned short type
;
5118 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5122 type
= *(const unsigned short*)pFormat
;
5123 if((type
& 0xff00) == 0x8000)
5125 unsigned char basetype
= LOBYTE(type
);
5126 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &basetype
);
5130 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5131 NDR_BUFFERSIZE m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
5140 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
5141 safe_buffer_length_increment(pStubMsg
, 4); /* for pointer ID */
5142 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5144 int saved_buffer_length
= pStubMsg
->BufferLength
;
5145 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
5146 pStubMsg
->PointerLength
= 0;
5147 if(!pStubMsg
->BufferLength
)
5148 ERR("BufferLength == 0??\n");
5149 PointerBufferSize(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5150 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
5151 pStubMsg
->BufferLength
= saved_buffer_length
;
5155 m(pStubMsg
, pMemory
, desc
);
5158 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
5162 static ULONG
union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg
,
5164 PFORMAT_STRING pFormat
)
5166 unsigned short type
, size
;
5168 size
= *(const unsigned short*)pFormat
;
5169 pStubMsg
->Memory
+= size
;
5172 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5176 type
= *(const unsigned short*)pFormat
;
5177 if((type
& 0xff00) == 0x8000)
5179 return NdrBaseTypeMemorySize(pStubMsg
, pFormat
);
5183 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5184 NDR_MEMORYSIZE m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
5185 unsigned char *saved_buffer
;
5194 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5195 saved_buffer
= pStubMsg
->Buffer
;
5196 safe_buffer_increment(pStubMsg
, 4);
5197 ALIGN_LENGTH(pStubMsg
->MemorySize
, 4);
5198 pStubMsg
->MemorySize
+= 4;
5199 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5200 PointerMemorySize(pStubMsg
, saved_buffer
, pFormat
);
5203 return m(pStubMsg
, desc
);
5206 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5209 TRACE("size %d\n", size
);
5213 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg
,
5214 unsigned char *pMemory
,
5216 PFORMAT_STRING pFormat
)
5218 unsigned short type
;
5222 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5226 type
= *(const unsigned short*)pFormat
;
5227 if((type
& 0xff00) != 0x8000)
5229 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5230 NDR_FREE m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
5239 PointerFree(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5242 m(pStubMsg
, pMemory
, desc
);
5245 else FIXME("no freer for embedded type %02x\n", *desc
);
5249 /***********************************************************************
5250 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5252 unsigned char * WINAPI
NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5253 unsigned char *pMemory
,
5254 PFORMAT_STRING pFormat
)
5256 unsigned char switch_type
;
5257 unsigned char increment
;
5260 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5263 switch_type
= *pFormat
& 0xf;
5264 increment
= (*pFormat
& 0xf0) >> 4;
5267 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, increment
);
5269 switch_value
= get_discriminant(switch_type
, pMemory
);
5270 TRACE("got switch value 0x%x\n", switch_value
);
5272 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &switch_type
);
5273 pMemory
+= increment
;
5275 return union_arm_marshall(pStubMsg
, pMemory
, switch_value
, pFormat
);
5278 /***********************************************************************
5279 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5281 unsigned char * WINAPI
NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5282 unsigned char **ppMemory
,
5283 PFORMAT_STRING pFormat
,
5284 unsigned char fMustAlloc
)
5286 unsigned char switch_type
;
5287 unsigned char increment
;
5289 unsigned short size
;
5290 unsigned char *pMemoryArm
;
5292 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5295 switch_type
= *pFormat
& 0xf;
5296 increment
= (*pFormat
& 0xf0) >> 4;
5299 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
5300 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
5301 TRACE("got switch value 0x%x\n", switch_value
);
5303 size
= *(const unsigned short*)pFormat
+ increment
;
5304 if(!*ppMemory
|| fMustAlloc
)
5305 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5307 NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &switch_type
, FALSE
);
5308 pMemoryArm
= *ppMemory
+ increment
;
5310 return union_arm_unmarshall(pStubMsg
, &pMemoryArm
, switch_value
, pFormat
, fMustAlloc
);
5313 /***********************************************************************
5314 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5316 void WINAPI
NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5317 unsigned char *pMemory
,
5318 PFORMAT_STRING pFormat
)
5320 unsigned char switch_type
;
5321 unsigned char increment
;
5324 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5327 switch_type
= *pFormat
& 0xf;
5328 increment
= (*pFormat
& 0xf0) >> 4;
5331 ALIGN_LENGTH(pStubMsg
->BufferLength
, increment
);
5332 switch_value
= get_discriminant(switch_type
, pMemory
);
5333 TRACE("got switch value 0x%x\n", switch_value
);
5335 /* Add discriminant size */
5336 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&switch_value
, &switch_type
);
5337 pMemory
+= increment
;
5339 union_arm_buffer_size(pStubMsg
, pMemory
, switch_value
, pFormat
);
5342 /***********************************************************************
5343 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5345 ULONG WINAPI
NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5346 PFORMAT_STRING pFormat
)
5348 unsigned char switch_type
;
5349 unsigned char increment
;
5352 switch_type
= *pFormat
& 0xf;
5353 increment
= (*pFormat
& 0xf0) >> 4;
5356 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
5357 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
5358 TRACE("got switch value 0x%x\n", switch_value
);
5360 pStubMsg
->Memory
+= increment
;
5362 return increment
+ union_arm_memory_size(pStubMsg
, switch_value
, pFormat
+ *(const SHORT
*)pFormat
);
5365 /***********************************************************************
5366 * NdrEncapsulatedUnionFree [RPCRT4.@]
5368 void WINAPI
NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
5369 unsigned char *pMemory
,
5370 PFORMAT_STRING pFormat
)
5372 unsigned char switch_type
;
5373 unsigned char increment
;
5376 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5379 switch_type
= *pFormat
& 0xf;
5380 increment
= (*pFormat
& 0xf0) >> 4;
5383 switch_value
= get_discriminant(switch_type
, pMemory
);
5384 TRACE("got switch value 0x%x\n", switch_value
);
5386 pMemory
+= increment
;
5388 return union_arm_free(pStubMsg
, pMemory
, switch_value
, pFormat
);
5391 /***********************************************************************
5392 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5394 unsigned char * WINAPI
NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5395 unsigned char *pMemory
,
5396 PFORMAT_STRING pFormat
)
5398 unsigned char switch_type
;
5400 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5403 switch_type
= *pFormat
;
5406 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5407 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5408 /* Marshall discriminant */
5409 NdrBaseTypeMarshall(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
5411 return union_arm_marshall(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5414 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg
,
5415 PFORMAT_STRING
*ppFormat
)
5417 long discriminant
= 0;
5427 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5436 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5437 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5445 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
5446 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5451 FIXME("Unhandled base type: 0x%02x\n", **ppFormat
);
5455 if (pStubMsg
->fHasNewCorrDesc
)
5459 return discriminant
;
5462 /**********************************************************************
5463 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5465 unsigned char * WINAPI
NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5466 unsigned char **ppMemory
,
5467 PFORMAT_STRING pFormat
,
5468 unsigned char fMustAlloc
)
5471 unsigned short size
;
5473 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5476 /* Unmarshall discriminant */
5477 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
5478 TRACE("unmarshalled discriminant %lx\n", discriminant
);
5480 pFormat
+= *(const SHORT
*)pFormat
;
5482 size
= *(const unsigned short*)pFormat
;
5484 if(!*ppMemory
|| fMustAlloc
)
5485 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5487 return union_arm_unmarshall(pStubMsg
, ppMemory
, discriminant
, pFormat
, fMustAlloc
);
5490 /***********************************************************************
5491 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5493 void WINAPI
NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5494 unsigned char *pMemory
,
5495 PFORMAT_STRING pFormat
)
5497 unsigned char switch_type
;
5499 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5502 switch_type
= *pFormat
;
5505 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5506 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5507 /* Add discriminant size */
5508 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
5510 union_arm_buffer_size(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5513 /***********************************************************************
5514 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5516 ULONG WINAPI
NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5517 PFORMAT_STRING pFormat
)
5522 /* Unmarshall discriminant */
5523 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
5524 TRACE("unmarshalled discriminant 0x%x\n", discriminant
);
5526 return union_arm_memory_size(pStubMsg
, discriminant
, pFormat
+ *(const SHORT
*)pFormat
);
5529 /***********************************************************************
5530 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5532 void WINAPI
NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
5533 unsigned char *pMemory
,
5534 PFORMAT_STRING pFormat
)
5536 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5540 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5541 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5543 return union_arm_free(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5546 /***********************************************************************
5547 * NdrByteCountPointerMarshall [RPCRT4.@]
5549 unsigned char * WINAPI
NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5550 unsigned char *pMemory
,
5551 PFORMAT_STRING pFormat
)
5557 /***********************************************************************
5558 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5560 unsigned char * WINAPI
NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5561 unsigned char **ppMemory
,
5562 PFORMAT_STRING pFormat
,
5563 unsigned char fMustAlloc
)
5569 /***********************************************************************
5570 * NdrByteCountPointerBufferSize [RPCRT4.@]
5572 void WINAPI
NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5573 unsigned char *pMemory
,
5574 PFORMAT_STRING pFormat
)
5579 /***********************************************************************
5580 * NdrByteCountPointerMemorySize [RPCRT4.@]
5582 ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5583 PFORMAT_STRING pFormat
)
5589 /***********************************************************************
5590 * NdrByteCountPointerFree [RPCRT4.@]
5592 void WINAPI
NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
5593 unsigned char *pMemory
,
5594 PFORMAT_STRING pFormat
)
5599 /***********************************************************************
5600 * NdrXmitOrRepAsMarshall [RPCRT4.@]
5602 unsigned char * WINAPI
NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5603 unsigned char *pMemory
,
5604 PFORMAT_STRING pFormat
)
5610 /***********************************************************************
5611 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
5613 unsigned char * WINAPI
NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5614 unsigned char **ppMemory
,
5615 PFORMAT_STRING pFormat
,
5616 unsigned char fMustAlloc
)
5622 /***********************************************************************
5623 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
5625 void WINAPI
NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5626 unsigned char *pMemory
,
5627 PFORMAT_STRING pFormat
)
5632 /***********************************************************************
5633 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
5635 ULONG WINAPI
NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5636 PFORMAT_STRING pFormat
)
5642 /***********************************************************************
5643 * NdrXmitOrRepAsFree [RPCRT4.@]
5645 void WINAPI
NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg
,
5646 unsigned char *pMemory
,
5647 PFORMAT_STRING pFormat
)
5652 #include "pshpack1.h"
5656 unsigned char flags_type
; /* flags in upper nibble, type in lower nibble */
5660 #include "poppack.h"
5662 /***********************************************************************
5663 * NdrRangeMarshall [internal]
5665 unsigned char *WINAPI
NdrRangeMarshall(
5666 PMIDL_STUB_MESSAGE pStubMsg
,
5667 unsigned char *pMemory
,
5668 PFORMAT_STRING pFormat
)
5670 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5671 unsigned char base_type
;
5673 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5675 if (pRange
->type
!= RPC_FC_RANGE
)
5677 ERR("invalid format type %x\n", pRange
->type
);
5678 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5682 base_type
= pRange
->flags_type
& 0xf;
5684 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &base_type
);
5687 /***********************************************************************
5688 * NdrRangeUnmarshall
5690 unsigned char *WINAPI
NdrRangeUnmarshall(
5691 PMIDL_STUB_MESSAGE pStubMsg
,
5692 unsigned char **ppMemory
,
5693 PFORMAT_STRING pFormat
,
5694 unsigned char fMustAlloc
)
5696 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5697 unsigned char base_type
;
5699 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
5701 if (pRange
->type
!= RPC_FC_RANGE
)
5703 ERR("invalid format type %x\n", pRange
->type
);
5704 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5707 base_type
= pRange
->flags_type
& 0xf;
5709 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5710 base_type
, pRange
->low_value
, pRange
->high_value
);
5712 #define RANGE_UNMARSHALL(type, format_spec) \
5715 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5716 if (fMustAlloc || !*ppMemory) \
5717 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5718 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
5720 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
5721 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
5722 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
5724 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5725 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5727 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5728 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5729 (type)pRange->high_value); \
5730 RpcRaiseException(RPC_S_INVALID_BOUND); \
5733 TRACE("*ppMemory: %p\n", *ppMemory); \
5734 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5735 pStubMsg->Buffer += sizeof(type); \
5742 RANGE_UNMARSHALL(UCHAR
, "%d");
5743 TRACE("value: 0x%02x\n", **(UCHAR
**)ppMemory
);
5747 RANGE_UNMARSHALL(CHAR
, "%u");
5748 TRACE("value: 0x%02x\n", **(UCHAR
**)ppMemory
);
5750 case RPC_FC_WCHAR
: /* FIXME: valid? */
5752 RANGE_UNMARSHALL(USHORT
, "%u");
5753 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5756 RANGE_UNMARSHALL(SHORT
, "%d");
5757 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5760 RANGE_UNMARSHALL(LONG
, "%d");
5761 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5764 RANGE_UNMARSHALL(ULONG
, "%u");
5765 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5769 FIXME("Unhandled enum type\n");
5771 case RPC_FC_ERROR_STATUS_T
: /* FIXME: valid? */
5776 ERR("invalid range base type: 0x%02x\n", base_type
);
5777 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5783 /***********************************************************************
5784 * NdrRangeBufferSize [internal]
5786 void WINAPI
NdrRangeBufferSize(
5787 PMIDL_STUB_MESSAGE pStubMsg
,
5788 unsigned char *pMemory
,
5789 PFORMAT_STRING pFormat
)
5791 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5792 unsigned char base_type
;
5794 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5796 if (pRange
->type
!= RPC_FC_RANGE
)
5798 ERR("invalid format type %x\n", pRange
->type
);
5799 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5801 base_type
= pRange
->flags_type
& 0xf;
5803 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &base_type
);
5806 /***********************************************************************
5807 * NdrRangeMemorySize [internal]
5809 ULONG WINAPI
NdrRangeMemorySize(
5810 PMIDL_STUB_MESSAGE pStubMsg
,
5811 PFORMAT_STRING pFormat
)
5813 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5814 unsigned char base_type
;
5816 if (pRange
->type
!= RPC_FC_RANGE
)
5818 ERR("invalid format type %x\n", pRange
->type
);
5819 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5822 base_type
= pRange
->flags_type
& 0xf;
5824 return NdrBaseTypeMemorySize(pStubMsg
, &base_type
);
5827 /***********************************************************************
5828 * NdrRangeFree [internal]
5830 void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg
,
5831 unsigned char *pMemory
,
5832 PFORMAT_STRING pFormat
)
5834 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5839 /***********************************************************************
5840 * NdrBaseTypeMarshall [internal]
5842 static unsigned char *WINAPI
NdrBaseTypeMarshall(
5843 PMIDL_STUB_MESSAGE pStubMsg
,
5844 unsigned char *pMemory
,
5845 PFORMAT_STRING pFormat
)
5847 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5855 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(UCHAR
));
5856 TRACE("value: 0x%02x\n", *(UCHAR
*)pMemory
);
5861 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(USHORT
));
5862 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(USHORT
));
5863 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
5867 case RPC_FC_ERROR_STATUS_T
:
5869 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(ULONG
));
5870 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONG
));
5871 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
5874 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(float));
5875 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
5878 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(double));
5879 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
5882 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(ULONGLONG
));
5883 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONGLONG
));
5884 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
5887 /* only 16-bits on the wire, so do a sanity check */
5888 if (*(UINT
*)pMemory
> SHRT_MAX
)
5889 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
5890 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(USHORT
));
5891 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5892 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5893 *(USHORT
*)pStubMsg
->Buffer
= *(UINT
*)pMemory
;
5894 pStubMsg
->Buffer
+= sizeof(USHORT
);
5895 TRACE("value: 0x%04x\n", *(UINT
*)pMemory
);
5900 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5903 /* FIXME: what is the correct return value? */
5907 /***********************************************************************
5908 * NdrBaseTypeUnmarshall [internal]
5910 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(
5911 PMIDL_STUB_MESSAGE pStubMsg
,
5912 unsigned char **ppMemory
,
5913 PFORMAT_STRING pFormat
,
5914 unsigned char fMustAlloc
)
5916 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
5918 #define BASE_TYPE_UNMARSHALL(type) \
5919 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5920 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
5922 *ppMemory = pStubMsg->Buffer; \
5923 TRACE("*ppMemory: %p\n", *ppMemory); \
5928 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5929 TRACE("*ppMemory: %p\n", *ppMemory); \
5930 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5932 pStubMsg->Buffer += sizeof(type);
5940 BASE_TYPE_UNMARSHALL(UCHAR
);
5941 TRACE("value: 0x%02x\n", **(UCHAR
**)ppMemory
);
5946 BASE_TYPE_UNMARSHALL(USHORT
);
5947 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5951 case RPC_FC_ERROR_STATUS_T
:
5953 BASE_TYPE_UNMARSHALL(ULONG
);
5954 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5957 BASE_TYPE_UNMARSHALL(float);
5958 TRACE("value: %f\n", **(float **)ppMemory
);
5961 BASE_TYPE_UNMARSHALL(double);
5962 TRACE("value: %f\n", **(double **)ppMemory
);
5965 BASE_TYPE_UNMARSHALL(ULONGLONG
);
5966 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG
**)ppMemory
));
5969 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5970 if (fMustAlloc
|| !*ppMemory
)
5971 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT
));
5972 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > pStubMsg
->BufferEnd
)
5973 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5974 TRACE("*ppMemory: %p\n", *ppMemory
);
5975 /* 16-bits on the wire, but int in memory */
5976 **(UINT
**)ppMemory
= *(USHORT
*)pStubMsg
->Buffer
;
5977 pStubMsg
->Buffer
+= sizeof(USHORT
);
5978 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
5983 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5985 #undef BASE_TYPE_UNMARSHALL
5987 /* FIXME: what is the correct return value? */
5992 /***********************************************************************
5993 * NdrBaseTypeBufferSize [internal]
5995 static void WINAPI
NdrBaseTypeBufferSize(
5996 PMIDL_STUB_MESSAGE pStubMsg
,
5997 unsigned char *pMemory
,
5998 PFORMAT_STRING pFormat
)
6000 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6008 safe_buffer_length_increment(pStubMsg
, sizeof(UCHAR
));
6014 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(USHORT
));
6015 safe_buffer_length_increment(pStubMsg
, sizeof(USHORT
));
6020 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONG
));
6021 safe_buffer_length_increment(pStubMsg
, sizeof(ULONG
));
6024 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(float));
6025 safe_buffer_length_increment(pStubMsg
, sizeof(float));
6028 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(double));
6029 safe_buffer_length_increment(pStubMsg
, sizeof(double));
6032 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONGLONG
));
6033 safe_buffer_length_increment(pStubMsg
, sizeof(ULONGLONG
));
6035 case RPC_FC_ERROR_STATUS_T
:
6036 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(error_status_t
));
6037 safe_buffer_length_increment(pStubMsg
, sizeof(error_status_t
));
6042 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6046 /***********************************************************************
6047 * NdrBaseTypeMemorySize [internal]
6049 static ULONG WINAPI
NdrBaseTypeMemorySize(
6050 PMIDL_STUB_MESSAGE pStubMsg
,
6051 PFORMAT_STRING pFormat
)
6053 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg
, *pFormat
);
6061 safe_buffer_increment(pStubMsg
, sizeof(UCHAR
));
6062 pStubMsg
->MemorySize
+= sizeof(UCHAR
);
6063 return sizeof(UCHAR
);
6067 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6068 pStubMsg
->MemorySize
+= sizeof(USHORT
);
6069 return sizeof(USHORT
);
6073 safe_buffer_increment(pStubMsg
, sizeof(ULONG
));
6074 pStubMsg
->MemorySize
+= sizeof(ULONG
);
6075 return sizeof(ULONG
);
6077 safe_buffer_increment(pStubMsg
, sizeof(float));
6078 pStubMsg
->MemorySize
+= sizeof(float);
6079 return sizeof(float);
6081 safe_buffer_increment(pStubMsg
, sizeof(double));
6082 pStubMsg
->MemorySize
+= sizeof(double);
6083 return sizeof(double);
6085 safe_buffer_increment(pStubMsg
, sizeof(ULONGLONG
));
6086 pStubMsg
->MemorySize
+= sizeof(ULONGLONG
);
6087 return sizeof(ULONGLONG
);
6088 case RPC_FC_ERROR_STATUS_T
:
6089 safe_buffer_increment(pStubMsg
, sizeof(error_status_t
));
6090 pStubMsg
->MemorySize
+= sizeof(error_status_t
);
6091 return sizeof(error_status_t
);
6093 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6094 pStubMsg
->MemorySize
+= sizeof(UINT
);
6095 return sizeof(UINT
);
6097 pStubMsg
->MemorySize
+= sizeof(void *);
6098 return sizeof(void *);
6100 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6105 /***********************************************************************
6106 * NdrBaseTypeFree [internal]
6108 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6109 unsigned char *pMemory
,
6110 PFORMAT_STRING pFormat
)
6112 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6117 /***********************************************************************
6118 * NdrContextHandleBufferSize [internal]
6120 static void WINAPI
NdrContextHandleBufferSize(
6121 PMIDL_STUB_MESSAGE pStubMsg
,
6122 unsigned char *pMemory
,
6123 PFORMAT_STRING pFormat
)
6125 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6127 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6129 ERR("invalid format type %x\n", *pFormat
);
6130 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6132 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
6133 safe_buffer_length_increment(pStubMsg
, cbNDRContext
);
6136 /***********************************************************************
6137 * NdrContextHandleMarshall [internal]
6139 static unsigned char *WINAPI
NdrContextHandleMarshall(
6140 PMIDL_STUB_MESSAGE pStubMsg
,
6141 unsigned char *pMemory
,
6142 PFORMAT_STRING pFormat
)
6144 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6146 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6148 ERR("invalid format type %x\n", *pFormat
);
6149 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6152 if (pFormat
[1] & 0x80)
6153 NdrClientContextMarshall(pStubMsg
, *(NDR_CCONTEXT
**)pMemory
, FALSE
);
6155 NdrClientContextMarshall(pStubMsg
, (NDR_CCONTEXT
*)pMemory
, FALSE
);
6160 /***********************************************************************
6161 * NdrContextHandleUnmarshall [internal]
6163 static unsigned char *WINAPI
NdrContextHandleUnmarshall(
6164 PMIDL_STUB_MESSAGE pStubMsg
,
6165 unsigned char **ppMemory
,
6166 PFORMAT_STRING pFormat
,
6167 unsigned char fMustAlloc
)
6169 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6171 ERR("invalid format type %x\n", *pFormat
);
6172 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6175 **(NDR_CCONTEXT
**)ppMemory
= NULL
;
6176 NdrClientContextUnmarshall(pStubMsg
, *(NDR_CCONTEXT
**)ppMemory
, pStubMsg
->RpcMsg
->Handle
);
6181 /***********************************************************************
6182 * NdrClientContextMarshall [RPCRT4.@]
6184 void WINAPI
NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6185 NDR_CCONTEXT ContextHandle
,
6188 TRACE("(%p, %p, %d)\n", pStubMsg
, ContextHandle
, fCheck
);
6190 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
6192 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6194 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6195 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6196 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6199 /* FIXME: what does fCheck do? */
6200 NDRCContextMarshall(ContextHandle
,
6203 pStubMsg
->Buffer
+= cbNDRContext
;
6206 /***********************************************************************
6207 * NdrClientContextUnmarshall [RPCRT4.@]
6209 void WINAPI
NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6210 NDR_CCONTEXT
* pContextHandle
,
6211 RPC_BINDING_HANDLE BindHandle
)
6213 TRACE("(%p, %p, %p)\n", pStubMsg
, pContextHandle
, BindHandle
);
6215 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6217 if (pStubMsg
->Buffer
+ cbNDRContext
> pStubMsg
->BufferEnd
)
6218 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6220 NDRCContextUnmarshall(pContextHandle
,
6223 pStubMsg
->RpcMsg
->DataRepresentation
);
6225 pStubMsg
->Buffer
+= cbNDRContext
;
6228 void WINAPI
NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6229 NDR_SCONTEXT ContextHandle
,
6230 NDR_RUNDOWN RundownRoutine
)
6232 TRACE("(%p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
);
6234 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6236 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6238 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6239 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6240 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6243 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
6244 pStubMsg
->Buffer
, RundownRoutine
, NULL
,
6245 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
6246 pStubMsg
->Buffer
+= cbNDRContext
;
6249 NDR_SCONTEXT WINAPI
NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
)
6251 NDR_SCONTEXT ContextHandle
;
6253 TRACE("(%p)\n", pStubMsg
);
6255 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6257 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6259 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6260 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6261 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6264 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
6266 pStubMsg
->RpcMsg
->DataRepresentation
,
6267 NULL
, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
6268 pStubMsg
->Buffer
+= cbNDRContext
;
6270 return ContextHandle
;
6273 void WINAPI
NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg
,
6274 unsigned char* pMemory
,
6275 PFORMAT_STRING pFormat
)
6277 FIXME("(%p, %p, %p): stub\n", pStubMsg
, pMemory
, pFormat
);
6280 NDR_SCONTEXT WINAPI
NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg
,
6281 PFORMAT_STRING pFormat
)
6283 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6284 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6286 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
6288 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
6289 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
6290 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
6291 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
6292 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
6294 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
6295 if_id
= &sif
->InterfaceId
;
6298 return NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
, NULL
,
6299 pStubMsg
->RpcMsg
->DataRepresentation
, if_id
,
6303 void WINAPI
NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6304 NDR_SCONTEXT ContextHandle
,
6305 NDR_RUNDOWN RundownRoutine
,
6306 PFORMAT_STRING pFormat
)
6308 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6309 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6311 TRACE("(%p, %p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
, pFormat
);
6313 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6315 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6317 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6318 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6319 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6322 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
6323 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
6324 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
6325 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
6326 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
6328 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
6329 if_id
= &sif
->InterfaceId
;
6332 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
6333 pStubMsg
->Buffer
, RundownRoutine
, if_id
, flags
);
6334 pStubMsg
->Buffer
+= cbNDRContext
;
6337 NDR_SCONTEXT WINAPI
NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6338 PFORMAT_STRING pFormat
)
6340 NDR_SCONTEXT ContextHandle
;
6341 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6342 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6344 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
6346 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6348 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6350 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6351 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6352 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6355 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
6356 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
6357 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
6358 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
6359 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
6361 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
6362 if_id
= &sif
->InterfaceId
;
6365 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
6367 pStubMsg
->RpcMsg
->DataRepresentation
,
6369 pStubMsg
->Buffer
+= cbNDRContext
;
6371 return ContextHandle
;
6374 /***********************************************************************
6375 * NdrCorrelationInitialize [RPCRT4.@]
6377 * Initializes correlation validity checking.
6380 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6381 * pMemory [I] Pointer to memory to use as a cache.
6382 * CacheSize [I] Size of the memory pointed to by pMemory.
6383 * Flags [I] Reserved. Set to zero.
6388 void WINAPI
NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg
, void *pMemory
, ULONG CacheSize
, ULONG Flags
)
6390 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg
, pMemory
, CacheSize
, Flags
);
6391 pStubMsg
->fHasNewCorrDesc
= TRUE
;
6394 /***********************************************************************
6395 * NdrCorrelationPass [RPCRT4.@]
6397 * Performs correlation validity checking.
6400 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6405 void WINAPI
NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg
)
6407 FIXME("(%p): stub\n", pStubMsg
);
6410 /***********************************************************************
6411 * NdrCorrelationFree [RPCRT4.@]
6413 * Frees any resources used while unmarshalling parameters that need
6414 * correlation validity checking.
6417 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6422 void WINAPI
NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg
)
6424 FIXME("(%p): stub\n", pStubMsg
);