4 * Copyright 2002 Greg Turner
5 * Copyright 2003-2006 CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 * - Byte count pointers
24 * - transmit_as/represent as
25 * - Multi-dimensional arrays
26 * - Conversion functions (NdrConvert)
27 * - Checks for integer addition overflow in user marshall functions
35 #define NONAMELESSUNION
43 #include "wine/unicode.h"
44 #include "wine/rpcfc.h"
46 #include "wine/debug.h"
48 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
51 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
52 (*((UINT32 *)(pchar)) = (uint32))
54 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
55 (*((UINT32 *)(pchar)))
57 /* these would work for i386 too, but less efficient */
58 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
59 (*(pchar) = LOBYTE(LOWORD(uint32)), \
60 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
61 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
62 *((pchar)+3) = HIBYTE(HIWORD(uint32)))
64 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
66 MAKEWORD(*(pchar), *((pchar)+1)), \
67 MAKEWORD(*((pchar)+2), *((pchar)+3))))
70 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
71 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
72 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
73 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
74 *(pchar) = HIBYTE(HIWORD(uint32)))
76 #define BIG_ENDIAN_UINT32_READ(pchar) \
78 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
79 MAKEWORD(*((pchar)+1), *(pchar))))
81 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
82 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
83 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
84 # define NDR_LOCAL_UINT32_READ(pchar) \
85 BIG_ENDIAN_UINT32_READ(pchar)
87 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
88 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
89 # define NDR_LOCAL_UINT32_READ(pchar) \
90 LITTLE_ENDIAN_UINT32_READ(pchar)
93 /* _Align must be the desired alignment,
94 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
95 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
96 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
97 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
98 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
99 #define ALIGN_POINTER_CLEAR(_Ptr, _Align) \
101 memset((_Ptr), 0, ((_Align) - (ULONG_PTR)(_Ptr)) & ((_Align) - 1)); \
102 ALIGN_POINTER(_Ptr, _Align); \
105 #define STD_OVERFLOW_CHECK(_Msg) do { \
106 TRACE("buffer=%d/%d\n", (ULONG)(_Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer), _Msg->BufferLength); \
107 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
108 ERR("buffer overflow %d bytes\n", (ULONG)(_Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength))); \
111 #define NDR_POINTER_ID_BASE 0x20000
112 #define NDR_POINTER_ID(pStubMsg) (NDR_POINTER_ID_BASE + ((pStubMsg)->UniquePtrCount++) * 4)
113 #define NDR_TABLE_SIZE 128
114 #define NDR_TABLE_MASK 127
116 static unsigned char *WINAPI
NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
117 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
118 static void WINAPI
NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
119 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
120 static ULONG WINAPI
NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
122 static unsigned char *WINAPI
NdrContextHandleMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
123 static void WINAPI
NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
124 static unsigned char *WINAPI
NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
126 static unsigned char *WINAPI
NdrRangeMarshall(PMIDL_STUB_MESSAGE
,unsigned char *, PFORMAT_STRING
);
127 static void WINAPI
NdrRangeBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
128 static ULONG WINAPI
NdrRangeMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
129 static void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
131 static ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
133 const NDR_MARSHALL NdrMarshaller
[NDR_TABLE_SIZE
] = {
135 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
136 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
137 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
138 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
142 NdrPointerMarshall
, NdrPointerMarshall
,
143 NdrPointerMarshall
, NdrPointerMarshall
,
145 NdrSimpleStructMarshall
, NdrSimpleStructMarshall
,
146 NdrConformantStructMarshall
, NdrConformantStructMarshall
,
147 NdrConformantVaryingStructMarshall
,
148 NdrComplexStructMarshall
,
150 NdrConformantArrayMarshall
,
151 NdrConformantVaryingArrayMarshall
,
152 NdrFixedArrayMarshall
, NdrFixedArrayMarshall
,
153 NdrVaryingArrayMarshall
, NdrVaryingArrayMarshall
,
154 NdrComplexArrayMarshall
,
156 NdrConformantStringMarshall
, 0, 0,
157 NdrConformantStringMarshall
,
158 NdrNonConformantStringMarshall
, 0, 0, 0,
160 NdrEncapsulatedUnionMarshall
,
161 NdrNonEncapsulatedUnionMarshall
,
162 NdrByteCountPointerMarshall
,
163 NdrXmitOrRepAsMarshall
, NdrXmitOrRepAsMarshall
,
165 NdrInterfacePointerMarshall
,
167 NdrContextHandleMarshall
,
170 NdrUserMarshalMarshall
,
175 const NDR_UNMARSHALL NdrUnmarshaller
[NDR_TABLE_SIZE
] = {
177 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
178 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
179 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
180 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
182 NdrBaseTypeUnmarshall
,
184 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
185 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
187 NdrSimpleStructUnmarshall
, NdrSimpleStructUnmarshall
,
188 NdrConformantStructUnmarshall
, NdrConformantStructUnmarshall
,
189 NdrConformantVaryingStructUnmarshall
,
190 NdrComplexStructUnmarshall
,
192 NdrConformantArrayUnmarshall
,
193 NdrConformantVaryingArrayUnmarshall
,
194 NdrFixedArrayUnmarshall
, NdrFixedArrayUnmarshall
,
195 NdrVaryingArrayUnmarshall
, NdrVaryingArrayUnmarshall
,
196 NdrComplexArrayUnmarshall
,
198 NdrConformantStringUnmarshall
, 0, 0,
199 NdrConformantStringUnmarshall
,
200 NdrNonConformantStringUnmarshall
, 0, 0, 0,
202 NdrEncapsulatedUnionUnmarshall
,
203 NdrNonEncapsulatedUnionUnmarshall
,
204 NdrByteCountPointerUnmarshall
,
205 NdrXmitOrRepAsUnmarshall
, NdrXmitOrRepAsUnmarshall
,
207 NdrInterfacePointerUnmarshall
,
209 NdrContextHandleUnmarshall
,
212 NdrUserMarshalUnmarshall
,
217 const NDR_BUFFERSIZE NdrBufferSizer
[NDR_TABLE_SIZE
] = {
219 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
220 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
221 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
222 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
224 NdrBaseTypeBufferSize
,
226 NdrPointerBufferSize
, NdrPointerBufferSize
,
227 NdrPointerBufferSize
, NdrPointerBufferSize
,
229 NdrSimpleStructBufferSize
, NdrSimpleStructBufferSize
,
230 NdrConformantStructBufferSize
, NdrConformantStructBufferSize
,
231 NdrConformantVaryingStructBufferSize
,
232 NdrComplexStructBufferSize
,
234 NdrConformantArrayBufferSize
,
235 NdrConformantVaryingArrayBufferSize
,
236 NdrFixedArrayBufferSize
, NdrFixedArrayBufferSize
,
237 NdrVaryingArrayBufferSize
, NdrVaryingArrayBufferSize
,
238 NdrComplexArrayBufferSize
,
240 NdrConformantStringBufferSize
, 0, 0,
241 NdrConformantStringBufferSize
,
242 NdrNonConformantStringBufferSize
, 0, 0, 0,
244 NdrEncapsulatedUnionBufferSize
,
245 NdrNonEncapsulatedUnionBufferSize
,
246 NdrByteCountPointerBufferSize
,
247 NdrXmitOrRepAsBufferSize
, NdrXmitOrRepAsBufferSize
,
249 NdrInterfacePointerBufferSize
,
251 NdrContextHandleBufferSize
,
254 NdrUserMarshalBufferSize
,
259 const NDR_MEMORYSIZE NdrMemorySizer
[NDR_TABLE_SIZE
] = {
261 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
262 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
263 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
264 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
266 NdrBaseTypeMemorySize
,
268 NdrPointerMemorySize
, NdrPointerMemorySize
,
269 NdrPointerMemorySize
, NdrPointerMemorySize
,
271 NdrSimpleStructMemorySize
, NdrSimpleStructMemorySize
,
272 NdrConformantStructMemorySize
, NdrConformantStructMemorySize
,
273 NdrConformantVaryingStructMemorySize
,
274 NdrComplexStructMemorySize
,
276 NdrConformantArrayMemorySize
,
277 NdrConformantVaryingArrayMemorySize
,
278 NdrFixedArrayMemorySize
, NdrFixedArrayMemorySize
,
279 NdrVaryingArrayMemorySize
, NdrVaryingArrayMemorySize
,
280 NdrComplexArrayMemorySize
,
282 NdrConformantStringMemorySize
, 0, 0,
283 NdrConformantStringMemorySize
,
284 NdrNonConformantStringMemorySize
, 0, 0, 0,
286 NdrEncapsulatedUnionMemorySize
,
287 NdrNonEncapsulatedUnionMemorySize
,
288 NdrByteCountPointerMemorySize
,
289 NdrXmitOrRepAsMemorySize
, NdrXmitOrRepAsMemorySize
,
291 NdrInterfacePointerMemorySize
,
296 NdrUserMarshalMemorySize
,
301 const NDR_FREE NdrFreer
[NDR_TABLE_SIZE
] = {
303 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
304 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
305 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
306 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
310 NdrPointerFree
, NdrPointerFree
,
311 NdrPointerFree
, NdrPointerFree
,
313 NdrSimpleStructFree
, NdrSimpleStructFree
,
314 NdrConformantStructFree
, NdrConformantStructFree
,
315 NdrConformantVaryingStructFree
,
316 NdrComplexStructFree
,
318 NdrConformantArrayFree
,
319 NdrConformantVaryingArrayFree
,
320 NdrFixedArrayFree
, NdrFixedArrayFree
,
321 NdrVaryingArrayFree
, NdrVaryingArrayFree
,
327 NdrEncapsulatedUnionFree
,
328 NdrNonEncapsulatedUnionFree
,
330 NdrXmitOrRepAsFree
, NdrXmitOrRepAsFree
,
332 NdrInterfacePointerFree
,
343 typedef struct _NDR_MEMORY_LIST
348 struct _NDR_MEMORY_LIST
*next
;
351 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
353 /***********************************************************************
354 * NdrAllocate [RPCRT4.@]
356 * Allocates a block of memory using pStubMsg->pfnAllocate.
359 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
360 * len [I] Size of memory block to allocate.
363 * The memory block of size len that was allocated.
366 * The memory block is always 8-byte aligned.
367 * If the function is unable to allocate memory an ERROR_OUTOFMEMORY
368 * exception is raised.
370 void * WINAPI
NdrAllocate(MIDL_STUB_MESSAGE
*pStubMsg
, SIZE_T len
)
375 NDR_MEMORY_LIST
*mem_list
;
377 aligned_len
= ALIGNED_LENGTH(len
, 8);
378 adjusted_len
= aligned_len
+ sizeof(NDR_MEMORY_LIST
);
379 /* check for overflow */
380 if (adjusted_len
< len
)
382 ERR("overflow of adjusted_len %ld, len %ld\n", adjusted_len
, len
);
383 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
386 p
= pStubMsg
->pfnAllocate(adjusted_len
);
387 if (!p
) RpcRaiseException(ERROR_OUTOFMEMORY
);
389 mem_list
= (NDR_MEMORY_LIST
*)((char *)p
+ aligned_len
);
390 mem_list
->magic
= MEML_MAGIC
;
391 mem_list
->size
= aligned_len
;
392 mem_list
->reserved
= 0;
393 mem_list
->next
= pStubMsg
->pMemoryList
;
394 pStubMsg
->pMemoryList
= mem_list
;
400 static void NdrFree(MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *Pointer
)
402 TRACE("(%p, %p)\n", pStubMsg
, Pointer
);
404 pStubMsg
->pfnFree(Pointer
);
407 static inline BOOL
IsConformanceOrVariancePresent(PFORMAT_STRING pFormat
)
409 return (*(const ULONG
*)pFormat
!= -1);
412 static PFORMAT_STRING
ReadConformance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
)
414 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
415 if (pStubMsg
->Buffer
+ 4 > pStubMsg
->BufferEnd
)
416 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
417 pStubMsg
->MaxCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
418 pStubMsg
->Buffer
+= 4;
419 TRACE("unmarshalled conformance is %ld\n", pStubMsg
->MaxCount
);
420 if (pStubMsg
->fHasNewCorrDesc
)
426 static inline PFORMAT_STRING
ReadVariance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
, ULONG MaxValue
)
428 if (pFormat
&& !IsConformanceOrVariancePresent(pFormat
))
430 pStubMsg
->Offset
= 0;
431 pStubMsg
->ActualCount
= pStubMsg
->MaxCount
;
435 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
436 if (pStubMsg
->Buffer
+ 8 > pStubMsg
->BufferEnd
)
437 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
438 pStubMsg
->Offset
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
439 pStubMsg
->Buffer
+= 4;
440 TRACE("offset is %d\n", pStubMsg
->Offset
);
441 pStubMsg
->ActualCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
442 pStubMsg
->Buffer
+= 4;
443 TRACE("variance is %d\n", pStubMsg
->ActualCount
);
445 if ((pStubMsg
->ActualCount
> MaxValue
) ||
446 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> MaxValue
))
448 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
449 pStubMsg
->ActualCount
, pStubMsg
->Offset
, MaxValue
);
450 RpcRaiseException(RPC_S_INVALID_BOUND
);
455 if (pStubMsg
->fHasNewCorrDesc
)
461 /* writes the conformance value to the buffer */
462 static inline void WriteConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
464 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
465 if (pStubMsg
->Buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
466 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
467 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->MaxCount
);
468 pStubMsg
->Buffer
+= 4;
471 /* writes the variance values to the buffer */
472 static inline void WriteVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
474 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
475 if (pStubMsg
->Buffer
+ 8 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
476 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
477 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->Offset
);
478 pStubMsg
->Buffer
+= 4;
479 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->ActualCount
);
480 pStubMsg
->Buffer
+= 4;
483 /* requests buffer space for the conformance value */
484 static inline void SizeConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
486 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
487 if (pStubMsg
->BufferLength
+ 4 < pStubMsg
->BufferLength
)
488 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
489 pStubMsg
->BufferLength
+= 4;
492 /* requests buffer space for the variance values */
493 static inline void SizeVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
495 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
496 if (pStubMsg
->BufferLength
+ 8 < pStubMsg
->BufferLength
)
497 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
498 pStubMsg
->BufferLength
+= 8;
501 PFORMAT_STRING
ComputeConformanceOrVariance(
502 MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *pMemory
,
503 PFORMAT_STRING pFormat
, ULONG_PTR def
, ULONG_PTR
*pCount
)
505 BYTE dtype
= pFormat
[0] & 0xf;
506 short ofs
= *(const short *)&pFormat
[2];
510 if (!IsConformanceOrVariancePresent(pFormat
)) {
511 /* null descriptor */
516 switch (pFormat
[0] & 0xf0) {
517 case RPC_FC_NORMAL_CONFORMANCE
:
518 TRACE("normal conformance, ofs=%d\n", ofs
);
521 case RPC_FC_POINTER_CONFORMANCE
:
522 TRACE("pointer conformance, ofs=%d\n", ofs
);
523 ptr
= pStubMsg
->Memory
;
525 case RPC_FC_TOP_LEVEL_CONFORMANCE
:
526 TRACE("toplevel conformance, ofs=%d\n", ofs
);
527 if (pStubMsg
->StackTop
) {
528 ptr
= pStubMsg
->StackTop
;
531 /* -Os mode, *pCount is already set */
535 case RPC_FC_CONSTANT_CONFORMANCE
:
536 data
= ofs
| ((DWORD
)pFormat
[1] << 16);
537 TRACE("constant conformance, val=%d\n", data
);
540 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE
:
541 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs
);
542 if (pStubMsg
->StackTop
) {
543 ptr
= pStubMsg
->StackTop
;
551 FIXME("unknown conformance type %x\n", pFormat
[0] & 0xf0);
554 switch (pFormat
[1]) {
555 case RPC_FC_DEREFERENCE
:
556 ptr
= *(LPVOID
*)((char *)ptr
+ ofs
);
558 case RPC_FC_CALLBACK
:
560 unsigned char *old_stack_top
= pStubMsg
->StackTop
;
561 pStubMsg
->StackTop
= ptr
;
563 /* ofs is index into StubDesc->apfnExprEval */
564 TRACE("callback conformance into apfnExprEval[%d]\n", ofs
);
565 pStubMsg
->StubDesc
->apfnExprEval
[ofs
](pStubMsg
);
567 pStubMsg
->StackTop
= old_stack_top
;
569 /* the callback function always stores the computed value in MaxCount */
570 *pCount
= pStubMsg
->MaxCount
;
574 ptr
= (char *)ptr
+ ofs
;
587 data
= *(USHORT
*)ptr
;
598 FIXME("unknown conformance data type %x\n", dtype
);
601 TRACE("dereferenced data type %x at %p, got %d\n", dtype
, ptr
, data
);
604 switch (pFormat
[1]) {
605 case RPC_FC_DEREFERENCE
: /* already handled */
622 FIXME("unknown conformance op %d\n", pFormat
[1]);
627 TRACE("resulting conformance is %ld\n", *pCount
);
628 if (pStubMsg
->fHasNewCorrDesc
)
634 static inline PFORMAT_STRING
SkipConformance(PMIDL_STUB_MESSAGE pStubMsg
,
635 PFORMAT_STRING pFormat
)
637 if (IsConformanceOrVariancePresent(pFormat
))
639 if (pStubMsg
->fHasNewCorrDesc
)
647 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
648 * the result overflows 32-bits */
649 static inline ULONG
safe_multiply(ULONG a
, ULONG b
)
651 ULONGLONG ret
= (ULONGLONG
)a
* b
;
652 if (ret
> 0xffffffff)
654 RpcRaiseException(RPC_S_INVALID_BOUND
);
660 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
662 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
663 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
664 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
665 pStubMsg
->Buffer
+= size
;
668 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
670 if (pStubMsg
->BufferLength
+ size
< pStubMsg
->BufferLength
) /* integer overflow of pStubMsg->BufferSize */
672 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
673 pStubMsg
->BufferLength
, size
);
674 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
676 pStubMsg
->BufferLength
+= size
;
679 /* copies data from the buffer, checking that there is enough data in the buffer
681 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, void *p
, ULONG size
)
683 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
684 (pStubMsg
->Buffer
+ size
> pStubMsg
->BufferEnd
))
686 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
687 pStubMsg
->Buffer
, pStubMsg
->BufferEnd
, size
);
688 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
690 if (p
== pStubMsg
->Buffer
)
691 ERR("pointer is the same as the buffer\n");
692 memcpy(p
, pStubMsg
->Buffer
, size
);
693 pStubMsg
->Buffer
+= size
;
696 /* copies data to the buffer, checking that there is enough space to do so */
697 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, const void *p
, ULONG size
)
699 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
700 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
702 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
703 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
,
705 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
707 memcpy(pStubMsg
->Buffer
, p
, size
);
708 pStubMsg
->Buffer
+= size
;
711 /* verify that string data sitting in the buffer is valid and safe to
713 static void validate_string_data(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG bufsize
, ULONG esize
)
717 /* verify the buffer is safe to access */
718 if ((pStubMsg
->Buffer
+ bufsize
< pStubMsg
->Buffer
) ||
719 (pStubMsg
->Buffer
+ bufsize
> pStubMsg
->BufferEnd
))
721 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize
,
722 pStubMsg
->BufferEnd
, pStubMsg
->Buffer
);
723 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
726 /* strings must always have null terminating bytes */
729 ERR("invalid string length of %d\n", bufsize
/ esize
);
730 RpcRaiseException(RPC_S_INVALID_BOUND
);
733 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
734 if (pStubMsg
->Buffer
[i
] != 0)
736 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
737 i
, pStubMsg
->Buffer
[i
]);
738 RpcRaiseException(RPC_S_INVALID_BOUND
);
742 static inline void dump_pointer_attr(unsigned char attr
)
744 if (attr
& RPC_FC_P_ALLOCALLNODES
)
745 TRACE(" RPC_FC_P_ALLOCALLNODES");
746 if (attr
& RPC_FC_P_DONTFREE
)
747 TRACE(" RPC_FC_P_DONTFREE");
748 if (attr
& RPC_FC_P_ONSTACK
)
749 TRACE(" RPC_FC_P_ONSTACK");
750 if (attr
& RPC_FC_P_SIMPLEPOINTER
)
751 TRACE(" RPC_FC_P_SIMPLEPOINTER");
752 if (attr
& RPC_FC_P_DEREF
)
753 TRACE(" RPC_FC_P_DEREF");
757 /***********************************************************************
758 * PointerMarshall [internal]
760 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
761 unsigned char *Buffer
,
762 unsigned char *Pointer
,
763 PFORMAT_STRING pFormat
)
765 unsigned type
= pFormat
[0], attr
= pFormat
[1];
769 int pointer_needs_marshaling
;
771 TRACE("(%p,%p,%p,%p)\n", pStubMsg
, Buffer
, Pointer
, pFormat
);
772 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
774 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
775 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
778 case RPC_FC_RP
: /* ref pointer (always non-null) */
781 ERR("NULL ref pointer is not allowed\n");
782 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
784 pointer_needs_marshaling
= 1;
786 case RPC_FC_UP
: /* unique pointer */
787 case RPC_FC_OP
: /* object pointer - same as unique here */
789 pointer_needs_marshaling
= 1;
791 pointer_needs_marshaling
= 0;
792 pointer_id
= Pointer
? NDR_POINTER_ID(pStubMsg
) : 0;
793 TRACE("writing 0x%08x to buffer\n", pointer_id
);
794 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
797 pointer_needs_marshaling
= !NdrFullPointerQueryPointer(
798 pStubMsg
->FullPtrXlatTables
, Pointer
, 1, &pointer_id
);
799 TRACE("writing 0x%08x to buffer\n", pointer_id
);
800 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
803 FIXME("unhandled ptr type=%02x\n", type
);
804 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
808 TRACE("calling marshaller for type 0x%x\n", (int)*desc
);
810 if (pointer_needs_marshaling
) {
811 if (attr
& RPC_FC_P_DEREF
) {
812 Pointer
= *(unsigned char**)Pointer
;
813 TRACE("deref => %p\n", Pointer
);
815 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
816 if (m
) m(pStubMsg
, Pointer
, desc
);
817 else FIXME("no marshaller for data type=%02x\n", *desc
);
820 STD_OVERFLOW_CHECK(pStubMsg
);
823 /***********************************************************************
824 * PointerUnmarshall [internal]
826 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
827 unsigned char *Buffer
,
828 unsigned char **pPointer
,
829 unsigned char *pSrcPointer
,
830 PFORMAT_STRING pFormat
,
831 unsigned char fMustAlloc
)
833 unsigned type
= pFormat
[0], attr
= pFormat
[1];
836 DWORD pointer_id
= 0;
837 int pointer_needs_unmarshaling
;
839 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg
, Buffer
, pPointer
, pSrcPointer
, pFormat
, fMustAlloc
);
840 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
842 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
843 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
846 case RPC_FC_RP
: /* ref pointer (always non-null) */
847 pointer_needs_unmarshaling
= 1;
849 case RPC_FC_UP
: /* unique pointer */
850 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
851 TRACE("pointer_id is 0x%08x\n", pointer_id
);
853 pointer_needs_unmarshaling
= 1;
856 pointer_needs_unmarshaling
= 0;
859 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
860 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
861 TRACE("pointer_id is 0x%08x\n", pointer_id
);
862 if (!fMustAlloc
&& pSrcPointer
)
864 FIXME("free object pointer %p\n", pSrcPointer
);
868 pointer_needs_unmarshaling
= 1;
872 pointer_needs_unmarshaling
= 0;
876 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
877 TRACE("pointer_id is 0x%08x\n", pointer_id
);
878 pointer_needs_unmarshaling
= !NdrFullPointerQueryRefId(
879 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, (void **)pPointer
);
882 FIXME("unhandled ptr type=%02x\n", type
);
883 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
887 if (pointer_needs_unmarshaling
) {
888 unsigned char *base_ptr_val
= *pPointer
;
889 unsigned char **current_ptr
= pPointer
;
890 if (pStubMsg
->IsClient
) {
892 /* if we aren't forcing allocation of memory then try to use the existing
893 * (source) pointer to unmarshall the data into so that [in,out]
894 * parameters behave correctly. it doesn't matter if the parameter is
895 * [out] only since in that case the pointer will be NULL. we force
896 * allocation when the source pointer is NULL here instead of in the type
897 * unmarshalling routine for the benefit of the deref code below */
900 TRACE("setting *pPointer to %p\n", pSrcPointer
);
901 *pPointer
= base_ptr_val
= pSrcPointer
;
907 /* the memory in a stub is never initialised, so we have to work out here
908 * whether we have to initialise it so we can use the optimisation of
909 * setting the pointer to the buffer, if possible, or set fMustAlloc to
911 if (attr
& RPC_FC_P_DEREF
) {
919 if (attr
& RPC_FC_P_ALLOCALLNODES
)
920 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
922 if (attr
& RPC_FC_P_DEREF
) {
924 base_ptr_val
= NdrAllocate(pStubMsg
, sizeof(void *));
925 *pPointer
= base_ptr_val
;
926 current_ptr
= (unsigned char **)base_ptr_val
;
928 current_ptr
= *(unsigned char***)current_ptr
;
929 TRACE("deref => %p\n", current_ptr
);
930 if (!fMustAlloc
&& !*current_ptr
) fMustAlloc
= TRUE
;
932 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
933 if (m
) m(pStubMsg
, current_ptr
, desc
, fMustAlloc
);
934 else FIXME("no unmarshaller for data type=%02x\n", *desc
);
936 if (type
== RPC_FC_FP
)
937 NdrFullPointerInsertRefId(pStubMsg
->FullPtrXlatTables
, pointer_id
,
941 TRACE("pointer=%p\n", *pPointer
);
944 /***********************************************************************
945 * PointerBufferSize [internal]
947 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
948 unsigned char *Pointer
,
949 PFORMAT_STRING pFormat
)
951 unsigned type
= pFormat
[0], attr
= pFormat
[1];
954 int pointer_needs_sizing
;
957 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
958 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
960 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
961 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
964 case RPC_FC_RP
: /* ref pointer (always non-null) */
967 ERR("NULL ref pointer is not allowed\n");
968 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
973 /* NULL pointer has no further representation */
978 pointer_needs_sizing
= !NdrFullPointerQueryPointer(
979 pStubMsg
->FullPtrXlatTables
, Pointer
, 0, &pointer_id
);
980 if (!pointer_needs_sizing
)
984 FIXME("unhandled ptr type=%02x\n", type
);
985 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
989 if (attr
& RPC_FC_P_DEREF
) {
990 Pointer
= *(unsigned char**)Pointer
;
991 TRACE("deref => %p\n", Pointer
);
994 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
995 if (m
) m(pStubMsg
, Pointer
, desc
);
996 else FIXME("no buffersizer for data type=%02x\n", *desc
);
999 /***********************************************************************
1000 * PointerMemorySize [internal]
1002 static ULONG
PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1003 unsigned char *Buffer
, PFORMAT_STRING pFormat
)
1005 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1006 PFORMAT_STRING desc
;
1008 DWORD pointer_id
= 0;
1009 int pointer_needs_sizing
;
1011 TRACE("(%p,%p,%p)\n", pStubMsg
, Buffer
, pFormat
);
1012 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1014 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1015 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1018 case RPC_FC_RP
: /* ref pointer (always non-null) */
1019 pointer_needs_sizing
= 1;
1021 case RPC_FC_UP
: /* unique pointer */
1022 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
1023 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1024 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1026 pointer_needs_sizing
= 1;
1028 pointer_needs_sizing
= 0;
1033 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1034 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1035 pointer_needs_sizing
= !NdrFullPointerQueryRefId(
1036 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, &pointer
);
1040 FIXME("unhandled ptr type=%02x\n", type
);
1041 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1045 if (attr
& RPC_FC_P_DEREF
) {
1046 ALIGN_LENGTH(pStubMsg
->MemorySize
, sizeof(void*));
1047 pStubMsg
->MemorySize
+= sizeof(void*);
1051 if (pointer_needs_sizing
) {
1052 m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
1053 if (m
) m(pStubMsg
, desc
);
1054 else FIXME("no memorysizer for data type=%02x\n", *desc
);
1057 return pStubMsg
->MemorySize
;
1060 /***********************************************************************
1061 * PointerFree [internal]
1063 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1064 unsigned char *Pointer
,
1065 PFORMAT_STRING pFormat
)
1067 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1068 PFORMAT_STRING desc
;
1070 unsigned char *current_pointer
= Pointer
;
1072 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1073 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1074 if (attr
& RPC_FC_P_DONTFREE
) return;
1076 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1077 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1079 if (!Pointer
) return;
1081 if (type
== RPC_FC_FP
) {
1082 int pointer_needs_freeing
= NdrFullPointerFree(
1083 pStubMsg
->FullPtrXlatTables
, Pointer
);
1084 if (!pointer_needs_freeing
)
1088 if (attr
& RPC_FC_P_DEREF
) {
1089 current_pointer
= *(unsigned char**)Pointer
;
1090 TRACE("deref => %p\n", current_pointer
);
1093 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
1094 if (m
) m(pStubMsg
, current_pointer
, desc
);
1096 /* this check stops us from trying to free buffer memory. we don't have to
1097 * worry about clients, since they won't call this function.
1098 * we don't have to check for the buffer being reallocated because
1099 * BufferStart and BufferEnd won't be reset when allocating memory for
1100 * sending the response. we don't have to check for the new buffer here as
1101 * it won't be used a type memory, only for buffer memory */
1102 if (Pointer
>= pStubMsg
->BufferStart
&& Pointer
< pStubMsg
->BufferEnd
)
1105 if (attr
& RPC_FC_P_ONSTACK
) {
1106 TRACE("not freeing stack ptr %p\n", Pointer
);
1109 TRACE("freeing %p\n", Pointer
);
1110 NdrFree(pStubMsg
, Pointer
);
1113 TRACE("not freeing %p\n", Pointer
);
1116 /***********************************************************************
1117 * EmbeddedPointerMarshall
1119 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1120 unsigned char *pMemory
,
1121 PFORMAT_STRING pFormat
)
1123 unsigned char *Mark
= pStubMsg
->BufferMark
;
1124 unsigned rep
, count
, stride
;
1126 unsigned char *saved_buffer
= NULL
;
1128 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1130 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1133 if (pStubMsg
->PointerBufferMark
)
1135 saved_buffer
= pStubMsg
->Buffer
;
1136 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1137 pStubMsg
->PointerBufferMark
= NULL
;
1140 while (pFormat
[0] != RPC_FC_END
) {
1141 switch (pFormat
[0]) {
1143 FIXME("unknown repeat type %d\n", pFormat
[0]);
1144 case RPC_FC_NO_REPEAT
:
1150 case RPC_FC_FIXED_REPEAT
:
1151 rep
= *(const WORD
*)&pFormat
[2];
1152 stride
= *(const WORD
*)&pFormat
[4];
1153 count
= *(const WORD
*)&pFormat
[8];
1156 case RPC_FC_VARIABLE_REPEAT
:
1157 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1158 stride
= *(const WORD
*)&pFormat
[2];
1159 count
= *(const WORD
*)&pFormat
[6];
1163 for (i
= 0; i
< rep
; i
++) {
1164 PFORMAT_STRING info
= pFormat
;
1165 unsigned char *membase
= pMemory
+ (i
* stride
);
1166 unsigned char *bufbase
= Mark
+ (i
* stride
);
1169 for (u
=0; u
<count
; u
++,info
+=8) {
1170 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1171 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1172 unsigned char *saved_memory
= pStubMsg
->Memory
;
1174 pStubMsg
->Memory
= pMemory
;
1175 PointerMarshall(pStubMsg
, bufptr
, *(unsigned char**)memptr
, info
+4);
1176 pStubMsg
->Memory
= saved_memory
;
1179 pFormat
+= 8 * count
;
1184 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1185 pStubMsg
->Buffer
= saved_buffer
;
1188 STD_OVERFLOW_CHECK(pStubMsg
);
1193 /***********************************************************************
1194 * EmbeddedPointerUnmarshall
1196 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1197 unsigned char *pDstBuffer
,
1198 unsigned char *pSrcMemoryPtrs
,
1199 PFORMAT_STRING pFormat
,
1200 unsigned char fMustAlloc
)
1202 unsigned char *Mark
= pStubMsg
->BufferMark
;
1203 unsigned rep
, count
, stride
;
1205 unsigned char *saved_buffer
= NULL
;
1207 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg
, pDstBuffer
, pSrcMemoryPtrs
, pFormat
, fMustAlloc
);
1209 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1212 if (pStubMsg
->PointerBufferMark
)
1214 saved_buffer
= pStubMsg
->Buffer
;
1215 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1216 pStubMsg
->PointerBufferMark
= NULL
;
1219 while (pFormat
[0] != RPC_FC_END
) {
1220 TRACE("pFormat[0] = 0x%x\n", pFormat
[0]);
1221 switch (pFormat
[0]) {
1223 FIXME("unknown repeat type %d\n", pFormat
[0]);
1224 case RPC_FC_NO_REPEAT
:
1230 case RPC_FC_FIXED_REPEAT
:
1231 rep
= *(const WORD
*)&pFormat
[2];
1232 stride
= *(const WORD
*)&pFormat
[4];
1233 count
= *(const WORD
*)&pFormat
[8];
1236 case RPC_FC_VARIABLE_REPEAT
:
1237 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1238 stride
= *(const WORD
*)&pFormat
[2];
1239 count
= *(const WORD
*)&pFormat
[6];
1243 for (i
= 0; i
< rep
; i
++) {
1244 PFORMAT_STRING info
= pFormat
;
1245 unsigned char *bufdstbase
= pDstBuffer
+ (i
* stride
);
1246 unsigned char *memsrcbase
= pSrcMemoryPtrs
+ (i
* stride
);
1247 unsigned char *bufbase
= Mark
+ (i
* stride
);
1250 for (u
=0; u
<count
; u
++,info
+=8) {
1251 unsigned char **bufdstptr
= (unsigned char **)(bufdstbase
+ *(const SHORT
*)&info
[2]);
1252 unsigned char **memsrcptr
= (unsigned char **)(memsrcbase
+ *(const SHORT
*)&info
[0]);
1253 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1254 PointerUnmarshall(pStubMsg
, bufptr
, bufdstptr
, *memsrcptr
, info
+4, fMustAlloc
);
1257 pFormat
+= 8 * count
;
1262 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1263 pStubMsg
->Buffer
= saved_buffer
;
1269 /***********************************************************************
1270 * EmbeddedPointerBufferSize
1272 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1273 unsigned char *pMemory
,
1274 PFORMAT_STRING pFormat
)
1276 unsigned rep
, count
, stride
;
1278 ULONG saved_buffer_length
= 0;
1280 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1282 if (pStubMsg
->IgnoreEmbeddedPointers
) return;
1284 if (*pFormat
!= RPC_FC_PP
) return;
1287 if (pStubMsg
->PointerLength
)
1289 saved_buffer_length
= pStubMsg
->BufferLength
;
1290 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
1291 pStubMsg
->PointerLength
= 0;
1294 while (pFormat
[0] != RPC_FC_END
) {
1295 switch (pFormat
[0]) {
1297 FIXME("unknown repeat type %d\n", pFormat
[0]);
1298 case RPC_FC_NO_REPEAT
:
1304 case RPC_FC_FIXED_REPEAT
:
1305 rep
= *(const WORD
*)&pFormat
[2];
1306 stride
= *(const WORD
*)&pFormat
[4];
1307 count
= *(const WORD
*)&pFormat
[8];
1310 case RPC_FC_VARIABLE_REPEAT
:
1311 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1312 stride
= *(const WORD
*)&pFormat
[2];
1313 count
= *(const WORD
*)&pFormat
[6];
1317 for (i
= 0; i
< rep
; i
++) {
1318 PFORMAT_STRING info
= pFormat
;
1319 unsigned char *membase
= pMemory
+ (i
* stride
);
1322 for (u
=0; u
<count
; u
++,info
+=8) {
1323 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1324 unsigned char *saved_memory
= pStubMsg
->Memory
;
1326 pStubMsg
->Memory
= pMemory
;
1327 PointerBufferSize(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1328 pStubMsg
->Memory
= saved_memory
;
1331 pFormat
+= 8 * count
;
1334 if (saved_buffer_length
)
1336 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
1337 pStubMsg
->BufferLength
= saved_buffer_length
;
1341 /***********************************************************************
1342 * EmbeddedPointerMemorySize [internal]
1344 static ULONG
EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1345 PFORMAT_STRING pFormat
)
1347 unsigned char *Mark
= pStubMsg
->BufferMark
;
1348 unsigned rep
, count
, stride
;
1350 unsigned char *saved_buffer
= NULL
;
1352 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1354 if (pStubMsg
->IgnoreEmbeddedPointers
) return 0;
1356 if (pStubMsg
->PointerBufferMark
)
1358 saved_buffer
= pStubMsg
->Buffer
;
1359 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1360 pStubMsg
->PointerBufferMark
= NULL
;
1363 if (*pFormat
!= RPC_FC_PP
) return 0;
1366 while (pFormat
[0] != RPC_FC_END
) {
1367 switch (pFormat
[0]) {
1369 FIXME("unknown repeat type %d\n", pFormat
[0]);
1370 case RPC_FC_NO_REPEAT
:
1376 case RPC_FC_FIXED_REPEAT
:
1377 rep
= *(const WORD
*)&pFormat
[2];
1378 stride
= *(const WORD
*)&pFormat
[4];
1379 count
= *(const WORD
*)&pFormat
[8];
1382 case RPC_FC_VARIABLE_REPEAT
:
1383 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1384 stride
= *(const WORD
*)&pFormat
[2];
1385 count
= *(const WORD
*)&pFormat
[6];
1389 for (i
= 0; i
< rep
; i
++) {
1390 PFORMAT_STRING info
= pFormat
;
1391 unsigned char *bufbase
= Mark
+ (i
* stride
);
1393 for (u
=0; u
<count
; u
++,info
+=8) {
1394 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1395 PointerMemorySize(pStubMsg
, bufptr
, info
+4);
1398 pFormat
+= 8 * count
;
1403 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1404 pStubMsg
->Buffer
= saved_buffer
;
1410 /***********************************************************************
1411 * EmbeddedPointerFree [internal]
1413 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1414 unsigned char *pMemory
,
1415 PFORMAT_STRING pFormat
)
1417 unsigned rep
, count
, stride
;
1420 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1421 if (*pFormat
!= RPC_FC_PP
) return;
1424 while (pFormat
[0] != RPC_FC_END
) {
1425 switch (pFormat
[0]) {
1427 FIXME("unknown repeat type %d\n", pFormat
[0]);
1428 case RPC_FC_NO_REPEAT
:
1434 case RPC_FC_FIXED_REPEAT
:
1435 rep
= *(const WORD
*)&pFormat
[2];
1436 stride
= *(const WORD
*)&pFormat
[4];
1437 count
= *(const WORD
*)&pFormat
[8];
1440 case RPC_FC_VARIABLE_REPEAT
:
1441 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1442 stride
= *(const WORD
*)&pFormat
[2];
1443 count
= *(const WORD
*)&pFormat
[6];
1447 for (i
= 0; i
< rep
; i
++) {
1448 PFORMAT_STRING info
= pFormat
;
1449 unsigned char *membase
= pMemory
+ (i
* stride
);
1452 for (u
=0; u
<count
; u
++,info
+=8) {
1453 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1454 unsigned char *saved_memory
= pStubMsg
->Memory
;
1456 pStubMsg
->Memory
= pMemory
;
1457 PointerFree(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1458 pStubMsg
->Memory
= saved_memory
;
1461 pFormat
+= 8 * count
;
1465 /***********************************************************************
1466 * NdrPointerMarshall [RPCRT4.@]
1468 unsigned char * WINAPI
NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1469 unsigned char *pMemory
,
1470 PFORMAT_STRING pFormat
)
1472 unsigned char *Buffer
;
1474 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1476 /* Increment the buffer here instead of in PointerMarshall,
1477 * as that is used by embedded pointers which already handle the incrementing
1478 * the buffer, and shouldn't write any additional pointer data to the wire */
1479 if (*pFormat
!= RPC_FC_RP
)
1481 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
1482 Buffer
= pStubMsg
->Buffer
;
1483 safe_buffer_increment(pStubMsg
, 4);
1486 Buffer
= pStubMsg
->Buffer
;
1488 PointerMarshall(pStubMsg
, Buffer
, pMemory
, pFormat
);
1493 /***********************************************************************
1494 * NdrPointerUnmarshall [RPCRT4.@]
1496 unsigned char * WINAPI
NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1497 unsigned char **ppMemory
,
1498 PFORMAT_STRING pFormat
,
1499 unsigned char fMustAlloc
)
1501 unsigned char *Buffer
;
1503 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1505 if (*pFormat
== RPC_FC_RP
)
1507 Buffer
= pStubMsg
->Buffer
;
1508 /* Do the NULL ref pointer check here because embedded pointers can be
1509 * NULL if the type the pointer is embedded in was allocated rather than
1510 * being passed in by the client */
1511 if (pStubMsg
->IsClient
&& !*ppMemory
)
1513 ERR("NULL ref pointer is not allowed\n");
1514 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
1519 /* Increment the buffer here instead of in PointerUnmarshall,
1520 * as that is used by embedded pointers which already handle the incrementing
1521 * the buffer, and shouldn't read any additional pointer data from the
1523 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1524 Buffer
= pStubMsg
->Buffer
;
1525 safe_buffer_increment(pStubMsg
, 4);
1528 PointerUnmarshall(pStubMsg
, Buffer
, ppMemory
, *ppMemory
, pFormat
, fMustAlloc
);
1533 /***********************************************************************
1534 * NdrPointerBufferSize [RPCRT4.@]
1536 void WINAPI
NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1537 unsigned char *pMemory
,
1538 PFORMAT_STRING pFormat
)
1540 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1542 /* Increment the buffer length here instead of in PointerBufferSize,
1543 * as that is used by embedded pointers which already handle the buffer
1544 * length, and shouldn't write anything more to the wire */
1545 if (*pFormat
!= RPC_FC_RP
)
1547 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
1548 safe_buffer_length_increment(pStubMsg
, 4);
1551 PointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1554 /***********************************************************************
1555 * NdrPointerMemorySize [RPCRT4.@]
1557 ULONG WINAPI
NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1558 PFORMAT_STRING pFormat
)
1560 unsigned char *Buffer
= pStubMsg
->Buffer
;
1561 if (*pFormat
!= RPC_FC_RP
)
1563 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1564 safe_buffer_increment(pStubMsg
, 4);
1566 ALIGN_LENGTH(pStubMsg
->MemorySize
, sizeof(void *));
1567 return PointerMemorySize(pStubMsg
, Buffer
, pFormat
);
1570 /***********************************************************************
1571 * NdrPointerFree [RPCRT4.@]
1573 void WINAPI
NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1574 unsigned char *pMemory
,
1575 PFORMAT_STRING pFormat
)
1577 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1578 PointerFree(pStubMsg
, pMemory
, pFormat
);
1581 /***********************************************************************
1582 * NdrSimpleTypeMarshall [RPCRT4.@]
1584 void WINAPI
NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1585 unsigned char FormatChar
)
1587 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &FormatChar
);
1590 /***********************************************************************
1591 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1593 * Unmarshall a base type.
1596 * Doesn't check that the buffer is long enough before copying, so the caller
1599 void WINAPI
NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1600 unsigned char FormatChar
)
1602 #define BASE_TYPE_UNMARSHALL(type) \
1603 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
1604 TRACE("pMemory: %p\n", pMemory); \
1605 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1606 pStubMsg->Buffer += sizeof(type);
1614 BASE_TYPE_UNMARSHALL(UCHAR
);
1615 TRACE("value: 0x%02x\n", *pMemory
);
1620 BASE_TYPE_UNMARSHALL(USHORT
);
1621 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
1625 case RPC_FC_ERROR_STATUS_T
:
1627 BASE_TYPE_UNMARSHALL(ULONG
);
1628 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
1631 BASE_TYPE_UNMARSHALL(float);
1632 TRACE("value: %f\n", *(float *)pMemory
);
1635 BASE_TYPE_UNMARSHALL(double);
1636 TRACE("value: %f\n", *(double *)pMemory
);
1639 BASE_TYPE_UNMARSHALL(ULONGLONG
);
1640 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
1643 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
1644 TRACE("pMemory: %p\n", pMemory
);
1645 /* 16-bits on the wire, but int in memory */
1646 *(UINT
*)pMemory
= *(USHORT
*)pStubMsg
->Buffer
;
1647 pStubMsg
->Buffer
+= sizeof(USHORT
);
1648 TRACE("value: 0x%08x\n", *(UINT
*)pMemory
);
1653 FIXME("Unhandled base type: 0x%02x\n", FormatChar
);
1655 #undef BASE_TYPE_UNMARSHALL
1658 /***********************************************************************
1659 * NdrSimpleStructMarshall [RPCRT4.@]
1661 unsigned char * WINAPI
NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1662 unsigned char *pMemory
,
1663 PFORMAT_STRING pFormat
)
1665 unsigned size
= *(const WORD
*)(pFormat
+2);
1666 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1668 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pFormat
[1] + 1);
1670 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1671 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
1673 if (pFormat
[0] != RPC_FC_STRUCT
)
1674 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
+4);
1679 /***********************************************************************
1680 * NdrSimpleStructUnmarshall [RPCRT4.@]
1682 unsigned char * WINAPI
NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1683 unsigned char **ppMemory
,
1684 PFORMAT_STRING pFormat
,
1685 unsigned char fMustAlloc
)
1687 unsigned size
= *(const WORD
*)(pFormat
+2);
1688 unsigned char *saved_buffer
;
1689 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1691 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1694 *ppMemory
= NdrAllocate(pStubMsg
, size
);
1697 if (!pStubMsg
->IsClient
&& !*ppMemory
)
1698 /* for servers, we just point straight into the RPC buffer */
1699 *ppMemory
= pStubMsg
->Buffer
;
1702 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1703 safe_buffer_increment(pStubMsg
, size
);
1704 if (pFormat
[0] == RPC_FC_PSTRUCT
)
1705 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
+4, fMustAlloc
);
1707 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
1708 if (*ppMemory
!= saved_buffer
)
1709 memcpy(*ppMemory
, saved_buffer
, size
);
1714 /***********************************************************************
1715 * NdrSimpleStructBufferSize [RPCRT4.@]
1717 void WINAPI
NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1718 unsigned char *pMemory
,
1719 PFORMAT_STRING pFormat
)
1721 unsigned size
= *(const WORD
*)(pFormat
+2);
1722 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1724 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
1726 safe_buffer_length_increment(pStubMsg
, size
);
1727 if (pFormat
[0] != RPC_FC_STRUCT
)
1728 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
+4);
1731 /***********************************************************************
1732 * NdrSimpleStructMemorySize [RPCRT4.@]
1734 ULONG WINAPI
NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1735 PFORMAT_STRING pFormat
)
1737 unsigned short size
= *(const WORD
*)(pFormat
+2);
1739 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1741 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1742 pStubMsg
->MemorySize
+= size
;
1743 safe_buffer_increment(pStubMsg
, size
);
1745 if (pFormat
[0] != RPC_FC_STRUCT
)
1746 EmbeddedPointerMemorySize(pStubMsg
, pFormat
+4);
1747 return pStubMsg
->MemorySize
;
1750 /***********************************************************************
1751 * NdrSimpleStructFree [RPCRT4.@]
1753 void WINAPI
NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
1754 unsigned char *pMemory
,
1755 PFORMAT_STRING pFormat
)
1757 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1758 if (pFormat
[0] != RPC_FC_STRUCT
)
1759 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
+4);
1764 static inline void array_compute_and_size_conformance(
1765 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1766 PFORMAT_STRING pFormat
)
1771 ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1772 SizeConformance(pStubMsg
);
1774 case RPC_FC_CVARRAY
:
1775 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, 0);
1776 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
1777 SizeConformance(pStubMsg
);
1779 case RPC_FC_C_CSTRING
:
1780 case RPC_FC_C_WSTRING
:
1781 if (pFormat
[0] == RPC_FC_C_CSTRING
)
1783 TRACE("string=%s\n", debugstr_a((const char *)pMemory
));
1784 pStubMsg
->ActualCount
= strlen((const char *)pMemory
)+1;
1788 TRACE("string=%s\n", debugstr_w((LPCWSTR
)pMemory
));
1789 pStubMsg
->ActualCount
= strlenW((LPCWSTR
)pMemory
)+1;
1792 if (fc
== RPC_FC_STRING_SIZED
)
1793 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
1795 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
1797 SizeConformance(pStubMsg
);
1800 ERR("unknown array format 0x%x\n", fc
);
1801 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1805 static inline void array_buffer_size(
1806 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1807 PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
1811 unsigned char alignment
;
1816 esize
= *(const WORD
*)(pFormat
+2);
1817 alignment
= pFormat
[1] + 1;
1819 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1821 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
1823 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
1824 /* conformance value plus array */
1825 safe_buffer_length_increment(pStubMsg
, size
);
1828 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1830 case RPC_FC_CVARRAY
:
1831 esize
= *(const WORD
*)(pFormat
+2);
1832 alignment
= pFormat
[1] + 1;
1834 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1835 pFormat
= SkipConformance(pStubMsg
, pFormat
);
1837 SizeVariance(pStubMsg
);
1839 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
1841 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1842 safe_buffer_length_increment(pStubMsg
, size
);
1845 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1847 case RPC_FC_C_CSTRING
:
1848 case RPC_FC_C_WSTRING
:
1849 if (fc
== RPC_FC_C_CSTRING
)
1854 SizeVariance(pStubMsg
);
1856 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1857 safe_buffer_length_increment(pStubMsg
, size
);
1860 ERR("unknown array format 0x%x\n", fc
);
1861 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1865 static inline void array_compute_and_write_conformance(
1866 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1867 PFORMAT_STRING pFormat
)
1872 ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1873 WriteConformance(pStubMsg
);
1875 case RPC_FC_CVARRAY
:
1876 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, 0);
1877 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
1878 WriteConformance(pStubMsg
);
1880 case RPC_FC_C_CSTRING
:
1881 case RPC_FC_C_WSTRING
:
1882 if (fc
== RPC_FC_C_CSTRING
)
1884 TRACE("string=%s\n", debugstr_a((const char *)pMemory
));
1885 pStubMsg
->ActualCount
= strlen((const char *)pMemory
)+1;
1889 TRACE("string=%s\n", debugstr_w((LPCWSTR
)pMemory
));
1890 pStubMsg
->ActualCount
= strlenW((LPCWSTR
)pMemory
)+1;
1892 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
1893 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
1895 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
1896 pStubMsg
->Offset
= 0;
1897 WriteConformance(pStubMsg
);
1900 ERR("unknown array format 0x%x\n", fc
);
1901 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1905 static inline void array_write_variance_and_marshall(
1906 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1907 PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
1911 unsigned char alignment
;
1916 esize
= *(const WORD
*)(pFormat
+2);
1917 alignment
= pFormat
[1] + 1;
1919 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1921 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
1923 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
1925 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1926 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
1929 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
1931 case RPC_FC_CVARRAY
:
1932 esize
= *(const WORD
*)(pFormat
+2);
1933 alignment
= pFormat
[1] + 1;
1936 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1938 pFormat
= SkipConformance(pStubMsg
, pFormat
);
1940 WriteVariance(pStubMsg
);
1942 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
1944 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1947 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1948 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, size
);
1951 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
1953 case RPC_FC_C_CSTRING
:
1954 case RPC_FC_C_WSTRING
:
1955 if (fc
== RPC_FC_C_CSTRING
)
1960 WriteVariance(pStubMsg
);
1962 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1963 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
1966 ERR("unknown array format 0x%x\n", fc
);
1967 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1971 static inline ULONG
array_read_conformance(
1972 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
1979 esize
= *(const WORD
*)(pFormat
+2);
1980 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
1981 return safe_multiply(esize
, pStubMsg
->MaxCount
);
1982 case RPC_FC_CVARRAY
:
1983 esize
= *(const WORD
*)(pFormat
+2);
1984 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
1985 return safe_multiply(esize
, pStubMsg
->MaxCount
);
1986 case RPC_FC_C_CSTRING
:
1987 case RPC_FC_C_WSTRING
:
1988 if (fc
== RPC_FC_C_CSTRING
)
1993 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
1994 ReadConformance(pStubMsg
, pFormat
+ 2);
1996 ReadConformance(pStubMsg
, NULL
);
1997 return safe_multiply(esize
, pStubMsg
->MaxCount
);
1999 ERR("unknown array format 0x%x\n", fc
);
2000 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2004 static inline ULONG
array_read_variance_and_unmarshall(
2005 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char **ppMemory
,
2006 PFORMAT_STRING pFormat
, unsigned char fMustAlloc
,
2007 unsigned char fUseBufferMemoryServer
, unsigned char fUnmarshall
)
2009 ULONG bufsize
, memsize
;
2011 unsigned char alignment
;
2012 unsigned char *saved_buffer
;
2018 esize
= *(const WORD
*)(pFormat
+2);
2019 alignment
= pFormat
[1] + 1;
2021 bufsize
= memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2023 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2025 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2030 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2033 if (fUseBufferMemoryServer
&& !pStubMsg
->IsClient
&& !*ppMemory
)
2034 /* for servers, we just point straight into the RPC buffer */
2035 *ppMemory
= pStubMsg
->Buffer
;
2038 saved_buffer
= pStubMsg
->Buffer
;
2039 safe_buffer_increment(pStubMsg
, bufsize
);
2041 pStubMsg
->BufferMark
= saved_buffer
;
2042 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
2044 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
2045 if (*ppMemory
!= saved_buffer
)
2046 memcpy(*ppMemory
, saved_buffer
, bufsize
);
2049 case RPC_FC_CVARRAY
:
2050 esize
= *(const WORD
*)(pFormat
+2);
2051 alignment
= pFormat
[1] + 1;
2053 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2055 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2057 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2059 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2060 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2064 offset
= pStubMsg
->Offset
;
2066 if (!fMustAlloc
&& !*ppMemory
)
2069 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2070 saved_buffer
= pStubMsg
->Buffer
;
2071 safe_buffer_increment(pStubMsg
, bufsize
);
2073 pStubMsg
->BufferMark
= saved_buffer
;
2074 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
,
2077 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
2080 case RPC_FC_C_CSTRING
:
2081 case RPC_FC_C_WSTRING
:
2082 if (fc
== RPC_FC_C_CSTRING
)
2087 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
2089 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
2091 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2092 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
2093 RpcRaiseException(RPC_S_INVALID_BOUND
);
2095 if (pStubMsg
->Offset
)
2097 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2098 RpcRaiseException(RPC_S_INVALID_BOUND
);
2101 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2102 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2104 validate_string_data(pStubMsg
, bufsize
, esize
);
2109 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2112 if (fUseBufferMemoryServer
&& !pStubMsg
->IsClient
&&
2113 !*ppMemory
&& (pStubMsg
->MaxCount
== pStubMsg
->ActualCount
))
2114 /* if the data in the RPC buffer is big enough, we just point
2115 * straight into it */
2116 *ppMemory
= pStubMsg
->Buffer
;
2117 else if (!*ppMemory
)
2118 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2121 if (*ppMemory
== pStubMsg
->Buffer
)
2122 safe_buffer_increment(pStubMsg
, bufsize
);
2124 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
2126 if (*pFormat
== RPC_FC_C_CSTRING
)
2127 TRACE("string=%s\n", debugstr_a((char*)*ppMemory
));
2129 TRACE("string=%s\n", debugstr_w((LPWSTR
)*ppMemory
));
2133 ERR("unknown array format 0x%x\n", fc
);
2134 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2138 static inline void array_memory_size(
2139 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
,
2140 unsigned char fHasPointers
)
2142 ULONG bufsize
, memsize
;
2144 unsigned char alignment
;
2149 esize
= *(const WORD
*)(pFormat
+2);
2150 alignment
= pFormat
[1] + 1;
2152 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2154 bufsize
= memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2155 pStubMsg
->MemorySize
+= memsize
;
2157 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2159 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2160 safe_buffer_increment(pStubMsg
, bufsize
);
2163 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2165 case RPC_FC_CVARRAY
:
2166 esize
= *(const WORD
*)(pFormat
+2);
2167 alignment
= pFormat
[1] + 1;
2169 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2171 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2173 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2174 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2175 pStubMsg
->MemorySize
+= memsize
;
2177 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2179 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2180 safe_buffer_increment(pStubMsg
, bufsize
);
2183 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2185 case RPC_FC_C_CSTRING
:
2186 case RPC_FC_C_WSTRING
:
2187 if (fc
== RPC_FC_C_CSTRING
)
2192 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
2194 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
2196 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2197 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
2198 RpcRaiseException(RPC_S_INVALID_BOUND
);
2200 if (pStubMsg
->Offset
)
2202 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2203 RpcRaiseException(RPC_S_INVALID_BOUND
);
2206 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2207 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2209 validate_string_data(pStubMsg
, bufsize
, esize
);
2211 safe_buffer_increment(pStubMsg
, bufsize
);
2212 pStubMsg
->MemorySize
+= memsize
;
2215 ERR("unknown array format 0x%x\n", fc
);
2216 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2220 static inline void array_free(
2221 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
,
2222 unsigned char *pMemory
, PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
2227 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2229 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2231 case RPC_FC_CVARRAY
:
2232 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2233 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2235 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2237 case RPC_FC_C_CSTRING
:
2238 case RPC_FC_C_WSTRING
:
2239 /* No embedded pointers so nothing to do */
2242 ERR("unknown array format 0x%x\n", fc
);
2243 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2248 * NdrConformantString:
2250 * What MS calls a ConformantString is, in DCE terminology,
2251 * a Varying-Conformant String.
2253 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2254 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2255 * into unmarshalled string)
2256 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2258 * data: CHARTYPE[maxlen]
2260 * ], where CHARTYPE is the appropriate character type (specified externally)
2264 /***********************************************************************
2265 * NdrConformantStringMarshall [RPCRT4.@]
2267 unsigned char *WINAPI
NdrConformantStringMarshall(MIDL_STUB_MESSAGE
*pStubMsg
,
2268 unsigned char *pszMessage
, PFORMAT_STRING pFormat
)
2270 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg
, pszMessage
, pFormat
);
2272 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2273 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2274 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2277 /* allow compiler to optimise inline function by passing constant into
2278 * these functions */
2279 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2280 array_compute_and_write_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pszMessage
,
2282 array_write_variance_and_marshall(RPC_FC_C_CSTRING
, pStubMsg
, pszMessage
,
2283 pFormat
, TRUE
/* fHasPointers */);
2285 array_compute_and_write_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pszMessage
,
2287 array_write_variance_and_marshall(RPC_FC_C_WSTRING
, pStubMsg
, pszMessage
,
2288 pFormat
, TRUE
/* fHasPointers */);
2294 /***********************************************************************
2295 * NdrConformantStringBufferSize [RPCRT4.@]
2297 void WINAPI
NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2298 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
2300 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2302 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2303 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2304 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2307 /* allow compiler to optimise inline function by passing constant into
2308 * these functions */
2309 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2310 array_compute_and_size_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pMemory
,
2312 array_buffer_size(RPC_FC_C_CSTRING
, pStubMsg
, pMemory
, pFormat
,
2313 TRUE
/* fHasPointers */);
2315 array_compute_and_size_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pMemory
,
2317 array_buffer_size(RPC_FC_C_WSTRING
, pStubMsg
, pMemory
, pFormat
,
2318 TRUE
/* fHasPointers */);
2322 /************************************************************************
2323 * NdrConformantStringMemorySize [RPCRT4.@]
2325 ULONG WINAPI
NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
2326 PFORMAT_STRING pFormat
)
2328 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
2330 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2331 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2332 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2335 /* allow compiler to optimise inline function by passing constant into
2336 * these functions */
2337 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2338 array_read_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
);
2339 array_memory_size(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
,
2340 TRUE
/* fHasPointers */);
2342 array_read_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
);
2343 array_memory_size(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
,
2344 TRUE
/* fHasPointers */);
2347 return pStubMsg
->MemorySize
;
2350 /************************************************************************
2351 * NdrConformantStringUnmarshall [RPCRT4.@]
2353 unsigned char *WINAPI
NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2354 unsigned char** ppMemory
, PFORMAT_STRING pFormat
, unsigned char fMustAlloc
)
2356 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2357 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
2359 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2360 ERR("Unhandled string type: %#x\n", *pFormat
);
2361 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2364 /* allow compiler to optimise inline function by passing constant into
2365 * these functions */
2366 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2367 array_read_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
);
2368 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING
, pStubMsg
, ppMemory
,
2369 pFormat
, fMustAlloc
,
2370 TRUE
/* fUseBufferMemoryServer */,
2371 TRUE
/* fUnmarshall */);
2373 array_read_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
);
2374 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING
, pStubMsg
, ppMemory
,
2375 pFormat
, fMustAlloc
,
2376 TRUE
/* fUseBufferMemoryServer */,
2377 TRUE
/* fUnmarshall */);
2383 /***********************************************************************
2384 * NdrNonConformantStringMarshall [RPCRT4.@]
2386 unsigned char * WINAPI
NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2387 unsigned char *pMemory
,
2388 PFORMAT_STRING pFormat
)
2390 ULONG esize
, size
, maxsize
;
2392 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2394 maxsize
= *(USHORT
*)&pFormat
[2];
2396 if (*pFormat
== RPC_FC_CSTRING
)
2399 const char *str
= (const char *)pMemory
;
2400 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
2402 TRACE("string=%s\n", debugstr_an(str
, i
));
2403 pStubMsg
->ActualCount
= i
+ 1;
2406 else if (*pFormat
== RPC_FC_WSTRING
)
2409 const WCHAR
*str
= (const WCHAR
*)pMemory
;
2410 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
2412 TRACE("string=%s\n", debugstr_wn(str
, i
));
2413 pStubMsg
->ActualCount
= i
+ 1;
2418 ERR("Unhandled string type: %#x\n", *pFormat
);
2419 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2422 pStubMsg
->Offset
= 0;
2423 WriteVariance(pStubMsg
);
2425 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2426 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
2431 /***********************************************************************
2432 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2434 unsigned char * WINAPI
NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2435 unsigned char **ppMemory
,
2436 PFORMAT_STRING pFormat
,
2437 unsigned char fMustAlloc
)
2439 ULONG bufsize
, memsize
, esize
, maxsize
;
2441 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2442 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
2444 maxsize
= *(USHORT
*)&pFormat
[2];
2446 ReadVariance(pStubMsg
, NULL
, maxsize
);
2447 if (pStubMsg
->Offset
)
2449 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2450 RpcRaiseException(RPC_S_INVALID_BOUND
);
2453 if (*pFormat
== RPC_FC_CSTRING
) esize
= 1;
2454 else if (*pFormat
== RPC_FC_WSTRING
) esize
= 2;
2457 ERR("Unhandled string type: %#x\n", *pFormat
);
2458 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2461 memsize
= esize
* maxsize
;
2462 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2464 validate_string_data(pStubMsg
, bufsize
, esize
);
2466 if (!fMustAlloc
&& !*ppMemory
)
2469 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2471 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
2473 if (*pFormat
== RPC_FC_CSTRING
) {
2474 TRACE("string=%s\n", debugstr_an((char*)*ppMemory
, pStubMsg
->ActualCount
));
2476 else if (*pFormat
== RPC_FC_WSTRING
) {
2477 TRACE("string=%s\n", debugstr_wn((LPWSTR
)*ppMemory
, pStubMsg
->ActualCount
));
2483 /***********************************************************************
2484 * NdrNonConformantStringBufferSize [RPCRT4.@]
2486 void WINAPI
NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2487 unsigned char *pMemory
,
2488 PFORMAT_STRING pFormat
)
2490 ULONG esize
, maxsize
;
2492 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2494 maxsize
= *(USHORT
*)&pFormat
[2];
2496 SizeVariance(pStubMsg
);
2498 if (*pFormat
== RPC_FC_CSTRING
)
2501 const char *str
= (const char *)pMemory
;
2502 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
2504 TRACE("string=%s\n", debugstr_an(str
, i
));
2505 pStubMsg
->ActualCount
= i
+ 1;
2508 else if (*pFormat
== RPC_FC_WSTRING
)
2511 const WCHAR
*str
= (const WCHAR
*)pMemory
;
2512 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
2514 TRACE("string=%s\n", debugstr_wn(str
, i
));
2515 pStubMsg
->ActualCount
= i
+ 1;
2520 ERR("Unhandled string type: %#x\n", *pFormat
);
2521 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2524 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
2527 /***********************************************************************
2528 * NdrNonConformantStringMemorySize [RPCRT4.@]
2530 ULONG WINAPI
NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2531 PFORMAT_STRING pFormat
)
2533 ULONG bufsize
, memsize
, esize
, maxsize
;
2535 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
2537 maxsize
= *(USHORT
*)&pFormat
[2];
2539 ReadVariance(pStubMsg
, NULL
, maxsize
);
2541 if (pStubMsg
->Offset
)
2543 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2544 RpcRaiseException(RPC_S_INVALID_BOUND
);
2547 if (*pFormat
== RPC_FC_CSTRING
) esize
= 1;
2548 else if (*pFormat
== RPC_FC_WSTRING
) esize
= 2;
2551 ERR("Unhandled string type: %#x\n", *pFormat
);
2552 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2555 memsize
= esize
* maxsize
;
2556 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2558 validate_string_data(pStubMsg
, bufsize
, esize
);
2560 safe_buffer_increment(pStubMsg
, bufsize
);
2561 pStubMsg
->MemorySize
+= memsize
;
2563 return pStubMsg
->MemorySize
;
2568 #include "pshpack1.h"
2572 unsigned char flags_type
; /* flags in upper nibble, type in lower nibble */
2576 #include "poppack.h"
2578 static ULONG
EmbeddedComplexSize(MIDL_STUB_MESSAGE
*pStubMsg
,
2579 PFORMAT_STRING pFormat
)
2583 case RPC_FC_PSTRUCT
:
2584 case RPC_FC_CSTRUCT
:
2585 case RPC_FC_BOGUS_STRUCT
:
2586 case RPC_FC_SMFARRAY
:
2587 case RPC_FC_SMVARRAY
:
2588 case RPC_FC_CSTRING
:
2589 return *(const WORD
*)&pFormat
[2];
2590 case RPC_FC_USER_MARSHAL
:
2591 return *(const WORD
*)&pFormat
[4];
2592 case RPC_FC_RANGE
: {
2593 switch (((const NDR_RANGE
*)pFormat
)->flags_type
& 0xf) {
2598 return sizeof(UCHAR
);
2602 return sizeof(USHORT
);
2606 return sizeof(ULONG
);
2608 return sizeof(float);
2610 return sizeof(double);
2612 return sizeof(ULONGLONG
);
2614 return sizeof(UINT
);
2616 ERR("unknown type 0x%x\n", ((const NDR_RANGE
*)pFormat
)->flags_type
& 0xf);
2617 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2620 case RPC_FC_NON_ENCAPSULATED_UNION
:
2622 if (pStubMsg
->fHasNewCorrDesc
)
2627 pFormat
+= *(const SHORT
*)pFormat
;
2628 return *(const SHORT
*)pFormat
;
2630 return sizeof(void *);
2631 case RPC_FC_WSTRING
:
2632 return *(const WORD
*)&pFormat
[2] * 2;
2634 FIXME("unhandled embedded type %02x\n", *pFormat
);
2640 static ULONG
EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2641 PFORMAT_STRING pFormat
)
2643 NDR_MEMORYSIZE m
= NdrMemorySizer
[*pFormat
& NDR_TABLE_MASK
];
2647 FIXME("no memorysizer for data type=%02x\n", *pFormat
);
2651 return m(pStubMsg
, pFormat
);
2655 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2656 unsigned char *pMemory
,
2657 PFORMAT_STRING pFormat
,
2658 PFORMAT_STRING pPointer
)
2660 PFORMAT_STRING desc
;
2664 while (*pFormat
!= RPC_FC_END
) {
2670 TRACE("byte=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2671 safe_copy_to_buffer(pStubMsg
, pMemory
, 1);
2677 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2678 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
2682 TRACE("enum16=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2683 if (32767 < *(DWORD
*)pMemory
)
2684 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
2685 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
2691 TRACE("long=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2692 safe_copy_to_buffer(pStubMsg
, pMemory
, 4);
2696 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2697 safe_copy_to_buffer(pStubMsg
, pMemory
, 8);
2700 case RPC_FC_POINTER
:
2702 unsigned char *saved_buffer
;
2703 int pointer_buffer_mark_set
= 0;
2704 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
2705 TRACE("pStubMsg->Buffer before %p\n", pStubMsg
->Buffer
);
2706 if (*pPointer
!= RPC_FC_RP
)
2707 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
2708 saved_buffer
= pStubMsg
->Buffer
;
2709 if (pStubMsg
->PointerBufferMark
)
2711 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2712 pStubMsg
->PointerBufferMark
= NULL
;
2713 pointer_buffer_mark_set
= 1;
2715 else if (*pPointer
!= RPC_FC_RP
)
2716 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2717 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char**)pMemory
, pPointer
);
2718 if (pointer_buffer_mark_set
)
2720 STD_OVERFLOW_CHECK(pStubMsg
);
2721 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2722 pStubMsg
->Buffer
= saved_buffer
;
2723 if (*pPointer
!= RPC_FC_RP
)
2724 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2726 TRACE("pStubMsg->Buffer after %p\n", pStubMsg
->Buffer
);
2728 pMemory
+= sizeof(void *);
2731 case RPC_FC_ALIGNM2
:
2732 ALIGN_POINTER(pMemory
, 2);
2734 case RPC_FC_ALIGNM4
:
2735 ALIGN_POINTER(pMemory
, 4);
2737 case RPC_FC_ALIGNM8
:
2738 ALIGN_POINTER(pMemory
, 8);
2740 case RPC_FC_STRUCTPAD1
:
2741 case RPC_FC_STRUCTPAD2
:
2742 case RPC_FC_STRUCTPAD3
:
2743 case RPC_FC_STRUCTPAD4
:
2744 case RPC_FC_STRUCTPAD5
:
2745 case RPC_FC_STRUCTPAD6
:
2746 case RPC_FC_STRUCTPAD7
:
2747 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2749 case RPC_FC_EMBEDDED_COMPLEX
:
2750 pMemory
+= pFormat
[1];
2752 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2753 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2754 TRACE("embedded complex (size=%d) <= %p\n", size
, pMemory
);
2755 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
2758 /* for some reason interface pointers aren't generated as
2759 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2760 * they still need the derefencing treatment that pointers are
2762 if (*desc
== RPC_FC_IP
)
2763 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2765 m(pStubMsg
, pMemory
, desc
);
2767 else FIXME("no marshaller for embedded type %02x\n", *desc
);
2774 FIXME("unhandled format 0x%02x\n", *pFormat
);
2782 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2783 unsigned char *pMemory
,
2784 PFORMAT_STRING pFormat
,
2785 PFORMAT_STRING pPointer
,
2786 unsigned char fMustAlloc
)
2788 PFORMAT_STRING desc
;
2792 while (*pFormat
!= RPC_FC_END
) {
2798 safe_copy_from_buffer(pStubMsg
, pMemory
, 1);
2799 TRACE("byte=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2805 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
2806 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2810 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
2811 *(DWORD
*)pMemory
&= 0xffff;
2812 TRACE("enum16=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
2813 if (32767 < *(DWORD
*)pMemory
)
2814 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
2820 safe_copy_from_buffer(pStubMsg
, pMemory
, 4);
2821 TRACE("long=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
2825 safe_copy_from_buffer(pStubMsg
, pMemory
, 8);
2826 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2829 case RPC_FC_POINTER
:
2831 unsigned char *saved_buffer
;
2832 int pointer_buffer_mark_set
= 0;
2833 TRACE("pointer => %p\n", pMemory
);
2834 if (*pPointer
!= RPC_FC_RP
)
2835 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2836 saved_buffer
= pStubMsg
->Buffer
;
2837 if (pStubMsg
->PointerBufferMark
)
2839 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2840 pStubMsg
->PointerBufferMark
= NULL
;
2841 pointer_buffer_mark_set
= 1;
2843 else if (*pPointer
!= RPC_FC_RP
)
2844 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2846 PointerUnmarshall(pStubMsg
, saved_buffer
, (unsigned char**)pMemory
, *(unsigned char**)pMemory
, pPointer
, fMustAlloc
);
2847 if (pointer_buffer_mark_set
)
2849 STD_OVERFLOW_CHECK(pStubMsg
);
2850 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2851 pStubMsg
->Buffer
= saved_buffer
;
2852 if (*pPointer
!= RPC_FC_RP
)
2853 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2856 pMemory
+= sizeof(void *);
2859 case RPC_FC_ALIGNM2
:
2860 ALIGN_POINTER_CLEAR(pMemory
, 2);
2862 case RPC_FC_ALIGNM4
:
2863 ALIGN_POINTER_CLEAR(pMemory
, 4);
2865 case RPC_FC_ALIGNM8
:
2866 ALIGN_POINTER_CLEAR(pMemory
, 8);
2868 case RPC_FC_STRUCTPAD1
:
2869 case RPC_FC_STRUCTPAD2
:
2870 case RPC_FC_STRUCTPAD3
:
2871 case RPC_FC_STRUCTPAD4
:
2872 case RPC_FC_STRUCTPAD5
:
2873 case RPC_FC_STRUCTPAD6
:
2874 case RPC_FC_STRUCTPAD7
:
2875 memset(pMemory
, 0, *pFormat
- RPC_FC_STRUCTPAD1
+ 1);
2876 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2878 case RPC_FC_EMBEDDED_COMPLEX
:
2879 pMemory
+= pFormat
[1];
2881 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2882 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2883 TRACE("embedded complex (size=%d) => %p\n", size
, pMemory
);
2885 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
2886 * since the type is part of the memory block that is encompassed by
2887 * the whole complex type. Memory is forced to allocate when pointers
2888 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
2889 * clearing the memory we pass in to the unmarshaller */
2890 memset(pMemory
, 0, size
);
2891 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
2894 /* for some reason interface pointers aren't generated as
2895 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2896 * they still need the derefencing treatment that pointers are
2898 if (*desc
== RPC_FC_IP
)
2899 m(pStubMsg
, (unsigned char **)pMemory
, desc
, FALSE
);
2901 m(pStubMsg
, &pMemory
, desc
, FALSE
);
2903 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
2910 FIXME("unhandled format %d\n", *pFormat
);
2918 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2919 unsigned char *pMemory
,
2920 PFORMAT_STRING pFormat
,
2921 PFORMAT_STRING pPointer
)
2923 PFORMAT_STRING desc
;
2927 while (*pFormat
!= RPC_FC_END
) {
2933 safe_buffer_length_increment(pStubMsg
, 1);
2939 safe_buffer_length_increment(pStubMsg
, 2);
2943 safe_buffer_length_increment(pStubMsg
, 2);
2949 safe_buffer_length_increment(pStubMsg
, 4);
2953 safe_buffer_length_increment(pStubMsg
, 8);
2956 case RPC_FC_POINTER
:
2957 if (!pStubMsg
->IgnoreEmbeddedPointers
)
2959 int saved_buffer_length
= pStubMsg
->BufferLength
;
2960 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2961 pStubMsg
->PointerLength
= 0;
2962 if(!pStubMsg
->BufferLength
)
2963 ERR("BufferLength == 0??\n");
2964 PointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
2965 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2966 pStubMsg
->BufferLength
= saved_buffer_length
;
2968 if (*pPointer
!= RPC_FC_RP
)
2970 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
2971 safe_buffer_length_increment(pStubMsg
, 4);
2974 pMemory
+= sizeof(void*);
2976 case RPC_FC_ALIGNM2
:
2977 ALIGN_POINTER(pMemory
, 2);
2979 case RPC_FC_ALIGNM4
:
2980 ALIGN_POINTER(pMemory
, 4);
2982 case RPC_FC_ALIGNM8
:
2983 ALIGN_POINTER(pMemory
, 8);
2985 case RPC_FC_STRUCTPAD1
:
2986 case RPC_FC_STRUCTPAD2
:
2987 case RPC_FC_STRUCTPAD3
:
2988 case RPC_FC_STRUCTPAD4
:
2989 case RPC_FC_STRUCTPAD5
:
2990 case RPC_FC_STRUCTPAD6
:
2991 case RPC_FC_STRUCTPAD7
:
2992 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2994 case RPC_FC_EMBEDDED_COMPLEX
:
2995 pMemory
+= pFormat
[1];
2997 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2998 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2999 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
3002 /* for some reason interface pointers aren't generated as
3003 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3004 * they still need the derefencing treatment that pointers are
3006 if (*desc
== RPC_FC_IP
)
3007 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
3009 m(pStubMsg
, pMemory
, desc
);
3011 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
3018 FIXME("unhandled format 0x%02x\n", *pFormat
);
3026 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
3027 unsigned char *pMemory
,
3028 PFORMAT_STRING pFormat
,
3029 PFORMAT_STRING pPointer
)
3031 PFORMAT_STRING desc
;
3035 while (*pFormat
!= RPC_FC_END
) {
3057 case RPC_FC_POINTER
:
3058 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
3060 pMemory
+= sizeof(void *);
3062 case RPC_FC_ALIGNM2
:
3063 ALIGN_POINTER(pMemory
, 2);
3065 case RPC_FC_ALIGNM4
:
3066 ALIGN_POINTER(pMemory
, 4);
3068 case RPC_FC_ALIGNM8
:
3069 ALIGN_POINTER(pMemory
, 8);
3071 case RPC_FC_STRUCTPAD1
:
3072 case RPC_FC_STRUCTPAD2
:
3073 case RPC_FC_STRUCTPAD3
:
3074 case RPC_FC_STRUCTPAD4
:
3075 case RPC_FC_STRUCTPAD5
:
3076 case RPC_FC_STRUCTPAD6
:
3077 case RPC_FC_STRUCTPAD7
:
3078 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3080 case RPC_FC_EMBEDDED_COMPLEX
:
3081 pMemory
+= pFormat
[1];
3083 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3084 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3085 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
3088 /* for some reason interface pointers aren't generated as
3089 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3090 * they still need the derefencing treatment that pointers are
3092 if (*desc
== RPC_FC_IP
)
3093 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
3095 m(pStubMsg
, pMemory
, desc
);
3103 FIXME("unhandled format 0x%02x\n", *pFormat
);
3111 static ULONG
ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3112 PFORMAT_STRING pFormat
,
3113 PFORMAT_STRING pPointer
)
3115 PFORMAT_STRING desc
;
3118 while (*pFormat
!= RPC_FC_END
) {
3125 safe_buffer_increment(pStubMsg
, 1);
3131 safe_buffer_increment(pStubMsg
, 2);
3135 safe_buffer_increment(pStubMsg
, 2);
3141 safe_buffer_increment(pStubMsg
, 4);
3145 safe_buffer_increment(pStubMsg
, 8);
3147 case RPC_FC_POINTER
:
3149 unsigned char *saved_buffer
;
3150 int pointer_buffer_mark_set
= 0;
3151 if (*pPointer
!= RPC_FC_RP
)
3152 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3153 saved_buffer
= pStubMsg
->Buffer
;
3154 if (pStubMsg
->PointerBufferMark
)
3156 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3157 pStubMsg
->PointerBufferMark
= NULL
;
3158 pointer_buffer_mark_set
= 1;
3160 else if (*pPointer
!= RPC_FC_RP
)
3161 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3163 if (!pStubMsg
->IgnoreEmbeddedPointers
)
3164 PointerMemorySize(pStubMsg
, saved_buffer
, pPointer
);
3165 if (pointer_buffer_mark_set
)
3167 STD_OVERFLOW_CHECK(pStubMsg
);
3168 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3169 pStubMsg
->Buffer
= saved_buffer
;
3170 if (*pPointer
!= RPC_FC_RP
)
3171 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3174 size
+= sizeof(void *);
3177 case RPC_FC_ALIGNM2
:
3178 ALIGN_LENGTH(size
, 2);
3180 case RPC_FC_ALIGNM4
:
3181 ALIGN_LENGTH(size
, 4);
3183 case RPC_FC_ALIGNM8
:
3184 ALIGN_LENGTH(size
, 8);
3186 case RPC_FC_STRUCTPAD1
:
3187 case RPC_FC_STRUCTPAD2
:
3188 case RPC_FC_STRUCTPAD3
:
3189 case RPC_FC_STRUCTPAD4
:
3190 case RPC_FC_STRUCTPAD5
:
3191 case RPC_FC_STRUCTPAD6
:
3192 case RPC_FC_STRUCTPAD7
:
3193 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3195 case RPC_FC_EMBEDDED_COMPLEX
:
3198 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3199 size
+= EmbeddedComplexMemorySize(pStubMsg
, desc
);
3205 FIXME("unhandled format 0x%02x\n", *pFormat
);
3213 ULONG
ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
3215 PFORMAT_STRING desc
;
3218 while (*pFormat
!= RPC_FC_END
) {
3240 case RPC_FC_POINTER
:
3241 size
+= sizeof(void *);
3243 case RPC_FC_ALIGNM2
:
3244 ALIGN_LENGTH(size
, 2);
3246 case RPC_FC_ALIGNM4
:
3247 ALIGN_LENGTH(size
, 4);
3249 case RPC_FC_ALIGNM8
:
3250 ALIGN_LENGTH(size
, 8);
3252 case RPC_FC_STRUCTPAD1
:
3253 case RPC_FC_STRUCTPAD2
:
3254 case RPC_FC_STRUCTPAD3
:
3255 case RPC_FC_STRUCTPAD4
:
3256 case RPC_FC_STRUCTPAD5
:
3257 case RPC_FC_STRUCTPAD6
:
3258 case RPC_FC_STRUCTPAD7
:
3259 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3261 case RPC_FC_EMBEDDED_COMPLEX
:
3264 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3265 size
+= EmbeddedComplexSize(pStubMsg
, desc
);
3271 FIXME("unhandled format 0x%02x\n", *pFormat
);
3279 /***********************************************************************
3280 * NdrComplexStructMarshall [RPCRT4.@]
3282 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3283 unsigned char *pMemory
,
3284 PFORMAT_STRING pFormat
)
3286 PFORMAT_STRING conf_array
= NULL
;
3287 PFORMAT_STRING pointer_desc
= NULL
;
3288 unsigned char *OldMemory
= pStubMsg
->Memory
;
3289 int pointer_buffer_mark_set
= 0;
3291 ULONG max_count
= 0;
3294 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3296 if (!pStubMsg
->PointerBufferMark
)
3298 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3299 /* save buffer length */
3300 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
3302 /* get the buffer pointer after complex array data, but before
3304 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
;
3305 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3306 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
3307 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3309 /* save it for use by embedded pointer code later */
3310 pStubMsg
->PointerBufferMark
= (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
;
3311 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->PointerBufferMark
- pStubMsg
->Buffer
));
3312 pointer_buffer_mark_set
= 1;
3314 /* restore the original buffer length */
3315 pStubMsg
->BufferLength
= saved_buffer_length
;
3318 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pFormat
[1] + 1);
3321 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3323 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3326 pStubMsg
->Memory
= pMemory
;
3330 ULONG struct_size
= ComplexStructSize(pStubMsg
, pFormat
);
3331 array_compute_and_write_conformance(conf_array
[0], pStubMsg
,
3332 pMemory
+ struct_size
, conf_array
);
3333 /* these could be changed in ComplexMarshall so save them for later */
3334 max_count
= pStubMsg
->MaxCount
;
3335 count
= pStubMsg
->ActualCount
;
3336 offset
= pStubMsg
->Offset
;
3339 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3343 pStubMsg
->MaxCount
= max_count
;
3344 pStubMsg
->ActualCount
= count
;
3345 pStubMsg
->Offset
= offset
;
3346 array_write_variance_and_marshall(conf_array
[0], pStubMsg
, pMemory
,
3347 conf_array
, TRUE
/* fHasPointers */);
3350 pStubMsg
->Memory
= OldMemory
;
3352 if (pointer_buffer_mark_set
)
3354 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3355 pStubMsg
->PointerBufferMark
= NULL
;
3358 STD_OVERFLOW_CHECK(pStubMsg
);
3363 /***********************************************************************
3364 * NdrComplexStructUnmarshall [RPCRT4.@]
3366 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3367 unsigned char **ppMemory
,
3368 PFORMAT_STRING pFormat
,
3369 unsigned char fMustAlloc
)
3371 unsigned size
= *(const WORD
*)(pFormat
+2);
3372 PFORMAT_STRING conf_array
= NULL
;
3373 PFORMAT_STRING pointer_desc
= NULL
;
3374 unsigned char *pMemory
;
3375 int pointer_buffer_mark_set
= 0;
3377 ULONG max_count
= 0;
3379 ULONG array_size
= 0;
3381 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3383 if (!pStubMsg
->PointerBufferMark
)
3385 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3386 /* save buffer pointer */
3387 unsigned char *saved_buffer
= pStubMsg
->Buffer
;
3389 /* get the buffer pointer after complex array data, but before
3391 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3392 NdrComplexStructMemorySize(pStubMsg
, pFormat
);
3393 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3395 /* save it for use by embedded pointer code later */
3396 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3397 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->PointerBufferMark
- saved_buffer
));
3398 pointer_buffer_mark_set
= 1;
3400 /* restore the original buffer */
3401 pStubMsg
->Buffer
= saved_buffer
;
3404 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
3407 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3409 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3414 array_size
= array_read_conformance(conf_array
[0], pStubMsg
, conf_array
);
3417 /* these could be changed in ComplexMarshall so save them for later */
3418 max_count
= pStubMsg
->MaxCount
;
3419 count
= pStubMsg
->ActualCount
;
3420 offset
= pStubMsg
->Offset
;
3423 if (!fMustAlloc
&& !*ppMemory
)
3426 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3428 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
, fMustAlloc
);
3432 pStubMsg
->MaxCount
= max_count
;
3433 pStubMsg
->ActualCount
= count
;
3434 pStubMsg
->Offset
= offset
;
3436 memset(pMemory
, 0, array_size
);
3437 array_read_variance_and_unmarshall(conf_array
[0], pStubMsg
, &pMemory
,
3439 FALSE
/* fUseBufferMemoryServer */,
3440 TRUE
/* fUnmarshall */);
3443 if (pointer_buffer_mark_set
)
3445 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3446 pStubMsg
->PointerBufferMark
= NULL
;
3452 /***********************************************************************
3453 * NdrComplexStructBufferSize [RPCRT4.@]
3455 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3456 unsigned char *pMemory
,
3457 PFORMAT_STRING pFormat
)
3459 PFORMAT_STRING conf_array
= NULL
;
3460 PFORMAT_STRING pointer_desc
= NULL
;
3461 unsigned char *OldMemory
= pStubMsg
->Memory
;
3462 int pointer_length_set
= 0;
3464 ULONG max_count
= 0;
3467 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3469 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
3471 if(!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
3473 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3474 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
3476 /* get the buffer length after complex struct data, but before
3478 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3479 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
3480 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3482 /* save it for use by embedded pointer code later */
3483 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3484 pointer_length_set
= 1;
3485 TRACE("difference = 0x%x\n", pStubMsg
->PointerLength
- saved_buffer_length
);
3487 /* restore the original buffer length */
3488 pStubMsg
->BufferLength
= saved_buffer_length
;
3492 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3494 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3497 pStubMsg
->Memory
= pMemory
;
3501 ULONG struct_size
= ComplexStructSize(pStubMsg
, pFormat
);
3502 array_compute_and_size_conformance(conf_array
[0], pStubMsg
, pMemory
+ struct_size
,
3505 /* these could be changed in ComplexMarshall so save them for later */
3506 max_count
= pStubMsg
->MaxCount
;
3507 count
= pStubMsg
->ActualCount
;
3508 offset
= pStubMsg
->Offset
;
3511 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3515 pStubMsg
->MaxCount
= max_count
;
3516 pStubMsg
->ActualCount
= count
;
3517 pStubMsg
->Offset
= offset
;
3518 array_buffer_size(conf_array
[0], pStubMsg
, pMemory
, conf_array
,
3519 TRUE
/* fHasPointers */);
3522 pStubMsg
->Memory
= OldMemory
;
3524 if(pointer_length_set
)
3526 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3527 pStubMsg
->PointerLength
= 0;
3532 /***********************************************************************
3533 * NdrComplexStructMemorySize [RPCRT4.@]
3535 ULONG WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3536 PFORMAT_STRING pFormat
)
3538 unsigned size
= *(const WORD
*)(pFormat
+2);
3539 PFORMAT_STRING conf_array
= NULL
;
3540 PFORMAT_STRING pointer_desc
= NULL
;
3542 ULONG max_count
= 0;
3545 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3547 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
3550 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3552 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3557 array_read_conformance(conf_array
[0], pStubMsg
, conf_array
);
3559 /* these could be changed in ComplexStructMemorySize so save them for
3561 max_count
= pStubMsg
->MaxCount
;
3562 count
= pStubMsg
->ActualCount
;
3563 offset
= pStubMsg
->Offset
;
3566 ComplexStructMemorySize(pStubMsg
, pFormat
, pointer_desc
);
3570 pStubMsg
->MaxCount
= max_count
;
3571 pStubMsg
->ActualCount
= count
;
3572 pStubMsg
->Offset
= offset
;
3573 array_memory_size(conf_array
[0], pStubMsg
, conf_array
,
3574 TRUE
/* fHasPointers */);
3580 /***********************************************************************
3581 * NdrComplexStructFree [RPCRT4.@]
3583 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3584 unsigned char *pMemory
,
3585 PFORMAT_STRING pFormat
)
3587 PFORMAT_STRING conf_array
= NULL
;
3588 PFORMAT_STRING pointer_desc
= NULL
;
3589 unsigned char *OldMemory
= pStubMsg
->Memory
;
3591 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3594 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3596 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3599 pStubMsg
->Memory
= pMemory
;
3601 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3604 array_free(conf_array
[0], pStubMsg
, pMemory
, conf_array
,
3605 TRUE
/* fHasPointers */);
3607 pStubMsg
->Memory
= OldMemory
;
3610 /***********************************************************************
3611 * NdrConformantArrayMarshall [RPCRT4.@]
3613 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3614 unsigned char *pMemory
,
3615 PFORMAT_STRING pFormat
)
3617 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3618 if (pFormat
[0] != RPC_FC_CARRAY
)
3620 ERR("invalid format = 0x%x\n", pFormat
[0]);
3621 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3624 array_compute_and_write_conformance(RPC_FC_CARRAY
, pStubMsg
, pMemory
,
3626 array_write_variance_and_marshall(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3627 TRUE
/* fHasPointers */);
3632 /***********************************************************************
3633 * NdrConformantArrayUnmarshall [RPCRT4.@]
3635 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3636 unsigned char **ppMemory
,
3637 PFORMAT_STRING pFormat
,
3638 unsigned char fMustAlloc
)
3640 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3641 if (pFormat
[0] != RPC_FC_CARRAY
)
3643 ERR("invalid format = 0x%x\n", pFormat
[0]);
3644 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3647 array_read_conformance(RPC_FC_CARRAY
, pStubMsg
, pFormat
);
3648 array_read_variance_and_unmarshall(RPC_FC_CARRAY
, pStubMsg
, ppMemory
, pFormat
,
3650 TRUE
/* fUseBufferMemoryServer */,
3651 TRUE
/* fUnmarshall */);
3656 /***********************************************************************
3657 * NdrConformantArrayBufferSize [RPCRT4.@]
3659 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3660 unsigned char *pMemory
,
3661 PFORMAT_STRING pFormat
)
3663 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3664 if (pFormat
[0] != RPC_FC_CARRAY
)
3666 ERR("invalid format = 0x%x\n", pFormat
[0]);
3667 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3670 array_compute_and_size_conformance(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
);
3671 array_buffer_size(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3672 TRUE
/* fHasPointers */);
3675 /***********************************************************************
3676 * NdrConformantArrayMemorySize [RPCRT4.@]
3678 ULONG WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3679 PFORMAT_STRING pFormat
)
3681 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3682 if (pFormat
[0] != RPC_FC_CARRAY
)
3684 ERR("invalid format = 0x%x\n", pFormat
[0]);
3685 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3688 array_read_conformance(RPC_FC_CARRAY
, pStubMsg
, pFormat
);
3689 array_memory_size(RPC_FC_CARRAY
, pStubMsg
, pFormat
, TRUE
/* fHasPointers */);
3691 return pStubMsg
->MemorySize
;
3694 /***********************************************************************
3695 * NdrConformantArrayFree [RPCRT4.@]
3697 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3698 unsigned char *pMemory
,
3699 PFORMAT_STRING pFormat
)
3701 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3702 if (pFormat
[0] != RPC_FC_CARRAY
)
3704 ERR("invalid format = 0x%x\n", pFormat
[0]);
3705 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3708 array_free(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3709 TRUE
/* fHasPointers */);
3713 /***********************************************************************
3714 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3716 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
3717 unsigned char* pMemory
,
3718 PFORMAT_STRING pFormat
)
3720 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3722 if (pFormat
[0] != RPC_FC_CVARRAY
)
3724 ERR("invalid format type %x\n", pFormat
[0]);
3725 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3729 array_compute_and_write_conformance(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
3731 array_write_variance_and_marshall(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
3732 pFormat
, TRUE
/* fHasPointers */);
3738 /***********************************************************************
3739 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
3741 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
3742 unsigned char** ppMemory
,
3743 PFORMAT_STRING pFormat
,
3744 unsigned char fMustAlloc
)
3746 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3748 if (pFormat
[0] != RPC_FC_CVARRAY
)
3750 ERR("invalid format type %x\n", pFormat
[0]);
3751 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3755 array_read_conformance(RPC_FC_CVARRAY
, pStubMsg
, pFormat
);
3756 array_read_variance_and_unmarshall(RPC_FC_CVARRAY
, pStubMsg
, ppMemory
,
3757 pFormat
, fMustAlloc
,
3758 TRUE
/* fUseBufferMemoryServer */,
3759 TRUE
/* fUnmarshall */);
3765 /***********************************************************************
3766 * NdrConformantVaryingArrayFree [RPCRT4.@]
3768 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
3769 unsigned char* pMemory
,
3770 PFORMAT_STRING pFormat
)
3772 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3774 if (pFormat
[0] != RPC_FC_CVARRAY
)
3776 ERR("invalid format type %x\n", pFormat
[0]);
3777 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3781 array_free(RPC_FC_CVARRAY
, pStubMsg
, pMemory
, pFormat
,
3782 TRUE
/* fHasPointers */);
3786 /***********************************************************************
3787 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
3789 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
3790 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
3792 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3794 if (pFormat
[0] != RPC_FC_CVARRAY
)
3796 ERR("invalid format type %x\n", pFormat
[0]);
3797 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3801 array_compute_and_size_conformance(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
3803 array_buffer_size(RPC_FC_CVARRAY
, pStubMsg
, pMemory
, pFormat
,
3804 TRUE
/* fHasPointers */);
3808 /***********************************************************************
3809 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
3811 ULONG WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
3812 PFORMAT_STRING pFormat
)
3814 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
3816 if (pFormat
[0] != RPC_FC_CVARRAY
)
3818 ERR("invalid format type %x\n", pFormat
[0]);
3819 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3820 return pStubMsg
->MemorySize
;
3823 array_read_conformance(RPC_FC_CVARRAY
, pStubMsg
, pFormat
);
3824 array_memory_size(RPC_FC_CVARRAY
, pStubMsg
, pFormat
,
3825 TRUE
/* fHasPointers */);
3827 return pStubMsg
->MemorySize
;
3831 /***********************************************************************
3832 * NdrComplexArrayMarshall [RPCRT4.@]
3834 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3835 unsigned char *pMemory
,
3836 PFORMAT_STRING pFormat
)
3838 ULONG i
, count
, def
;
3839 BOOL variance_present
;
3840 unsigned char alignment
;
3841 int pointer_buffer_mark_set
= 0;
3843 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3845 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3847 ERR("invalid format type %x\n", pFormat
[0]);
3848 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3852 alignment
= pFormat
[1] + 1;
3854 if (!pStubMsg
->PointerBufferMark
)
3856 /* save buffer fields that may be changed by buffer sizer functions
3857 * and that may be needed later on */
3858 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3859 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
3860 ULONG_PTR saved_max_count
= pStubMsg
->MaxCount
;
3861 ULONG saved_offset
= pStubMsg
->Offset
;
3862 ULONG saved_actual_count
= pStubMsg
->ActualCount
;
3864 /* get the buffer pointer after complex array data, but before
3866 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
;
3867 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3868 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
3869 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3871 /* save it for use by embedded pointer code later */
3872 pStubMsg
->PointerBufferMark
= (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
;
3873 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
));
3874 pointer_buffer_mark_set
= 1;
3876 /* restore fields */
3877 pStubMsg
->ActualCount
= saved_actual_count
;
3878 pStubMsg
->Offset
= saved_offset
;
3879 pStubMsg
->MaxCount
= saved_max_count
;
3880 pStubMsg
->BufferLength
= saved_buffer_length
;
3883 def
= *(const WORD
*)&pFormat
[2];
3886 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3887 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3889 variance_present
= IsConformanceOrVariancePresent(pFormat
);
3890 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3891 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3893 WriteConformance(pStubMsg
);
3894 if (variance_present
)
3895 WriteVariance(pStubMsg
);
3897 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
3899 count
= pStubMsg
->ActualCount
;
3900 for (i
= 0; i
< count
; i
++)
3901 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
3903 STD_OVERFLOW_CHECK(pStubMsg
);
3905 if (pointer_buffer_mark_set
)
3907 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3908 pStubMsg
->PointerBufferMark
= NULL
;
3914 /***********************************************************************
3915 * NdrComplexArrayUnmarshall [RPCRT4.@]
3917 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3918 unsigned char **ppMemory
,
3919 PFORMAT_STRING pFormat
,
3920 unsigned char fMustAlloc
)
3922 ULONG i
, count
, size
;
3923 unsigned char alignment
;
3924 unsigned char *pMemory
;
3925 unsigned char *saved_buffer
;
3926 int pointer_buffer_mark_set
= 0;
3927 int saved_ignore_embedded
;
3929 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3931 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3933 ERR("invalid format type %x\n", pFormat
[0]);
3934 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3938 alignment
= pFormat
[1] + 1;
3940 saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3941 /* save buffer pointer */
3942 saved_buffer
= pStubMsg
->Buffer
;
3943 /* get the buffer pointer after complex array data, but before
3945 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3946 pStubMsg
->MemorySize
= 0;
3947 NdrComplexArrayMemorySize(pStubMsg
, pFormat
);
3948 size
= pStubMsg
->MemorySize
;
3949 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3951 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->Buffer
- saved_buffer
));
3952 if (!pStubMsg
->PointerBufferMark
)
3954 /* save it for use by embedded pointer code later */
3955 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3956 pointer_buffer_mark_set
= 1;
3958 /* restore the original buffer */
3959 pStubMsg
->Buffer
= saved_buffer
;
3963 pFormat
= ReadConformance(pStubMsg
, pFormat
);
3964 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3966 if (!fMustAlloc
&& !*ppMemory
)
3969 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3971 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3973 pMemory
= *ppMemory
;
3974 count
= pStubMsg
->ActualCount
;
3975 for (i
= 0; i
< count
; i
++)
3976 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
, fMustAlloc
);
3978 if (pointer_buffer_mark_set
)
3980 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3981 pStubMsg
->PointerBufferMark
= NULL
;
3987 /***********************************************************************
3988 * NdrComplexArrayBufferSize [RPCRT4.@]
3990 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3991 unsigned char *pMemory
,
3992 PFORMAT_STRING pFormat
)
3994 ULONG i
, count
, def
;
3995 unsigned char alignment
;
3996 BOOL variance_present
;
3997 int pointer_length_set
= 0;
3999 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4001 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4003 ERR("invalid format type %x\n", pFormat
[0]);
4004 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4008 alignment
= pFormat
[1] + 1;
4010 if (!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
4012 /* save buffer fields that may be changed by buffer sizer functions
4013 * and that may be needed later on */
4014 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
4015 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
4016 ULONG_PTR saved_max_count
= pStubMsg
->MaxCount
;
4017 ULONG saved_offset
= pStubMsg
->Offset
;
4018 ULONG saved_actual_count
= pStubMsg
->ActualCount
;
4020 /* get the buffer pointer after complex array data, but before
4022 pStubMsg
->IgnoreEmbeddedPointers
= 1;
4023 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
4024 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
4026 /* save it for use by embedded pointer code later */
4027 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4028 pointer_length_set
= 1;
4030 /* restore fields */
4031 pStubMsg
->ActualCount
= saved_actual_count
;
4032 pStubMsg
->Offset
= saved_offset
;
4033 pStubMsg
->MaxCount
= saved_max_count
;
4034 pStubMsg
->BufferLength
= saved_buffer_length
;
4036 def
= *(const WORD
*)&pFormat
[2];
4039 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
4040 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
4041 SizeConformance(pStubMsg
);
4043 variance_present
= IsConformanceOrVariancePresent(pFormat
);
4044 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
4045 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
4047 if (variance_present
)
4048 SizeVariance(pStubMsg
);
4050 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
4052 count
= pStubMsg
->ActualCount
;
4053 for (i
= 0; i
< count
; i
++)
4054 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
4056 if(pointer_length_set
)
4058 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4059 pStubMsg
->PointerLength
= 0;
4063 /***********************************************************************
4064 * NdrComplexArrayMemorySize [RPCRT4.@]
4066 ULONG WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4067 PFORMAT_STRING pFormat
)
4069 ULONG i
, count
, esize
, SavedMemorySize
, MemorySize
;
4070 unsigned char alignment
;
4072 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
4074 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4076 ERR("invalid format type %x\n", pFormat
[0]);
4077 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4081 alignment
= pFormat
[1] + 1;
4085 pFormat
= ReadConformance(pStubMsg
, pFormat
);
4086 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
4088 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4090 SavedMemorySize
= pStubMsg
->MemorySize
;
4092 esize
= ComplexStructSize(pStubMsg
, pFormat
);
4094 MemorySize
= safe_multiply(pStubMsg
->MaxCount
, esize
);
4096 count
= pStubMsg
->ActualCount
;
4097 for (i
= 0; i
< count
; i
++)
4098 ComplexStructMemorySize(pStubMsg
, pFormat
, NULL
);
4100 pStubMsg
->MemorySize
= SavedMemorySize
;
4102 pStubMsg
->MemorySize
+= MemorySize
;
4106 /***********************************************************************
4107 * NdrComplexArrayFree [RPCRT4.@]
4109 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4110 unsigned char *pMemory
,
4111 PFORMAT_STRING pFormat
)
4113 ULONG i
, count
, def
;
4115 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4117 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4119 ERR("invalid format type %x\n", pFormat
[0]);
4120 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4124 def
= *(const WORD
*)&pFormat
[2];
4127 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
4128 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
4130 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
4131 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
4133 count
= pStubMsg
->ActualCount
;
4134 for (i
= 0; i
< count
; i
++)
4135 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
4138 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg
,
4139 USER_MARSHAL_CB_TYPE cbtype
, PFORMAT_STRING pFormat
,
4140 USER_MARSHAL_CB
*umcb
)
4142 umcb
->Flags
= MAKELONG(pStubMsg
->dwDestContext
,
4143 pStubMsg
->RpcMsg
->DataRepresentation
);
4144 umcb
->pStubMsg
= pStubMsg
;
4145 umcb
->pReserve
= NULL
;
4146 umcb
->Signature
= USER_MARSHAL_CB_SIGNATURE
;
4147 umcb
->CBType
= cbtype
;
4148 umcb
->pFormat
= pFormat
;
4149 umcb
->pTypeFormat
= NULL
/* FIXME */;
4152 #define USER_MARSHAL_PTR_PREFIX \
4153 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4154 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4156 /***********************************************************************
4157 * NdrUserMarshalMarshall [RPCRT4.@]
4159 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4160 unsigned char *pMemory
,
4161 PFORMAT_STRING pFormat
)
4163 unsigned flags
= pFormat
[1];
4164 unsigned index
= *(const WORD
*)&pFormat
[2];
4165 unsigned char *saved_buffer
= NULL
;
4166 USER_MARSHAL_CB umcb
;
4168 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4169 TRACE("index=%d\n", index
);
4171 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_MARSHALL
, pFormat
, &umcb
);
4173 if (flags
& USER_MARSHAL_POINTER
)
4175 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
4176 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, USER_MARSHAL_PTR_PREFIX
);
4177 pStubMsg
->Buffer
+= 4;
4178 if (pStubMsg
->PointerBufferMark
)
4180 saved_buffer
= pStubMsg
->Buffer
;
4181 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4182 pStubMsg
->PointerBufferMark
= NULL
;
4184 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 8);
4187 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4190 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
4191 &umcb
.Flags
, pStubMsg
->Buffer
, pMemory
);
4195 STD_OVERFLOW_CHECK(pStubMsg
);
4196 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4197 pStubMsg
->Buffer
= saved_buffer
;
4200 STD_OVERFLOW_CHECK(pStubMsg
);
4205 /***********************************************************************
4206 * NdrUserMarshalUnmarshall [RPCRT4.@]
4208 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4209 unsigned char **ppMemory
,
4210 PFORMAT_STRING pFormat
,
4211 unsigned char fMustAlloc
)
4213 unsigned flags
= pFormat
[1];
4214 unsigned index
= *(const WORD
*)&pFormat
[2];
4215 DWORD memsize
= *(const WORD
*)&pFormat
[4];
4216 unsigned char *saved_buffer
= NULL
;
4217 USER_MARSHAL_CB umcb
;
4219 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4220 TRACE("index=%d\n", index
);
4222 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_UNMARSHALL
, pFormat
, &umcb
);
4224 if (flags
& USER_MARSHAL_POINTER
)
4226 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4227 /* skip pointer prefix */
4228 pStubMsg
->Buffer
+= 4;
4229 if (pStubMsg
->PointerBufferMark
)
4231 saved_buffer
= pStubMsg
->Buffer
;
4232 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4233 pStubMsg
->PointerBufferMark
= NULL
;
4235 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
4238 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4240 if (!fMustAlloc
&& !*ppMemory
)
4244 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
4245 memset(*ppMemory
, 0, memsize
);
4249 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
4250 &umcb
.Flags
, pStubMsg
->Buffer
, *ppMemory
);
4254 STD_OVERFLOW_CHECK(pStubMsg
);
4255 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4256 pStubMsg
->Buffer
= saved_buffer
;
4262 /***********************************************************************
4263 * NdrUserMarshalBufferSize [RPCRT4.@]
4265 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4266 unsigned char *pMemory
,
4267 PFORMAT_STRING pFormat
)
4269 unsigned flags
= pFormat
[1];
4270 unsigned index
= *(const WORD
*)&pFormat
[2];
4271 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
4272 USER_MARSHAL_CB umcb
;
4273 ULONG saved_buffer_length
= 0;
4275 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4276 TRACE("index=%d\n", index
);
4278 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_BUFFER_SIZE
, pFormat
, &umcb
);
4280 if (flags
& USER_MARSHAL_POINTER
)
4282 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
4283 /* skip pointer prefix */
4284 safe_buffer_length_increment(pStubMsg
, 4);
4285 if (pStubMsg
->IgnoreEmbeddedPointers
)
4287 if (pStubMsg
->PointerLength
)
4289 saved_buffer_length
= pStubMsg
->BufferLength
;
4290 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4291 pStubMsg
->PointerLength
= 0;
4293 ALIGN_LENGTH(pStubMsg
->BufferLength
, 8);
4296 ALIGN_LENGTH(pStubMsg
->BufferLength
, (flags
& 0xf) + 1);
4299 TRACE("size=%d\n", bufsize
);
4300 safe_buffer_length_increment(pStubMsg
, bufsize
);
4303 pStubMsg
->BufferLength
=
4304 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
4305 &umcb
.Flags
, pStubMsg
->BufferLength
, pMemory
);
4307 if (saved_buffer_length
)
4309 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4310 pStubMsg
->BufferLength
= saved_buffer_length
;
4315 /***********************************************************************
4316 * NdrUserMarshalMemorySize [RPCRT4.@]
4318 ULONG WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4319 PFORMAT_STRING pFormat
)
4321 unsigned flags
= pFormat
[1];
4322 unsigned index
= *(const WORD
*)&pFormat
[2];
4323 DWORD memsize
= *(const WORD
*)&pFormat
[4];
4324 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
4326 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
4327 TRACE("index=%d\n", index
);
4329 pStubMsg
->MemorySize
+= memsize
;
4331 if (flags
& USER_MARSHAL_POINTER
)
4333 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4334 /* skip pointer prefix */
4335 pStubMsg
->Buffer
+= 4;
4336 if (pStubMsg
->IgnoreEmbeddedPointers
)
4337 return pStubMsg
->MemorySize
;
4338 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
4341 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4344 FIXME("not implemented for varying buffer size\n");
4346 pStubMsg
->Buffer
+= bufsize
;
4348 return pStubMsg
->MemorySize
;
4351 /***********************************************************************
4352 * NdrUserMarshalFree [RPCRT4.@]
4354 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
4355 unsigned char *pMemory
,
4356 PFORMAT_STRING pFormat
)
4358 /* unsigned flags = pFormat[1]; */
4359 unsigned index
= *(const WORD
*)&pFormat
[2];
4360 USER_MARSHAL_CB umcb
;
4362 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4363 TRACE("index=%d\n", index
);
4365 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_FREE
, pFormat
, &umcb
);
4367 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
4368 &umcb
.Flags
, pMemory
);
4371 /***********************************************************************
4372 * NdrGetUserMarshalInfo [RPCRT4.@]
4374 RPC_STATUS RPC_ENTRY
NdrGetUserMarshalInfo(ULONG
*flags
, ULONG level
, NDR_USER_MARSHAL_INFO
*umi
)
4376 USER_MARSHAL_CB
*umcb
= CONTAINING_RECORD(flags
, USER_MARSHAL_CB
, Flags
);
4378 TRACE("(%p,%u,%p)\n", flags
, level
, umi
);
4381 return RPC_S_INVALID_ARG
;
4383 memset(&umi
->u1
.Level1
, 0, sizeof(umi
->u1
.Level1
));
4384 umi
->InformationLevel
= level
;
4386 if (umcb
->Signature
!= USER_MARSHAL_CB_SIGNATURE
)
4387 return RPC_S_INVALID_ARG
;
4389 umi
->u1
.Level1
.pfnAllocate
= umcb
->pStubMsg
->pfnAllocate
;
4390 umi
->u1
.Level1
.pfnFree
= umcb
->pStubMsg
->pfnFree
;
4391 umi
->u1
.Level1
.pRpcChannelBuffer
= umcb
->pStubMsg
->pRpcChannelBuffer
;
4393 switch (umcb
->CBType
)
4395 case USER_MARSHAL_CB_MARSHALL
:
4396 case USER_MARSHAL_CB_UNMARSHALL
:
4398 RPC_MESSAGE
*msg
= umcb
->pStubMsg
->RpcMsg
;
4399 unsigned char *buffer_start
= msg
->Buffer
;
4400 unsigned char *buffer_end
=
4401 (unsigned char *)msg
->Buffer
+ msg
->BufferLength
;
4403 if (umcb
->pStubMsg
->Buffer
< buffer_start
||
4404 umcb
->pStubMsg
->Buffer
> buffer_end
)
4405 return ERROR_INVALID_USER_BUFFER
;
4407 umi
->u1
.Level1
.Buffer
= umcb
->pStubMsg
->Buffer
;
4408 umi
->u1
.Level1
.BufferSize
= buffer_end
- umcb
->pStubMsg
->Buffer
;
4411 case USER_MARSHAL_CB_BUFFER_SIZE
:
4412 case USER_MARSHAL_CB_FREE
:
4415 WARN("unrecognised CBType %d\n", umcb
->CBType
);
4421 /***********************************************************************
4422 * NdrClearOutParameters [RPCRT4.@]
4424 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
4425 PFORMAT_STRING pFormat
,
4428 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
4431 /***********************************************************************
4432 * NdrConvert [RPCRT4.@]
4434 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
4436 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
4437 /* FIXME: since this stub doesn't do any converting, the proper behavior
4438 is to raise an exception */
4441 /***********************************************************************
4442 * NdrConvert2 [RPCRT4.@]
4444 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, LONG NumberParams
)
4446 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4447 pStubMsg
, pFormat
, NumberParams
);
4448 /* FIXME: since this stub doesn't do any converting, the proper behavior
4449 is to raise an exception */
4452 #include "pshpack1.h"
4453 typedef struct _NDR_CSTRUCT_FORMAT
4456 unsigned char alignment
;
4457 unsigned short memory_size
;
4458 short offset_to_array_description
;
4459 } NDR_CSTRUCT_FORMAT
, NDR_CVSTRUCT_FORMAT
;
4460 #include "poppack.h"
4462 /***********************************************************************
4463 * NdrConformantStructMarshall [RPCRT4.@]
4465 unsigned char * WINAPI
NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4466 unsigned char *pMemory
,
4467 PFORMAT_STRING pFormat
)
4469 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4470 PFORMAT_STRING pCArrayFormat
;
4471 ULONG esize
, bufsize
;
4473 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4475 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4476 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4478 ERR("invalid format type %x\n", pCStructFormat
->type
);
4479 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4483 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4484 pCStructFormat
->offset_to_array_description
;
4485 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4487 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4488 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4491 esize
= *(const WORD
*)(pCArrayFormat
+2);
4493 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4494 pCArrayFormat
+ 4, 0);
4496 WriteConformance(pStubMsg
);
4498 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4500 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4502 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4503 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4505 ERR("integer overflow of memory_size %u with bufsize %u\n",
4506 pCStructFormat
->memory_size
, bufsize
);
4507 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4509 /* copy constant sized part of struct */
4510 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4511 safe_copy_to_buffer(pStubMsg
, pMemory
, pCStructFormat
->memory_size
+ bufsize
);
4513 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4514 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4519 /***********************************************************************
4520 * NdrConformantStructUnmarshall [RPCRT4.@]
4522 unsigned char * WINAPI
NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4523 unsigned char **ppMemory
,
4524 PFORMAT_STRING pFormat
,
4525 unsigned char fMustAlloc
)
4527 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4528 PFORMAT_STRING pCArrayFormat
;
4529 ULONG esize
, bufsize
;
4530 unsigned char *saved_buffer
;
4532 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4534 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4535 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4537 ERR("invalid format type %x\n", pCStructFormat
->type
);
4538 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4541 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4542 pCStructFormat
->offset_to_array_description
;
4543 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4545 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4546 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4549 esize
= *(const WORD
*)(pCArrayFormat
+2);
4551 pCArrayFormat
= ReadConformance(pStubMsg
, pCArrayFormat
+ 4);
4553 ALIGN_POINTER(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4555 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4557 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4558 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4560 ERR("integer overflow of memory_size %u with bufsize %u\n",
4561 pCStructFormat
->memory_size
, bufsize
);
4562 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4567 SIZE_T size
= pCStructFormat
->memory_size
+ bufsize
;
4568 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4572 if (!pStubMsg
->IsClient
&& !*ppMemory
)
4573 /* for servers, we just point straight into the RPC buffer */
4574 *ppMemory
= pStubMsg
->Buffer
;
4577 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4578 safe_buffer_increment(pStubMsg
, pCStructFormat
->memory_size
+ bufsize
);
4579 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4580 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4582 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
4583 if (*ppMemory
!= saved_buffer
)
4584 memcpy(*ppMemory
, saved_buffer
, pCStructFormat
->memory_size
+ bufsize
);
4589 /***********************************************************************
4590 * NdrConformantStructBufferSize [RPCRT4.@]
4592 void WINAPI
NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4593 unsigned char *pMemory
,
4594 PFORMAT_STRING pFormat
)
4596 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4597 PFORMAT_STRING pCArrayFormat
;
4600 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4602 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4603 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4605 ERR("invalid format type %x\n", pCStructFormat
->type
);
4606 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4609 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4610 pCStructFormat
->offset_to_array_description
;
4611 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4613 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4614 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4617 esize
= *(const WORD
*)(pCArrayFormat
+2);
4619 pCArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
, pCArrayFormat
+4, 0);
4620 SizeConformance(pStubMsg
);
4622 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCStructFormat
->alignment
+ 1);
4624 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4626 safe_buffer_length_increment(pStubMsg
, pCStructFormat
->memory_size
);
4627 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
4629 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4630 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4633 /***********************************************************************
4634 * NdrConformantStructMemorySize [RPCRT4.@]
4636 ULONG WINAPI
NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4637 PFORMAT_STRING pFormat
)
4643 /***********************************************************************
4644 * NdrConformantStructFree [RPCRT4.@]
4646 void WINAPI
NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
4647 unsigned char *pMemory
,
4648 PFORMAT_STRING pFormat
)
4650 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4651 PFORMAT_STRING pCArrayFormat
;
4653 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4655 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4656 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4658 ERR("invalid format type %x\n", pCStructFormat
->type
);
4659 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4663 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4664 pCStructFormat
->offset_to_array_description
;
4665 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4667 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4668 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4672 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4673 pCArrayFormat
+ 4, 0);
4675 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4677 /* copy constant sized part of struct */
4678 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4680 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4681 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4684 /***********************************************************************
4685 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4687 unsigned char * WINAPI
NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4688 unsigned char *pMemory
,
4689 PFORMAT_STRING pFormat
)
4691 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4692 PFORMAT_STRING pCVArrayFormat
;
4694 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4696 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4697 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4699 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4700 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4704 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4705 pCVStructFormat
->offset_to_array_description
;
4707 array_compute_and_write_conformance(*pCVArrayFormat
, pStubMsg
,
4708 pMemory
+ pCVStructFormat
->memory_size
,
4711 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4713 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4715 /* write constant sized part */
4716 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4717 safe_copy_to_buffer(pStubMsg
, pMemory
, pCVStructFormat
->memory_size
);
4719 array_write_variance_and_marshall(*pCVArrayFormat
, pStubMsg
,
4720 pMemory
+ pCVStructFormat
->memory_size
,
4721 pCVArrayFormat
, FALSE
/* fHasPointers */);
4723 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4728 /***********************************************************************
4729 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4731 unsigned char * WINAPI
NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4732 unsigned char **ppMemory
,
4733 PFORMAT_STRING pFormat
,
4734 unsigned char fMustAlloc
)
4736 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4737 PFORMAT_STRING pCVArrayFormat
;
4738 ULONG memsize
, bufsize
;
4739 unsigned char *saved_buffer
, *saved_array_buffer
;
4741 unsigned char *array_memory
;
4743 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4745 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4746 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4748 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4749 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4753 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4754 pCVStructFormat
->offset_to_array_description
;
4756 memsize
= array_read_conformance(*pCVArrayFormat
, pStubMsg
,
4759 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4761 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4763 /* work out how much memory to allocate if we need to do so */
4764 if (!fMustAlloc
&& !*ppMemory
)
4768 SIZE_T size
= pCVStructFormat
->memory_size
+ memsize
;
4769 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4772 /* mark the start of the constant data */
4773 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4774 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4776 array_memory
= *ppMemory
+ pCVStructFormat
->memory_size
;
4777 bufsize
= array_read_variance_and_unmarshall(*pCVArrayFormat
, pStubMsg
,
4778 &array_memory
, pCVArrayFormat
,
4779 FALSE
/* fMustAlloc */,
4780 FALSE
/* fUseServerBufferMemory */,
4781 FALSE
/* fUnmarshall */);
4783 /* save offset in case unmarshalling pointers changes it */
4784 offset
= pStubMsg
->Offset
;
4786 /* mark the start of the array data */
4787 saved_array_buffer
= pStubMsg
->Buffer
;
4788 safe_buffer_increment(pStubMsg
, bufsize
);
4790 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4792 /* copy the constant data */
4793 memcpy(*ppMemory
, saved_buffer
, pCVStructFormat
->memory_size
);
4794 /* copy the array data */
4795 TRACE("copying %p to %p\n", saved_array_buffer
, *ppMemory
+ pCVStructFormat
->memory_size
);
4796 memcpy(*ppMemory
+ pCVStructFormat
->memory_size
+ offset
,
4797 saved_array_buffer
, bufsize
);
4799 if (*pCVArrayFormat
== RPC_FC_C_CSTRING
)
4800 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory
+ pCVStructFormat
->memory_size
)));
4801 else if (*pCVArrayFormat
== RPC_FC_C_WSTRING
)
4802 TRACE("string=%s\n", debugstr_w((WCHAR
*)(*ppMemory
+ pCVStructFormat
->memory_size
)));
4807 /***********************************************************************
4808 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
4810 void WINAPI
NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4811 unsigned char *pMemory
,
4812 PFORMAT_STRING pFormat
)
4814 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4815 PFORMAT_STRING pCVArrayFormat
;
4817 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4819 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4820 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4822 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4823 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4827 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4828 pCVStructFormat
->offset_to_array_description
;
4829 array_compute_and_size_conformance(*pCVArrayFormat
, pStubMsg
,
4830 pMemory
+ pCVStructFormat
->memory_size
,
4833 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCVStructFormat
->alignment
+ 1);
4835 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4837 safe_buffer_length_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4839 array_buffer_size(*pCVArrayFormat
, pStubMsg
,
4840 pMemory
+ pCVStructFormat
->memory_size
, pCVArrayFormat
,
4841 FALSE
/* fHasPointers */);
4843 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4846 /***********************************************************************
4847 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4849 ULONG WINAPI
NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4850 PFORMAT_STRING pFormat
)
4852 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4853 PFORMAT_STRING pCVArrayFormat
;
4855 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4857 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4858 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4860 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4861 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4865 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4866 pCVStructFormat
->offset_to_array_description
;
4867 array_read_conformance(*pCVArrayFormat
, pStubMsg
, pCVArrayFormat
);
4869 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4871 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4873 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4874 array_memory_size(*pCVArrayFormat
, pStubMsg
, pCVArrayFormat
,
4875 FALSE
/* fHasPointers */);
4877 pStubMsg
->MemorySize
+= pCVStructFormat
->memory_size
;
4879 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4881 return pStubMsg
->MemorySize
;
4884 /***********************************************************************
4885 * NdrConformantVaryingStructFree [RPCRT4.@]
4887 void WINAPI
NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
4888 unsigned char *pMemory
,
4889 PFORMAT_STRING pFormat
)
4891 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4892 PFORMAT_STRING pCVArrayFormat
;
4894 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4896 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4897 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4899 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4900 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4904 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4905 pCVStructFormat
->offset_to_array_description
;
4906 array_free(*pCVArrayFormat
, pStubMsg
,
4907 pMemory
+ pCVStructFormat
->memory_size
, pCVArrayFormat
,
4908 FALSE
/* fHasPointers */);
4910 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4912 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4915 #include "pshpack1.h"
4919 unsigned char alignment
;
4920 unsigned short total_size
;
4921 } NDR_SMFARRAY_FORMAT
;
4926 unsigned char alignment
;
4928 } NDR_LGFARRAY_FORMAT
;
4929 #include "poppack.h"
4931 /***********************************************************************
4932 * NdrFixedArrayMarshall [RPCRT4.@]
4934 unsigned char * WINAPI
NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4935 unsigned char *pMemory
,
4936 PFORMAT_STRING pFormat
)
4938 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4941 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4943 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4944 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4946 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4947 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4951 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4953 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4955 total_size
= pSmFArrayFormat
->total_size
;
4956 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4960 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4961 total_size
= pLgFArrayFormat
->total_size
;
4962 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4965 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4966 safe_copy_to_buffer(pStubMsg
, pMemory
, total_size
);
4968 pFormat
= EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4973 /***********************************************************************
4974 * NdrFixedArrayUnmarshall [RPCRT4.@]
4976 unsigned char * WINAPI
NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4977 unsigned char **ppMemory
,
4978 PFORMAT_STRING pFormat
,
4979 unsigned char fMustAlloc
)
4981 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4983 unsigned char *saved_buffer
;
4985 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4987 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4988 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4990 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4991 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4995 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4997 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4999 total_size
= pSmFArrayFormat
->total_size
;
5000 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5004 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5005 total_size
= pLgFArrayFormat
->total_size
;
5006 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5010 *ppMemory
= NdrAllocate(pStubMsg
, total_size
);
5013 if (!pStubMsg
->IsClient
&& !*ppMemory
)
5014 /* for servers, we just point straight into the RPC buffer */
5015 *ppMemory
= pStubMsg
->Buffer
;
5018 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5019 safe_buffer_increment(pStubMsg
, total_size
);
5020 pFormat
= EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
5022 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
5023 if (*ppMemory
!= saved_buffer
)
5024 memcpy(*ppMemory
, saved_buffer
, total_size
);
5029 /***********************************************************************
5030 * NdrFixedArrayBufferSize [RPCRT4.@]
5032 void WINAPI
NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5033 unsigned char *pMemory
,
5034 PFORMAT_STRING pFormat
)
5036 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5039 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5041 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5042 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5044 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5045 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5049 ALIGN_LENGTH(pStubMsg
->BufferLength
, pSmFArrayFormat
->alignment
+ 1);
5051 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5053 total_size
= pSmFArrayFormat
->total_size
;
5054 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5058 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5059 total_size
= pLgFArrayFormat
->total_size
;
5060 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5062 safe_buffer_length_increment(pStubMsg
, total_size
);
5064 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5067 /***********************************************************************
5068 * NdrFixedArrayMemorySize [RPCRT4.@]
5070 ULONG WINAPI
NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5071 PFORMAT_STRING pFormat
)
5073 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5076 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5078 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5079 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5081 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5082 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5086 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
5088 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5090 total_size
= pSmFArrayFormat
->total_size
;
5091 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5095 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5096 total_size
= pLgFArrayFormat
->total_size
;
5097 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5099 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5100 safe_buffer_increment(pStubMsg
, total_size
);
5101 pStubMsg
->MemorySize
+= total_size
;
5103 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5108 /***********************************************************************
5109 * NdrFixedArrayFree [RPCRT4.@]
5111 void WINAPI
NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
5112 unsigned char *pMemory
,
5113 PFORMAT_STRING pFormat
)
5115 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5117 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5119 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5120 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5122 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5123 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5127 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5128 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5131 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5132 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5135 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5138 /***********************************************************************
5139 * NdrVaryingArrayMarshall [RPCRT4.@]
5141 unsigned char * WINAPI
NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5142 unsigned char *pMemory
,
5143 PFORMAT_STRING pFormat
)
5145 unsigned char alignment
;
5146 DWORD elements
, esize
;
5149 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5151 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5152 (pFormat
[0] != RPC_FC_LGVARRAY
))
5154 ERR("invalid format type %x\n", pFormat
[0]);
5155 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5159 alignment
= pFormat
[1] + 1;
5161 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5164 pFormat
+= sizeof(WORD
);
5165 elements
= *(const WORD
*)pFormat
;
5166 pFormat
+= sizeof(WORD
);
5171 pFormat
+= sizeof(DWORD
);
5172 elements
= *(const DWORD
*)pFormat
;
5173 pFormat
+= sizeof(DWORD
);
5176 esize
= *(const WORD
*)pFormat
;
5177 pFormat
+= sizeof(WORD
);
5179 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5180 if ((pStubMsg
->ActualCount
> elements
) ||
5181 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5183 RpcRaiseException(RPC_S_INVALID_BOUND
);
5187 WriteVariance(pStubMsg
);
5189 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
5191 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
5192 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5193 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
5195 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
5200 /***********************************************************************
5201 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5203 unsigned char * WINAPI
NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5204 unsigned char **ppMemory
,
5205 PFORMAT_STRING pFormat
,
5206 unsigned char fMustAlloc
)
5208 unsigned char alignment
;
5209 DWORD size
, elements
, esize
;
5211 unsigned char *saved_buffer
;
5214 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5216 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5217 (pFormat
[0] != RPC_FC_LGVARRAY
))
5219 ERR("invalid format type %x\n", pFormat
[0]);
5220 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5224 alignment
= pFormat
[1] + 1;
5226 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5229 size
= *(const WORD
*)pFormat
;
5230 pFormat
+= sizeof(WORD
);
5231 elements
= *(const WORD
*)pFormat
;
5232 pFormat
+= sizeof(WORD
);
5237 size
= *(const DWORD
*)pFormat
;
5238 pFormat
+= sizeof(DWORD
);
5239 elements
= *(const DWORD
*)pFormat
;
5240 pFormat
+= sizeof(DWORD
);
5243 esize
= *(const WORD
*)pFormat
;
5244 pFormat
+= sizeof(WORD
);
5246 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
5248 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
5250 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
5251 offset
= pStubMsg
->Offset
;
5253 if (!fMustAlloc
&& !*ppMemory
)
5256 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5257 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5258 safe_buffer_increment(pStubMsg
, bufsize
);
5260 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
5262 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
5267 /***********************************************************************
5268 * NdrVaryingArrayBufferSize [RPCRT4.@]
5270 void WINAPI
NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5271 unsigned char *pMemory
,
5272 PFORMAT_STRING pFormat
)
5274 unsigned char alignment
;
5275 DWORD elements
, esize
;
5277 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5279 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5280 (pFormat
[0] != RPC_FC_LGVARRAY
))
5282 ERR("invalid format type %x\n", pFormat
[0]);
5283 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5287 alignment
= pFormat
[1] + 1;
5289 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5292 pFormat
+= sizeof(WORD
);
5293 elements
= *(const WORD
*)pFormat
;
5294 pFormat
+= sizeof(WORD
);
5299 pFormat
+= sizeof(DWORD
);
5300 elements
= *(const DWORD
*)pFormat
;
5301 pFormat
+= sizeof(DWORD
);
5304 esize
= *(const WORD
*)pFormat
;
5305 pFormat
+= sizeof(WORD
);
5307 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5308 if ((pStubMsg
->ActualCount
> elements
) ||
5309 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5311 RpcRaiseException(RPC_S_INVALID_BOUND
);
5315 SizeVariance(pStubMsg
);
5317 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
5319 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
5321 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5324 /***********************************************************************
5325 * NdrVaryingArrayMemorySize [RPCRT4.@]
5327 ULONG WINAPI
NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5328 PFORMAT_STRING pFormat
)
5330 unsigned char alignment
;
5331 DWORD size
, elements
, esize
;
5333 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5335 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5336 (pFormat
[0] != RPC_FC_LGVARRAY
))
5338 ERR("invalid format type %x\n", pFormat
[0]);
5339 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5343 alignment
= pFormat
[1] + 1;
5345 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5348 size
= *(const WORD
*)pFormat
;
5349 pFormat
+= sizeof(WORD
);
5350 elements
= *(const WORD
*)pFormat
;
5351 pFormat
+= sizeof(WORD
);
5356 size
= *(const DWORD
*)pFormat
;
5357 pFormat
+= sizeof(DWORD
);
5358 elements
= *(const DWORD
*)pFormat
;
5359 pFormat
+= sizeof(DWORD
);
5362 esize
= *(const WORD
*)pFormat
;
5363 pFormat
+= sizeof(WORD
);
5365 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
5367 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
5369 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
5370 pStubMsg
->MemorySize
+= size
;
5372 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5374 return pStubMsg
->MemorySize
;
5377 /***********************************************************************
5378 * NdrVaryingArrayFree [RPCRT4.@]
5380 void WINAPI
NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
5381 unsigned char *pMemory
,
5382 PFORMAT_STRING pFormat
)
5386 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5388 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5389 (pFormat
[0] != RPC_FC_LGVARRAY
))
5391 ERR("invalid format type %x\n", pFormat
[0]);
5392 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5396 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5399 pFormat
+= sizeof(WORD
);
5400 elements
= *(const WORD
*)pFormat
;
5401 pFormat
+= sizeof(WORD
);
5406 pFormat
+= sizeof(DWORD
);
5407 elements
= *(const DWORD
*)pFormat
;
5408 pFormat
+= sizeof(DWORD
);
5411 pFormat
+= sizeof(WORD
);
5413 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5414 if ((pStubMsg
->ActualCount
> elements
) ||
5415 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5417 RpcRaiseException(RPC_S_INVALID_BOUND
);
5421 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5424 static ULONG
get_discriminant(unsigned char fc
, const unsigned char *pMemory
)
5437 return *(const USHORT
*)pMemory
;
5441 return *(const ULONG
*)pMemory
;
5443 FIXME("Unhandled base type: 0x%02x\n", fc
);
5448 static PFORMAT_STRING
get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg
,
5450 PFORMAT_STRING pFormat
)
5452 unsigned short num_arms
, arm
, type
;
5454 num_arms
= *(const SHORT
*)pFormat
& 0x0fff;
5456 for(arm
= 0; arm
< num_arms
; arm
++)
5458 if(discriminant
== *(const ULONG
*)pFormat
)
5466 type
= *(const unsigned short*)pFormat
;
5467 TRACE("type %04x\n", type
);
5468 if(arm
== num_arms
) /* default arm extras */
5472 ERR("no arm for 0x%x and no default case\n", discriminant
);
5473 RpcRaiseException(RPC_S_INVALID_TAG
);
5478 TRACE("falling back to empty default case for 0x%x\n", discriminant
);
5485 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
, ULONG discriminant
, PFORMAT_STRING pFormat
)
5487 unsigned short type
;
5491 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5495 type
= *(const unsigned short*)pFormat
;
5496 if((type
& 0xff00) == 0x8000)
5498 unsigned char basetype
= LOBYTE(type
);
5499 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &basetype
);
5503 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5504 NDR_MARSHALL m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
5507 unsigned char *saved_buffer
= NULL
;
5508 int pointer_buffer_mark_set
= 0;
5515 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
5516 saved_buffer
= pStubMsg
->Buffer
;
5517 if (pStubMsg
->PointerBufferMark
)
5519 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5520 pStubMsg
->PointerBufferMark
= NULL
;
5521 pointer_buffer_mark_set
= 1;
5524 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
5526 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char **)pMemory
, desc
);
5527 if (pointer_buffer_mark_set
)
5529 STD_OVERFLOW_CHECK(pStubMsg
);
5530 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5531 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5533 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5534 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
5535 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5537 pStubMsg
->Buffer
= saved_buffer
+ 4;
5541 m(pStubMsg
, pMemory
, desc
);
5544 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5549 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5550 unsigned char **ppMemory
,
5552 PFORMAT_STRING pFormat
,
5553 unsigned char fMustAlloc
)
5555 unsigned short type
;
5559 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5563 type
= *(const unsigned short*)pFormat
;
5564 if((type
& 0xff00) == 0x8000)
5566 unsigned char basetype
= LOBYTE(type
);
5567 return NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &basetype
, FALSE
);
5571 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5572 NDR_UNMARSHALL m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
5575 unsigned char *saved_buffer
= NULL
;
5576 int pointer_buffer_mark_set
= 0;
5583 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5584 saved_buffer
= pStubMsg
->Buffer
;
5585 if (pStubMsg
->PointerBufferMark
)
5587 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5588 pStubMsg
->PointerBufferMark
= NULL
;
5589 pointer_buffer_mark_set
= 1;
5592 pStubMsg
->Buffer
+= 4; /* for pointer ID */
5594 if (saved_buffer
+ 4 > pStubMsg
->BufferEnd
)
5596 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5597 saved_buffer
, pStubMsg
->BufferEnd
);
5598 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5601 PointerUnmarshall(pStubMsg
, saved_buffer
, *(unsigned char ***)ppMemory
, **(unsigned char ***)ppMemory
, desc
, fMustAlloc
);
5602 if (pointer_buffer_mark_set
)
5604 STD_OVERFLOW_CHECK(pStubMsg
);
5605 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5606 pStubMsg
->Buffer
= saved_buffer
+ 4;
5610 m(pStubMsg
, ppMemory
, desc
, fMustAlloc
);
5613 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5618 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg
,
5619 unsigned char *pMemory
,
5621 PFORMAT_STRING pFormat
)
5623 unsigned short type
;
5627 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5631 type
= *(const unsigned short*)pFormat
;
5632 if((type
& 0xff00) == 0x8000)
5634 unsigned char basetype
= LOBYTE(type
);
5635 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &basetype
);
5639 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5640 NDR_BUFFERSIZE m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
5649 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
5650 safe_buffer_length_increment(pStubMsg
, 4); /* for pointer ID */
5651 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5653 int saved_buffer_length
= pStubMsg
->BufferLength
;
5654 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
5655 pStubMsg
->PointerLength
= 0;
5656 if(!pStubMsg
->BufferLength
)
5657 ERR("BufferLength == 0??\n");
5658 PointerBufferSize(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5659 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
5660 pStubMsg
->BufferLength
= saved_buffer_length
;
5664 m(pStubMsg
, pMemory
, desc
);
5667 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
5671 static ULONG
union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg
,
5673 PFORMAT_STRING pFormat
)
5675 unsigned short type
, size
;
5677 size
= *(const unsigned short*)pFormat
;
5678 pStubMsg
->Memory
+= size
;
5681 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5685 type
= *(const unsigned short*)pFormat
;
5686 if((type
& 0xff00) == 0x8000)
5688 return NdrBaseTypeMemorySize(pStubMsg
, pFormat
);
5692 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5693 NDR_MEMORYSIZE m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
5694 unsigned char *saved_buffer
;
5703 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5704 saved_buffer
= pStubMsg
->Buffer
;
5705 safe_buffer_increment(pStubMsg
, 4);
5706 ALIGN_LENGTH(pStubMsg
->MemorySize
, sizeof(void *));
5707 pStubMsg
->MemorySize
+= sizeof(void *);
5708 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5709 PointerMemorySize(pStubMsg
, saved_buffer
, pFormat
);
5712 return m(pStubMsg
, desc
);
5715 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5718 TRACE("size %d\n", size
);
5722 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg
,
5723 unsigned char *pMemory
,
5725 PFORMAT_STRING pFormat
)
5727 unsigned short type
;
5731 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5735 type
= *(const unsigned short*)pFormat
;
5736 if((type
& 0xff00) != 0x8000)
5738 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5739 NDR_FREE m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
5748 PointerFree(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5751 m(pStubMsg
, pMemory
, desc
);
5757 /***********************************************************************
5758 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5760 unsigned char * WINAPI
NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5761 unsigned char *pMemory
,
5762 PFORMAT_STRING pFormat
)
5764 unsigned char switch_type
;
5765 unsigned char increment
;
5768 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5771 switch_type
= *pFormat
& 0xf;
5772 increment
= (*pFormat
& 0xf0) >> 4;
5775 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, increment
);
5777 switch_value
= get_discriminant(switch_type
, pMemory
);
5778 TRACE("got switch value 0x%x\n", switch_value
);
5780 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &switch_type
);
5781 pMemory
+= increment
;
5783 return union_arm_marshall(pStubMsg
, pMemory
, switch_value
, pFormat
);
5786 /***********************************************************************
5787 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5789 unsigned char * WINAPI
NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5790 unsigned char **ppMemory
,
5791 PFORMAT_STRING pFormat
,
5792 unsigned char fMustAlloc
)
5794 unsigned char switch_type
;
5795 unsigned char increment
;
5797 unsigned short size
;
5798 unsigned char *pMemoryArm
;
5800 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5803 switch_type
= *pFormat
& 0xf;
5804 increment
= (*pFormat
& 0xf0) >> 4;
5807 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
5808 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
5809 TRACE("got switch value 0x%x\n", switch_value
);
5811 size
= *(const unsigned short*)pFormat
+ increment
;
5812 if (!fMustAlloc
&& !*ppMemory
)
5815 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5817 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
5818 * since the arm is part of the memory block that is encompassed by
5819 * the whole union. Memory is forced to allocate when pointers
5820 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
5821 * clearing the memory we pass in to the unmarshaller */
5823 memset(*ppMemory
, 0, size
);
5825 NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &switch_type
, FALSE
);
5826 pMemoryArm
= *ppMemory
+ increment
;
5828 return union_arm_unmarshall(pStubMsg
, &pMemoryArm
, switch_value
, pFormat
, FALSE
);
5831 /***********************************************************************
5832 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5834 void WINAPI
NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5835 unsigned char *pMemory
,
5836 PFORMAT_STRING pFormat
)
5838 unsigned char switch_type
;
5839 unsigned char increment
;
5842 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5845 switch_type
= *pFormat
& 0xf;
5846 increment
= (*pFormat
& 0xf0) >> 4;
5849 ALIGN_LENGTH(pStubMsg
->BufferLength
, increment
);
5850 switch_value
= get_discriminant(switch_type
, pMemory
);
5851 TRACE("got switch value 0x%x\n", switch_value
);
5853 /* Add discriminant size */
5854 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&switch_value
, &switch_type
);
5855 pMemory
+= increment
;
5857 union_arm_buffer_size(pStubMsg
, pMemory
, switch_value
, pFormat
);
5860 /***********************************************************************
5861 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5863 ULONG WINAPI
NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5864 PFORMAT_STRING pFormat
)
5866 unsigned char switch_type
;
5867 unsigned char increment
;
5870 switch_type
= *pFormat
& 0xf;
5871 increment
= (*pFormat
& 0xf0) >> 4;
5874 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
5875 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
5876 TRACE("got switch value 0x%x\n", switch_value
);
5878 pStubMsg
->Memory
+= increment
;
5880 return increment
+ union_arm_memory_size(pStubMsg
, switch_value
, pFormat
+ *(const SHORT
*)pFormat
);
5883 /***********************************************************************
5884 * NdrEncapsulatedUnionFree [RPCRT4.@]
5886 void WINAPI
NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
5887 unsigned char *pMemory
,
5888 PFORMAT_STRING pFormat
)
5890 unsigned char switch_type
;
5891 unsigned char increment
;
5894 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5897 switch_type
= *pFormat
& 0xf;
5898 increment
= (*pFormat
& 0xf0) >> 4;
5901 switch_value
= get_discriminant(switch_type
, pMemory
);
5902 TRACE("got switch value 0x%x\n", switch_value
);
5904 pMemory
+= increment
;
5906 union_arm_free(pStubMsg
, pMemory
, switch_value
, pFormat
);
5909 /***********************************************************************
5910 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5912 unsigned char * WINAPI
NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5913 unsigned char *pMemory
,
5914 PFORMAT_STRING pFormat
)
5916 unsigned char switch_type
;
5918 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5921 switch_type
= *pFormat
;
5924 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5925 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5926 /* Marshall discriminant */
5927 NdrBaseTypeMarshall(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
5929 return union_arm_marshall(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5932 static LONG
unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg
,
5933 PFORMAT_STRING
*ppFormat
)
5935 LONG discriminant
= 0;
5945 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5954 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5955 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5963 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
5964 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5969 FIXME("Unhandled base type: 0x%02x\n", **ppFormat
);
5973 if (pStubMsg
->fHasNewCorrDesc
)
5977 return discriminant
;
5980 /**********************************************************************
5981 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5983 unsigned char * WINAPI
NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5984 unsigned char **ppMemory
,
5985 PFORMAT_STRING pFormat
,
5986 unsigned char fMustAlloc
)
5989 unsigned short size
;
5991 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5994 /* Unmarshall discriminant */
5995 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
5996 TRACE("unmarshalled discriminant %x\n", discriminant
);
5998 pFormat
+= *(const SHORT
*)pFormat
;
6000 size
= *(const unsigned short*)pFormat
;
6002 if (!fMustAlloc
&& !*ppMemory
)
6005 *ppMemory
= NdrAllocate(pStubMsg
, size
);
6007 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6008 * since the arm is part of the memory block that is encompassed by
6009 * the whole union. Memory is forced to allocate when pointers
6010 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6011 * clearing the memory we pass in to the unmarshaller */
6013 memset(*ppMemory
, 0, size
);
6015 return union_arm_unmarshall(pStubMsg
, ppMemory
, discriminant
, pFormat
, FALSE
);
6018 /***********************************************************************
6019 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
6021 void WINAPI
NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6022 unsigned char *pMemory
,
6023 PFORMAT_STRING pFormat
)
6025 unsigned char switch_type
;
6027 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6030 switch_type
= *pFormat
;
6033 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6034 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6035 /* Add discriminant size */
6036 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
6038 union_arm_buffer_size(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6041 /***********************************************************************
6042 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
6044 ULONG WINAPI
NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6045 PFORMAT_STRING pFormat
)
6050 /* Unmarshall discriminant */
6051 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
6052 TRACE("unmarshalled discriminant 0x%x\n", discriminant
);
6054 return union_arm_memory_size(pStubMsg
, discriminant
, pFormat
+ *(const SHORT
*)pFormat
);
6057 /***********************************************************************
6058 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6060 void WINAPI
NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
6061 unsigned char *pMemory
,
6062 PFORMAT_STRING pFormat
)
6064 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6068 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6069 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6071 union_arm_free(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6074 /***********************************************************************
6075 * NdrByteCountPointerMarshall [RPCRT4.@]
6077 unsigned char * WINAPI
NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6078 unsigned char *pMemory
,
6079 PFORMAT_STRING pFormat
)
6085 /***********************************************************************
6086 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6088 unsigned char * WINAPI
NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6089 unsigned char **ppMemory
,
6090 PFORMAT_STRING pFormat
,
6091 unsigned char fMustAlloc
)
6097 /***********************************************************************
6098 * NdrByteCountPointerBufferSize [RPCRT4.@]
6100 void WINAPI
NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6101 unsigned char *pMemory
,
6102 PFORMAT_STRING pFormat
)
6107 /***********************************************************************
6108 * NdrByteCountPointerMemorySize [internal]
6110 static ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6111 PFORMAT_STRING pFormat
)
6117 /***********************************************************************
6118 * NdrByteCountPointerFree [RPCRT4.@]
6120 void WINAPI
NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
6121 unsigned char *pMemory
,
6122 PFORMAT_STRING pFormat
)
6127 /***********************************************************************
6128 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6130 unsigned char * WINAPI
NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6131 unsigned char *pMemory
,
6132 PFORMAT_STRING pFormat
)
6138 /***********************************************************************
6139 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6141 unsigned char * WINAPI
NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6142 unsigned char **ppMemory
,
6143 PFORMAT_STRING pFormat
,
6144 unsigned char fMustAlloc
)
6150 /***********************************************************************
6151 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6153 void WINAPI
NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6154 unsigned char *pMemory
,
6155 PFORMAT_STRING pFormat
)
6160 /***********************************************************************
6161 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6163 ULONG WINAPI
NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6164 PFORMAT_STRING pFormat
)
6170 /***********************************************************************
6171 * NdrXmitOrRepAsFree [RPCRT4.@]
6173 void WINAPI
NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg
,
6174 unsigned char *pMemory
,
6175 PFORMAT_STRING pFormat
)
6180 /***********************************************************************
6181 * NdrRangeMarshall [internal]
6183 static unsigned char *WINAPI
NdrRangeMarshall(
6184 PMIDL_STUB_MESSAGE pStubMsg
,
6185 unsigned char *pMemory
,
6186 PFORMAT_STRING pFormat
)
6188 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
6189 unsigned char base_type
;
6191 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6193 if (pRange
->type
!= RPC_FC_RANGE
)
6195 ERR("invalid format type %x\n", pRange
->type
);
6196 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6200 base_type
= pRange
->flags_type
& 0xf;
6202 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &base_type
);
6205 /***********************************************************************
6206 * NdrRangeUnmarshall [RPCRT4.@]
6208 unsigned char *WINAPI
NdrRangeUnmarshall(
6209 PMIDL_STUB_MESSAGE pStubMsg
,
6210 unsigned char **ppMemory
,
6211 PFORMAT_STRING pFormat
,
6212 unsigned char fMustAlloc
)
6214 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
6215 unsigned char base_type
;
6217 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6219 if (pRange
->type
!= RPC_FC_RANGE
)
6221 ERR("invalid format type %x\n", pRange
->type
);
6222 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6225 base_type
= pRange
->flags_type
& 0xf;
6227 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6228 base_type
, pRange
->low_value
, pRange
->high_value
);
6230 #define RANGE_UNMARSHALL(mem_type, wire_type, format_spec) \
6233 ALIGN_POINTER(pStubMsg->Buffer, sizeof(wire_type)); \
6234 if (!fMustAlloc && !*ppMemory) \
6235 fMustAlloc = TRUE; \
6237 *ppMemory = NdrAllocate(pStubMsg, sizeof(mem_type)); \
6238 if (pStubMsg->Buffer + sizeof(wire_type) > pStubMsg->BufferEnd) \
6240 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6241 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6242 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6244 if ((*(wire_type *)pStubMsg->Buffer < (mem_type)pRange->low_value) || \
6245 (*(wire_type *)pStubMsg->Buffer > (mem_type)pRange->high_value)) \
6247 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6248 *(wire_type *)pStubMsg->Buffer, (mem_type)pRange->low_value, \
6249 (mem_type)pRange->high_value); \
6250 RpcRaiseException(RPC_S_INVALID_BOUND); \
6253 TRACE("*ppMemory: %p\n", *ppMemory); \
6254 **(mem_type **)ppMemory = *(wire_type *)pStubMsg->Buffer; \
6255 pStubMsg->Buffer += sizeof(wire_type); \
6262 RANGE_UNMARSHALL(UCHAR
, UCHAR
, "%d");
6263 TRACE("value: 0x%02x\n", **ppMemory
);
6267 RANGE_UNMARSHALL(CHAR
, CHAR
, "%u");
6268 TRACE("value: 0x%02x\n", **ppMemory
);
6270 case RPC_FC_WCHAR
: /* FIXME: valid? */
6272 RANGE_UNMARSHALL(USHORT
, USHORT
, "%u");
6273 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6276 RANGE_UNMARSHALL(SHORT
, SHORT
, "%d");
6277 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6281 RANGE_UNMARSHALL(LONG
, LONG
, "%d");
6282 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6285 RANGE_UNMARSHALL(ULONG
, ULONG
, "%u");
6286 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6289 RANGE_UNMARSHALL(UINT
, USHORT
, "%u");
6290 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
6296 ERR("invalid range base type: 0x%02x\n", base_type
);
6297 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6303 /***********************************************************************
6304 * NdrRangeBufferSize [internal]
6306 static void WINAPI
NdrRangeBufferSize(
6307 PMIDL_STUB_MESSAGE pStubMsg
,
6308 unsigned char *pMemory
,
6309 PFORMAT_STRING pFormat
)
6311 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
6312 unsigned char base_type
;
6314 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6316 if (pRange
->type
!= RPC_FC_RANGE
)
6318 ERR("invalid format type %x\n", pRange
->type
);
6319 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6321 base_type
= pRange
->flags_type
& 0xf;
6323 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &base_type
);
6326 /***********************************************************************
6327 * NdrRangeMemorySize [internal]
6329 static ULONG WINAPI
NdrRangeMemorySize(
6330 PMIDL_STUB_MESSAGE pStubMsg
,
6331 PFORMAT_STRING pFormat
)
6333 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
6334 unsigned char base_type
;
6336 if (pRange
->type
!= RPC_FC_RANGE
)
6338 ERR("invalid format type %x\n", pRange
->type
);
6339 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6342 base_type
= pRange
->flags_type
& 0xf;
6344 return NdrBaseTypeMemorySize(pStubMsg
, &base_type
);
6347 /***********************************************************************
6348 * NdrRangeFree [internal]
6350 static void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6351 unsigned char *pMemory
,
6352 PFORMAT_STRING pFormat
)
6354 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6359 /***********************************************************************
6360 * NdrBaseTypeMarshall [internal]
6362 static unsigned char *WINAPI
NdrBaseTypeMarshall(
6363 PMIDL_STUB_MESSAGE pStubMsg
,
6364 unsigned char *pMemory
,
6365 PFORMAT_STRING pFormat
)
6367 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6375 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(UCHAR
));
6376 TRACE("value: 0x%02x\n", *pMemory
);
6381 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(USHORT
));
6382 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(USHORT
));
6383 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
6387 case RPC_FC_ERROR_STATUS_T
:
6389 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(ULONG
));
6390 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONG
));
6391 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
6394 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(float));
6395 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
6398 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(double));
6399 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
6402 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(ULONGLONG
));
6403 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONGLONG
));
6404 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
6407 /* only 16-bits on the wire, so do a sanity check */
6408 if (*(UINT
*)pMemory
> SHRT_MAX
)
6409 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
6410 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(USHORT
));
6411 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6412 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6413 *(USHORT
*)pStubMsg
->Buffer
= *(UINT
*)pMemory
;
6414 pStubMsg
->Buffer
+= sizeof(USHORT
);
6415 TRACE("value: 0x%04x\n", *(UINT
*)pMemory
);
6420 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6423 /* FIXME: what is the correct return value? */
6427 /***********************************************************************
6428 * NdrBaseTypeUnmarshall [internal]
6430 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(
6431 PMIDL_STUB_MESSAGE pStubMsg
,
6432 unsigned char **ppMemory
,
6433 PFORMAT_STRING pFormat
,
6434 unsigned char fMustAlloc
)
6436 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6438 #define BASE_TYPE_UNMARSHALL(type) \
6439 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6440 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6442 *ppMemory = pStubMsg->Buffer; \
6443 TRACE("*ppMemory: %p\n", *ppMemory); \
6444 safe_buffer_increment(pStubMsg, sizeof(type)); \
6449 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6450 TRACE("*ppMemory: %p\n", *ppMemory); \
6451 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6460 BASE_TYPE_UNMARSHALL(UCHAR
);
6461 TRACE("value: 0x%02x\n", **ppMemory
);
6466 BASE_TYPE_UNMARSHALL(USHORT
);
6467 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6471 case RPC_FC_ERROR_STATUS_T
:
6473 BASE_TYPE_UNMARSHALL(ULONG
);
6474 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6477 BASE_TYPE_UNMARSHALL(float);
6478 TRACE("value: %f\n", **(float **)ppMemory
);
6481 BASE_TYPE_UNMARSHALL(double);
6482 TRACE("value: %f\n", **(double **)ppMemory
);
6485 BASE_TYPE_UNMARSHALL(ULONGLONG
);
6486 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG
**)ppMemory
));
6489 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
6490 if (!fMustAlloc
&& !*ppMemory
)
6493 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT
));
6494 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > pStubMsg
->BufferEnd
)
6495 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6496 TRACE("*ppMemory: %p\n", *ppMemory
);
6497 /* 16-bits on the wire, but int in memory */
6498 **(UINT
**)ppMemory
= *(USHORT
*)pStubMsg
->Buffer
;
6499 pStubMsg
->Buffer
+= sizeof(USHORT
);
6500 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
6505 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6507 #undef BASE_TYPE_UNMARSHALL
6509 /* FIXME: what is the correct return value? */
6514 /***********************************************************************
6515 * NdrBaseTypeBufferSize [internal]
6517 static void WINAPI
NdrBaseTypeBufferSize(
6518 PMIDL_STUB_MESSAGE pStubMsg
,
6519 unsigned char *pMemory
,
6520 PFORMAT_STRING pFormat
)
6522 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6530 safe_buffer_length_increment(pStubMsg
, sizeof(UCHAR
));
6536 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(USHORT
));
6537 safe_buffer_length_increment(pStubMsg
, sizeof(USHORT
));
6542 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONG
));
6543 safe_buffer_length_increment(pStubMsg
, sizeof(ULONG
));
6546 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(float));
6547 safe_buffer_length_increment(pStubMsg
, sizeof(float));
6550 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(double));
6551 safe_buffer_length_increment(pStubMsg
, sizeof(double));
6554 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONGLONG
));
6555 safe_buffer_length_increment(pStubMsg
, sizeof(ULONGLONG
));
6557 case RPC_FC_ERROR_STATUS_T
:
6558 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(error_status_t
));
6559 safe_buffer_length_increment(pStubMsg
, sizeof(error_status_t
));
6564 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6568 /***********************************************************************
6569 * NdrBaseTypeMemorySize [internal]
6571 static ULONG WINAPI
NdrBaseTypeMemorySize(
6572 PMIDL_STUB_MESSAGE pStubMsg
,
6573 PFORMAT_STRING pFormat
)
6575 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg
, *pFormat
);
6583 safe_buffer_increment(pStubMsg
, sizeof(UCHAR
));
6584 pStubMsg
->MemorySize
+= sizeof(UCHAR
);
6585 return sizeof(UCHAR
);
6589 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
6590 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6591 ALIGN_LENGTH(pStubMsg
->MemorySize
, sizeof(USHORT
));
6592 pStubMsg
->MemorySize
+= sizeof(USHORT
);
6593 return sizeof(USHORT
);
6597 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
6598 safe_buffer_increment(pStubMsg
, sizeof(ULONG
));
6599 ALIGN_LENGTH(pStubMsg
->MemorySize
, sizeof(ULONG
));
6600 pStubMsg
->MemorySize
+= sizeof(ULONG
);
6601 return sizeof(ULONG
);
6603 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(float));
6604 safe_buffer_increment(pStubMsg
, sizeof(float));
6605 ALIGN_LENGTH(pStubMsg
->MemorySize
, sizeof(float));
6606 pStubMsg
->MemorySize
+= sizeof(float);
6607 return sizeof(float);
6609 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(double));
6610 safe_buffer_increment(pStubMsg
, sizeof(double));
6611 ALIGN_LENGTH(pStubMsg
->MemorySize
, sizeof(double));
6612 pStubMsg
->MemorySize
+= sizeof(double);
6613 return sizeof(double);
6615 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONGLONG
));
6616 safe_buffer_increment(pStubMsg
, sizeof(ULONGLONG
));
6617 ALIGN_LENGTH(pStubMsg
->MemorySize
, sizeof(ULONGLONG
));
6618 pStubMsg
->MemorySize
+= sizeof(ULONGLONG
);
6619 return sizeof(ULONGLONG
);
6620 case RPC_FC_ERROR_STATUS_T
:
6621 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(error_status_t
));
6622 safe_buffer_increment(pStubMsg
, sizeof(error_status_t
));
6623 ALIGN_LENGTH(pStubMsg
->MemorySize
, sizeof(error_status_t
));
6624 pStubMsg
->MemorySize
+= sizeof(error_status_t
);
6625 return sizeof(error_status_t
);
6627 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
6628 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6629 ALIGN_LENGTH(pStubMsg
->MemorySize
, sizeof(UINT
));
6630 pStubMsg
->MemorySize
+= sizeof(UINT
);
6631 return sizeof(UINT
);
6633 ALIGN_LENGTH(pStubMsg
->MemorySize
, sizeof(void *));
6634 pStubMsg
->MemorySize
+= sizeof(void *);
6635 return sizeof(void *);
6637 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6642 /***********************************************************************
6643 * NdrBaseTypeFree [internal]
6645 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6646 unsigned char *pMemory
,
6647 PFORMAT_STRING pFormat
)
6649 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6654 /***********************************************************************
6655 * NdrContextHandleBufferSize [internal]
6657 static void WINAPI
NdrContextHandleBufferSize(
6658 PMIDL_STUB_MESSAGE pStubMsg
,
6659 unsigned char *pMemory
,
6660 PFORMAT_STRING pFormat
)
6662 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6664 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6666 ERR("invalid format type %x\n", *pFormat
);
6667 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6669 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
6670 safe_buffer_length_increment(pStubMsg
, cbNDRContext
);
6673 /***********************************************************************
6674 * NdrContextHandleMarshall [internal]
6676 static unsigned char *WINAPI
NdrContextHandleMarshall(
6677 PMIDL_STUB_MESSAGE pStubMsg
,
6678 unsigned char *pMemory
,
6679 PFORMAT_STRING pFormat
)
6681 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6683 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6685 ERR("invalid format type %x\n", *pFormat
);
6686 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6688 TRACE("flags: 0x%02x\n", pFormat
[1]);
6690 if (pFormat
[1] & 0x80)
6691 NdrClientContextMarshall(pStubMsg
, *(NDR_CCONTEXT
**)pMemory
, FALSE
);
6693 NdrClientContextMarshall(pStubMsg
, pMemory
, FALSE
);
6698 /***********************************************************************
6699 * NdrContextHandleUnmarshall [internal]
6701 static unsigned char *WINAPI
NdrContextHandleUnmarshall(
6702 PMIDL_STUB_MESSAGE pStubMsg
,
6703 unsigned char **ppMemory
,
6704 PFORMAT_STRING pFormat
,
6705 unsigned char fMustAlloc
)
6707 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg
,
6708 ppMemory
, pFormat
, fMustAlloc
? "TRUE": "FALSE");
6710 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6712 ERR("invalid format type %x\n", *pFormat
);
6713 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6715 TRACE("flags: 0x%02x\n", pFormat
[1]);
6717 /* [out]-only or [ret] param */
6718 if ((pFormat
[1] & 0x60) == 0x20)
6719 **(NDR_CCONTEXT
**)ppMemory
= NULL
;
6720 NdrClientContextUnmarshall(pStubMsg
, *(NDR_CCONTEXT
**)ppMemory
, pStubMsg
->RpcMsg
->Handle
);
6725 /***********************************************************************
6726 * NdrClientContextMarshall [RPCRT4.@]
6728 void WINAPI
NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6729 NDR_CCONTEXT ContextHandle
,
6732 TRACE("(%p, %p, %d)\n", pStubMsg
, ContextHandle
, fCheck
);
6734 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
6736 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6738 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6739 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6740 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6743 /* FIXME: what does fCheck do? */
6744 NDRCContextMarshall(ContextHandle
,
6747 pStubMsg
->Buffer
+= cbNDRContext
;
6750 /***********************************************************************
6751 * NdrClientContextUnmarshall [RPCRT4.@]
6753 void WINAPI
NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6754 NDR_CCONTEXT
* pContextHandle
,
6755 RPC_BINDING_HANDLE BindHandle
)
6757 TRACE("(%p, %p, %p)\n", pStubMsg
, pContextHandle
, BindHandle
);
6759 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6761 if (pStubMsg
->Buffer
+ cbNDRContext
> pStubMsg
->BufferEnd
)
6762 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6764 NDRCContextUnmarshall(pContextHandle
,
6767 pStubMsg
->RpcMsg
->DataRepresentation
);
6769 pStubMsg
->Buffer
+= cbNDRContext
;
6772 void WINAPI
NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6773 NDR_SCONTEXT ContextHandle
,
6774 NDR_RUNDOWN RundownRoutine
)
6776 TRACE("(%p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
);
6778 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6780 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6782 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6783 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6784 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6787 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
6788 pStubMsg
->Buffer
, RundownRoutine
, NULL
,
6789 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
6790 pStubMsg
->Buffer
+= cbNDRContext
;
6793 NDR_SCONTEXT WINAPI
NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
)
6795 NDR_SCONTEXT ContextHandle
;
6797 TRACE("(%p)\n", pStubMsg
);
6799 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6801 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6803 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6804 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6805 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6808 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
6810 pStubMsg
->RpcMsg
->DataRepresentation
,
6811 NULL
, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
6812 pStubMsg
->Buffer
+= cbNDRContext
;
6814 return ContextHandle
;
6817 void WINAPI
NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg
,
6818 unsigned char* pMemory
,
6819 PFORMAT_STRING pFormat
)
6821 FIXME("(%p, %p, %p): stub\n", pStubMsg
, pMemory
, pFormat
);
6824 NDR_SCONTEXT WINAPI
NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg
,
6825 PFORMAT_STRING pFormat
)
6827 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6828 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6830 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
6832 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
6833 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
6834 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
6835 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
6836 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
6838 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
6839 if_id
= &sif
->InterfaceId
;
6842 return NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
, NULL
,
6843 pStubMsg
->RpcMsg
->DataRepresentation
, if_id
,
6847 void WINAPI
NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6848 NDR_SCONTEXT ContextHandle
,
6849 NDR_RUNDOWN RundownRoutine
,
6850 PFORMAT_STRING pFormat
)
6852 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6853 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6855 TRACE("(%p, %p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
, pFormat
);
6857 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6859 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6861 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6862 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6863 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6866 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
6867 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
6868 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
6869 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
6870 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
6872 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
6873 if_id
= &sif
->InterfaceId
;
6876 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
6877 pStubMsg
->Buffer
, RundownRoutine
, if_id
, flags
);
6878 pStubMsg
->Buffer
+= cbNDRContext
;
6881 NDR_SCONTEXT WINAPI
NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6882 PFORMAT_STRING pFormat
)
6884 NDR_SCONTEXT ContextHandle
;
6885 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6886 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6888 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
6890 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6892 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6894 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6895 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6896 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6899 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
6900 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
6901 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
6902 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
6903 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
6905 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
6906 if_id
= &sif
->InterfaceId
;
6909 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
6911 pStubMsg
->RpcMsg
->DataRepresentation
,
6913 pStubMsg
->Buffer
+= cbNDRContext
;
6915 return ContextHandle
;
6918 /***********************************************************************
6919 * NdrCorrelationInitialize [RPCRT4.@]
6921 * Initializes correlation validity checking.
6924 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6925 * pMemory [I] Pointer to memory to use as a cache.
6926 * CacheSize [I] Size of the memory pointed to by pMemory.
6927 * Flags [I] Reserved. Set to zero.
6932 void WINAPI
NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg
, void *pMemory
, ULONG CacheSize
, ULONG Flags
)
6934 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg
, pMemory
, CacheSize
, Flags
);
6935 pStubMsg
->fHasNewCorrDesc
= TRUE
;
6938 /***********************************************************************
6939 * NdrCorrelationPass [RPCRT4.@]
6941 * Performs correlation validity checking.
6944 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6949 void WINAPI
NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg
)
6951 FIXME("(%p): stub\n", pStubMsg
);
6954 /***********************************************************************
6955 * NdrCorrelationFree [RPCRT4.@]
6957 * Frees any resources used while unmarshalling parameters that need
6958 * correlation validity checking.
6961 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6966 void WINAPI
NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg
)
6968 FIXME("(%p): stub\n", pStubMsg
);