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
22 * - Non-conformant strings
24 * - Byte count pointers
25 * - transmit_as/represent as
26 * - Multi-dimensional arrays
27 * - Conversion functions (NdrConvert)
28 * - Checks for integer addition overflow in base type and user marshall functions
44 #include "wine/unicode.h"
45 #include "wine/rpcfc.h"
47 #include "wine/debug.h"
48 #include "wine/list.h"
50 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
53 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
54 (*((UINT32 *)(pchar)) = (uint32))
56 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
57 (*((UINT32 *)(pchar)))
59 /* these would work for i386 too, but less efficient */
60 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
61 (*(pchar) = LOBYTE(LOWORD(uint32)), \
62 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
63 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
64 *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
65 (uint32)) /* allow as r-value */
67 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
69 MAKEWORD(*(pchar), *((pchar)+1)), \
70 MAKEWORD(*((pchar)+2), *((pchar)+3))))
73 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
74 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
75 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
76 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
77 *(pchar) = HIBYTE(HIWORD(uint32)), \
78 (uint32)) /* allow as r-value */
80 #define BIG_ENDIAN_UINT32_READ(pchar) \
82 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
83 MAKEWORD(*((pchar)+1), *(pchar))))
85 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
86 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
87 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
88 # define NDR_LOCAL_UINT32_READ(pchar) \
89 BIG_ENDIAN_UINT32_READ(pchar)
91 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
92 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
93 # define NDR_LOCAL_UINT32_READ(pchar) \
94 LITTLE_ENDIAN_UINT32_READ(pchar)
97 /* _Align must be the desired alignment,
98 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
99 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
100 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
101 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
102 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
103 #define ALIGN_POINTER_CLEAR(_Ptr, _Align) \
105 memset((_Ptr), 0, ((_Align) - (ULONG_PTR)(_Ptr)) & ((_Align) - 1)); \
106 ALIGN_POINTER(_Ptr, _Align); \
109 #define STD_OVERFLOW_CHECK(_Msg) do { \
110 TRACE("buffer=%d/%d\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
111 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
112 ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
115 #define NDR_TABLE_SIZE 128
116 #define NDR_TABLE_MASK 127
118 static unsigned char *WINAPI
NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
119 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
120 static void WINAPI
NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
121 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
122 static ULONG WINAPI
NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
124 static unsigned char *WINAPI
NdrContextHandleMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
125 static void WINAPI
NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
126 static unsigned char *WINAPI
NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
128 const NDR_MARSHALL NdrMarshaller
[NDR_TABLE_SIZE
] = {
130 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
131 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
132 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
133 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
137 NdrPointerMarshall
, NdrPointerMarshall
,
138 NdrPointerMarshall
, NdrPointerMarshall
,
140 NdrSimpleStructMarshall
, NdrSimpleStructMarshall
,
141 NdrConformantStructMarshall
, NdrConformantStructMarshall
,
142 NdrConformantVaryingStructMarshall
,
143 NdrComplexStructMarshall
,
145 NdrConformantArrayMarshall
,
146 NdrConformantVaryingArrayMarshall
,
147 NdrFixedArrayMarshall
, NdrFixedArrayMarshall
,
148 NdrVaryingArrayMarshall
, NdrVaryingArrayMarshall
,
149 NdrComplexArrayMarshall
,
151 NdrConformantStringMarshall
, 0, 0,
152 NdrConformantStringMarshall
,
153 NdrNonConformantStringMarshall
, 0, 0, 0,
155 NdrEncapsulatedUnionMarshall
,
156 NdrNonEncapsulatedUnionMarshall
,
157 NdrByteCountPointerMarshall
,
158 NdrXmitOrRepAsMarshall
, NdrXmitOrRepAsMarshall
,
160 NdrInterfacePointerMarshall
,
162 NdrContextHandleMarshall
,
165 NdrUserMarshalMarshall
,
170 const NDR_UNMARSHALL NdrUnmarshaller
[NDR_TABLE_SIZE
] = {
172 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
173 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
174 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
175 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
177 NdrBaseTypeUnmarshall
,
179 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
180 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
182 NdrSimpleStructUnmarshall
, NdrSimpleStructUnmarshall
,
183 NdrConformantStructUnmarshall
, NdrConformantStructUnmarshall
,
184 NdrConformantVaryingStructUnmarshall
,
185 NdrComplexStructUnmarshall
,
187 NdrConformantArrayUnmarshall
,
188 NdrConformantVaryingArrayUnmarshall
,
189 NdrFixedArrayUnmarshall
, NdrFixedArrayUnmarshall
,
190 NdrVaryingArrayUnmarshall
, NdrVaryingArrayUnmarshall
,
191 NdrComplexArrayUnmarshall
,
193 NdrConformantStringUnmarshall
, 0, 0,
194 NdrConformantStringUnmarshall
,
195 NdrNonConformantStringUnmarshall
, 0, 0, 0,
197 NdrEncapsulatedUnionUnmarshall
,
198 NdrNonEncapsulatedUnionUnmarshall
,
199 NdrByteCountPointerUnmarshall
,
200 NdrXmitOrRepAsUnmarshall
, NdrXmitOrRepAsUnmarshall
,
202 NdrInterfacePointerUnmarshall
,
204 NdrContextHandleUnmarshall
,
207 NdrUserMarshalUnmarshall
,
212 const NDR_BUFFERSIZE NdrBufferSizer
[NDR_TABLE_SIZE
] = {
214 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
215 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
216 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
217 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
219 NdrBaseTypeBufferSize
,
221 NdrPointerBufferSize
, NdrPointerBufferSize
,
222 NdrPointerBufferSize
, NdrPointerBufferSize
,
224 NdrSimpleStructBufferSize
, NdrSimpleStructBufferSize
,
225 NdrConformantStructBufferSize
, NdrConformantStructBufferSize
,
226 NdrConformantVaryingStructBufferSize
,
227 NdrComplexStructBufferSize
,
229 NdrConformantArrayBufferSize
,
230 NdrConformantVaryingArrayBufferSize
,
231 NdrFixedArrayBufferSize
, NdrFixedArrayBufferSize
,
232 NdrVaryingArrayBufferSize
, NdrVaryingArrayBufferSize
,
233 NdrComplexArrayBufferSize
,
235 NdrConformantStringBufferSize
, 0, 0,
236 NdrConformantStringBufferSize
,
237 NdrNonConformantStringBufferSize
, 0, 0, 0,
239 NdrEncapsulatedUnionBufferSize
,
240 NdrNonEncapsulatedUnionBufferSize
,
241 NdrByteCountPointerBufferSize
,
242 NdrXmitOrRepAsBufferSize
, NdrXmitOrRepAsBufferSize
,
244 NdrInterfacePointerBufferSize
,
246 NdrContextHandleBufferSize
,
249 NdrUserMarshalBufferSize
,
254 const NDR_MEMORYSIZE NdrMemorySizer
[NDR_TABLE_SIZE
] = {
256 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
257 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
258 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
259 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
261 NdrBaseTypeMemorySize
,
263 NdrPointerMemorySize
, NdrPointerMemorySize
,
264 NdrPointerMemorySize
, NdrPointerMemorySize
,
266 NdrSimpleStructMemorySize
, NdrSimpleStructMemorySize
,
267 NdrConformantStructMemorySize
, NdrConformantStructMemorySize
,
268 NdrConformantVaryingStructMemorySize
,
269 NdrComplexStructMemorySize
,
271 NdrConformantArrayMemorySize
,
272 NdrConformantVaryingArrayMemorySize
,
273 NdrFixedArrayMemorySize
, NdrFixedArrayMemorySize
,
274 NdrVaryingArrayMemorySize
, NdrVaryingArrayMemorySize
,
275 NdrComplexArrayMemorySize
,
277 NdrConformantStringMemorySize
, 0, 0,
278 NdrConformantStringMemorySize
,
279 NdrNonConformantStringMemorySize
, 0, 0, 0,
281 NdrEncapsulatedUnionMemorySize
,
282 NdrNonEncapsulatedUnionMemorySize
,
283 NdrByteCountPointerMemorySize
,
284 NdrXmitOrRepAsMemorySize
, NdrXmitOrRepAsMemorySize
,
286 NdrInterfacePointerMemorySize
,
291 NdrUserMarshalMemorySize
,
296 const NDR_FREE NdrFreer
[NDR_TABLE_SIZE
] = {
298 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
299 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
300 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
301 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
305 NdrPointerFree
, NdrPointerFree
,
306 NdrPointerFree
, NdrPointerFree
,
308 NdrSimpleStructFree
, NdrSimpleStructFree
,
309 NdrConformantStructFree
, NdrConformantStructFree
,
310 NdrConformantVaryingStructFree
,
311 NdrComplexStructFree
,
313 NdrConformantArrayFree
,
314 NdrConformantVaryingArrayFree
,
315 NdrFixedArrayFree
, NdrFixedArrayFree
,
316 NdrVaryingArrayFree
, NdrVaryingArrayFree
,
322 NdrEncapsulatedUnionFree
,
323 NdrNonEncapsulatedUnionFree
,
325 NdrXmitOrRepAsFree
, NdrXmitOrRepAsFree
,
327 NdrInterfacePointerFree
,
338 typedef struct _NDR_MEMORY_LIST
343 struct _NDR_MEMORY_LIST
*next
;
346 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
348 /***********************************************************************
349 * NdrAllocate [RPCRT4.@]
351 * Allocates a block of memory using pStubMsg->pfnAllocate.
354 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
355 * len [I] Size of memory block to allocate.
358 * The memory block of size len that was allocated.
361 * The memory block is always 8-byte aligned.
362 * If the function is unable to allocate memory an ERROR_OUTOFMEMORY
363 * exception is raised.
365 void * WINAPI
NdrAllocate(MIDL_STUB_MESSAGE
*pStubMsg
, size_t len
)
370 NDR_MEMORY_LIST
*mem_list
;
372 aligned_len
= ALIGNED_LENGTH(len
, 8);
373 adjusted_len
= aligned_len
+ sizeof(NDR_MEMORY_LIST
);
374 /* check for overflow */
375 if (adjusted_len
< len
)
377 ERR("overflow of adjusted_len %d, len %d\n", adjusted_len
, len
);
378 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
381 p
= pStubMsg
->pfnAllocate(adjusted_len
);
382 if (!p
) RpcRaiseException(ERROR_OUTOFMEMORY
);
384 mem_list
= (NDR_MEMORY_LIST
*)((char *)p
+ aligned_len
);
385 mem_list
->magic
= MEML_MAGIC
;
386 mem_list
->size
= aligned_len
;
387 mem_list
->reserved
= 0;
388 mem_list
->next
= pStubMsg
->pMemoryList
;
389 pStubMsg
->pMemoryList
= mem_list
;
395 static void WINAPI
NdrFree(MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *Pointer
)
397 TRACE("(%p, %p)\n", pStubMsg
, Pointer
);
399 pStubMsg
->pfnFree(Pointer
);
402 static inline BOOL
IsConformanceOrVariancePresent(PFORMAT_STRING pFormat
)
404 return (*(const ULONG
*)pFormat
!= -1);
407 static PFORMAT_STRING
ReadConformance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
)
409 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
410 if (pStubMsg
->Buffer
+ 4 > pStubMsg
->BufferEnd
)
411 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
412 pStubMsg
->MaxCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
413 pStubMsg
->Buffer
+= 4;
414 TRACE("unmarshalled conformance is %ld\n", pStubMsg
->MaxCount
);
415 if (pStubMsg
->fHasNewCorrDesc
)
421 static inline PFORMAT_STRING
ReadVariance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
, ULONG MaxValue
)
423 if (pFormat
&& !IsConformanceOrVariancePresent(pFormat
))
425 pStubMsg
->Offset
= 0;
426 pStubMsg
->ActualCount
= pStubMsg
->MaxCount
;
430 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
431 if (pStubMsg
->Buffer
+ 8 > pStubMsg
->BufferEnd
)
432 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
433 pStubMsg
->Offset
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
434 pStubMsg
->Buffer
+= 4;
435 TRACE("offset is %d\n", pStubMsg
->Offset
);
436 pStubMsg
->ActualCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
437 pStubMsg
->Buffer
+= 4;
438 TRACE("variance is %d\n", pStubMsg
->ActualCount
);
440 if ((pStubMsg
->ActualCount
> MaxValue
) ||
441 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> MaxValue
))
443 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
444 pStubMsg
->ActualCount
, pStubMsg
->Offset
, MaxValue
);
445 RpcRaiseException(RPC_S_INVALID_BOUND
);
450 if (pStubMsg
->fHasNewCorrDesc
)
456 /* writes the conformance value to the buffer */
457 static inline void WriteConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
459 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
460 if (pStubMsg
->Buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
461 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
462 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->MaxCount
);
463 pStubMsg
->Buffer
+= 4;
466 /* writes the variance values to the buffer */
467 static inline void WriteVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
469 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
470 if (pStubMsg
->Buffer
+ 8 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
471 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
472 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->Offset
);
473 pStubMsg
->Buffer
+= 4;
474 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->ActualCount
);
475 pStubMsg
->Buffer
+= 4;
478 /* requests buffer space for the conformance value */
479 static inline void SizeConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
481 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
482 if (pStubMsg
->BufferLength
+ 4 < pStubMsg
->BufferLength
)
483 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
484 pStubMsg
->BufferLength
+= 4;
487 /* requests buffer space for the variance values */
488 static inline void SizeVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
490 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
491 if (pStubMsg
->BufferLength
+ 8 < pStubMsg
->BufferLength
)
492 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
493 pStubMsg
->BufferLength
+= 8;
496 PFORMAT_STRING
ComputeConformanceOrVariance(
497 MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *pMemory
,
498 PFORMAT_STRING pFormat
, ULONG_PTR def
, ULONG_PTR
*pCount
)
500 BYTE dtype
= pFormat
[0] & 0xf;
501 short ofs
= *(const short *)&pFormat
[2];
505 if (!IsConformanceOrVariancePresent(pFormat
)) {
506 /* null descriptor */
511 switch (pFormat
[0] & 0xf0) {
512 case RPC_FC_NORMAL_CONFORMANCE
:
513 TRACE("normal conformance, ofs=%d\n", ofs
);
516 case RPC_FC_POINTER_CONFORMANCE
:
517 TRACE("pointer conformance, ofs=%d\n", ofs
);
518 ptr
= pStubMsg
->Memory
;
520 case RPC_FC_TOP_LEVEL_CONFORMANCE
:
521 TRACE("toplevel conformance, ofs=%d\n", ofs
);
522 if (pStubMsg
->StackTop
) {
523 ptr
= pStubMsg
->StackTop
;
526 /* -Os mode, *pCount is already set */
530 case RPC_FC_CONSTANT_CONFORMANCE
:
531 data
= ofs
| ((DWORD
)pFormat
[1] << 16);
532 TRACE("constant conformance, val=%d\n", data
);
535 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE
:
536 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs
);
537 if (pStubMsg
->StackTop
) {
538 ptr
= pStubMsg
->StackTop
;
546 FIXME("unknown conformance type %x\n", pFormat
[0] & 0xf0);
549 switch (pFormat
[1]) {
550 case RPC_FC_DEREFERENCE
:
551 ptr
= *(LPVOID
*)((char *)ptr
+ ofs
);
553 case RPC_FC_CALLBACK
:
555 unsigned char *old_stack_top
= pStubMsg
->StackTop
;
556 pStubMsg
->StackTop
= ptr
;
558 /* ofs is index into StubDesc->apfnExprEval */
559 TRACE("callback conformance into apfnExprEval[%d]\n", ofs
);
560 pStubMsg
->StubDesc
->apfnExprEval
[ofs
](pStubMsg
);
562 pStubMsg
->StackTop
= old_stack_top
;
564 /* the callback function always stores the computed value in MaxCount */
565 *pCount
= pStubMsg
->MaxCount
;
569 ptr
= (char *)ptr
+ ofs
;
582 data
= *(USHORT
*)ptr
;
593 FIXME("unknown conformance data type %x\n", dtype
);
596 TRACE("dereferenced data type %x at %p, got %d\n", dtype
, ptr
, data
);
599 switch (pFormat
[1]) {
600 case RPC_FC_DEREFERENCE
: /* already handled */
617 FIXME("unknown conformance op %d\n", pFormat
[1]);
622 TRACE("resulting conformance is %ld\n", *pCount
);
623 if (pStubMsg
->fHasNewCorrDesc
)
629 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
630 * the result overflows 32-bits */
631 static inline ULONG
safe_multiply(ULONG a
, ULONG b
)
633 ULONGLONG ret
= (ULONGLONG
)a
* b
;
634 if (ret
> 0xffffffff)
636 RpcRaiseException(RPC_S_INVALID_BOUND
);
642 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
644 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
645 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
646 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
647 pStubMsg
->Buffer
+= size
;
650 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
652 if (pStubMsg
->BufferLength
+ size
< pStubMsg
->BufferLength
) /* integer overflow of pStubMsg->BufferSize */
654 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
655 pStubMsg
->BufferLength
, size
);
656 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
658 pStubMsg
->BufferLength
+= size
;
661 /* copies data from the buffer, checking that there is enough data in the buffer
663 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, void *p
, ULONG size
)
665 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
666 (pStubMsg
->Buffer
+ size
> pStubMsg
->BufferEnd
))
668 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
669 pStubMsg
->Buffer
, pStubMsg
->BufferEnd
, size
);
670 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
672 if (p
== pStubMsg
->Buffer
)
673 ERR("pointer is the same as the buffer\n");
674 memcpy(p
, pStubMsg
->Buffer
, size
);
675 pStubMsg
->Buffer
+= size
;
678 /* copies data to the buffer, checking that there is enough space to do so */
679 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, const void *p
, ULONG size
)
681 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
682 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
684 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
685 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
,
687 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
689 memcpy(pStubMsg
->Buffer
, p
, size
);
690 pStubMsg
->Buffer
+= size
;
694 * NdrConformantString:
696 * What MS calls a ConformantString is, in DCE terminology,
697 * a Varying-Conformant String.
699 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
700 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
701 * into unmarshalled string)
702 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
704 * data: CHARTYPE[maxlen]
706 * ], where CHARTYPE is the appropriate character type (specified externally)
710 /***********************************************************************
711 * NdrConformantStringMarshall [RPCRT4.@]
713 unsigned char *WINAPI
NdrConformantStringMarshall(MIDL_STUB_MESSAGE
*pStubMsg
,
714 unsigned char *pszMessage
, PFORMAT_STRING pFormat
)
718 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg
, pszMessage
, pFormat
);
720 if (*pFormat
== RPC_FC_C_CSTRING
) {
721 TRACE("string=%s\n", debugstr_a((char*)pszMessage
));
722 pStubMsg
->ActualCount
= strlen((char*)pszMessage
)+1;
725 else if (*pFormat
== RPC_FC_C_WSTRING
) {
726 TRACE("string=%s\n", debugstr_w((LPWSTR
)pszMessage
));
727 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pszMessage
)+1;
731 ERR("Unhandled string type: %#x\n", *pFormat
);
732 /* FIXME: raise an exception. */
736 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
737 pFormat
= ComputeConformance(pStubMsg
, pszMessage
, pFormat
+ 2, 0);
739 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
740 pStubMsg
->Offset
= 0;
741 WriteConformance(pStubMsg
);
742 WriteVariance(pStubMsg
);
744 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
745 safe_copy_to_buffer(pStubMsg
, pszMessage
, size
); /* the string itself */
748 return NULL
; /* is this always right? */
751 /***********************************************************************
752 * NdrConformantStringBufferSize [RPCRT4.@]
754 void WINAPI
NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
755 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
759 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
761 SizeConformance(pStubMsg
);
762 SizeVariance(pStubMsg
);
764 if (*pFormat
== RPC_FC_C_CSTRING
) {
765 TRACE("string=%s\n", debugstr_a((char*)pMemory
));
766 pStubMsg
->ActualCount
= strlen((char*)pMemory
)+1;
769 else if (*pFormat
== RPC_FC_C_WSTRING
) {
770 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
));
771 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
)+1;
775 ERR("Unhandled string type: %#x\n", *pFormat
);
776 /* FIXME: raise an exception */
780 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
781 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
783 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
785 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
788 /************************************************************************
789 * NdrConformantStringMemorySize [RPCRT4.@]
791 ULONG WINAPI
NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
792 PFORMAT_STRING pFormat
)
796 FIXME("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
798 assert(pStubMsg
&& pFormat
);
800 if (*pFormat
== RPC_FC_C_CSTRING
) {
801 rslt
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
); /* maxlen */
803 else if (*pFormat
== RPC_FC_C_WSTRING
) {
804 rslt
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
)*2; /* maxlen */
807 ERR("Unhandled string type: %#x\n", *pFormat
);
808 /* FIXME: raise an exception */
811 if (pFormat
[1] != RPC_FC_PAD
) {
812 FIXME("sized string format=%d\n", pFormat
[1]);
815 TRACE(" --> %u\n", rslt
);
819 /************************************************************************
820 * NdrConformantStringUnmarshall [RPCRT4.@]
822 unsigned char *WINAPI
NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
823 unsigned char** ppMemory
, PFORMAT_STRING pFormat
, unsigned char fMustAlloc
)
825 ULONG bufsize
, memsize
, esize
, i
;
827 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
828 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
830 assert(pFormat
&& ppMemory
&& pStubMsg
);
832 ReadConformance(pStubMsg
, NULL
);
833 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
835 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
837 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
838 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
839 RpcRaiseException(RPC_S_INVALID_BOUND
);
842 if (pStubMsg
->Offset
)
844 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
845 RpcRaiseException(RPC_S_INVALID_BOUND
);
849 if (*pFormat
== RPC_FC_C_CSTRING
) esize
= 1;
850 else if (*pFormat
== RPC_FC_C_WSTRING
) esize
= 2;
852 ERR("Unhandled string type: %#x\n", *pFormat
);
853 /* FIXME: raise an exception */
857 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
858 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
860 /* strings must always have null terminating bytes */
863 ERR("invalid string length of %d\n", pStubMsg
->ActualCount
);
864 RpcRaiseException(RPC_S_INVALID_BOUND
);
868 /* verify the buffer is safe to access */
869 if ((pStubMsg
->Buffer
+ bufsize
< pStubMsg
->Buffer
) ||
870 (pStubMsg
->Buffer
+ bufsize
> pStubMsg
->BufferEnd
))
872 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize
,
873 pStubMsg
->BufferEnd
, pStubMsg
->Buffer
);
874 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
878 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
879 if (pStubMsg
->Buffer
[i
] != 0)
881 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
882 i
, pStubMsg
->Buffer
[i
]);
883 RpcRaiseException(RPC_S_INVALID_BOUND
);
888 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
891 if (!pStubMsg
->IsClient
&& !*ppMemory
&& (pStubMsg
->MaxCount
== pStubMsg
->ActualCount
))
892 /* if the data in the RPC buffer is big enough, we just point straight
894 *ppMemory
= pStubMsg
->Buffer
;
896 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
899 if (*ppMemory
== pStubMsg
->Buffer
)
900 safe_buffer_increment(pStubMsg
, bufsize
);
902 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
904 if (*pFormat
== RPC_FC_C_CSTRING
) {
905 TRACE("string=%s\n", debugstr_a((char*)*ppMemory
));
907 else if (*pFormat
== RPC_FC_C_WSTRING
) {
908 TRACE("string=%s\n", debugstr_w((LPWSTR
)*ppMemory
));
911 return NULL
; /* FIXME: is this always right? */
914 /***********************************************************************
915 * NdrNonConformantStringMarshall [RPCRT4.@]
917 unsigned char * WINAPI
NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
918 unsigned char *pMemory
,
919 PFORMAT_STRING pFormat
)
925 /***********************************************************************
926 * NdrNonConformantStringUnmarshall [RPCRT4.@]
928 unsigned char * WINAPI
NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
929 unsigned char **ppMemory
,
930 PFORMAT_STRING pFormat
,
931 unsigned char fMustAlloc
)
937 /***********************************************************************
938 * NdrNonConformantStringBufferSize [RPCRT4.@]
940 void WINAPI
NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
941 unsigned char *pMemory
,
942 PFORMAT_STRING pFormat
)
947 /***********************************************************************
948 * NdrNonConformantStringMemorySize [RPCRT4.@]
950 ULONG WINAPI
NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
951 PFORMAT_STRING pFormat
)
957 static inline void dump_pointer_attr(unsigned char attr
)
959 if (attr
& RPC_FC_P_ALLOCALLNODES
)
960 TRACE(" RPC_FC_P_ALLOCALLNODES");
961 if (attr
& RPC_FC_P_DONTFREE
)
962 TRACE(" RPC_FC_P_DONTFREE");
963 if (attr
& RPC_FC_P_ONSTACK
)
964 TRACE(" RPC_FC_P_ONSTACK");
965 if (attr
& RPC_FC_P_SIMPLEPOINTER
)
966 TRACE(" RPC_FC_P_SIMPLEPOINTER");
967 if (attr
& RPC_FC_P_DEREF
)
968 TRACE(" RPC_FC_P_DEREF");
972 /***********************************************************************
973 * PointerMarshall [internal]
975 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
976 unsigned char *Buffer
,
977 unsigned char *Pointer
,
978 PFORMAT_STRING pFormat
)
980 unsigned type
= pFormat
[0], attr
= pFormat
[1];
984 int pointer_needs_marshaling
;
986 TRACE("(%p,%p,%p,%p)\n", pStubMsg
, Buffer
, Pointer
, pFormat
);
987 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
989 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
990 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
993 case RPC_FC_RP
: /* ref pointer (always non-null) */
996 ERR("NULL ref pointer is not allowed\n");
997 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
999 pointer_needs_marshaling
= 1;
1001 case RPC_FC_UP
: /* unique pointer */
1002 case RPC_FC_OP
: /* object pointer - same as unique here */
1004 pointer_needs_marshaling
= 1;
1006 pointer_needs_marshaling
= 0;
1007 pointer_id
= (ULONG
)Pointer
;
1008 TRACE("writing 0x%08x to buffer\n", pointer_id
);
1009 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
1012 pointer_needs_marshaling
= !NdrFullPointerQueryPointer(
1013 pStubMsg
->FullPtrXlatTables
, Pointer
, 1, &pointer_id
);
1014 TRACE("writing 0x%08x to buffer\n", pointer_id
);
1015 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
1018 FIXME("unhandled ptr type=%02x\n", type
);
1019 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1023 TRACE("calling marshaller for type 0x%x\n", (int)*desc
);
1025 if (pointer_needs_marshaling
) {
1026 if (attr
& RPC_FC_P_DEREF
) {
1027 Pointer
= *(unsigned char**)Pointer
;
1028 TRACE("deref => %p\n", Pointer
);
1030 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
1031 if (m
) m(pStubMsg
, Pointer
, desc
);
1032 else FIXME("no marshaller for data type=%02x\n", *desc
);
1035 STD_OVERFLOW_CHECK(pStubMsg
);
1038 /***********************************************************************
1039 * PointerUnmarshall [internal]
1041 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1042 unsigned char *Buffer
,
1043 unsigned char **pPointer
,
1044 unsigned char *pSrcPointer
,
1045 PFORMAT_STRING pFormat
,
1046 unsigned char fMustAlloc
)
1048 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1049 PFORMAT_STRING desc
;
1051 DWORD pointer_id
= 0;
1052 int pointer_needs_unmarshaling
;
1054 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg
, Buffer
, pPointer
, pSrcPointer
, pFormat
, fMustAlloc
);
1055 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1057 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1058 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1061 case RPC_FC_RP
: /* ref pointer (always non-null) */
1062 pointer_needs_unmarshaling
= 1;
1064 case RPC_FC_UP
: /* unique pointer */
1065 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1066 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1068 pointer_needs_unmarshaling
= 1;
1071 pointer_needs_unmarshaling
= 0;
1074 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
1075 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1076 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1077 if (!fMustAlloc
&& pSrcPointer
)
1079 FIXME("free object pointer %p\n", pSrcPointer
);
1083 pointer_needs_unmarshaling
= 1;
1085 pointer_needs_unmarshaling
= 0;
1088 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1089 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1090 pointer_needs_unmarshaling
= !NdrFullPointerQueryRefId(
1091 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, (void **)pPointer
);
1094 FIXME("unhandled ptr type=%02x\n", type
);
1095 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1099 if (pointer_needs_unmarshaling
) {
1100 unsigned char *base_ptr_val
= *pPointer
;
1101 unsigned char **current_ptr
= pPointer
;
1102 if (pStubMsg
->IsClient
) {
1104 /* if we aren't forcing allocation of memory then try to use the existing
1105 * (source) pointer to unmarshall the data into so that [in,out]
1106 * parameters behave correctly. it doesn't matter if the parameter is
1107 * [out] only since in that case the pointer will be NULL. we force
1108 * allocation when the source pointer is NULL here instead of in the type
1109 * unmarshalling routine for the benefit of the deref code below */
1112 TRACE("setting *pPointer to %p\n", pSrcPointer
);
1113 *pPointer
= base_ptr_val
= pSrcPointer
;
1119 /* the memory in a stub is never initialised, so we have to work out here
1120 * whether we have to initialise it so we can use the optimisation of
1121 * setting the pointer to the buffer, if possible, or set fMustAlloc to
1123 if (attr
& RPC_FC_P_DEREF
) {
1126 base_ptr_val
= NULL
;
1127 *current_ptr
= NULL
;
1131 if (attr
& RPC_FC_P_ALLOCALLNODES
)
1132 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
1134 if (attr
& RPC_FC_P_DEREF
) {
1136 base_ptr_val
= NdrAllocate(pStubMsg
, sizeof(void *));
1137 *pPointer
= base_ptr_val
;
1138 current_ptr
= (unsigned char **)base_ptr_val
;
1140 current_ptr
= *(unsigned char***)current_ptr
;
1141 TRACE("deref => %p\n", current_ptr
);
1142 if (!fMustAlloc
&& !*current_ptr
) fMustAlloc
= TRUE
;
1144 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
1145 if (m
) m(pStubMsg
, current_ptr
, desc
, fMustAlloc
);
1146 else FIXME("no unmarshaller for data type=%02x\n", *desc
);
1148 if (type
== RPC_FC_FP
)
1149 NdrFullPointerInsertRefId(pStubMsg
->FullPtrXlatTables
, pointer_id
,
1153 TRACE("pointer=%p\n", *pPointer
);
1156 /***********************************************************************
1157 * PointerBufferSize [internal]
1159 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1160 unsigned char *Pointer
,
1161 PFORMAT_STRING pFormat
)
1163 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1164 PFORMAT_STRING desc
;
1166 int pointer_needs_sizing
;
1169 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1170 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1172 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1173 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1176 case RPC_FC_RP
: /* ref pointer (always non-null) */
1179 ERR("NULL ref pointer is not allowed\n");
1180 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
1185 /* NULL pointer has no further representation */
1190 pointer_needs_sizing
= !NdrFullPointerQueryPointer(
1191 pStubMsg
->FullPtrXlatTables
, Pointer
, 0, &pointer_id
);
1192 if (!pointer_needs_sizing
)
1196 FIXME("unhandled ptr type=%02x\n", type
);
1197 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1201 if (attr
& RPC_FC_P_DEREF
) {
1202 Pointer
= *(unsigned char**)Pointer
;
1203 TRACE("deref => %p\n", Pointer
);
1206 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
1207 if (m
) m(pStubMsg
, Pointer
, desc
);
1208 else FIXME("no buffersizer for data type=%02x\n", *desc
);
1211 /***********************************************************************
1212 * PointerMemorySize [internal]
1214 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1215 unsigned char *Buffer
,
1216 PFORMAT_STRING pFormat
)
1218 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1219 PFORMAT_STRING desc
;
1221 DWORD pointer_id
= 0;
1222 int pointer_needs_sizing
;
1224 TRACE("(%p,%p,%p)\n", pStubMsg
, Buffer
, pFormat
);
1225 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1227 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1228 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1231 case RPC_FC_RP
: /* ref pointer (always non-null) */
1232 pointer_needs_sizing
= 1;
1234 case RPC_FC_UP
: /* unique pointer */
1235 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
1236 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1237 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1239 pointer_needs_sizing
= 1;
1241 pointer_needs_sizing
= 0;
1246 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1247 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1248 pointer_needs_sizing
= !NdrFullPointerQueryRefId(
1249 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, &pointer
);
1253 FIXME("unhandled ptr type=%02x\n", type
);
1254 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1258 if (attr
& RPC_FC_P_DEREF
) {
1262 if (pointer_needs_sizing
) {
1263 m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
1264 if (m
) m(pStubMsg
, desc
);
1265 else FIXME("no memorysizer for data type=%02x\n", *desc
);
1268 return pStubMsg
->MemorySize
;
1271 /***********************************************************************
1272 * PointerFree [internal]
1274 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1275 unsigned char *Pointer
,
1276 PFORMAT_STRING pFormat
)
1278 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1279 PFORMAT_STRING desc
;
1281 unsigned char *current_pointer
= Pointer
;
1283 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1284 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1285 if (attr
& RPC_FC_P_DONTFREE
) return;
1287 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1288 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1290 if (!Pointer
) return;
1292 if (type
== RPC_FC_FP
) {
1293 int pointer_needs_freeing
= NdrFullPointerFree(
1294 pStubMsg
->FullPtrXlatTables
, Pointer
);
1295 if (!pointer_needs_freeing
)
1299 if (attr
& RPC_FC_P_DEREF
) {
1300 current_pointer
= *(unsigned char**)Pointer
;
1301 TRACE("deref => %p\n", current_pointer
);
1304 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
1305 if (m
) m(pStubMsg
, current_pointer
, desc
);
1307 /* this check stops us from trying to free buffer memory. we don't have to
1308 * worry about clients, since they won't call this function.
1309 * we don't have to check for the buffer being reallocated because
1310 * BufferStart and BufferEnd won't be reset when allocating memory for
1311 * sending the response. we don't have to check for the new buffer here as
1312 * it won't be used a type memory, only for buffer memory */
1313 if (Pointer
>= (unsigned char *)pStubMsg
->BufferStart
&&
1314 Pointer
< (unsigned char *)pStubMsg
->BufferEnd
)
1317 if (attr
& RPC_FC_P_ONSTACK
) {
1318 TRACE("not freeing stack ptr %p\n", Pointer
);
1321 TRACE("freeing %p\n", Pointer
);
1322 NdrFree(pStubMsg
, Pointer
);
1325 TRACE("not freeing %p\n", Pointer
);
1328 /***********************************************************************
1329 * EmbeddedPointerMarshall
1331 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1332 unsigned char *pMemory
,
1333 PFORMAT_STRING pFormat
)
1335 unsigned char *Mark
= pStubMsg
->BufferMark
;
1336 unsigned rep
, count
, stride
;
1338 unsigned char *saved_buffer
= NULL
;
1340 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1342 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1345 if (pStubMsg
->PointerBufferMark
)
1347 saved_buffer
= pStubMsg
->Buffer
;
1348 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1349 pStubMsg
->PointerBufferMark
= NULL
;
1352 while (pFormat
[0] != RPC_FC_END
) {
1353 switch (pFormat
[0]) {
1355 FIXME("unknown repeat type %d\n", pFormat
[0]);
1356 case RPC_FC_NO_REPEAT
:
1362 case RPC_FC_FIXED_REPEAT
:
1363 rep
= *(const WORD
*)&pFormat
[2];
1364 stride
= *(const WORD
*)&pFormat
[4];
1365 count
= *(const WORD
*)&pFormat
[8];
1368 case RPC_FC_VARIABLE_REPEAT
:
1369 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1370 stride
= *(const WORD
*)&pFormat
[2];
1371 count
= *(const WORD
*)&pFormat
[6];
1375 for (i
= 0; i
< rep
; i
++) {
1376 PFORMAT_STRING info
= pFormat
;
1377 unsigned char *membase
= pMemory
+ (i
* stride
);
1378 unsigned char *bufbase
= Mark
+ (i
* stride
);
1381 for (u
=0; u
<count
; u
++,info
+=8) {
1382 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1383 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1384 unsigned char *saved_memory
= pStubMsg
->Memory
;
1386 pStubMsg
->Memory
= pMemory
;
1387 PointerMarshall(pStubMsg
, bufptr
, *(unsigned char**)memptr
, info
+4);
1388 pStubMsg
->Memory
= saved_memory
;
1391 pFormat
+= 8 * count
;
1396 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1397 pStubMsg
->Buffer
= saved_buffer
;
1400 STD_OVERFLOW_CHECK(pStubMsg
);
1405 /***********************************************************************
1406 * EmbeddedPointerUnmarshall
1408 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1409 unsigned char *pDstMemoryPtrs
,
1410 unsigned char *pSrcMemoryPtrs
,
1411 PFORMAT_STRING pFormat
,
1412 unsigned char fMustAlloc
)
1414 unsigned char *Mark
= pStubMsg
->BufferMark
;
1415 unsigned rep
, count
, stride
;
1417 unsigned char *saved_buffer
= NULL
;
1419 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg
, pDstMemoryPtrs
, pSrcMemoryPtrs
, pFormat
, fMustAlloc
);
1421 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1424 if (pStubMsg
->PointerBufferMark
)
1426 saved_buffer
= pStubMsg
->Buffer
;
1427 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1428 pStubMsg
->PointerBufferMark
= NULL
;
1431 while (pFormat
[0] != RPC_FC_END
) {
1432 TRACE("pFormat[0] = 0x%x\n", pFormat
[0]);
1433 switch (pFormat
[0]) {
1435 FIXME("unknown repeat type %d\n", pFormat
[0]);
1436 case RPC_FC_NO_REPEAT
:
1442 case RPC_FC_FIXED_REPEAT
:
1443 rep
= *(const WORD
*)&pFormat
[2];
1444 stride
= *(const WORD
*)&pFormat
[4];
1445 count
= *(const WORD
*)&pFormat
[8];
1448 case RPC_FC_VARIABLE_REPEAT
:
1449 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1450 stride
= *(const WORD
*)&pFormat
[2];
1451 count
= *(const WORD
*)&pFormat
[6];
1455 for (i
= 0; i
< rep
; i
++) {
1456 PFORMAT_STRING info
= pFormat
;
1457 unsigned char *memdstbase
= pDstMemoryPtrs
+ (i
* stride
);
1458 unsigned char *memsrcbase
= pSrcMemoryPtrs
+ (i
* stride
);
1459 unsigned char *bufbase
= Mark
+ (i
* stride
);
1462 for (u
=0; u
<count
; u
++,info
+=8) {
1463 unsigned char **memdstptr
= (unsigned char **)(memdstbase
+ *(const SHORT
*)&info
[0]);
1464 unsigned char **memsrcptr
= (unsigned char **)(memsrcbase
+ *(const SHORT
*)&info
[0]);
1465 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1466 PointerUnmarshall(pStubMsg
, bufptr
, memdstptr
, *memsrcptr
, info
+4, fMustAlloc
);
1469 pFormat
+= 8 * count
;
1474 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1475 pStubMsg
->Buffer
= saved_buffer
;
1481 /***********************************************************************
1482 * EmbeddedPointerBufferSize
1484 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1485 unsigned char *pMemory
,
1486 PFORMAT_STRING pFormat
)
1488 unsigned rep
, count
, stride
;
1490 ULONG saved_buffer_length
= 0;
1492 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1494 if (pStubMsg
->IgnoreEmbeddedPointers
) return;
1496 if (*pFormat
!= RPC_FC_PP
) return;
1499 if (pStubMsg
->PointerLength
)
1501 saved_buffer_length
= pStubMsg
->BufferLength
;
1502 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
1503 pStubMsg
->PointerLength
= 0;
1506 while (pFormat
[0] != RPC_FC_END
) {
1507 switch (pFormat
[0]) {
1509 FIXME("unknown repeat type %d\n", pFormat
[0]);
1510 case RPC_FC_NO_REPEAT
:
1516 case RPC_FC_FIXED_REPEAT
:
1517 rep
= *(const WORD
*)&pFormat
[2];
1518 stride
= *(const WORD
*)&pFormat
[4];
1519 count
= *(const WORD
*)&pFormat
[8];
1522 case RPC_FC_VARIABLE_REPEAT
:
1523 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1524 stride
= *(const WORD
*)&pFormat
[2];
1525 count
= *(const WORD
*)&pFormat
[6];
1529 for (i
= 0; i
< rep
; i
++) {
1530 PFORMAT_STRING info
= pFormat
;
1531 unsigned char *membase
= pMemory
+ (i
* stride
);
1534 for (u
=0; u
<count
; u
++,info
+=8) {
1535 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1536 unsigned char *saved_memory
= pStubMsg
->Memory
;
1538 pStubMsg
->Memory
= pMemory
;
1539 PointerBufferSize(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1540 pStubMsg
->Memory
= saved_memory
;
1543 pFormat
+= 8 * count
;
1546 if (saved_buffer_length
)
1548 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
1549 pStubMsg
->BufferLength
= saved_buffer_length
;
1553 /***********************************************************************
1554 * EmbeddedPointerMemorySize [internal]
1556 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1557 PFORMAT_STRING pFormat
)
1559 unsigned char *Mark
= pStubMsg
->BufferMark
;
1560 unsigned rep
, count
, stride
;
1562 unsigned char *saved_buffer
= NULL
;
1564 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1566 if (pStubMsg
->IgnoreEmbeddedPointers
) return 0;
1568 if (pStubMsg
->PointerBufferMark
)
1570 saved_buffer
= pStubMsg
->Buffer
;
1571 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1572 pStubMsg
->PointerBufferMark
= NULL
;
1575 if (*pFormat
!= RPC_FC_PP
) return 0;
1578 while (pFormat
[0] != RPC_FC_END
) {
1579 switch (pFormat
[0]) {
1581 FIXME("unknown repeat type %d\n", pFormat
[0]);
1582 case RPC_FC_NO_REPEAT
:
1588 case RPC_FC_FIXED_REPEAT
:
1589 rep
= *(const WORD
*)&pFormat
[2];
1590 stride
= *(const WORD
*)&pFormat
[4];
1591 count
= *(const WORD
*)&pFormat
[8];
1594 case RPC_FC_VARIABLE_REPEAT
:
1595 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1596 stride
= *(const WORD
*)&pFormat
[2];
1597 count
= *(const WORD
*)&pFormat
[6];
1601 for (i
= 0; i
< rep
; i
++) {
1602 PFORMAT_STRING info
= pFormat
;
1603 unsigned char *bufbase
= Mark
+ (i
* stride
);
1605 for (u
=0; u
<count
; u
++,info
+=8) {
1606 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1607 PointerMemorySize(pStubMsg
, bufptr
, info
+4);
1610 pFormat
+= 8 * count
;
1615 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1616 pStubMsg
->Buffer
= saved_buffer
;
1622 /***********************************************************************
1623 * EmbeddedPointerFree [internal]
1625 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1626 unsigned char *pMemory
,
1627 PFORMAT_STRING pFormat
)
1629 unsigned rep
, count
, stride
;
1632 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1633 if (*pFormat
!= RPC_FC_PP
) return;
1636 while (pFormat
[0] != RPC_FC_END
) {
1637 switch (pFormat
[0]) {
1639 FIXME("unknown repeat type %d\n", pFormat
[0]);
1640 case RPC_FC_NO_REPEAT
:
1646 case RPC_FC_FIXED_REPEAT
:
1647 rep
= *(const WORD
*)&pFormat
[2];
1648 stride
= *(const WORD
*)&pFormat
[4];
1649 count
= *(const WORD
*)&pFormat
[8];
1652 case RPC_FC_VARIABLE_REPEAT
:
1653 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1654 stride
= *(const WORD
*)&pFormat
[2];
1655 count
= *(const WORD
*)&pFormat
[6];
1659 for (i
= 0; i
< rep
; i
++) {
1660 PFORMAT_STRING info
= pFormat
;
1661 unsigned char *membase
= pMemory
+ (i
* stride
);
1664 for (u
=0; u
<count
; u
++,info
+=8) {
1665 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1666 unsigned char *saved_memory
= pStubMsg
->Memory
;
1668 pStubMsg
->Memory
= pMemory
;
1669 PointerFree(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1670 pStubMsg
->Memory
= saved_memory
;
1673 pFormat
+= 8 * count
;
1677 /***********************************************************************
1678 * NdrPointerMarshall [RPCRT4.@]
1680 unsigned char * WINAPI
NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1681 unsigned char *pMemory
,
1682 PFORMAT_STRING pFormat
)
1684 unsigned char *Buffer
;
1686 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1688 /* incremement the buffer here instead of in PointerMarshall,
1689 * as that is used by embedded pointers which already handle the incrementing
1690 * the buffer, and shouldn't write any additional pointer data to the wire */
1691 if (*pFormat
!= RPC_FC_RP
)
1693 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
1694 Buffer
= pStubMsg
->Buffer
;
1695 safe_buffer_increment(pStubMsg
, 4);
1698 Buffer
= pStubMsg
->Buffer
;
1700 PointerMarshall(pStubMsg
, Buffer
, pMemory
, pFormat
);
1705 /***********************************************************************
1706 * NdrPointerUnmarshall [RPCRT4.@]
1708 unsigned char * WINAPI
NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1709 unsigned char **ppMemory
,
1710 PFORMAT_STRING pFormat
,
1711 unsigned char fMustAlloc
)
1713 unsigned char *Buffer
;
1715 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1717 /* incremement the buffer here instead of in PointerUnmarshall,
1718 * as that is used by embedded pointers which already handle the incrementing
1719 * the buffer, and shouldn't read any additional pointer data from the
1721 if (*pFormat
!= RPC_FC_RP
)
1723 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1724 Buffer
= pStubMsg
->Buffer
;
1725 safe_buffer_increment(pStubMsg
, 4);
1728 Buffer
= pStubMsg
->Buffer
;
1730 PointerUnmarshall(pStubMsg
, Buffer
, ppMemory
, *ppMemory
, pFormat
, fMustAlloc
);
1735 /***********************************************************************
1736 * NdrPointerBufferSize [RPCRT4.@]
1738 void WINAPI
NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1739 unsigned char *pMemory
,
1740 PFORMAT_STRING pFormat
)
1742 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1744 /* incremement the buffer length here instead of in PointerBufferSize,
1745 * as that is used by embedded pointers which already handle the buffer
1746 * length, and shouldn't write anything more to the wire */
1747 if (*pFormat
!= RPC_FC_RP
)
1749 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
1750 safe_buffer_length_increment(pStubMsg
, 4);
1753 PointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1756 /***********************************************************************
1757 * NdrPointerMemorySize [RPCRT4.@]
1759 ULONG WINAPI
NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1760 PFORMAT_STRING pFormat
)
1762 /* unsigned size = *(LPWORD)(pFormat+2); */
1763 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1764 PointerMemorySize(pStubMsg
, pStubMsg
->Buffer
, pFormat
);
1768 /***********************************************************************
1769 * NdrPointerFree [RPCRT4.@]
1771 void WINAPI
NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1772 unsigned char *pMemory
,
1773 PFORMAT_STRING pFormat
)
1775 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1776 PointerFree(pStubMsg
, pMemory
, pFormat
);
1779 /***********************************************************************
1780 * NdrSimpleTypeMarshall [RPCRT4.@]
1782 void WINAPI
NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1783 unsigned char FormatChar
)
1785 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &FormatChar
);
1788 /***********************************************************************
1789 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1791 void WINAPI
NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1792 unsigned char FormatChar
)
1794 NdrBaseTypeUnmarshall(pStubMsg
, &pMemory
, &FormatChar
, 0);
1797 /***********************************************************************
1798 * NdrSimpleStructMarshall [RPCRT4.@]
1800 unsigned char * WINAPI
NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1801 unsigned char *pMemory
,
1802 PFORMAT_STRING pFormat
)
1804 unsigned size
= *(const WORD
*)(pFormat
+2);
1805 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1807 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pFormat
[1] + 1);
1809 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1810 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
1812 if (pFormat
[0] != RPC_FC_STRUCT
)
1813 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
+4);
1818 /***********************************************************************
1819 * NdrSimpleStructUnmarshall [RPCRT4.@]
1821 unsigned char * WINAPI
NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1822 unsigned char **ppMemory
,
1823 PFORMAT_STRING pFormat
,
1824 unsigned char fMustAlloc
)
1826 unsigned size
= *(const WORD
*)(pFormat
+2);
1827 unsigned char *saved_buffer
;
1828 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1830 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1833 *ppMemory
= NdrAllocate(pStubMsg
, size
);
1836 if (!pStubMsg
->IsClient
&& !*ppMemory
)
1837 /* for servers, we just point straight into the RPC buffer */
1838 *ppMemory
= pStubMsg
->Buffer
;
1841 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1842 safe_buffer_increment(pStubMsg
, size
);
1843 if (pFormat
[0] == RPC_FC_PSTRUCT
)
1844 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
+4, fMustAlloc
);
1846 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
1847 if (*ppMemory
!= saved_buffer
)
1848 memcpy(*ppMemory
, saved_buffer
, size
);
1853 /***********************************************************************
1854 * NdrSimpleStructBufferSize [RPCRT4.@]
1856 void WINAPI
NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1857 unsigned char *pMemory
,
1858 PFORMAT_STRING pFormat
)
1860 unsigned size
= *(const WORD
*)(pFormat
+2);
1861 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1863 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
1865 safe_buffer_length_increment(pStubMsg
, size
);
1866 if (pFormat
[0] != RPC_FC_STRUCT
)
1867 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
+4);
1870 /***********************************************************************
1871 * NdrSimpleStructMemorySize [RPCRT4.@]
1873 ULONG WINAPI
NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1874 PFORMAT_STRING pFormat
)
1876 unsigned short size
= *(const WORD
*)(pFormat
+2);
1878 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1880 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1881 pStubMsg
->MemorySize
+= size
;
1882 safe_buffer_increment(pStubMsg
, size
);
1884 if (pFormat
[0] != RPC_FC_STRUCT
)
1885 EmbeddedPointerMemorySize(pStubMsg
, pFormat
+4);
1886 return pStubMsg
->MemorySize
;
1889 /***********************************************************************
1890 * NdrSimpleStructFree [RPCRT4.@]
1892 void WINAPI
NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
1893 unsigned char *pMemory
,
1894 PFORMAT_STRING pFormat
)
1896 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1897 if (pFormat
[0] != RPC_FC_STRUCT
)
1898 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
+4);
1902 static unsigned long EmbeddedComplexSize(const MIDL_STUB_MESSAGE
*pStubMsg
,
1903 PFORMAT_STRING pFormat
)
1907 case RPC_FC_PSTRUCT
:
1908 case RPC_FC_CSTRUCT
:
1909 case RPC_FC_BOGUS_STRUCT
:
1910 case RPC_FC_SMFARRAY
:
1911 case RPC_FC_SMVARRAY
:
1912 return *(const WORD
*)&pFormat
[2];
1913 case RPC_FC_USER_MARSHAL
:
1914 return *(const WORD
*)&pFormat
[4];
1915 case RPC_FC_NON_ENCAPSULATED_UNION
:
1917 if (pStubMsg
->fHasNewCorrDesc
)
1922 pFormat
+= *(const SHORT
*)pFormat
;
1923 return *(const SHORT
*)pFormat
;
1925 return sizeof(void *);
1927 FIXME("unhandled embedded type %02x\n", *pFormat
);
1933 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1934 PFORMAT_STRING pFormat
)
1936 NDR_MEMORYSIZE m
= NdrMemorySizer
[*pFormat
& NDR_TABLE_MASK
];
1940 FIXME("no memorysizer for data type=%02x\n", *pFormat
);
1944 return m(pStubMsg
, pFormat
);
1948 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1949 unsigned char *pMemory
,
1950 PFORMAT_STRING pFormat
,
1951 PFORMAT_STRING pPointer
)
1953 PFORMAT_STRING desc
;
1957 while (*pFormat
!= RPC_FC_END
) {
1963 TRACE("byte=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
1964 safe_copy_to_buffer(pStubMsg
, pMemory
, 1);
1970 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
1971 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
1977 TRACE("long=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
1978 safe_copy_to_buffer(pStubMsg
, pMemory
, 4);
1982 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
1983 safe_copy_to_buffer(pStubMsg
, pMemory
, 8);
1986 case RPC_FC_POINTER
:
1988 unsigned char *saved_buffer
;
1989 int pointer_buffer_mark_set
= 0;
1990 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
1991 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
1992 saved_buffer
= pStubMsg
->Buffer
;
1993 if (pStubMsg
->PointerBufferMark
)
1995 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1996 pStubMsg
->PointerBufferMark
= NULL
;
1997 pointer_buffer_mark_set
= 1;
2000 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2001 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char**)pMemory
, pPointer
);
2002 if (pointer_buffer_mark_set
)
2004 STD_OVERFLOW_CHECK(pStubMsg
);
2005 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2006 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
2008 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2009 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
2010 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2012 pStubMsg
->Buffer
= saved_buffer
+ 4;
2018 case RPC_FC_ALIGNM4
:
2019 ALIGN_POINTER(pMemory
, 4);
2021 case RPC_FC_ALIGNM8
:
2022 ALIGN_POINTER(pMemory
, 8);
2024 case RPC_FC_STRUCTPAD1
:
2025 case RPC_FC_STRUCTPAD2
:
2026 case RPC_FC_STRUCTPAD3
:
2027 case RPC_FC_STRUCTPAD4
:
2028 case RPC_FC_STRUCTPAD5
:
2029 case RPC_FC_STRUCTPAD6
:
2030 case RPC_FC_STRUCTPAD7
:
2031 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2033 case RPC_FC_EMBEDDED_COMPLEX
:
2034 pMemory
+= pFormat
[1];
2036 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2037 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2038 TRACE("embedded complex (size=%ld) <= %p\n", size
, pMemory
);
2039 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
2042 /* for some reason interface pointers aren't generated as
2043 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2044 * they still need the derefencing treatment that pointers are
2046 if (*desc
== RPC_FC_IP
)
2047 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2049 m(pStubMsg
, pMemory
, desc
);
2051 else FIXME("no marshaller for embedded type %02x\n", *desc
);
2058 FIXME("unhandled format 0x%02x\n", *pFormat
);
2066 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2067 unsigned char *pMemory
,
2068 PFORMAT_STRING pFormat
,
2069 PFORMAT_STRING pPointer
)
2071 PFORMAT_STRING desc
;
2075 while (*pFormat
!= RPC_FC_END
) {
2081 safe_copy_from_buffer(pStubMsg
, pMemory
, 1);
2082 TRACE("byte=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2088 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
2089 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2095 safe_copy_from_buffer(pStubMsg
, pMemory
, 4);
2096 TRACE("long=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
2100 safe_copy_from_buffer(pStubMsg
, pMemory
, 8);
2101 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2104 case RPC_FC_POINTER
:
2106 unsigned char *saved_buffer
;
2107 int pointer_buffer_mark_set
= 0;
2108 TRACE("pointer => %p\n", pMemory
);
2109 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2110 saved_buffer
= pStubMsg
->Buffer
;
2111 if (pStubMsg
->PointerBufferMark
)
2113 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2114 pStubMsg
->PointerBufferMark
= NULL
;
2115 pointer_buffer_mark_set
= 1;
2118 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2120 PointerUnmarshall(pStubMsg
, saved_buffer
, (unsigned char**)pMemory
, *(unsigned char**)pMemory
, pPointer
, TRUE
);
2121 if (pointer_buffer_mark_set
)
2123 STD_OVERFLOW_CHECK(pStubMsg
);
2124 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2125 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
2127 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2128 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
2129 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2131 pStubMsg
->Buffer
= saved_buffer
+ 4;
2137 case RPC_FC_ALIGNM4
:
2138 ALIGN_POINTER_CLEAR(pMemory
, 4);
2140 case RPC_FC_ALIGNM8
:
2141 ALIGN_POINTER_CLEAR(pMemory
, 8);
2143 case RPC_FC_STRUCTPAD1
:
2144 case RPC_FC_STRUCTPAD2
:
2145 case RPC_FC_STRUCTPAD3
:
2146 case RPC_FC_STRUCTPAD4
:
2147 case RPC_FC_STRUCTPAD5
:
2148 case RPC_FC_STRUCTPAD6
:
2149 case RPC_FC_STRUCTPAD7
:
2150 memset(pMemory
, 0, *pFormat
- RPC_FC_STRUCTPAD1
+ 1);
2151 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2153 case RPC_FC_EMBEDDED_COMPLEX
:
2154 pMemory
+= pFormat
[1];
2156 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2157 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2158 TRACE("embedded complex (size=%ld) => %p\n", size
, pMemory
);
2159 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
2160 memset(pMemory
, 0, size
); /* just in case */
2163 /* for some reason interface pointers aren't generated as
2164 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2165 * they still need the derefencing treatment that pointers are
2167 if (*desc
== RPC_FC_IP
)
2168 m(pStubMsg
, (unsigned char **)pMemory
, desc
, FALSE
);
2170 m(pStubMsg
, &pMemory
, desc
, FALSE
);
2172 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
2179 FIXME("unhandled format %d\n", *pFormat
);
2187 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2188 unsigned char *pMemory
,
2189 PFORMAT_STRING pFormat
,
2190 PFORMAT_STRING pPointer
)
2192 PFORMAT_STRING desc
;
2196 while (*pFormat
!= RPC_FC_END
) {
2202 safe_buffer_length_increment(pStubMsg
, 1);
2208 safe_buffer_length_increment(pStubMsg
, 2);
2214 safe_buffer_length_increment(pStubMsg
, 4);
2218 safe_buffer_length_increment(pStubMsg
, 8);
2221 case RPC_FC_POINTER
:
2222 if (!pStubMsg
->IgnoreEmbeddedPointers
)
2224 int saved_buffer_length
= pStubMsg
->BufferLength
;
2225 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2226 pStubMsg
->PointerLength
= 0;
2227 if(!pStubMsg
->BufferLength
)
2228 ERR("BufferLength == 0??\n");
2229 PointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
2230 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2231 pStubMsg
->BufferLength
= saved_buffer_length
;
2233 safe_buffer_length_increment(pStubMsg
, 4);
2237 case RPC_FC_ALIGNM4
:
2238 ALIGN_POINTER(pMemory
, 4);
2240 case RPC_FC_ALIGNM8
:
2241 ALIGN_POINTER(pMemory
, 8);
2243 case RPC_FC_STRUCTPAD1
:
2244 case RPC_FC_STRUCTPAD2
:
2245 case RPC_FC_STRUCTPAD3
:
2246 case RPC_FC_STRUCTPAD4
:
2247 case RPC_FC_STRUCTPAD5
:
2248 case RPC_FC_STRUCTPAD6
:
2249 case RPC_FC_STRUCTPAD7
:
2250 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2252 case RPC_FC_EMBEDDED_COMPLEX
:
2253 pMemory
+= pFormat
[1];
2255 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2256 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2257 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
2260 /* for some reason interface pointers aren't generated as
2261 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2262 * they still need the derefencing treatment that pointers are
2264 if (*desc
== RPC_FC_IP
)
2265 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2267 m(pStubMsg
, pMemory
, desc
);
2269 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
2276 FIXME("unhandled format 0x%02x\n", *pFormat
);
2284 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
2285 unsigned char *pMemory
,
2286 PFORMAT_STRING pFormat
,
2287 PFORMAT_STRING pPointer
)
2289 PFORMAT_STRING desc
;
2293 while (*pFormat
!= RPC_FC_END
) {
2314 case RPC_FC_POINTER
:
2315 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
2319 case RPC_FC_ALIGNM4
:
2320 ALIGN_POINTER(pMemory
, 4);
2322 case RPC_FC_ALIGNM8
:
2323 ALIGN_POINTER(pMemory
, 8);
2325 case RPC_FC_STRUCTPAD1
:
2326 case RPC_FC_STRUCTPAD2
:
2327 case RPC_FC_STRUCTPAD3
:
2328 case RPC_FC_STRUCTPAD4
:
2329 case RPC_FC_STRUCTPAD5
:
2330 case RPC_FC_STRUCTPAD6
:
2331 case RPC_FC_STRUCTPAD7
:
2332 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2334 case RPC_FC_EMBEDDED_COMPLEX
:
2335 pMemory
+= pFormat
[1];
2337 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2338 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2339 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
2342 /* for some reason interface pointers aren't generated as
2343 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2344 * they still need the derefencing treatment that pointers are
2346 if (*desc
== RPC_FC_IP
)
2347 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2349 m(pStubMsg
, pMemory
, desc
);
2351 else FIXME("no freer for embedded type %02x\n", *desc
);
2358 FIXME("unhandled format 0x%02x\n", *pFormat
);
2366 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2367 PFORMAT_STRING pFormat
)
2369 PFORMAT_STRING desc
;
2370 unsigned long size
= 0;
2372 while (*pFormat
!= RPC_FC_END
) {
2379 safe_buffer_increment(pStubMsg
, 1);
2385 safe_buffer_increment(pStubMsg
, 2);
2391 safe_buffer_increment(pStubMsg
, 4);
2395 safe_buffer_increment(pStubMsg
, 8);
2397 case RPC_FC_POINTER
:
2399 safe_buffer_increment(pStubMsg
, 4);
2400 if (!pStubMsg
->IgnoreEmbeddedPointers
)
2401 FIXME("embedded pointers\n");
2403 case RPC_FC_ALIGNM4
:
2404 ALIGN_LENGTH(size
, 4);
2405 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2407 case RPC_FC_ALIGNM8
:
2408 ALIGN_LENGTH(size
, 8);
2409 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
2411 case RPC_FC_STRUCTPAD1
:
2412 case RPC_FC_STRUCTPAD2
:
2413 case RPC_FC_STRUCTPAD3
:
2414 case RPC_FC_STRUCTPAD4
:
2415 case RPC_FC_STRUCTPAD5
:
2416 case RPC_FC_STRUCTPAD6
:
2417 case RPC_FC_STRUCTPAD7
:
2418 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2420 case RPC_FC_EMBEDDED_COMPLEX
:
2423 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2424 size
+= EmbeddedComplexMemorySize(pStubMsg
, desc
);
2430 FIXME("unhandled format 0x%02x\n", *pFormat
);
2438 /***********************************************************************
2439 * NdrComplexStructMarshall [RPCRT4.@]
2441 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2442 unsigned char *pMemory
,
2443 PFORMAT_STRING pFormat
)
2445 PFORMAT_STRING conf_array
= NULL
;
2446 PFORMAT_STRING pointer_desc
= NULL
;
2447 unsigned char *OldMemory
= pStubMsg
->Memory
;
2448 int pointer_buffer_mark_set
= 0;
2450 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2452 if (!pStubMsg
->PointerBufferMark
)
2454 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2455 /* save buffer length */
2456 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2458 /* get the buffer pointer after complex array data, but before
2460 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- pStubMsg
->BufferStart
;
2461 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2462 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
2463 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2465 /* save it for use by embedded pointer code later */
2466 pStubMsg
->PointerBufferMark
= pStubMsg
->BufferStart
+ pStubMsg
->BufferLength
;
2467 TRACE("difference = 0x%x\n", pStubMsg
->PointerBufferMark
- pStubMsg
->Buffer
);
2468 pointer_buffer_mark_set
= 1;
2470 /* restore the original buffer length */
2471 pStubMsg
->BufferLength
= saved_buffer_length
;
2474 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pFormat
[1] + 1);
2477 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2479 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2482 pStubMsg
->Memory
= pMemory
;
2484 ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2487 NdrConformantArrayMarshall(pStubMsg
, pMemory
, conf_array
);
2489 pStubMsg
->Memory
= OldMemory
;
2491 if (pointer_buffer_mark_set
)
2493 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2494 pStubMsg
->PointerBufferMark
= NULL
;
2497 STD_OVERFLOW_CHECK(pStubMsg
);
2502 /***********************************************************************
2503 * NdrComplexStructUnmarshall [RPCRT4.@]
2505 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2506 unsigned char **ppMemory
,
2507 PFORMAT_STRING pFormat
,
2508 unsigned char fMustAlloc
)
2510 unsigned size
= *(const WORD
*)(pFormat
+2);
2511 PFORMAT_STRING conf_array
= NULL
;
2512 PFORMAT_STRING pointer_desc
= NULL
;
2513 unsigned char *pMemory
;
2514 int pointer_buffer_mark_set
= 0;
2516 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2518 if (!pStubMsg
->PointerBufferMark
)
2520 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2521 /* save buffer pointer */
2522 unsigned char *saved_buffer
= pStubMsg
->Buffer
;
2524 /* get the buffer pointer after complex array data, but before
2526 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2527 NdrComplexStructMemorySize(pStubMsg
, pFormat
);
2528 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2530 /* save it for use by embedded pointer code later */
2531 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2532 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->PointerBufferMark
- saved_buffer
));
2533 pointer_buffer_mark_set
= 1;
2535 /* restore the original buffer */
2536 pStubMsg
->Buffer
= saved_buffer
;
2539 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2541 if (fMustAlloc
|| !*ppMemory
)
2543 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2544 memset(*ppMemory
, 0, size
);
2548 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2550 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2553 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
);
2556 NdrConformantArrayUnmarshall(pStubMsg
, &pMemory
, conf_array
, fMustAlloc
);
2558 if (pointer_buffer_mark_set
)
2560 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2561 pStubMsg
->PointerBufferMark
= NULL
;
2567 /***********************************************************************
2568 * NdrComplexStructBufferSize [RPCRT4.@]
2570 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2571 unsigned char *pMemory
,
2572 PFORMAT_STRING pFormat
)
2574 PFORMAT_STRING conf_array
= NULL
;
2575 PFORMAT_STRING pointer_desc
= NULL
;
2576 unsigned char *OldMemory
= pStubMsg
->Memory
;
2577 int pointer_length_set
= 0;
2579 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2581 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
2583 if(!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
2585 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2586 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2588 /* get the buffer length after complex struct data, but before
2590 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2591 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
2592 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2594 /* save it for use by embedded pointer code later */
2595 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2596 pointer_length_set
= 1;
2597 TRACE("difference = 0x%lx\n", pStubMsg
->PointerLength
- saved_buffer_length
);
2599 /* restore the original buffer length */
2600 pStubMsg
->BufferLength
= saved_buffer_length
;
2604 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2606 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2609 pStubMsg
->Memory
= pMemory
;
2611 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2614 NdrConformantArrayBufferSize(pStubMsg
, pMemory
, conf_array
);
2616 pStubMsg
->Memory
= OldMemory
;
2618 if(pointer_length_set
)
2620 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2621 pStubMsg
->PointerLength
= 0;
2626 /***********************************************************************
2627 * NdrComplexStructMemorySize [RPCRT4.@]
2629 ULONG WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2630 PFORMAT_STRING pFormat
)
2632 unsigned size
= *(const WORD
*)(pFormat
+2);
2633 PFORMAT_STRING conf_array
= NULL
;
2634 PFORMAT_STRING pointer_desc
= NULL
;
2636 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2638 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2641 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2643 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2646 ComplexStructMemorySize(pStubMsg
, pFormat
);
2649 NdrConformantArrayMemorySize(pStubMsg
, conf_array
);
2654 /***********************************************************************
2655 * NdrComplexStructFree [RPCRT4.@]
2657 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
2658 unsigned char *pMemory
,
2659 PFORMAT_STRING pFormat
)
2661 PFORMAT_STRING conf_array
= NULL
;
2662 PFORMAT_STRING pointer_desc
= NULL
;
2663 unsigned char *OldMemory
= pStubMsg
->Memory
;
2665 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2668 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2670 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2673 pStubMsg
->Memory
= pMemory
;
2675 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2678 NdrConformantArrayFree(pStubMsg
, pMemory
, conf_array
);
2680 pStubMsg
->Memory
= OldMemory
;
2683 /***********************************************************************
2684 * NdrConformantArrayMarshall [RPCRT4.@]
2686 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2687 unsigned char *pMemory
,
2688 PFORMAT_STRING pFormat
)
2690 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
2691 unsigned char alignment
= pFormat
[1] + 1;
2693 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2694 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2696 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2698 WriteConformance(pStubMsg
);
2700 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
2702 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2703 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2704 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
2706 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2711 /***********************************************************************
2712 * NdrConformantArrayUnmarshall [RPCRT4.@]
2714 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2715 unsigned char **ppMemory
,
2716 PFORMAT_STRING pFormat
,
2717 unsigned char fMustAlloc
)
2719 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
2720 unsigned char alignment
= pFormat
[1] + 1;
2721 unsigned char *saved_buffer
;
2723 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2724 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2726 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2728 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2729 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2732 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2735 if (!pStubMsg
->IsClient
&& !*ppMemory
)
2736 /* for servers, we just point straight into the RPC buffer */
2737 *ppMemory
= pStubMsg
->Buffer
;
2740 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2741 safe_buffer_increment(pStubMsg
, size
);
2742 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
2744 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
2745 if (*ppMemory
!= saved_buffer
)
2746 memcpy(*ppMemory
, saved_buffer
, size
);
2751 /***********************************************************************
2752 * NdrConformantArrayBufferSize [RPCRT4.@]
2754 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2755 unsigned char *pMemory
,
2756 PFORMAT_STRING pFormat
)
2758 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
2759 unsigned char alignment
= pFormat
[1] + 1;
2761 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2762 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2764 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2766 SizeConformance(pStubMsg
);
2768 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
2770 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2771 /* conformance value plus array */
2772 safe_buffer_length_increment(pStubMsg
, size
);
2774 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
2777 /***********************************************************************
2778 * NdrConformantArrayMemorySize [RPCRT4.@]
2780 ULONG WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2781 PFORMAT_STRING pFormat
)
2783 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
2784 unsigned char alignment
= pFormat
[1] + 1;
2786 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2787 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2789 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2790 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2791 pStubMsg
->MemorySize
+= size
;
2793 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2794 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2795 safe_buffer_increment(pStubMsg
, size
);
2797 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2799 return pStubMsg
->MemorySize
;
2802 /***********************************************************************
2803 * NdrConformantArrayFree [RPCRT4.@]
2805 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
2806 unsigned char *pMemory
,
2807 PFORMAT_STRING pFormat
)
2809 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2810 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2812 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2814 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2818 /***********************************************************************
2819 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2821 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2822 unsigned char* pMemory
,
2823 PFORMAT_STRING pFormat
)
2826 unsigned char alignment
= pFormat
[1] + 1;
2827 DWORD esize
= *(const WORD
*)(pFormat
+2);
2829 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
2831 if (pFormat
[0] != RPC_FC_CVARRAY
)
2833 ERR("invalid format type %x\n", pFormat
[0]);
2834 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2838 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2839 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2841 WriteConformance(pStubMsg
);
2842 WriteVariance(pStubMsg
);
2844 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
2846 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2848 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2849 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
2851 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2857 /***********************************************************************
2858 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2860 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2861 unsigned char** ppMemory
,
2862 PFORMAT_STRING pFormat
,
2863 unsigned char fMustAlloc
)
2865 ULONG bufsize
, memsize
;
2866 unsigned char alignment
= pFormat
[1] + 1;
2867 DWORD esize
= *(const WORD
*)(pFormat
+2);
2869 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2871 if (pFormat
[0] != RPC_FC_CVARRAY
)
2873 ERR("invalid format type %x\n", pFormat
[0]);
2874 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2878 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2879 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2881 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2883 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2884 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2886 if (!*ppMemory
|| fMustAlloc
)
2887 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2888 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2889 safe_copy_from_buffer(pStubMsg
, *ppMemory
+ pStubMsg
->Offset
, bufsize
);
2891 EmbeddedPointerUnmarshall(pStubMsg
, *ppMemory
, *ppMemory
, pFormat
, TRUE
/* FIXME */);
2897 /***********************************************************************
2898 * NdrConformantVaryingArrayFree [RPCRT4.@]
2900 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
2901 unsigned char* pMemory
,
2902 PFORMAT_STRING pFormat
)
2904 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2906 if (pFormat
[0] != RPC_FC_CVARRAY
)
2908 ERR("invalid format type %x\n", pFormat
[0]);
2909 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2913 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2914 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2916 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2920 /***********************************************************************
2921 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2923 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
2924 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
2926 unsigned char alignment
= pFormat
[1] + 1;
2927 DWORD esize
= *(const WORD
*)(pFormat
+2);
2929 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
2931 if (pFormat
[0] != RPC_FC_CVARRAY
)
2933 ERR("invalid format type %x\n", pFormat
[0]);
2934 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2939 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2940 /* compute length */
2941 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2943 SizeConformance(pStubMsg
);
2944 SizeVariance(pStubMsg
);
2946 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
2948 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
2950 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
2954 /***********************************************************************
2955 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2957 ULONG WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
2958 PFORMAT_STRING pFormat
)
2960 ULONG bufsize
, memsize
;
2961 unsigned char alignment
= pFormat
[1] + 1;
2962 DWORD esize
= *(const WORD
*)(pFormat
+2);
2964 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
2966 if (pFormat
[0] != RPC_FC_CVARRAY
)
2968 ERR("invalid format type %x\n", pFormat
[0]);
2969 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2970 return pStubMsg
->MemorySize
;
2973 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2974 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2976 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2978 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2979 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2981 safe_buffer_increment(pStubMsg
, bufsize
);
2982 pStubMsg
->MemorySize
+= memsize
;
2984 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2986 return pStubMsg
->MemorySize
;
2990 /***********************************************************************
2991 * NdrComplexArrayMarshall [RPCRT4.@]
2993 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2994 unsigned char *pMemory
,
2995 PFORMAT_STRING pFormat
)
2997 ULONG i
, count
, def
;
2998 BOOL variance_present
;
2999 unsigned char alignment
;
3000 int pointer_buffer_mark_set
= 0;
3002 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3004 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3006 ERR("invalid format type %x\n", pFormat
[0]);
3007 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3011 alignment
= pFormat
[1] + 1;
3013 if (!pStubMsg
->PointerBufferMark
)
3015 /* save buffer fields that may be changed by buffer sizer functions
3016 * and that may be needed later on */
3017 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3018 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
3019 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
3020 unsigned long saved_offset
= pStubMsg
->Offset
;
3021 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
3023 /* get the buffer pointer after complex array data, but before
3025 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- pStubMsg
->BufferStart
;
3026 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3027 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
3028 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3030 /* save it for use by embedded pointer code later */
3031 pStubMsg
->PointerBufferMark
= pStubMsg
->BufferStart
+ pStubMsg
->BufferLength
;
3032 TRACE("difference = 0x%x\n", pStubMsg
->Buffer
- pStubMsg
->BufferStart
);
3033 pointer_buffer_mark_set
= 1;
3035 /* restore fields */
3036 pStubMsg
->ActualCount
= saved_actual_count
;
3037 pStubMsg
->Offset
= saved_offset
;
3038 pStubMsg
->MaxCount
= saved_max_count
;
3039 pStubMsg
->BufferLength
= saved_buffer_length
;
3042 def
= *(const WORD
*)&pFormat
[2];
3045 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3046 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3048 variance_present
= IsConformanceOrVariancePresent(pFormat
);
3049 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3050 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3052 WriteConformance(pStubMsg
);
3053 if (variance_present
)
3054 WriteVariance(pStubMsg
);
3056 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
3058 count
= pStubMsg
->ActualCount
;
3059 for (i
= 0; i
< count
; i
++)
3060 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
3062 STD_OVERFLOW_CHECK(pStubMsg
);
3064 if (pointer_buffer_mark_set
)
3066 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3067 pStubMsg
->PointerBufferMark
= NULL
;
3073 /***********************************************************************
3074 * NdrComplexArrayUnmarshall [RPCRT4.@]
3076 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3077 unsigned char **ppMemory
,
3078 PFORMAT_STRING pFormat
,
3079 unsigned char fMustAlloc
)
3081 ULONG i
, count
, size
;
3082 unsigned char alignment
;
3083 unsigned char *pMemory
;
3084 unsigned char *saved_buffer
;
3085 int pointer_buffer_mark_set
= 0;
3086 int saved_ignore_embedded
;
3088 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3090 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3092 ERR("invalid format type %x\n", pFormat
[0]);
3093 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3097 alignment
= pFormat
[1] + 1;
3099 saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3100 /* save buffer pointer */
3101 saved_buffer
= pStubMsg
->Buffer
;
3102 /* get the buffer pointer after complex array data, but before
3104 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3105 pStubMsg
->MemorySize
= 0;
3106 NdrComplexArrayMemorySize(pStubMsg
, pFormat
);
3107 size
= pStubMsg
->MemorySize
;
3108 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3110 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->Buffer
- saved_buffer
));
3111 if (!pStubMsg
->PointerBufferMark
)
3113 /* save it for use by embedded pointer code later */
3114 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3115 pointer_buffer_mark_set
= 1;
3117 /* restore the original buffer */
3118 pStubMsg
->Buffer
= saved_buffer
;
3122 pFormat
= ReadConformance(pStubMsg
, pFormat
);
3123 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3125 if (fMustAlloc
|| !*ppMemory
)
3127 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3128 memset(*ppMemory
, 0, size
);
3131 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3133 pMemory
= *ppMemory
;
3134 count
= pStubMsg
->ActualCount
;
3135 for (i
= 0; i
< count
; i
++)
3136 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
3138 if (pointer_buffer_mark_set
)
3140 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3141 pStubMsg
->PointerBufferMark
= NULL
;
3147 /***********************************************************************
3148 * NdrComplexArrayBufferSize [RPCRT4.@]
3150 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3151 unsigned char *pMemory
,
3152 PFORMAT_STRING pFormat
)
3154 ULONG i
, count
, def
;
3155 unsigned char alignment
;
3156 BOOL variance_present
;
3157 int pointer_length_set
= 0;
3159 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3161 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3163 ERR("invalid format type %x\n", pFormat
[0]);
3164 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3168 alignment
= pFormat
[1] + 1;
3170 if (!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
3172 /* save buffer fields that may be changed by buffer sizer functions
3173 * and that may be needed later on */
3174 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3175 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
3176 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
3177 unsigned long saved_offset
= pStubMsg
->Offset
;
3178 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
3180 /* get the buffer pointer after complex array data, but before
3182 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3183 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
3184 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3186 /* save it for use by embedded pointer code later */
3187 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3188 pointer_length_set
= 1;
3190 /* restore fields */
3191 pStubMsg
->ActualCount
= saved_actual_count
;
3192 pStubMsg
->Offset
= saved_offset
;
3193 pStubMsg
->MaxCount
= saved_max_count
;
3194 pStubMsg
->BufferLength
= saved_buffer_length
;
3196 def
= *(const WORD
*)&pFormat
[2];
3199 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3200 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3201 SizeConformance(pStubMsg
);
3203 variance_present
= IsConformanceOrVariancePresent(pFormat
);
3204 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3205 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3207 if (variance_present
)
3208 SizeVariance(pStubMsg
);
3210 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
3212 count
= pStubMsg
->ActualCount
;
3213 for (i
= 0; i
< count
; i
++)
3214 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
3216 if(pointer_length_set
)
3218 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3219 pStubMsg
->PointerLength
= 0;
3223 /***********************************************************************
3224 * NdrComplexArrayMemorySize [RPCRT4.@]
3226 ULONG WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3227 PFORMAT_STRING pFormat
)
3229 ULONG i
, count
, esize
, SavedMemorySize
, MemorySize
;
3230 unsigned char alignment
;
3231 unsigned char *Buffer
;
3233 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3235 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3237 ERR("invalid format type %x\n", pFormat
[0]);
3238 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3242 alignment
= pFormat
[1] + 1;
3246 pFormat
= ReadConformance(pStubMsg
, pFormat
);
3247 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3249 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3251 SavedMemorySize
= pStubMsg
->MemorySize
;
3253 Buffer
= pStubMsg
->Buffer
;
3254 pStubMsg
->MemorySize
= 0;
3255 esize
= ComplexStructMemorySize(pStubMsg
, pFormat
);
3256 pStubMsg
->Buffer
= Buffer
;
3258 MemorySize
= safe_multiply(pStubMsg
->MaxCount
, esize
);
3260 count
= pStubMsg
->ActualCount
;
3261 for (i
= 0; i
< count
; i
++)
3262 ComplexStructMemorySize(pStubMsg
, pFormat
);
3264 pStubMsg
->MemorySize
= SavedMemorySize
;
3266 pStubMsg
->MemorySize
+= MemorySize
;
3270 /***********************************************************************
3271 * NdrComplexArrayFree [RPCRT4.@]
3273 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3274 unsigned char *pMemory
,
3275 PFORMAT_STRING pFormat
)
3277 ULONG i
, count
, def
;
3279 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3281 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3283 ERR("invalid format type %x\n", pFormat
[0]);
3284 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3288 def
= *(const WORD
*)&pFormat
[2];
3291 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3292 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3294 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3295 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3297 count
= pStubMsg
->ActualCount
;
3298 for (i
= 0; i
< count
; i
++)
3299 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
3302 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg
,
3303 USER_MARSHAL_CB_TYPE cbtype
, PFORMAT_STRING pFormat
,
3304 USER_MARSHAL_CB
*umcb
)
3306 umcb
->Flags
= MAKELONG(pStubMsg
->dwDestContext
,
3307 pStubMsg
->RpcMsg
->DataRepresentation
);
3308 umcb
->pStubMsg
= pStubMsg
;
3309 umcb
->pReserve
= NULL
;
3310 umcb
->Signature
= USER_MARSHAL_CB_SIGNATURE
;
3311 umcb
->CBType
= cbtype
;
3312 umcb
->pFormat
= pFormat
;
3313 umcb
->pTypeFormat
= NULL
/* FIXME */;
3316 #define USER_MARSHAL_PTR_PREFIX \
3317 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3318 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3320 /***********************************************************************
3321 * NdrUserMarshalMarshall [RPCRT4.@]
3323 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3324 unsigned char *pMemory
,
3325 PFORMAT_STRING pFormat
)
3327 unsigned flags
= pFormat
[1];
3328 unsigned index
= *(const WORD
*)&pFormat
[2];
3329 unsigned char *saved_buffer
= NULL
;
3330 USER_MARSHAL_CB umcb
;
3332 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3333 TRACE("index=%d\n", index
);
3335 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_MARSHALL
, pFormat
, &umcb
);
3337 if (flags
& USER_MARSHAL_POINTER
)
3339 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
3340 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, USER_MARSHAL_PTR_PREFIX
);
3341 pStubMsg
->Buffer
+= 4;
3342 if (pStubMsg
->PointerBufferMark
)
3344 saved_buffer
= pStubMsg
->Buffer
;
3345 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3346 pStubMsg
->PointerBufferMark
= NULL
;
3348 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 8);
3351 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3354 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
3355 &umcb
.Flags
, pStubMsg
->Buffer
, pMemory
);
3359 STD_OVERFLOW_CHECK(pStubMsg
);
3360 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3361 pStubMsg
->Buffer
= saved_buffer
;
3364 STD_OVERFLOW_CHECK(pStubMsg
);
3369 /***********************************************************************
3370 * NdrUserMarshalUnmarshall [RPCRT4.@]
3372 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3373 unsigned char **ppMemory
,
3374 PFORMAT_STRING pFormat
,
3375 unsigned char fMustAlloc
)
3377 unsigned flags
= pFormat
[1];
3378 unsigned index
= *(const WORD
*)&pFormat
[2];
3379 DWORD memsize
= *(const WORD
*)&pFormat
[4];
3380 unsigned char *saved_buffer
= NULL
;
3381 USER_MARSHAL_CB umcb
;
3383 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3384 TRACE("index=%d\n", index
);
3386 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_UNMARSHALL
, pFormat
, &umcb
);
3388 if (flags
& USER_MARSHAL_POINTER
)
3390 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3391 /* skip pointer prefix */
3392 pStubMsg
->Buffer
+= 4;
3393 if (pStubMsg
->PointerBufferMark
)
3395 saved_buffer
= pStubMsg
->Buffer
;
3396 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3397 pStubMsg
->PointerBufferMark
= NULL
;
3399 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3402 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3404 if (fMustAlloc
|| !*ppMemory
)
3405 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
3408 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
3409 &umcb
.Flags
, pStubMsg
->Buffer
, *ppMemory
);
3413 STD_OVERFLOW_CHECK(pStubMsg
);
3414 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3415 pStubMsg
->Buffer
= saved_buffer
;
3421 /***********************************************************************
3422 * NdrUserMarshalBufferSize [RPCRT4.@]
3424 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3425 unsigned char *pMemory
,
3426 PFORMAT_STRING pFormat
)
3428 unsigned flags
= pFormat
[1];
3429 unsigned index
= *(const WORD
*)&pFormat
[2];
3430 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
3431 USER_MARSHAL_CB umcb
;
3432 unsigned long saved_buffer_length
= 0;
3434 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3435 TRACE("index=%d\n", index
);
3437 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_BUFFER_SIZE
, pFormat
, &umcb
);
3439 if (flags
& USER_MARSHAL_POINTER
)
3441 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
3442 /* skip pointer prefix */
3443 safe_buffer_length_increment(pStubMsg
, 4);
3444 if (pStubMsg
->IgnoreEmbeddedPointers
)
3446 if (pStubMsg
->PointerLength
)
3448 saved_buffer_length
= pStubMsg
->BufferLength
;
3449 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3450 pStubMsg
->PointerLength
= 0;
3452 ALIGN_LENGTH(pStubMsg
->BufferLength
, 8);
3455 ALIGN_LENGTH(pStubMsg
->BufferLength
, (flags
& 0xf) + 1);
3458 TRACE("size=%d\n", bufsize
);
3459 safe_buffer_length_increment(pStubMsg
, bufsize
);
3462 pStubMsg
->BufferLength
=
3463 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
3464 &umcb
.Flags
, pStubMsg
->BufferLength
, pMemory
);
3466 if (saved_buffer_length
)
3468 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3469 pStubMsg
->BufferLength
= saved_buffer_length
;
3474 /***********************************************************************
3475 * NdrUserMarshalMemorySize [RPCRT4.@]
3477 ULONG WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3478 PFORMAT_STRING pFormat
)
3480 unsigned flags
= pFormat
[1];
3481 unsigned index
= *(const WORD
*)&pFormat
[2];
3482 DWORD memsize
= *(const WORD
*)&pFormat
[4];
3483 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
3485 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3486 TRACE("index=%d\n", index
);
3488 pStubMsg
->MemorySize
+= memsize
;
3490 if (flags
& USER_MARSHAL_POINTER
)
3492 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3493 /* skip pointer prefix */
3494 pStubMsg
->Buffer
+= 4;
3495 if (pStubMsg
->IgnoreEmbeddedPointers
)
3496 return pStubMsg
->MemorySize
;
3497 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3500 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3503 FIXME("not implemented for varying buffer size\n");
3505 pStubMsg
->Buffer
+= bufsize
;
3507 return pStubMsg
->MemorySize
;
3510 /***********************************************************************
3511 * NdrUserMarshalFree [RPCRT4.@]
3513 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
3514 unsigned char *pMemory
,
3515 PFORMAT_STRING pFormat
)
3517 /* unsigned flags = pFormat[1]; */
3518 unsigned index
= *(const WORD
*)&pFormat
[2];
3519 USER_MARSHAL_CB umcb
;
3521 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3522 TRACE("index=%d\n", index
);
3524 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_FREE
, pFormat
, &umcb
);
3526 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
3527 &umcb
.Flags
, pMemory
);
3530 /***********************************************************************
3531 * NdrClearOutParameters [RPCRT4.@]
3533 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
3534 PFORMAT_STRING pFormat
,
3537 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
3540 /***********************************************************************
3541 * NdrConvert [RPCRT4.@]
3543 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
3545 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
3546 /* FIXME: since this stub doesn't do any converting, the proper behavior
3547 is to raise an exception */
3550 /***********************************************************************
3551 * NdrConvert2 [RPCRT4.@]
3553 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, LONG NumberParams
)
3555 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3556 pStubMsg
, pFormat
, NumberParams
);
3557 /* FIXME: since this stub doesn't do any converting, the proper behavior
3558 is to raise an exception */
3561 #include "pshpack1.h"
3562 typedef struct _NDR_CSTRUCT_FORMAT
3565 unsigned char alignment
;
3566 unsigned short memory_size
;
3567 short offset_to_array_description
;
3568 } NDR_CSTRUCT_FORMAT
, NDR_CVSTRUCT_FORMAT
;
3569 #include "poppack.h"
3571 /***********************************************************************
3572 * NdrConformantStructMarshall [RPCRT4.@]
3574 unsigned char * WINAPI
NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3575 unsigned char *pMemory
,
3576 PFORMAT_STRING pFormat
)
3578 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3579 PFORMAT_STRING pCArrayFormat
;
3580 ULONG esize
, bufsize
;
3582 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3584 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3585 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3587 ERR("invalid format type %x\n", pCStructFormat
->type
);
3588 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3592 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3593 pCStructFormat
->offset_to_array_description
;
3594 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3596 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3597 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3600 esize
= *(const WORD
*)(pCArrayFormat
+2);
3602 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
3603 pCArrayFormat
+ 4, 0);
3605 WriteConformance(pStubMsg
);
3607 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
3609 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3611 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3612 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
3614 ERR("integer overflow of memory_size %u with bufsize %u\n",
3615 pCStructFormat
->memory_size
, bufsize
);
3616 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3618 /* copy constant sized part of struct */
3619 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3620 safe_copy_to_buffer(pStubMsg
, pMemory
, pCStructFormat
->memory_size
+ bufsize
);
3622 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3623 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3628 /***********************************************************************
3629 * NdrConformantStructUnmarshall [RPCRT4.@]
3631 unsigned char * WINAPI
NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3632 unsigned char **ppMemory
,
3633 PFORMAT_STRING pFormat
,
3634 unsigned char fMustAlloc
)
3636 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3637 PFORMAT_STRING pCArrayFormat
;
3638 ULONG esize
, bufsize
;
3639 unsigned char *saved_buffer
;
3641 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3643 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3644 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3646 ERR("invalid format type %x\n", pCStructFormat
->type
);
3647 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3650 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3651 pCStructFormat
->offset_to_array_description
;
3652 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3654 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3655 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3658 esize
= *(const WORD
*)(pCArrayFormat
+2);
3660 pCArrayFormat
= ReadConformance(pStubMsg
, pCArrayFormat
+ 4);
3662 ALIGN_POINTER(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
3664 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3666 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3667 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
3669 ERR("integer overflow of memory_size %u with bufsize %u\n",
3670 pCStructFormat
->memory_size
, bufsize
);
3671 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3676 SIZE_T size
= pCStructFormat
->memory_size
+ bufsize
;
3677 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3681 if (!pStubMsg
->IsClient
&& !*ppMemory
)
3682 /* for servers, we just point straight into the RPC buffer */
3683 *ppMemory
= pStubMsg
->Buffer
;
3686 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3687 safe_buffer_increment(pStubMsg
, pCStructFormat
->memory_size
+ bufsize
);
3688 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3689 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
3691 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
3692 if (*ppMemory
!= saved_buffer
)
3693 memcpy(*ppMemory
, saved_buffer
, pCStructFormat
->memory_size
+ bufsize
);
3698 /***********************************************************************
3699 * NdrConformantStructBufferSize [RPCRT4.@]
3701 void WINAPI
NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3702 unsigned char *pMemory
,
3703 PFORMAT_STRING pFormat
)
3705 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3706 PFORMAT_STRING pCArrayFormat
;
3709 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3711 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3712 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3714 ERR("invalid format type %x\n", pCStructFormat
->type
);
3715 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3718 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3719 pCStructFormat
->offset_to_array_description
;
3720 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3722 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3723 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3726 esize
= *(const WORD
*)(pCArrayFormat
+2);
3728 pCArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
, pCArrayFormat
+4, 0);
3729 SizeConformance(pStubMsg
);
3731 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCStructFormat
->alignment
+ 1);
3733 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3735 safe_buffer_length_increment(pStubMsg
, pCStructFormat
->memory_size
);
3736 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
3738 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3739 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3742 /***********************************************************************
3743 * NdrConformantStructMemorySize [RPCRT4.@]
3745 ULONG WINAPI
NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3746 PFORMAT_STRING pFormat
)
3752 /***********************************************************************
3753 * NdrConformantStructFree [RPCRT4.@]
3755 void WINAPI
NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3756 unsigned char *pMemory
,
3757 PFORMAT_STRING pFormat
)
3759 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3760 PFORMAT_STRING pCArrayFormat
;
3763 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3765 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3766 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3768 ERR("invalid format type %x\n", pCStructFormat
->type
);
3769 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3773 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3774 pCStructFormat
->offset_to_array_description
;
3775 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3777 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3778 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3781 esize
= *(const WORD
*)(pCArrayFormat
+2);
3783 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
3784 pCArrayFormat
+ 4, 0);
3786 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3788 /* copy constant sized part of struct */
3789 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3791 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3792 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
3795 /***********************************************************************
3796 * NdrConformantVaryingStructMarshall [RPCRT4.@]
3798 unsigned char * WINAPI
NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3799 unsigned char *pMemory
,
3800 PFORMAT_STRING pFormat
)
3802 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3803 PFORMAT_STRING pCVArrayFormat
;
3804 ULONG esize
, bufsize
;
3806 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3808 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3809 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3811 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3812 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3816 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3817 pCVStructFormat
->offset_to_array_description
;
3818 switch (*pCVArrayFormat
)
3820 case RPC_FC_CVARRAY
:
3821 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3823 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3824 pCVArrayFormat
+ 4, 0);
3825 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3828 case RPC_FC_C_CSTRING
:
3829 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
3830 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
3831 esize
= sizeof(char);
3832 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3833 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3834 pCVArrayFormat
+ 2, 0);
3836 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3838 case RPC_FC_C_WSTRING
:
3839 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
3840 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
3841 esize
= sizeof(WCHAR
);
3842 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3843 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3844 pCVArrayFormat
+ 2, 0);
3846 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3849 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3850 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3854 WriteConformance(pStubMsg
);
3856 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
3858 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3860 /* write constant sized part */
3861 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3862 safe_copy_to_buffer(pStubMsg
, pMemory
, pCVStructFormat
->memory_size
);
3864 WriteVariance(pStubMsg
);
3866 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3868 /* write array part */
3869 safe_copy_to_buffer(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
, bufsize
);
3871 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3876 /***********************************************************************
3877 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3879 unsigned char * WINAPI
NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3880 unsigned char **ppMemory
,
3881 PFORMAT_STRING pFormat
,
3882 unsigned char fMustAlloc
)
3884 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3885 PFORMAT_STRING pCVArrayFormat
;
3886 ULONG esize
, bufsize
;
3887 unsigned char cvarray_type
;
3889 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3891 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3892 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3894 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3895 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3899 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3900 pCVStructFormat
->offset_to_array_description
;
3901 cvarray_type
= *pCVArrayFormat
;
3902 switch (cvarray_type
)
3904 case RPC_FC_CVARRAY
:
3905 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3906 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 4);
3908 case RPC_FC_C_CSTRING
:
3909 esize
= sizeof(char);
3910 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3911 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3913 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3915 case RPC_FC_C_WSTRING
:
3916 esize
= sizeof(WCHAR
);
3917 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3918 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3920 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3923 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3924 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3928 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
3930 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3932 /* work out how much memory to allocate if we need to do so */
3933 if (!*ppMemory
|| fMustAlloc
)
3935 SIZE_T size
= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->MaxCount
);
3936 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3939 /* copy the constant data */
3940 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3941 safe_copy_from_buffer(pStubMsg
, *ppMemory
, pCVStructFormat
->memory_size
);
3943 pCVArrayFormat
= ReadVariance(pStubMsg
, pCVArrayFormat
, pStubMsg
->MaxCount
);
3945 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3947 if ((cvarray_type
== RPC_FC_C_CSTRING
) ||
3948 (cvarray_type
== RPC_FC_C_WSTRING
))
3951 /* strings must always have null terminating bytes */
3952 if (bufsize
< esize
)
3954 ERR("invalid string length of %d\n", pStubMsg
->ActualCount
);
3955 RpcRaiseException(RPC_S_INVALID_BOUND
);
3958 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
3959 if (pStubMsg
->Buffer
[i
] != 0)
3961 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
3962 i
, pStubMsg
->Buffer
[i
]);
3963 RpcRaiseException(RPC_S_INVALID_BOUND
);
3968 /* copy the array data */
3969 safe_copy_from_buffer(pStubMsg
, *ppMemory
+ pCVStructFormat
->memory_size
, bufsize
);
3971 if (cvarray_type
== RPC_FC_C_CSTRING
)
3972 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory
+ pCVStructFormat
->memory_size
)));
3973 else if (cvarray_type
== RPC_FC_C_WSTRING
)
3974 TRACE("string=%s\n", debugstr_w((WCHAR
*)(*ppMemory
+ pCVStructFormat
->memory_size
)));
3976 EmbeddedPointerUnmarshall(pStubMsg
, *ppMemory
, *ppMemory
, pFormat
, TRUE
/* FIXME */);
3981 /***********************************************************************
3982 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3984 void WINAPI
NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3985 unsigned char *pMemory
,
3986 PFORMAT_STRING pFormat
)
3988 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3989 PFORMAT_STRING pCVArrayFormat
;
3992 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3994 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3995 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3997 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3998 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4002 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4003 pCVStructFormat
->offset_to_array_description
;
4004 switch (*pCVArrayFormat
)
4006 case RPC_FC_CVARRAY
:
4007 esize
= *(const WORD
*)(pCVArrayFormat
+2);
4009 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4010 pCVArrayFormat
+ 4, 0);
4011 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4014 case RPC_FC_C_CSTRING
:
4015 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
4016 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
4017 esize
= sizeof(char);
4018 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4019 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4020 pCVArrayFormat
+ 2, 0);
4022 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4024 case RPC_FC_C_WSTRING
:
4025 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
4026 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
4027 esize
= sizeof(WCHAR
);
4028 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4029 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4030 pCVArrayFormat
+ 2, 0);
4032 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4035 ERR("invalid array format type %x\n", *pCVArrayFormat
);
4036 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4040 SizeConformance(pStubMsg
);
4042 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCVStructFormat
->alignment
+ 1);
4044 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4046 safe_buffer_length_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4047 SizeVariance(pStubMsg
);
4048 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
4050 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4053 /***********************************************************************
4054 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4056 ULONG WINAPI
NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4057 PFORMAT_STRING pFormat
)
4059 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4060 PFORMAT_STRING pCVArrayFormat
;
4062 unsigned char cvarray_type
;
4064 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4066 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4067 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4069 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4070 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4074 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4075 pCVStructFormat
->offset_to_array_description
;
4076 cvarray_type
= *pCVArrayFormat
;
4077 switch (cvarray_type
)
4079 case RPC_FC_CVARRAY
:
4080 esize
= *(const WORD
*)(pCVArrayFormat
+2);
4081 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 4);
4083 case RPC_FC_C_CSTRING
:
4084 esize
= sizeof(char);
4085 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4086 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
4088 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
4090 case RPC_FC_C_WSTRING
:
4091 esize
= sizeof(WCHAR
);
4092 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4093 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
4095 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
4098 ERR("invalid array format type %x\n", *pCVArrayFormat
);
4099 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4103 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4105 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4107 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4108 pCVArrayFormat
= ReadVariance(pStubMsg
, pCVArrayFormat
, pStubMsg
->MaxCount
);
4109 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
4111 pStubMsg
->MemorySize
+= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->MaxCount
);
4113 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4115 return pCVStructFormat
->memory_size
+ pStubMsg
->MaxCount
* esize
;
4118 /***********************************************************************
4119 * NdrConformantVaryingStructFree [RPCRT4.@]
4121 void WINAPI
NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
4122 unsigned char *pMemory
,
4123 PFORMAT_STRING pFormat
)
4125 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4126 PFORMAT_STRING pCVArrayFormat
;
4129 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4131 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4132 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4134 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4135 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4139 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4140 pCVStructFormat
->offset_to_array_description
;
4141 switch (*pCVArrayFormat
)
4143 case RPC_FC_CVARRAY
:
4144 esize
= *(const WORD
*)(pCVArrayFormat
+2);
4146 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4147 pCVArrayFormat
+ 4, 0);
4148 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4151 case RPC_FC_C_CSTRING
:
4152 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
4153 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
4154 esize
= sizeof(char);
4155 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4156 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4157 pCVArrayFormat
+ 2, 0);
4159 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4161 case RPC_FC_C_WSTRING
:
4162 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
4163 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
4164 esize
= sizeof(WCHAR
);
4165 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4166 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4167 pCVArrayFormat
+ 2, 0);
4169 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4172 ERR("invalid array format type %x\n", *pCVArrayFormat
);
4173 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4177 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4179 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4182 #include "pshpack1.h"
4186 unsigned char alignment
;
4187 unsigned short total_size
;
4188 } NDR_SMFARRAY_FORMAT
;
4193 unsigned char alignment
;
4194 unsigned long total_size
;
4195 } NDR_LGFARRAY_FORMAT
;
4196 #include "poppack.h"
4198 /***********************************************************************
4199 * NdrFixedArrayMarshall [RPCRT4.@]
4201 unsigned char * WINAPI
NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4202 unsigned char *pMemory
,
4203 PFORMAT_STRING pFormat
)
4205 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4206 unsigned long total_size
;
4208 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4210 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4211 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4213 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4214 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4218 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4220 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4222 total_size
= pSmFArrayFormat
->total_size
;
4223 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4227 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4228 total_size
= pLgFArrayFormat
->total_size
;
4229 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4232 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4233 safe_copy_to_buffer(pStubMsg
, pMemory
, total_size
);
4235 pFormat
= EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4240 /***********************************************************************
4241 * NdrFixedArrayUnmarshall [RPCRT4.@]
4243 unsigned char * WINAPI
NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4244 unsigned char **ppMemory
,
4245 PFORMAT_STRING pFormat
,
4246 unsigned char fMustAlloc
)
4248 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4249 unsigned long total_size
;
4250 unsigned char *saved_buffer
;
4252 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4254 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4255 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4257 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4258 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4262 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4264 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4266 total_size
= pSmFArrayFormat
->total_size
;
4267 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4271 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4272 total_size
= pLgFArrayFormat
->total_size
;
4273 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4277 *ppMemory
= NdrAllocate(pStubMsg
, total_size
);
4280 if (!pStubMsg
->IsClient
&& !*ppMemory
)
4281 /* for servers, we just point straight into the RPC buffer */
4282 *ppMemory
= pStubMsg
->Buffer
;
4285 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4286 safe_buffer_increment(pStubMsg
, total_size
);
4287 pFormat
= EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4289 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
4290 if (*ppMemory
!= saved_buffer
)
4291 memcpy(*ppMemory
, saved_buffer
, total_size
);
4296 /***********************************************************************
4297 * NdrFixedArrayBufferSize [RPCRT4.@]
4299 void WINAPI
NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4300 unsigned char *pMemory
,
4301 PFORMAT_STRING pFormat
)
4303 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4304 unsigned long total_size
;
4306 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4308 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4309 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4311 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4312 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4316 ALIGN_LENGTH(pStubMsg
->BufferLength
, pSmFArrayFormat
->alignment
+ 1);
4318 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4320 total_size
= pSmFArrayFormat
->total_size
;
4321 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4325 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4326 total_size
= pLgFArrayFormat
->total_size
;
4327 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4329 safe_buffer_length_increment(pStubMsg
, total_size
);
4331 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4334 /***********************************************************************
4335 * NdrFixedArrayMemorySize [RPCRT4.@]
4337 ULONG WINAPI
NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4338 PFORMAT_STRING pFormat
)
4340 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4343 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4345 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4346 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4348 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4349 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4353 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4355 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4357 total_size
= pSmFArrayFormat
->total_size
;
4358 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4362 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4363 total_size
= pLgFArrayFormat
->total_size
;
4364 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4366 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4367 safe_buffer_increment(pStubMsg
, total_size
);
4368 pStubMsg
->MemorySize
+= total_size
;
4370 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4375 /***********************************************************************
4376 * NdrFixedArrayFree [RPCRT4.@]
4378 void WINAPI
NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4379 unsigned char *pMemory
,
4380 PFORMAT_STRING pFormat
)
4382 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4384 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4386 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4387 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4389 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4390 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4394 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4395 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4398 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4399 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4402 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4405 /***********************************************************************
4406 * NdrVaryingArrayMarshall [RPCRT4.@]
4408 unsigned char * WINAPI
NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4409 unsigned char *pMemory
,
4410 PFORMAT_STRING pFormat
)
4412 unsigned char alignment
;
4413 DWORD elements
, esize
;
4416 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4418 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4419 (pFormat
[0] != RPC_FC_LGVARRAY
))
4421 ERR("invalid format type %x\n", pFormat
[0]);
4422 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4426 alignment
= pFormat
[1] + 1;
4428 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4431 pFormat
+= sizeof(WORD
);
4432 elements
= *(const WORD
*)pFormat
;
4433 pFormat
+= sizeof(WORD
);
4438 pFormat
+= sizeof(DWORD
);
4439 elements
= *(const DWORD
*)pFormat
;
4440 pFormat
+= sizeof(DWORD
);
4443 esize
= *(const WORD
*)pFormat
;
4444 pFormat
+= sizeof(WORD
);
4446 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4447 if ((pStubMsg
->ActualCount
> elements
) ||
4448 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4450 RpcRaiseException(RPC_S_INVALID_BOUND
);
4454 WriteVariance(pStubMsg
);
4456 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
4458 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4459 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4460 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
4462 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4467 /***********************************************************************
4468 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4470 unsigned char * WINAPI
NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4471 unsigned char **ppMemory
,
4472 PFORMAT_STRING pFormat
,
4473 unsigned char fMustAlloc
)
4475 unsigned char alignment
;
4476 DWORD size
, elements
, esize
;
4479 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4481 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4482 (pFormat
[0] != RPC_FC_LGVARRAY
))
4484 ERR("invalid format type %x\n", pFormat
[0]);
4485 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4489 alignment
= pFormat
[1] + 1;
4491 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4494 size
= *(const WORD
*)pFormat
;
4495 pFormat
+= sizeof(WORD
);
4496 elements
= *(const WORD
*)pFormat
;
4497 pFormat
+= sizeof(WORD
);
4502 size
= *(const DWORD
*)pFormat
;
4503 pFormat
+= sizeof(DWORD
);
4504 elements
= *(const DWORD
*)pFormat
;
4505 pFormat
+= sizeof(DWORD
);
4508 esize
= *(const WORD
*)pFormat
;
4509 pFormat
+= sizeof(WORD
);
4511 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
4513 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4515 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4517 if (!*ppMemory
|| fMustAlloc
)
4518 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4519 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4520 safe_copy_from_buffer(pStubMsg
, *ppMemory
+ pStubMsg
->Offset
, bufsize
);
4522 EmbeddedPointerUnmarshall(pStubMsg
, *ppMemory
, *ppMemory
, pFormat
, TRUE
/* FIXME */);
4527 /***********************************************************************
4528 * NdrVaryingArrayBufferSize [RPCRT4.@]
4530 void WINAPI
NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4531 unsigned char *pMemory
,
4532 PFORMAT_STRING pFormat
)
4534 unsigned char alignment
;
4535 DWORD elements
, esize
;
4537 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4539 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4540 (pFormat
[0] != RPC_FC_LGVARRAY
))
4542 ERR("invalid format type %x\n", pFormat
[0]);
4543 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4547 alignment
= pFormat
[1] + 1;
4549 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4552 pFormat
+= sizeof(WORD
);
4553 elements
= *(const WORD
*)pFormat
;
4554 pFormat
+= sizeof(WORD
);
4559 pFormat
+= sizeof(DWORD
);
4560 elements
= *(const DWORD
*)pFormat
;
4561 pFormat
+= sizeof(DWORD
);
4564 esize
= *(const WORD
*)pFormat
;
4565 pFormat
+= sizeof(WORD
);
4567 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4568 if ((pStubMsg
->ActualCount
> elements
) ||
4569 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4571 RpcRaiseException(RPC_S_INVALID_BOUND
);
4575 SizeVariance(pStubMsg
);
4577 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
4579 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
4581 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4584 /***********************************************************************
4585 * NdrVaryingArrayMemorySize [RPCRT4.@]
4587 ULONG WINAPI
NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4588 PFORMAT_STRING pFormat
)
4590 unsigned char alignment
;
4591 DWORD size
, elements
, esize
;
4593 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4595 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4596 (pFormat
[0] != RPC_FC_LGVARRAY
))
4598 ERR("invalid format type %x\n", pFormat
[0]);
4599 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4603 alignment
= pFormat
[1] + 1;
4605 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4608 size
= *(const WORD
*)pFormat
;
4609 pFormat
+= sizeof(WORD
);
4610 elements
= *(const WORD
*)pFormat
;
4611 pFormat
+= sizeof(WORD
);
4616 size
= *(const DWORD
*)pFormat
;
4617 pFormat
+= sizeof(DWORD
);
4618 elements
= *(const DWORD
*)pFormat
;
4619 pFormat
+= sizeof(DWORD
);
4622 esize
= *(const WORD
*)pFormat
;
4623 pFormat
+= sizeof(WORD
);
4625 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
4627 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4629 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
4630 pStubMsg
->MemorySize
+= size
;
4632 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4634 return pStubMsg
->MemorySize
;
4637 /***********************************************************************
4638 * NdrVaryingArrayFree [RPCRT4.@]
4640 void WINAPI
NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4641 unsigned char *pMemory
,
4642 PFORMAT_STRING pFormat
)
4644 unsigned char alignment
;
4647 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4649 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4650 (pFormat
[0] != RPC_FC_LGVARRAY
))
4652 ERR("invalid format type %x\n", pFormat
[0]);
4653 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4657 alignment
= pFormat
[1] + 1;
4659 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4662 pFormat
+= sizeof(WORD
);
4663 elements
= *(const WORD
*)pFormat
;
4664 pFormat
+= sizeof(WORD
);
4669 pFormat
+= sizeof(DWORD
);
4670 elements
= *(const DWORD
*)pFormat
;
4671 pFormat
+= sizeof(DWORD
);
4674 pFormat
+= sizeof(WORD
);
4676 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4677 if ((pStubMsg
->ActualCount
> elements
) ||
4678 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4680 RpcRaiseException(RPC_S_INVALID_BOUND
);
4684 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4687 static ULONG
get_discriminant(unsigned char fc
, const unsigned char *pMemory
)
4695 return *(const UCHAR
*)pMemory
;
4700 return *(const USHORT
*)pMemory
;
4704 return *(const ULONG
*)pMemory
;
4706 FIXME("Unhandled base type: 0x%02x\n", fc
);
4711 static PFORMAT_STRING
get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg
,
4712 unsigned long discriminant
,
4713 PFORMAT_STRING pFormat
)
4715 unsigned short num_arms
, arm
, type
;
4717 num_arms
= *(const SHORT
*)pFormat
& 0x0fff;
4719 for(arm
= 0; arm
< num_arms
; arm
++)
4721 if(discriminant
== *(const ULONG
*)pFormat
)
4729 type
= *(const unsigned short*)pFormat
;
4730 TRACE("type %04x\n", type
);
4731 if(arm
== num_arms
) /* default arm extras */
4735 ERR("no arm for 0x%lx and no default case\n", discriminant
);
4736 RpcRaiseException(RPC_S_INVALID_TAG
);
4741 TRACE("falling back to empty default case for 0x%lx\n", discriminant
);
4748 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
, ULONG discriminant
, PFORMAT_STRING pFormat
)
4750 unsigned short type
;
4754 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4758 type
= *(const unsigned short*)pFormat
;
4759 if((type
& 0xff00) == 0x8000)
4761 unsigned char basetype
= LOBYTE(type
);
4762 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &basetype
);
4766 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4767 NDR_MARSHALL m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
4770 unsigned char *saved_buffer
= NULL
;
4771 int pointer_buffer_mark_set
= 0;
4778 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
4779 saved_buffer
= pStubMsg
->Buffer
;
4780 if (pStubMsg
->PointerBufferMark
)
4782 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4783 pStubMsg
->PointerBufferMark
= NULL
;
4784 pointer_buffer_mark_set
= 1;
4787 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
4789 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char **)pMemory
, desc
);
4790 if (pointer_buffer_mark_set
)
4792 STD_OVERFLOW_CHECK(pStubMsg
);
4793 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4794 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
4796 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
4797 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
4798 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4800 pStubMsg
->Buffer
= saved_buffer
+ 4;
4804 m(pStubMsg
, pMemory
, desc
);
4807 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4812 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4813 unsigned char **ppMemory
,
4815 PFORMAT_STRING pFormat
,
4816 unsigned char fMustAlloc
)
4818 unsigned short type
;
4822 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4826 type
= *(const unsigned short*)pFormat
;
4827 if((type
& 0xff00) == 0x8000)
4829 unsigned char basetype
= LOBYTE(type
);
4830 return NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &basetype
, FALSE
);
4834 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4835 NDR_UNMARSHALL m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
4838 unsigned char *saved_buffer
= NULL
;
4839 int pointer_buffer_mark_set
= 0;
4846 **(void***)ppMemory
= NULL
;
4847 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4848 saved_buffer
= pStubMsg
->Buffer
;
4849 if (pStubMsg
->PointerBufferMark
)
4851 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4852 pStubMsg
->PointerBufferMark
= NULL
;
4853 pointer_buffer_mark_set
= 1;
4856 pStubMsg
->Buffer
+= 4; /* for pointer ID */
4858 if (saved_buffer
+ 4 > pStubMsg
->BufferEnd
)
4860 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
4861 saved_buffer
, pStubMsg
->BufferEnd
);
4862 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4865 PointerUnmarshall(pStubMsg
, saved_buffer
, *(unsigned char ***)ppMemory
, **(unsigned char ***)ppMemory
, desc
, fMustAlloc
);
4866 if (pointer_buffer_mark_set
)
4868 STD_OVERFLOW_CHECK(pStubMsg
);
4869 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4870 pStubMsg
->Buffer
= saved_buffer
+ 4;
4874 m(pStubMsg
, ppMemory
, desc
, fMustAlloc
);
4877 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4882 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg
,
4883 unsigned char *pMemory
,
4885 PFORMAT_STRING pFormat
)
4887 unsigned short type
;
4891 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4895 type
= *(const unsigned short*)pFormat
;
4896 if((type
& 0xff00) == 0x8000)
4898 unsigned char basetype
= LOBYTE(type
);
4899 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &basetype
);
4903 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4904 NDR_BUFFERSIZE m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
4913 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
4914 safe_buffer_length_increment(pStubMsg
, 4); /* for pointer ID */
4915 if (!pStubMsg
->IgnoreEmbeddedPointers
)
4917 int saved_buffer_length
= pStubMsg
->BufferLength
;
4918 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4919 pStubMsg
->PointerLength
= 0;
4920 if(!pStubMsg
->BufferLength
)
4921 ERR("BufferLength == 0??\n");
4922 PointerBufferSize(pStubMsg
, *(unsigned char **)pMemory
, desc
);
4923 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4924 pStubMsg
->BufferLength
= saved_buffer_length
;
4928 m(pStubMsg
, pMemory
, desc
);
4931 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
4935 static ULONG
union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg
,
4937 PFORMAT_STRING pFormat
)
4939 unsigned short type
, size
;
4941 size
= *(const unsigned short*)pFormat
;
4942 pStubMsg
->Memory
+= size
;
4945 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4949 type
= *(const unsigned short*)pFormat
;
4950 if((type
& 0xff00) == 0x8000)
4952 return NdrBaseTypeMemorySize(pStubMsg
, pFormat
);
4956 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4957 NDR_MEMORYSIZE m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
4958 unsigned char *saved_buffer
;
4967 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4968 saved_buffer
= pStubMsg
->Buffer
;
4969 safe_buffer_increment(pStubMsg
, 4);
4970 ALIGN_LENGTH(pStubMsg
->MemorySize
, 4);
4971 pStubMsg
->MemorySize
+= 4;
4972 if (!pStubMsg
->IgnoreEmbeddedPointers
)
4973 PointerMemorySize(pStubMsg
, saved_buffer
, pFormat
);
4976 return m(pStubMsg
, desc
);
4979 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4982 TRACE("size %d\n", size
);
4986 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg
,
4987 unsigned char *pMemory
,
4989 PFORMAT_STRING pFormat
)
4991 unsigned short type
;
4995 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4999 type
= *(const unsigned short*)pFormat
;
5000 if((type
& 0xff00) != 0x8000)
5002 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5003 NDR_FREE m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
5012 PointerFree(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5015 m(pStubMsg
, pMemory
, desc
);
5018 else FIXME("no freer for embedded type %02x\n", *desc
);
5022 /***********************************************************************
5023 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5025 unsigned char * WINAPI
NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5026 unsigned char *pMemory
,
5027 PFORMAT_STRING pFormat
)
5029 unsigned char switch_type
;
5030 unsigned char increment
;
5033 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5036 switch_type
= *pFormat
& 0xf;
5037 increment
= (*pFormat
& 0xf0) >> 4;
5040 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, increment
);
5042 switch_value
= get_discriminant(switch_type
, pMemory
);
5043 TRACE("got switch value 0x%x\n", switch_value
);
5045 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &switch_type
);
5046 pMemory
+= increment
;
5048 return union_arm_marshall(pStubMsg
, pMemory
, switch_value
, pFormat
);
5051 /***********************************************************************
5052 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5054 unsigned char * WINAPI
NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5055 unsigned char **ppMemory
,
5056 PFORMAT_STRING pFormat
,
5057 unsigned char fMustAlloc
)
5059 unsigned char switch_type
;
5060 unsigned char increment
;
5062 unsigned short size
;
5063 unsigned char *pMemoryArm
;
5065 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5068 switch_type
= *pFormat
& 0xf;
5069 increment
= (*pFormat
& 0xf0) >> 4;
5072 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
5073 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
5074 TRACE("got switch value 0x%x\n", switch_value
);
5076 size
= *(const unsigned short*)pFormat
+ increment
;
5077 if(!*ppMemory
|| fMustAlloc
)
5078 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5080 NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &switch_type
, FALSE
);
5081 pMemoryArm
= *ppMemory
+ increment
;
5083 return union_arm_unmarshall(pStubMsg
, &pMemoryArm
, switch_value
, pFormat
, fMustAlloc
);
5086 /***********************************************************************
5087 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5089 void WINAPI
NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5090 unsigned char *pMemory
,
5091 PFORMAT_STRING pFormat
)
5093 unsigned char switch_type
;
5094 unsigned char increment
;
5097 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5100 switch_type
= *pFormat
& 0xf;
5101 increment
= (*pFormat
& 0xf0) >> 4;
5104 ALIGN_LENGTH(pStubMsg
->BufferLength
, increment
);
5105 switch_value
= get_discriminant(switch_type
, pMemory
);
5106 TRACE("got switch value 0x%x\n", switch_value
);
5108 /* Add discriminant size */
5109 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&switch_value
, &switch_type
);
5110 pMemory
+= increment
;
5112 union_arm_buffer_size(pStubMsg
, pMemory
, switch_value
, pFormat
);
5115 /***********************************************************************
5116 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5118 ULONG WINAPI
NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5119 PFORMAT_STRING pFormat
)
5121 unsigned char switch_type
;
5122 unsigned char increment
;
5125 switch_type
= *pFormat
& 0xf;
5126 increment
= (*pFormat
& 0xf0) >> 4;
5129 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
5130 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
5131 TRACE("got switch value 0x%x\n", switch_value
);
5133 pStubMsg
->Memory
+= increment
;
5135 return increment
+ union_arm_memory_size(pStubMsg
, switch_value
, pFormat
+ *(const SHORT
*)pFormat
);
5138 /***********************************************************************
5139 * NdrEncapsulatedUnionFree [RPCRT4.@]
5141 void WINAPI
NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
5142 unsigned char *pMemory
,
5143 PFORMAT_STRING pFormat
)
5145 unsigned char switch_type
;
5146 unsigned char increment
;
5149 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5152 switch_type
= *pFormat
& 0xf;
5153 increment
= (*pFormat
& 0xf0) >> 4;
5156 switch_value
= get_discriminant(switch_type
, pMemory
);
5157 TRACE("got switch value 0x%x\n", switch_value
);
5159 pMemory
+= increment
;
5161 return union_arm_free(pStubMsg
, pMemory
, switch_value
, pFormat
);
5164 /***********************************************************************
5165 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5167 unsigned char * WINAPI
NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5168 unsigned char *pMemory
,
5169 PFORMAT_STRING pFormat
)
5171 unsigned char switch_type
;
5173 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5176 switch_type
= *pFormat
;
5179 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5180 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5181 /* Marshall discriminant */
5182 NdrBaseTypeMarshall(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
5184 return union_arm_marshall(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5187 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg
,
5188 PFORMAT_STRING
*ppFormat
)
5190 long discriminant
= 0;
5200 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5209 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5210 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5218 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
5219 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5224 FIXME("Unhandled base type: 0x%02x\n", **ppFormat
);
5228 if (pStubMsg
->fHasNewCorrDesc
)
5232 return discriminant
;
5235 /**********************************************************************
5236 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5238 unsigned char * WINAPI
NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5239 unsigned char **ppMemory
,
5240 PFORMAT_STRING pFormat
,
5241 unsigned char fMustAlloc
)
5244 unsigned short size
;
5246 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5249 /* Unmarshall discriminant */
5250 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
5251 TRACE("unmarshalled discriminant %lx\n", discriminant
);
5253 pFormat
+= *(const SHORT
*)pFormat
;
5255 size
= *(const unsigned short*)pFormat
;
5257 if(!*ppMemory
|| fMustAlloc
)
5258 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5260 return union_arm_unmarshall(pStubMsg
, ppMemory
, discriminant
, pFormat
, fMustAlloc
);
5263 /***********************************************************************
5264 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5266 void WINAPI
NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5267 unsigned char *pMemory
,
5268 PFORMAT_STRING pFormat
)
5270 unsigned char switch_type
;
5272 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5275 switch_type
= *pFormat
;
5278 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5279 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5280 /* Add discriminant size */
5281 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
5283 union_arm_buffer_size(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5286 /***********************************************************************
5287 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5289 ULONG WINAPI
NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5290 PFORMAT_STRING pFormat
)
5295 /* Unmarshall discriminant */
5296 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
5297 TRACE("unmarshalled discriminant 0x%x\n", discriminant
);
5299 return union_arm_memory_size(pStubMsg
, discriminant
, pFormat
+ *(const SHORT
*)pFormat
);
5302 /***********************************************************************
5303 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5305 void WINAPI
NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
5306 unsigned char *pMemory
,
5307 PFORMAT_STRING pFormat
)
5309 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5313 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5314 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5316 return union_arm_free(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5319 /***********************************************************************
5320 * NdrByteCountPointerMarshall [RPCRT4.@]
5322 unsigned char * WINAPI
NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5323 unsigned char *pMemory
,
5324 PFORMAT_STRING pFormat
)
5330 /***********************************************************************
5331 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5333 unsigned char * WINAPI
NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5334 unsigned char **ppMemory
,
5335 PFORMAT_STRING pFormat
,
5336 unsigned char fMustAlloc
)
5342 /***********************************************************************
5343 * NdrByteCountPointerBufferSize [RPCRT4.@]
5345 void WINAPI
NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5346 unsigned char *pMemory
,
5347 PFORMAT_STRING pFormat
)
5352 /***********************************************************************
5353 * NdrByteCountPointerMemorySize [RPCRT4.@]
5355 ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5356 PFORMAT_STRING pFormat
)
5362 /***********************************************************************
5363 * NdrByteCountPointerFree [RPCRT4.@]
5365 void WINAPI
NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
5366 unsigned char *pMemory
,
5367 PFORMAT_STRING pFormat
)
5372 /***********************************************************************
5373 * NdrXmitOrRepAsMarshall [RPCRT4.@]
5375 unsigned char * WINAPI
NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5376 unsigned char *pMemory
,
5377 PFORMAT_STRING pFormat
)
5383 /***********************************************************************
5384 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
5386 unsigned char * WINAPI
NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5387 unsigned char **ppMemory
,
5388 PFORMAT_STRING pFormat
,
5389 unsigned char fMustAlloc
)
5395 /***********************************************************************
5396 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
5398 void WINAPI
NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5399 unsigned char *pMemory
,
5400 PFORMAT_STRING pFormat
)
5405 /***********************************************************************
5406 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
5408 ULONG WINAPI
NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5409 PFORMAT_STRING pFormat
)
5415 /***********************************************************************
5416 * NdrXmitOrRepAsFree [RPCRT4.@]
5418 void WINAPI
NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg
,
5419 unsigned char *pMemory
,
5420 PFORMAT_STRING pFormat
)
5425 #include "pshpack1.h"
5429 unsigned char flags_type
; /* flags in upper nibble, type in lower nibble */
5433 #include "poppack.h"
5435 /***********************************************************************
5436 * NdrRangeMarshall [internal]
5438 unsigned char *WINAPI
NdrRangeMarshall(
5439 PMIDL_STUB_MESSAGE pStubMsg
,
5440 unsigned char *pMemory
,
5441 PFORMAT_STRING pFormat
)
5443 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5444 unsigned char base_type
;
5446 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5448 if (pRange
->type
!= RPC_FC_RANGE
)
5450 ERR("invalid format type %x\n", pRange
->type
);
5451 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5455 base_type
= pRange
->flags_type
& 0xf;
5457 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &base_type
);
5460 /***********************************************************************
5461 * NdrRangeUnmarshall
5463 unsigned char *WINAPI
NdrRangeUnmarshall(
5464 PMIDL_STUB_MESSAGE pStubMsg
,
5465 unsigned char **ppMemory
,
5466 PFORMAT_STRING pFormat
,
5467 unsigned char fMustAlloc
)
5469 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5470 unsigned char base_type
;
5472 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
5474 if (pRange
->type
!= RPC_FC_RANGE
)
5476 ERR("invalid format type %x\n", pRange
->type
);
5477 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5480 base_type
= pRange
->flags_type
& 0xf;
5482 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5483 base_type
, pRange
->low_value
, pRange
->high_value
);
5485 #define RANGE_UNMARSHALL(type, format_spec) \
5488 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5489 if (fMustAlloc || !*ppMemory) \
5490 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5491 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
5493 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
5494 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
5495 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
5497 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5498 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5500 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5501 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5502 (type)pRange->high_value); \
5503 RpcRaiseException(RPC_S_INVALID_BOUND); \
5506 TRACE("*ppMemory: %p\n", *ppMemory); \
5507 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5508 pStubMsg->Buffer += sizeof(type); \
5515 RANGE_UNMARSHALL(UCHAR
, "%d");
5516 TRACE("value: 0x%02x\n", **(UCHAR
**)ppMemory
);
5520 RANGE_UNMARSHALL(CHAR
, "%u");
5521 TRACE("value: 0x%02x\n", **(UCHAR
**)ppMemory
);
5523 case RPC_FC_WCHAR
: /* FIXME: valid? */
5525 RANGE_UNMARSHALL(USHORT
, "%u");
5526 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5529 RANGE_UNMARSHALL(SHORT
, "%d");
5530 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5533 RANGE_UNMARSHALL(LONG
, "%d");
5534 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5537 RANGE_UNMARSHALL(ULONG
, "%u");
5538 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5542 FIXME("Unhandled enum type\n");
5544 case RPC_FC_ERROR_STATUS_T
: /* FIXME: valid? */
5549 ERR("invalid range base type: 0x%02x\n", base_type
);
5550 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5556 /***********************************************************************
5557 * NdrRangeBufferSize [internal]
5559 void WINAPI
NdrRangeBufferSize(
5560 PMIDL_STUB_MESSAGE pStubMsg
,
5561 unsigned char *pMemory
,
5562 PFORMAT_STRING pFormat
)
5564 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5565 unsigned char base_type
;
5567 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5569 if (pRange
->type
!= RPC_FC_RANGE
)
5571 ERR("invalid format type %x\n", pRange
->type
);
5572 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5574 base_type
= pRange
->flags_type
& 0xf;
5576 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &base_type
);
5579 /***********************************************************************
5580 * NdrRangeMemorySize [internal]
5582 ULONG WINAPI
NdrRangeMemorySize(
5583 PMIDL_STUB_MESSAGE pStubMsg
,
5584 PFORMAT_STRING pFormat
)
5586 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5587 unsigned char base_type
;
5589 if (pRange
->type
!= RPC_FC_RANGE
)
5591 ERR("invalid format type %x\n", pRange
->type
);
5592 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5595 base_type
= pRange
->flags_type
& 0xf;
5597 return NdrBaseTypeMemorySize(pStubMsg
, &base_type
);
5600 /***********************************************************************
5601 * NdrRangeFree [internal]
5603 void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg
,
5604 unsigned char *pMemory
,
5605 PFORMAT_STRING pFormat
)
5607 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5612 /***********************************************************************
5613 * NdrBaseTypeMarshall [internal]
5615 static unsigned char *WINAPI
NdrBaseTypeMarshall(
5616 PMIDL_STUB_MESSAGE pStubMsg
,
5617 unsigned char *pMemory
,
5618 PFORMAT_STRING pFormat
)
5620 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5628 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(UCHAR
));
5629 TRACE("value: 0x%02x\n", *(UCHAR
*)pMemory
);
5634 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(USHORT
));
5635 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(USHORT
));
5636 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
5640 case RPC_FC_ERROR_STATUS_T
:
5642 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(ULONG
));
5643 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONG
));
5644 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
5647 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(float));
5648 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
5651 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(double));
5652 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
5655 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(ULONGLONG
));
5656 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONGLONG
));
5657 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
5660 /* only 16-bits on the wire, so do a sanity check */
5661 if (*(UINT
*)pMemory
> SHRT_MAX
)
5662 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
5663 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(USHORT
));
5664 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5665 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5666 *(USHORT
*)pStubMsg
->Buffer
= *(UINT
*)pMemory
;
5667 pStubMsg
->Buffer
+= sizeof(USHORT
);
5668 TRACE("value: 0x%04x\n", *(UINT
*)pMemory
);
5673 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5676 /* FIXME: what is the correct return value? */
5680 /***********************************************************************
5681 * NdrBaseTypeUnmarshall [internal]
5683 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(
5684 PMIDL_STUB_MESSAGE pStubMsg
,
5685 unsigned char **ppMemory
,
5686 PFORMAT_STRING pFormat
,
5687 unsigned char fMustAlloc
)
5689 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
5691 #define BASE_TYPE_UNMARSHALL(type) \
5692 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5693 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
5695 *ppMemory = pStubMsg->Buffer; \
5696 TRACE("*ppMemory: %p\n", *ppMemory); \
5701 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5702 TRACE("*ppMemory: %p\n", *ppMemory); \
5703 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5705 pStubMsg->Buffer += sizeof(type);
5713 BASE_TYPE_UNMARSHALL(UCHAR
);
5714 TRACE("value: 0x%02x\n", **(UCHAR
**)ppMemory
);
5719 BASE_TYPE_UNMARSHALL(USHORT
);
5720 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5724 case RPC_FC_ERROR_STATUS_T
:
5726 BASE_TYPE_UNMARSHALL(ULONG
);
5727 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5730 BASE_TYPE_UNMARSHALL(float);
5731 TRACE("value: %f\n", **(float **)ppMemory
);
5734 BASE_TYPE_UNMARSHALL(double);
5735 TRACE("value: %f\n", **(double **)ppMemory
);
5738 BASE_TYPE_UNMARSHALL(ULONGLONG
);
5739 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG
**)ppMemory
));
5742 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5743 if (fMustAlloc
|| !*ppMemory
)
5744 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT
));
5745 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > pStubMsg
->BufferEnd
)
5746 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5747 TRACE("*ppMemory: %p\n", *ppMemory
);
5748 /* 16-bits on the wire, but int in memory */
5749 **(UINT
**)ppMemory
= *(USHORT
*)pStubMsg
->Buffer
;
5750 pStubMsg
->Buffer
+= sizeof(USHORT
);
5751 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
5756 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5758 #undef BASE_TYPE_UNMARSHALL
5760 /* FIXME: what is the correct return value? */
5765 /***********************************************************************
5766 * NdrBaseTypeBufferSize [internal]
5768 static void WINAPI
NdrBaseTypeBufferSize(
5769 PMIDL_STUB_MESSAGE pStubMsg
,
5770 unsigned char *pMemory
,
5771 PFORMAT_STRING pFormat
)
5773 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5781 safe_buffer_length_increment(pStubMsg
, sizeof(UCHAR
));
5787 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(USHORT
));
5788 safe_buffer_length_increment(pStubMsg
, sizeof(USHORT
));
5793 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONG
));
5794 safe_buffer_length_increment(pStubMsg
, sizeof(ULONG
));
5797 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(float));
5798 safe_buffer_length_increment(pStubMsg
, sizeof(float));
5801 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(double));
5802 safe_buffer_length_increment(pStubMsg
, sizeof(double));
5805 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONGLONG
));
5806 safe_buffer_length_increment(pStubMsg
, sizeof(ULONGLONG
));
5808 case RPC_FC_ERROR_STATUS_T
:
5809 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(error_status_t
));
5810 safe_buffer_length_increment(pStubMsg
, sizeof(error_status_t
));
5815 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5819 /***********************************************************************
5820 * NdrBaseTypeMemorySize [internal]
5822 static ULONG WINAPI
NdrBaseTypeMemorySize(
5823 PMIDL_STUB_MESSAGE pStubMsg
,
5824 PFORMAT_STRING pFormat
)
5826 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg
, *pFormat
);
5834 safe_buffer_increment(pStubMsg
, sizeof(UCHAR
));
5835 pStubMsg
->MemorySize
+= sizeof(UCHAR
);
5836 return sizeof(UCHAR
);
5840 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
5841 pStubMsg
->MemorySize
+= sizeof(USHORT
);
5842 return sizeof(USHORT
);
5846 safe_buffer_increment(pStubMsg
, sizeof(ULONG
));
5847 pStubMsg
->MemorySize
+= sizeof(ULONG
);
5848 return sizeof(ULONG
);
5850 safe_buffer_increment(pStubMsg
, sizeof(float));
5851 pStubMsg
->MemorySize
+= sizeof(float);
5852 return sizeof(float);
5854 safe_buffer_increment(pStubMsg
, sizeof(double));
5855 pStubMsg
->MemorySize
+= sizeof(double);
5856 return sizeof(double);
5858 safe_buffer_increment(pStubMsg
, sizeof(ULONGLONG
));
5859 pStubMsg
->MemorySize
+= sizeof(ULONGLONG
);
5860 return sizeof(ULONGLONG
);
5861 case RPC_FC_ERROR_STATUS_T
:
5862 safe_buffer_increment(pStubMsg
, sizeof(error_status_t
));
5863 pStubMsg
->MemorySize
+= sizeof(error_status_t
);
5864 return sizeof(error_status_t
);
5866 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
5867 pStubMsg
->MemorySize
+= sizeof(UINT
);
5868 return sizeof(UINT
);
5870 pStubMsg
->MemorySize
+= sizeof(void *);
5871 return sizeof(void *);
5873 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5878 /***********************************************************************
5879 * NdrBaseTypeFree [internal]
5881 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg
,
5882 unsigned char *pMemory
,
5883 PFORMAT_STRING pFormat
)
5885 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5890 /***********************************************************************
5891 * NdrContextHandleBufferSize [internal]
5893 static void WINAPI
NdrContextHandleBufferSize(
5894 PMIDL_STUB_MESSAGE pStubMsg
,
5895 unsigned char *pMemory
,
5896 PFORMAT_STRING pFormat
)
5898 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5900 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
5902 ERR("invalid format type %x\n", *pFormat
);
5903 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5905 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
5906 safe_buffer_length_increment(pStubMsg
, cbNDRContext
);
5909 /***********************************************************************
5910 * NdrContextHandleMarshall [internal]
5912 static unsigned char *WINAPI
NdrContextHandleMarshall(
5913 PMIDL_STUB_MESSAGE pStubMsg
,
5914 unsigned char *pMemory
,
5915 PFORMAT_STRING pFormat
)
5917 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5919 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
5921 ERR("invalid format type %x\n", *pFormat
);
5922 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5925 if (pFormat
[1] & 0x80)
5926 NdrClientContextMarshall(pStubMsg
, *(NDR_CCONTEXT
**)pMemory
, FALSE
);
5928 NdrClientContextMarshall(pStubMsg
, (NDR_CCONTEXT
*)pMemory
, FALSE
);
5933 /***********************************************************************
5934 * NdrContextHandleUnmarshall [internal]
5936 static unsigned char *WINAPI
NdrContextHandleUnmarshall(
5937 PMIDL_STUB_MESSAGE pStubMsg
,
5938 unsigned char **ppMemory
,
5939 PFORMAT_STRING pFormat
,
5940 unsigned char fMustAlloc
)
5942 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
5944 ERR("invalid format type %x\n", *pFormat
);
5945 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5948 **(NDR_CCONTEXT
**)ppMemory
= NULL
;
5949 NdrClientContextUnmarshall(pStubMsg
, *(NDR_CCONTEXT
**)ppMemory
, pStubMsg
->RpcMsg
->Handle
);
5954 /***********************************************************************
5955 * NdrClientContextMarshall [RPCRT4.@]
5957 void WINAPI
NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5958 NDR_CCONTEXT ContextHandle
,
5961 TRACE("(%p, %p, %d)\n", pStubMsg
, ContextHandle
, fCheck
);
5963 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
5965 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5967 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
5968 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
5969 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5972 /* FIXME: what does fCheck do? */
5973 NDRCContextMarshall(ContextHandle
,
5976 pStubMsg
->Buffer
+= cbNDRContext
;
5979 /***********************************************************************
5980 * NdrClientContextUnmarshall [RPCRT4.@]
5982 void WINAPI
NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5983 NDR_CCONTEXT
* pContextHandle
,
5984 RPC_BINDING_HANDLE BindHandle
)
5986 TRACE("(%p, %p, %p)\n", pStubMsg
, pContextHandle
, BindHandle
);
5988 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5990 if (pStubMsg
->Buffer
+ cbNDRContext
> pStubMsg
->BufferEnd
)
5991 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5993 NDRCContextUnmarshall(pContextHandle
,
5996 pStubMsg
->RpcMsg
->DataRepresentation
);
5998 pStubMsg
->Buffer
+= cbNDRContext
;
6001 void WINAPI
NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6002 NDR_SCONTEXT ContextHandle
,
6003 NDR_RUNDOWN RundownRoutine
)
6005 FIXME("(%p, %p, %p): stub\n", pStubMsg
, ContextHandle
, RundownRoutine
);
6008 NDR_SCONTEXT WINAPI
NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
)
6010 FIXME("(%p): stub\n", pStubMsg
);
6014 void WINAPI
NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg
,
6015 unsigned char* pMemory
,
6016 PFORMAT_STRING pFormat
)
6018 FIXME("(%p, %p, %p): stub\n", pStubMsg
, pMemory
, pFormat
);
6021 NDR_SCONTEXT WINAPI
NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg
,
6022 PFORMAT_STRING pFormat
)
6024 FIXME("(%p, %p): stub\n", pStubMsg
, pFormat
);
6028 void WINAPI
NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6029 NDR_SCONTEXT ContextHandle
,
6030 NDR_RUNDOWN RundownRoutine
,
6031 PFORMAT_STRING pFormat
)
6033 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg
, ContextHandle
, RundownRoutine
, pFormat
);
6036 NDR_SCONTEXT WINAPI
NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6037 PFORMAT_STRING pFormat
)
6039 FIXME("(%p, %p): stub\n", pStubMsg
, pFormat
);
6043 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
6045 typedef struct ndr_context_handle
6049 } ndr_context_handle
;
6051 struct context_handle_entry
6055 RPC_BINDING_HANDLE handle
;
6056 ndr_context_handle wire_data
;
6059 static struct list context_handle_list
= LIST_INIT(context_handle_list
);
6061 static CRITICAL_SECTION ndr_context_cs
;
6062 static CRITICAL_SECTION_DEBUG ndr_context_debug
=
6064 0, 0, &ndr_context_cs
,
6065 { &ndr_context_debug
.ProcessLocksList
, &ndr_context_debug
.ProcessLocksList
},
6066 0, 0, { (DWORD_PTR
)(__FILE__
": ndr_context") }
6068 static CRITICAL_SECTION ndr_context_cs
= { &ndr_context_debug
, -1, 0, 0, 0, 0 };
6070 static struct context_handle_entry
*get_context_entry(NDR_CCONTEXT CContext
)
6072 struct context_handle_entry
*che
= (struct context_handle_entry
*) CContext
;
6074 if (che
->magic
!= NDR_CONTEXT_HANDLE_MAGIC
)
6079 static struct context_handle_entry
*context_entry_from_guid(LPCGUID uuid
)
6081 struct context_handle_entry
*che
;
6082 LIST_FOR_EACH_ENTRY(che
, &context_handle_list
, struct context_handle_entry
, entry
)
6083 if (IsEqualGUID(&che
->wire_data
.uuid
, uuid
))
6088 RPC_BINDING_HANDLE WINAPI
NDRCContextBinding(NDR_CCONTEXT CContext
)
6090 struct context_handle_entry
*che
;
6091 RPC_BINDING_HANDLE handle
= NULL
;
6093 TRACE("%p\n", CContext
);
6095 EnterCriticalSection(&ndr_context_cs
);
6096 che
= get_context_entry(CContext
);
6098 handle
= che
->handle
;
6099 LeaveCriticalSection(&ndr_context_cs
);
6102 RpcRaiseException(ERROR_INVALID_HANDLE
);
6106 void WINAPI
NDRCContextMarshall(NDR_CCONTEXT CContext
, void *pBuff
)
6108 struct context_handle_entry
*che
;
6110 TRACE("%p %p\n", CContext
, pBuff
);
6114 EnterCriticalSection(&ndr_context_cs
);
6115 che
= get_context_entry(CContext
);
6116 memcpy(pBuff
, &che
->wire_data
, sizeof (ndr_context_handle
));
6117 LeaveCriticalSection(&ndr_context_cs
);
6121 ndr_context_handle
*wire_data
= (ndr_context_handle
*)pBuff
;
6122 wire_data
->attributes
= 0;
6123 wire_data
->uuid
= GUID_NULL
;
6127 /***********************************************************************
6128 * RpcSmDestroyClientContext [RPCRT4.@]
6130 RPC_STATUS WINAPI
RpcSmDestroyClientContext(void **ContextHandle
)
6132 RPC_STATUS status
= RPC_X_SS_CONTEXT_MISMATCH
;
6133 struct context_handle_entry
*che
= NULL
;
6135 TRACE("(%p)\n", ContextHandle
);
6137 EnterCriticalSection(&ndr_context_cs
);
6138 che
= get_context_entry(*ContextHandle
);
6139 *ContextHandle
= NULL
;
6143 list_remove(&che
->entry
);
6146 LeaveCriticalSection(&ndr_context_cs
);
6150 RpcBindingFree(&che
->handle
);
6151 HeapFree(GetProcessHeap(), 0, che
);
6157 /***********************************************************************
6158 * RpcSsDestroyClientContext [RPCRT4.@]
6160 void WINAPI
RpcSsDestroyClientContext(void **ContextHandle
)
6162 RPC_STATUS status
= RpcSmDestroyClientContext(ContextHandle
);
6163 if (status
!= RPC_S_OK
)
6164 RpcRaiseException(status
);
6167 static UINT
ndr_update_context_handle(NDR_CCONTEXT
*CContext
,
6168 RPC_BINDING_HANDLE hBinding
,
6169 const ndr_context_handle
*chi
)
6171 struct context_handle_entry
*che
= NULL
;
6173 /* a null UUID means we should free the context handle */
6174 if (IsEqualGUID(&chi
->uuid
, &GUID_NULL
))
6178 che
= get_context_entry(*CContext
);
6180 return ERROR_INVALID_HANDLE
;
6181 list_remove(&che
->entry
);
6182 RpcBindingFree(&che
->handle
);
6183 HeapFree(GetProcessHeap(), 0, che
);
6187 /* if there's no existing entry matching the GUID, allocate one */
6188 else if (!(che
= context_entry_from_guid(&chi
->uuid
)))
6190 che
= HeapAlloc(GetProcessHeap(), 0, sizeof *che
);
6192 return ERROR_NOT_ENOUGH_MEMORY
;
6193 che
->magic
= NDR_CONTEXT_HANDLE_MAGIC
;
6194 RpcBindingCopy(hBinding
, &che
->handle
);
6195 list_add_tail(&context_handle_list
, &che
->entry
);
6196 memcpy(&che
->wire_data
, chi
, sizeof *chi
);
6201 return ERROR_SUCCESS
;
6204 /***********************************************************************
6205 * NDRCContextUnmarshall [RPCRT4.@]
6207 void WINAPI
NDRCContextUnmarshall(NDR_CCONTEXT
*CContext
,
6208 RPC_BINDING_HANDLE hBinding
,
6209 void *pBuff
, ULONG DataRepresentation
)
6213 TRACE("*%p=(%p) %p %p %08x\n",
6214 CContext
, *CContext
, hBinding
, pBuff
, DataRepresentation
);
6216 EnterCriticalSection(&ndr_context_cs
);
6217 r
= ndr_update_context_handle(CContext
, hBinding
, pBuff
);
6218 LeaveCriticalSection(&ndr_context_cs
);
6220 RpcRaiseException(r
);
6223 /***********************************************************************
6224 * NDRSContextMarshall [RPCRT4.@]
6226 void WINAPI
NDRSContextMarshall(NDR_SCONTEXT CContext
,
6228 NDR_RUNDOWN userRunDownIn
)
6230 FIXME("(%p %p %p): stub\n", CContext
, pBuff
, userRunDownIn
);
6233 /***********************************************************************
6234 * NDRSContextMarshallEx [RPCRT4.@]
6236 void WINAPI
NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding
,
6237 NDR_SCONTEXT CContext
,
6239 NDR_RUNDOWN userRunDownIn
)
6241 FIXME("(%p %p %p %p): stub\n", hBinding
, CContext
, pBuff
, userRunDownIn
);
6244 /***********************************************************************
6245 * NDRSContextMarshall2 [RPCRT4.@]
6247 void WINAPI
NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding
,
6248 NDR_SCONTEXT CContext
,
6250 NDR_RUNDOWN userRunDownIn
,
6251 void *CtxGuard
, ULONG Flags
)
6253 FIXME("(%p %p %p %p %p %u): stub\n",
6254 hBinding
, CContext
, pBuff
, userRunDownIn
, CtxGuard
, Flags
);
6257 /***********************************************************************
6258 * NDRSContextUnmarshall [RPCRT4.@]
6260 NDR_SCONTEXT WINAPI
NDRSContextUnmarshall(void *pBuff
,
6261 ULONG DataRepresentation
)
6263 FIXME("(%p %08x): stub\n", pBuff
, DataRepresentation
);
6267 /***********************************************************************
6268 * NDRSContextUnmarshallEx [RPCRT4.@]
6270 NDR_SCONTEXT WINAPI
NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding
,
6272 ULONG DataRepresentation
)
6274 FIXME("(%p %p %08x): stub\n", hBinding
, pBuff
, DataRepresentation
);
6278 /***********************************************************************
6279 * NDRSContextUnmarshall2 [RPCRT4.@]
6281 NDR_SCONTEXT WINAPI
NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding
,
6283 ULONG DataRepresentation
,
6284 void *CtxGuard
, ULONG Flags
)
6286 FIXME("(%p %p %08x %p %u): stub\n",
6287 hBinding
, pBuff
, DataRepresentation
, CtxGuard
, Flags
);