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
44 #include "wine/unicode.h"
45 #include "wine/rpcfc.h"
47 #include "wine/debug.h"
49 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
52 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
53 (*((UINT32 *)(pchar)) = (uint32))
55 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
56 (*((UINT32 *)(pchar)))
58 /* these would work for i386 too, but less efficient */
59 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
60 (*(pchar) = LOBYTE(LOWORD(uint32)), \
61 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
62 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
63 *((pchar)+3) = HIBYTE(HIWORD(uint32)))
65 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
67 MAKEWORD(*(pchar), *((pchar)+1)), \
68 MAKEWORD(*((pchar)+2), *((pchar)+3))))
71 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
72 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
73 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
74 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
75 *(pchar) = HIBYTE(HIWORD(uint32)))
77 #define BIG_ENDIAN_UINT32_READ(pchar) \
79 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
80 MAKEWORD(*((pchar)+1), *(pchar))))
82 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
83 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
84 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
85 # define NDR_LOCAL_UINT32_READ(pchar) \
86 BIG_ENDIAN_UINT32_READ(pchar)
88 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
89 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
90 # define NDR_LOCAL_UINT32_READ(pchar) \
91 LITTLE_ENDIAN_UINT32_READ(pchar)
94 /* _Align must be the desired alignment,
95 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
96 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
97 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
98 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
99 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
100 #define ALIGN_POINTER_CLEAR(_Ptr, _Align) \
102 memset((_Ptr), 0, ((_Align) - (ULONG_PTR)(_Ptr)) & ((_Align) - 1)); \
103 ALIGN_POINTER(_Ptr, _Align); \
106 #define STD_OVERFLOW_CHECK(_Msg) do { \
107 TRACE("buffer=%d/%d\n", (ULONG)(_Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer), _Msg->BufferLength); \
108 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
109 ERR("buffer overflow %d bytes\n", (ULONG)(_Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength))); \
112 #define NDR_POINTER_ID_BASE 0x20000
113 #define NDR_POINTER_ID(pStubMsg) (NDR_POINTER_ID_BASE + ((pStubMsg)->UniquePtrCount++) * 4)
114 #define NDR_TABLE_SIZE 128
115 #define NDR_TABLE_MASK 127
117 #define NDRSContextFromValue(user_context) (NDR_SCONTEXT)((char *)(user_context) - (char *)NDRSContextValue((NDR_SCONTEXT)NULL))
119 static unsigned char *WINAPI
NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
120 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
121 static void WINAPI
NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
122 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
123 static ULONG WINAPI
NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
125 static unsigned char *WINAPI
NdrContextHandleMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
126 static void WINAPI
NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
127 static unsigned char *WINAPI
NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
129 static unsigned char *WINAPI
NdrRangeMarshall(PMIDL_STUB_MESSAGE
,unsigned char *, PFORMAT_STRING
);
130 static void WINAPI
NdrRangeBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
131 static ULONG WINAPI
NdrRangeMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
132 static void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
134 static ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
136 const NDR_MARSHALL NdrMarshaller
[NDR_TABLE_SIZE
] = {
138 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
139 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
140 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
141 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
145 NdrPointerMarshall
, NdrPointerMarshall
,
146 NdrPointerMarshall
, NdrPointerMarshall
,
148 NdrSimpleStructMarshall
, NdrSimpleStructMarshall
,
149 NdrConformantStructMarshall
, NdrConformantStructMarshall
,
150 NdrConformantVaryingStructMarshall
,
151 NdrComplexStructMarshall
,
153 NdrConformantArrayMarshall
,
154 NdrConformantVaryingArrayMarshall
,
155 NdrFixedArrayMarshall
, NdrFixedArrayMarshall
,
156 NdrVaryingArrayMarshall
, NdrVaryingArrayMarshall
,
157 NdrComplexArrayMarshall
,
159 NdrConformantStringMarshall
, 0, 0,
160 NdrConformantStringMarshall
,
161 NdrNonConformantStringMarshall
, 0, 0, 0,
163 NdrEncapsulatedUnionMarshall
,
164 NdrNonEncapsulatedUnionMarshall
,
165 NdrByteCountPointerMarshall
,
166 NdrXmitOrRepAsMarshall
, NdrXmitOrRepAsMarshall
,
168 NdrInterfacePointerMarshall
,
170 NdrContextHandleMarshall
,
173 NdrUserMarshalMarshall
,
178 const NDR_UNMARSHALL NdrUnmarshaller
[NDR_TABLE_SIZE
] = {
180 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
181 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
182 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
183 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
185 NdrBaseTypeUnmarshall
,
187 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
188 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
190 NdrSimpleStructUnmarshall
, NdrSimpleStructUnmarshall
,
191 NdrConformantStructUnmarshall
, NdrConformantStructUnmarshall
,
192 NdrConformantVaryingStructUnmarshall
,
193 NdrComplexStructUnmarshall
,
195 NdrConformantArrayUnmarshall
,
196 NdrConformantVaryingArrayUnmarshall
,
197 NdrFixedArrayUnmarshall
, NdrFixedArrayUnmarshall
,
198 NdrVaryingArrayUnmarshall
, NdrVaryingArrayUnmarshall
,
199 NdrComplexArrayUnmarshall
,
201 NdrConformantStringUnmarshall
, 0, 0,
202 NdrConformantStringUnmarshall
,
203 NdrNonConformantStringUnmarshall
, 0, 0, 0,
205 NdrEncapsulatedUnionUnmarshall
,
206 NdrNonEncapsulatedUnionUnmarshall
,
207 NdrByteCountPointerUnmarshall
,
208 NdrXmitOrRepAsUnmarshall
, NdrXmitOrRepAsUnmarshall
,
210 NdrInterfacePointerUnmarshall
,
212 NdrContextHandleUnmarshall
,
215 NdrUserMarshalUnmarshall
,
220 const NDR_BUFFERSIZE NdrBufferSizer
[NDR_TABLE_SIZE
] = {
222 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
223 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
224 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
225 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
227 NdrBaseTypeBufferSize
,
229 NdrPointerBufferSize
, NdrPointerBufferSize
,
230 NdrPointerBufferSize
, NdrPointerBufferSize
,
232 NdrSimpleStructBufferSize
, NdrSimpleStructBufferSize
,
233 NdrConformantStructBufferSize
, NdrConformantStructBufferSize
,
234 NdrConformantVaryingStructBufferSize
,
235 NdrComplexStructBufferSize
,
237 NdrConformantArrayBufferSize
,
238 NdrConformantVaryingArrayBufferSize
,
239 NdrFixedArrayBufferSize
, NdrFixedArrayBufferSize
,
240 NdrVaryingArrayBufferSize
, NdrVaryingArrayBufferSize
,
241 NdrComplexArrayBufferSize
,
243 NdrConformantStringBufferSize
, 0, 0,
244 NdrConformantStringBufferSize
,
245 NdrNonConformantStringBufferSize
, 0, 0, 0,
247 NdrEncapsulatedUnionBufferSize
,
248 NdrNonEncapsulatedUnionBufferSize
,
249 NdrByteCountPointerBufferSize
,
250 NdrXmitOrRepAsBufferSize
, NdrXmitOrRepAsBufferSize
,
252 NdrInterfacePointerBufferSize
,
254 NdrContextHandleBufferSize
,
257 NdrUserMarshalBufferSize
,
262 const NDR_MEMORYSIZE NdrMemorySizer
[NDR_TABLE_SIZE
] = {
264 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
265 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
266 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
267 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
269 NdrBaseTypeMemorySize
,
271 NdrPointerMemorySize
, NdrPointerMemorySize
,
272 NdrPointerMemorySize
, NdrPointerMemorySize
,
274 NdrSimpleStructMemorySize
, NdrSimpleStructMemorySize
,
275 NdrConformantStructMemorySize
, NdrConformantStructMemorySize
,
276 NdrConformantVaryingStructMemorySize
,
277 NdrComplexStructMemorySize
,
279 NdrConformantArrayMemorySize
,
280 NdrConformantVaryingArrayMemorySize
,
281 NdrFixedArrayMemorySize
, NdrFixedArrayMemorySize
,
282 NdrVaryingArrayMemorySize
, NdrVaryingArrayMemorySize
,
283 NdrComplexArrayMemorySize
,
285 NdrConformantStringMemorySize
, 0, 0,
286 NdrConformantStringMemorySize
,
287 NdrNonConformantStringMemorySize
, 0, 0, 0,
289 NdrEncapsulatedUnionMemorySize
,
290 NdrNonEncapsulatedUnionMemorySize
,
291 NdrByteCountPointerMemorySize
,
292 NdrXmitOrRepAsMemorySize
, NdrXmitOrRepAsMemorySize
,
294 NdrInterfacePointerMemorySize
,
299 NdrUserMarshalMemorySize
,
304 const NDR_FREE NdrFreer
[NDR_TABLE_SIZE
] = {
306 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
307 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
308 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
309 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
313 NdrPointerFree
, NdrPointerFree
,
314 NdrPointerFree
, NdrPointerFree
,
316 NdrSimpleStructFree
, NdrSimpleStructFree
,
317 NdrConformantStructFree
, NdrConformantStructFree
,
318 NdrConformantVaryingStructFree
,
319 NdrComplexStructFree
,
321 NdrConformantArrayFree
,
322 NdrConformantVaryingArrayFree
,
323 NdrFixedArrayFree
, NdrFixedArrayFree
,
324 NdrVaryingArrayFree
, NdrVaryingArrayFree
,
330 NdrEncapsulatedUnionFree
,
331 NdrNonEncapsulatedUnionFree
,
333 NdrXmitOrRepAsFree
, NdrXmitOrRepAsFree
,
335 NdrInterfacePointerFree
,
346 typedef struct _NDR_MEMORY_LIST
351 struct _NDR_MEMORY_LIST
*next
;
354 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
356 /***********************************************************************
357 * NdrAllocate [RPCRT4.@]
359 * Allocates a block of memory using pStubMsg->pfnAllocate.
362 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
363 * len [I] Size of memory block to allocate.
366 * The memory block of size len that was allocated.
369 * The memory block is always 8-byte aligned.
370 * If the function is unable to allocate memory an ERROR_OUTOFMEMORY
371 * exception is raised.
373 void * WINAPI
NdrAllocate(MIDL_STUB_MESSAGE
*pStubMsg
, SIZE_T len
)
378 NDR_MEMORY_LIST
*mem_list
;
380 aligned_len
= ALIGNED_LENGTH(len
, 8);
381 adjusted_len
= aligned_len
+ sizeof(NDR_MEMORY_LIST
);
382 /* check for overflow */
383 if (adjusted_len
< len
)
385 ERR("overflow of adjusted_len %ld, len %ld\n", adjusted_len
, len
);
386 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
389 p
= pStubMsg
->pfnAllocate(adjusted_len
);
390 if (!p
) RpcRaiseException(ERROR_OUTOFMEMORY
);
392 mem_list
= (NDR_MEMORY_LIST
*)((char *)p
+ aligned_len
);
393 mem_list
->magic
= MEML_MAGIC
;
394 mem_list
->size
= aligned_len
;
395 mem_list
->reserved
= 0;
396 mem_list
->next
= pStubMsg
->pMemoryList
;
397 pStubMsg
->pMemoryList
= mem_list
;
403 static void NdrFree(MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *Pointer
)
405 TRACE("(%p, %p)\n", pStubMsg
, Pointer
);
407 pStubMsg
->pfnFree(Pointer
);
410 static inline BOOL
IsConformanceOrVariancePresent(PFORMAT_STRING pFormat
)
412 return (*(const ULONG
*)pFormat
!= -1);
415 static PFORMAT_STRING
ReadConformance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
)
417 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
418 if (pStubMsg
->Buffer
+ 4 > pStubMsg
->BufferEnd
)
419 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
420 pStubMsg
->MaxCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
421 pStubMsg
->Buffer
+= 4;
422 TRACE("unmarshalled conformance is %ld\n", pStubMsg
->MaxCount
);
423 if (pStubMsg
->fHasNewCorrDesc
)
429 static inline PFORMAT_STRING
ReadVariance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
, ULONG MaxValue
)
431 if (pFormat
&& !IsConformanceOrVariancePresent(pFormat
))
433 pStubMsg
->Offset
= 0;
434 pStubMsg
->ActualCount
= pStubMsg
->MaxCount
;
438 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
439 if (pStubMsg
->Buffer
+ 8 > pStubMsg
->BufferEnd
)
440 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
441 pStubMsg
->Offset
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
442 pStubMsg
->Buffer
+= 4;
443 TRACE("offset is %d\n", pStubMsg
->Offset
);
444 pStubMsg
->ActualCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
445 pStubMsg
->Buffer
+= 4;
446 TRACE("variance is %d\n", pStubMsg
->ActualCount
);
448 if ((pStubMsg
->ActualCount
> MaxValue
) ||
449 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> MaxValue
))
451 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
452 pStubMsg
->ActualCount
, pStubMsg
->Offset
, MaxValue
);
453 RpcRaiseException(RPC_S_INVALID_BOUND
);
458 if (pStubMsg
->fHasNewCorrDesc
)
464 /* writes the conformance value to the buffer */
465 static inline void WriteConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
467 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
468 if (pStubMsg
->Buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
469 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
470 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->MaxCount
);
471 pStubMsg
->Buffer
+= 4;
474 /* writes the variance values to the buffer */
475 static inline void WriteVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
477 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
478 if (pStubMsg
->Buffer
+ 8 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
479 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
480 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->Offset
);
481 pStubMsg
->Buffer
+= 4;
482 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->ActualCount
);
483 pStubMsg
->Buffer
+= 4;
486 /* requests buffer space for the conformance value */
487 static inline void SizeConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
489 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
490 if (pStubMsg
->BufferLength
+ 4 < pStubMsg
->BufferLength
)
491 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
492 pStubMsg
->BufferLength
+= 4;
495 /* requests buffer space for the variance values */
496 static inline void SizeVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
498 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
499 if (pStubMsg
->BufferLength
+ 8 < pStubMsg
->BufferLength
)
500 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
501 pStubMsg
->BufferLength
+= 8;
504 PFORMAT_STRING
ComputeConformanceOrVariance(
505 MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *pMemory
,
506 PFORMAT_STRING pFormat
, ULONG_PTR def
, ULONG_PTR
*pCount
)
508 BYTE dtype
= pFormat
[0] & 0xf;
509 short ofs
= *(const short *)&pFormat
[2];
513 if (!IsConformanceOrVariancePresent(pFormat
)) {
514 /* null descriptor */
519 switch (pFormat
[0] & 0xf0) {
520 case RPC_FC_NORMAL_CONFORMANCE
:
521 TRACE("normal conformance, ofs=%d\n", ofs
);
524 case RPC_FC_POINTER_CONFORMANCE
:
525 TRACE("pointer conformance, ofs=%d\n", ofs
);
526 ptr
= pStubMsg
->Memory
;
528 case RPC_FC_TOP_LEVEL_CONFORMANCE
:
529 TRACE("toplevel conformance, ofs=%d\n", ofs
);
530 if (pStubMsg
->StackTop
) {
531 ptr
= pStubMsg
->StackTop
;
534 /* -Os mode, *pCount is already set */
538 case RPC_FC_CONSTANT_CONFORMANCE
:
539 data
= ofs
| ((DWORD
)pFormat
[1] << 16);
540 TRACE("constant conformance, val=%d\n", data
);
543 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE
:
544 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs
);
545 if (pStubMsg
->StackTop
) {
546 ptr
= pStubMsg
->StackTop
;
554 FIXME("unknown conformance type %x, expect crash.\n", pFormat
[0] & 0xf0);
558 switch (pFormat
[1]) {
559 case RPC_FC_DEREFERENCE
:
560 ptr
= *(LPVOID
*)((char *)ptr
+ ofs
);
562 case RPC_FC_CALLBACK
:
564 unsigned char *old_stack_top
= pStubMsg
->StackTop
;
565 pStubMsg
->StackTop
= ptr
;
567 /* ofs is index into StubDesc->apfnExprEval */
568 TRACE("callback conformance into apfnExprEval[%d]\n", ofs
);
569 pStubMsg
->StubDesc
->apfnExprEval
[ofs
](pStubMsg
);
571 pStubMsg
->StackTop
= old_stack_top
;
573 /* the callback function always stores the computed value in MaxCount */
574 *pCount
= pStubMsg
->MaxCount
;
578 ptr
= (char *)ptr
+ ofs
;
591 data
= *(USHORT
*)ptr
;
602 FIXME("unknown conformance data type %x\n", dtype
);
605 TRACE("dereferenced data type %x at %p, got %d\n", dtype
, ptr
, data
);
608 switch (pFormat
[1]) {
609 case RPC_FC_DEREFERENCE
: /* already handled */
626 FIXME("unknown conformance op %d\n", pFormat
[1]);
631 TRACE("resulting conformance is %ld\n", *pCount
);
632 if (pStubMsg
->fHasNewCorrDesc
)
638 static inline PFORMAT_STRING
SkipConformance(PMIDL_STUB_MESSAGE pStubMsg
,
639 PFORMAT_STRING pFormat
)
641 if (IsConformanceOrVariancePresent(pFormat
))
643 if (pStubMsg
->fHasNewCorrDesc
)
651 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
652 * the result overflows 32-bits */
653 static inline ULONG
safe_multiply(ULONG a
, ULONG b
)
655 ULONGLONG ret
= (ULONGLONG
)a
* b
;
656 if (ret
> 0xffffffff)
658 RpcRaiseException(RPC_S_INVALID_BOUND
);
664 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
666 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
667 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
668 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
669 pStubMsg
->Buffer
+= size
;
672 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
674 if (pStubMsg
->BufferLength
+ size
< pStubMsg
->BufferLength
) /* integer overflow of pStubMsg->BufferSize */
676 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
677 pStubMsg
->BufferLength
, size
);
678 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
680 pStubMsg
->BufferLength
+= size
;
683 /* copies data from the buffer, checking that there is enough data in the buffer
685 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, void *p
, ULONG size
)
687 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
688 (pStubMsg
->Buffer
+ size
> pStubMsg
->BufferEnd
))
690 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
691 pStubMsg
->Buffer
, pStubMsg
->BufferEnd
, size
);
692 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
694 if (p
== pStubMsg
->Buffer
)
695 ERR("pointer is the same as the buffer\n");
696 memcpy(p
, pStubMsg
->Buffer
, size
);
697 pStubMsg
->Buffer
+= size
;
700 /* copies data to the buffer, checking that there is enough space to do so */
701 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, const void *p
, ULONG size
)
703 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
704 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
706 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
707 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
,
709 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
711 memcpy(pStubMsg
->Buffer
, p
, size
);
712 pStubMsg
->Buffer
+= size
;
715 /* verify that string data sitting in the buffer is valid and safe to
717 static void validate_string_data(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG bufsize
, ULONG esize
)
721 /* verify the buffer is safe to access */
722 if ((pStubMsg
->Buffer
+ bufsize
< pStubMsg
->Buffer
) ||
723 (pStubMsg
->Buffer
+ bufsize
> pStubMsg
->BufferEnd
))
725 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize
,
726 pStubMsg
->BufferEnd
, pStubMsg
->Buffer
);
727 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
730 /* strings must always have null terminating bytes */
733 ERR("invalid string length of %d\n", bufsize
/ esize
);
734 RpcRaiseException(RPC_S_INVALID_BOUND
);
737 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
738 if (pStubMsg
->Buffer
[i
] != 0)
740 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
741 i
, pStubMsg
->Buffer
[i
]);
742 RpcRaiseException(RPC_S_INVALID_BOUND
);
746 static inline void dump_pointer_attr(unsigned char attr
)
748 if (attr
& RPC_FC_P_ALLOCALLNODES
)
749 TRACE(" RPC_FC_P_ALLOCALLNODES");
750 if (attr
& RPC_FC_P_DONTFREE
)
751 TRACE(" RPC_FC_P_DONTFREE");
752 if (attr
& RPC_FC_P_ONSTACK
)
753 TRACE(" RPC_FC_P_ONSTACK");
754 if (attr
& RPC_FC_P_SIMPLEPOINTER
)
755 TRACE(" RPC_FC_P_SIMPLEPOINTER");
756 if (attr
& RPC_FC_P_DEREF
)
757 TRACE(" RPC_FC_P_DEREF");
761 /***********************************************************************
762 * PointerMarshall [internal]
764 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
765 unsigned char *Buffer
,
766 unsigned char *Pointer
,
767 PFORMAT_STRING pFormat
)
769 unsigned type
= pFormat
[0], attr
= pFormat
[1];
773 int pointer_needs_marshaling
;
775 TRACE("(%p,%p,%p,%p)\n", pStubMsg
, Buffer
, Pointer
, pFormat
);
776 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
778 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
779 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
782 case RPC_FC_RP
: /* ref pointer (always non-null) */
785 ERR("NULL ref pointer is not allowed\n");
786 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
788 pointer_needs_marshaling
= 1;
790 case RPC_FC_UP
: /* unique pointer */
791 case RPC_FC_OP
: /* object pointer - same as unique here */
793 pointer_needs_marshaling
= 1;
795 pointer_needs_marshaling
= 0;
796 pointer_id
= Pointer
? NDR_POINTER_ID(pStubMsg
) : 0;
797 TRACE("writing 0x%08x to buffer\n", pointer_id
);
798 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
801 pointer_needs_marshaling
= !NdrFullPointerQueryPointer(
802 pStubMsg
->FullPtrXlatTables
, Pointer
, 1, &pointer_id
);
803 TRACE("writing 0x%08x to buffer\n", pointer_id
);
804 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
807 FIXME("unhandled ptr type=%02x\n", type
);
808 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
812 TRACE("calling marshaller for type 0x%x\n", (int)*desc
);
814 if (pointer_needs_marshaling
) {
815 if (attr
& RPC_FC_P_DEREF
) {
816 Pointer
= *(unsigned char**)Pointer
;
817 TRACE("deref => %p\n", Pointer
);
819 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
820 if (m
) m(pStubMsg
, Pointer
, desc
);
821 else FIXME("no marshaller for data type=%02x\n", *desc
);
824 STD_OVERFLOW_CHECK(pStubMsg
);
827 /***********************************************************************
828 * PointerUnmarshall [internal]
830 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
831 unsigned char *Buffer
,
832 unsigned char **pPointer
,
833 unsigned char *pSrcPointer
,
834 PFORMAT_STRING pFormat
,
835 unsigned char fMustAlloc
)
837 unsigned type
= pFormat
[0], attr
= pFormat
[1];
840 DWORD pointer_id
= 0;
841 int pointer_needs_unmarshaling
;
843 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg
, Buffer
, pPointer
, pSrcPointer
, pFormat
, fMustAlloc
);
844 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
846 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
847 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
850 case RPC_FC_RP
: /* ref pointer (always non-null) */
851 pointer_needs_unmarshaling
= 1;
853 case RPC_FC_UP
: /* unique pointer */
854 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
855 TRACE("pointer_id is 0x%08x\n", pointer_id
);
857 pointer_needs_unmarshaling
= 1;
860 pointer_needs_unmarshaling
= 0;
863 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
864 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
865 TRACE("pointer_id is 0x%08x\n", pointer_id
);
866 if (!fMustAlloc
&& pSrcPointer
)
868 FIXME("free object pointer %p\n", pSrcPointer
);
872 pointer_needs_unmarshaling
= 1;
876 pointer_needs_unmarshaling
= 0;
880 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
881 TRACE("pointer_id is 0x%08x\n", pointer_id
);
882 pointer_needs_unmarshaling
= !NdrFullPointerQueryRefId(
883 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, (void **)pPointer
);
886 FIXME("unhandled ptr type=%02x\n", type
);
887 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
891 if (pointer_needs_unmarshaling
) {
892 unsigned char *base_ptr_val
= *pPointer
;
893 unsigned char **current_ptr
= pPointer
;
894 if (pStubMsg
->IsClient
) {
896 /* if we aren't forcing allocation of memory then try to use the existing
897 * (source) pointer to unmarshall the data into so that [in,out]
898 * parameters behave correctly. it doesn't matter if the parameter is
899 * [out] only since in that case the pointer will be NULL. we force
900 * allocation when the source pointer is NULL here instead of in the type
901 * unmarshalling routine for the benefit of the deref code below */
904 TRACE("setting *pPointer to %p\n", pSrcPointer
);
905 *pPointer
= base_ptr_val
= pSrcPointer
;
911 /* the memory in a stub is never initialised, so we have to work out here
912 * whether we have to initialise it so we can use the optimisation of
913 * setting the pointer to the buffer, if possible, or set fMustAlloc to
915 if (attr
& RPC_FC_P_DEREF
) {
923 if (attr
& RPC_FC_P_ALLOCALLNODES
)
924 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
926 if (attr
& RPC_FC_P_DEREF
) {
928 base_ptr_val
= NdrAllocate(pStubMsg
, sizeof(void *));
929 *pPointer
= base_ptr_val
;
930 current_ptr
= (unsigned char **)base_ptr_val
;
932 current_ptr
= *(unsigned char***)current_ptr
;
933 TRACE("deref => %p\n", current_ptr
);
934 if (!fMustAlloc
&& !*current_ptr
) fMustAlloc
= TRUE
;
936 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
937 if (m
) m(pStubMsg
, current_ptr
, desc
, fMustAlloc
);
938 else FIXME("no unmarshaller for data type=%02x\n", *desc
);
940 if (type
== RPC_FC_FP
)
941 NdrFullPointerInsertRefId(pStubMsg
->FullPtrXlatTables
, pointer_id
,
945 TRACE("pointer=%p\n", *pPointer
);
948 /***********************************************************************
949 * PointerBufferSize [internal]
951 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
952 unsigned char *Pointer
,
953 PFORMAT_STRING pFormat
)
955 unsigned type
= pFormat
[0], attr
= pFormat
[1];
958 int pointer_needs_sizing
;
961 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
962 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
964 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
965 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
968 case RPC_FC_RP
: /* ref pointer (always non-null) */
971 ERR("NULL ref pointer is not allowed\n");
972 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
977 /* NULL pointer has no further representation */
982 pointer_needs_sizing
= !NdrFullPointerQueryPointer(
983 pStubMsg
->FullPtrXlatTables
, Pointer
, 0, &pointer_id
);
984 if (!pointer_needs_sizing
)
988 FIXME("unhandled ptr type=%02x\n", type
);
989 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
993 if (attr
& RPC_FC_P_DEREF
) {
994 Pointer
= *(unsigned char**)Pointer
;
995 TRACE("deref => %p\n", Pointer
);
998 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
999 if (m
) m(pStubMsg
, Pointer
, desc
);
1000 else FIXME("no buffersizer for data type=%02x\n", *desc
);
1003 /***********************************************************************
1004 * PointerMemorySize [internal]
1006 static ULONG
PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1007 unsigned char *Buffer
, PFORMAT_STRING pFormat
)
1009 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1010 PFORMAT_STRING desc
;
1012 DWORD pointer_id
= 0;
1013 int pointer_needs_sizing
;
1015 TRACE("(%p,%p,%p)\n", pStubMsg
, Buffer
, pFormat
);
1016 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1018 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1019 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1022 case RPC_FC_RP
: /* ref pointer (always non-null) */
1023 pointer_needs_sizing
= 1;
1025 case RPC_FC_UP
: /* unique pointer */
1026 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
1027 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1028 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1030 pointer_needs_sizing
= 1;
1032 pointer_needs_sizing
= 0;
1037 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1038 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1039 pointer_needs_sizing
= !NdrFullPointerQueryRefId(
1040 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, &pointer
);
1044 FIXME("unhandled ptr type=%02x\n", type
);
1045 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1049 if (attr
& RPC_FC_P_DEREF
) {
1050 ALIGN_LENGTH(pStubMsg
->MemorySize
, sizeof(void*));
1051 pStubMsg
->MemorySize
+= sizeof(void*);
1055 if (pointer_needs_sizing
) {
1056 m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
1057 if (m
) m(pStubMsg
, desc
);
1058 else FIXME("no memorysizer for data type=%02x\n", *desc
);
1061 return pStubMsg
->MemorySize
;
1064 /***********************************************************************
1065 * PointerFree [internal]
1067 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1068 unsigned char *Pointer
,
1069 PFORMAT_STRING pFormat
)
1071 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1072 PFORMAT_STRING desc
;
1074 unsigned char *current_pointer
= Pointer
;
1076 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1077 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1078 if (attr
& RPC_FC_P_DONTFREE
) return;
1080 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1081 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1083 if (!Pointer
) return;
1085 if (type
== RPC_FC_FP
) {
1086 int pointer_needs_freeing
= NdrFullPointerFree(
1087 pStubMsg
->FullPtrXlatTables
, Pointer
);
1088 if (!pointer_needs_freeing
)
1092 if (attr
& RPC_FC_P_DEREF
) {
1093 current_pointer
= *(unsigned char**)Pointer
;
1094 TRACE("deref => %p\n", current_pointer
);
1097 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
1098 if (m
) m(pStubMsg
, current_pointer
, desc
);
1100 /* this check stops us from trying to free buffer memory. we don't have to
1101 * worry about clients, since they won't call this function.
1102 * we don't have to check for the buffer being reallocated because
1103 * BufferStart and BufferEnd won't be reset when allocating memory for
1104 * sending the response. we don't have to check for the new buffer here as
1105 * it won't be used a type memory, only for buffer memory */
1106 if (Pointer
>= pStubMsg
->BufferStart
&& Pointer
< pStubMsg
->BufferEnd
)
1109 if (attr
& RPC_FC_P_ONSTACK
) {
1110 TRACE("not freeing stack ptr %p\n", Pointer
);
1113 TRACE("freeing %p\n", Pointer
);
1114 NdrFree(pStubMsg
, Pointer
);
1117 TRACE("not freeing %p\n", Pointer
);
1120 /***********************************************************************
1121 * EmbeddedPointerMarshall
1123 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1124 unsigned char *pMemory
,
1125 PFORMAT_STRING pFormat
)
1127 unsigned char *Mark
= pStubMsg
->BufferMark
;
1128 unsigned rep
, count
, stride
;
1130 unsigned char *saved_buffer
= NULL
;
1132 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1134 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1137 if (pStubMsg
->PointerBufferMark
)
1139 saved_buffer
= pStubMsg
->Buffer
;
1140 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1141 pStubMsg
->PointerBufferMark
= NULL
;
1144 while (pFormat
[0] != RPC_FC_END
) {
1145 switch (pFormat
[0]) {
1147 FIXME("unknown repeat type %d\n", pFormat
[0]);
1148 case RPC_FC_NO_REPEAT
:
1154 case RPC_FC_FIXED_REPEAT
:
1155 rep
= *(const WORD
*)&pFormat
[2];
1156 stride
= *(const WORD
*)&pFormat
[4];
1157 count
= *(const WORD
*)&pFormat
[8];
1160 case RPC_FC_VARIABLE_REPEAT
:
1161 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1162 stride
= *(const WORD
*)&pFormat
[2];
1163 count
= *(const WORD
*)&pFormat
[6];
1167 for (i
= 0; i
< rep
; i
++) {
1168 PFORMAT_STRING info
= pFormat
;
1169 unsigned char *membase
= pMemory
+ (i
* stride
);
1170 unsigned char *bufbase
= Mark
+ (i
* stride
);
1173 for (u
=0; u
<count
; u
++,info
+=8) {
1174 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1175 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1176 unsigned char *saved_memory
= pStubMsg
->Memory
;
1178 pStubMsg
->Memory
= pMemory
;
1179 PointerMarshall(pStubMsg
, bufptr
, *(unsigned char**)memptr
, info
+4);
1180 pStubMsg
->Memory
= saved_memory
;
1183 pFormat
+= 8 * count
;
1188 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1189 pStubMsg
->Buffer
= saved_buffer
;
1192 STD_OVERFLOW_CHECK(pStubMsg
);
1197 /***********************************************************************
1198 * EmbeddedPointerUnmarshall
1200 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1201 unsigned char *pDstBuffer
,
1202 unsigned char *pSrcMemoryPtrs
,
1203 PFORMAT_STRING pFormat
,
1204 unsigned char fMustAlloc
)
1206 unsigned char *Mark
= pStubMsg
->BufferMark
;
1207 unsigned rep
, count
, stride
;
1209 unsigned char *saved_buffer
= NULL
;
1211 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg
, pDstBuffer
, pSrcMemoryPtrs
, pFormat
, fMustAlloc
);
1213 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1216 if (pStubMsg
->PointerBufferMark
)
1218 saved_buffer
= pStubMsg
->Buffer
;
1219 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1220 pStubMsg
->PointerBufferMark
= NULL
;
1223 while (pFormat
[0] != RPC_FC_END
) {
1224 TRACE("pFormat[0] = 0x%x\n", pFormat
[0]);
1225 switch (pFormat
[0]) {
1227 FIXME("unknown repeat type %d\n", pFormat
[0]);
1228 case RPC_FC_NO_REPEAT
:
1234 case RPC_FC_FIXED_REPEAT
:
1235 rep
= *(const WORD
*)&pFormat
[2];
1236 stride
= *(const WORD
*)&pFormat
[4];
1237 count
= *(const WORD
*)&pFormat
[8];
1240 case RPC_FC_VARIABLE_REPEAT
:
1241 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1242 stride
= *(const WORD
*)&pFormat
[2];
1243 count
= *(const WORD
*)&pFormat
[6];
1247 for (i
= 0; i
< rep
; i
++) {
1248 PFORMAT_STRING info
= pFormat
;
1249 unsigned char *bufdstbase
= pDstBuffer
+ (i
* stride
);
1250 unsigned char *memsrcbase
= pSrcMemoryPtrs
+ (i
* stride
);
1251 unsigned char *bufbase
= Mark
+ (i
* stride
);
1254 for (u
=0; u
<count
; u
++,info
+=8) {
1255 unsigned char **bufdstptr
= (unsigned char **)(bufdstbase
+ *(const SHORT
*)&info
[2]);
1256 unsigned char **memsrcptr
= (unsigned char **)(memsrcbase
+ *(const SHORT
*)&info
[0]);
1257 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1258 PointerUnmarshall(pStubMsg
, bufptr
, bufdstptr
, *memsrcptr
, info
+4, fMustAlloc
);
1261 pFormat
+= 8 * count
;
1266 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1267 pStubMsg
->Buffer
= saved_buffer
;
1273 /***********************************************************************
1274 * EmbeddedPointerBufferSize
1276 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1277 unsigned char *pMemory
,
1278 PFORMAT_STRING pFormat
)
1280 unsigned rep
, count
, stride
;
1282 ULONG saved_buffer_length
= 0;
1284 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1286 if (pStubMsg
->IgnoreEmbeddedPointers
) return;
1288 if (*pFormat
!= RPC_FC_PP
) return;
1291 if (pStubMsg
->PointerLength
)
1293 saved_buffer_length
= pStubMsg
->BufferLength
;
1294 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
1295 pStubMsg
->PointerLength
= 0;
1298 while (pFormat
[0] != RPC_FC_END
) {
1299 switch (pFormat
[0]) {
1301 FIXME("unknown repeat type %d\n", pFormat
[0]);
1302 case RPC_FC_NO_REPEAT
:
1308 case RPC_FC_FIXED_REPEAT
:
1309 rep
= *(const WORD
*)&pFormat
[2];
1310 stride
= *(const WORD
*)&pFormat
[4];
1311 count
= *(const WORD
*)&pFormat
[8];
1314 case RPC_FC_VARIABLE_REPEAT
:
1315 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1316 stride
= *(const WORD
*)&pFormat
[2];
1317 count
= *(const WORD
*)&pFormat
[6];
1321 for (i
= 0; i
< rep
; i
++) {
1322 PFORMAT_STRING info
= pFormat
;
1323 unsigned char *membase
= pMemory
+ (i
* stride
);
1326 for (u
=0; u
<count
; u
++,info
+=8) {
1327 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1328 unsigned char *saved_memory
= pStubMsg
->Memory
;
1330 pStubMsg
->Memory
= pMemory
;
1331 PointerBufferSize(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1332 pStubMsg
->Memory
= saved_memory
;
1335 pFormat
+= 8 * count
;
1338 if (saved_buffer_length
)
1340 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
1341 pStubMsg
->BufferLength
= saved_buffer_length
;
1345 /***********************************************************************
1346 * EmbeddedPointerMemorySize [internal]
1348 static ULONG
EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1349 PFORMAT_STRING pFormat
)
1351 unsigned char *Mark
= pStubMsg
->BufferMark
;
1352 unsigned rep
, count
, stride
;
1354 unsigned char *saved_buffer
= NULL
;
1356 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1358 if (pStubMsg
->IgnoreEmbeddedPointers
) return 0;
1360 if (pStubMsg
->PointerBufferMark
)
1362 saved_buffer
= pStubMsg
->Buffer
;
1363 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1364 pStubMsg
->PointerBufferMark
= NULL
;
1367 if (*pFormat
!= RPC_FC_PP
) return 0;
1370 while (pFormat
[0] != RPC_FC_END
) {
1371 switch (pFormat
[0]) {
1373 FIXME("unknown repeat type %d\n", pFormat
[0]);
1374 case RPC_FC_NO_REPEAT
:
1380 case RPC_FC_FIXED_REPEAT
:
1381 rep
= *(const WORD
*)&pFormat
[2];
1382 stride
= *(const WORD
*)&pFormat
[4];
1383 count
= *(const WORD
*)&pFormat
[8];
1386 case RPC_FC_VARIABLE_REPEAT
:
1387 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1388 stride
= *(const WORD
*)&pFormat
[2];
1389 count
= *(const WORD
*)&pFormat
[6];
1393 for (i
= 0; i
< rep
; i
++) {
1394 PFORMAT_STRING info
= pFormat
;
1395 unsigned char *bufbase
= Mark
+ (i
* stride
);
1397 for (u
=0; u
<count
; u
++,info
+=8) {
1398 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1399 PointerMemorySize(pStubMsg
, bufptr
, info
+4);
1402 pFormat
+= 8 * count
;
1407 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1408 pStubMsg
->Buffer
= saved_buffer
;
1414 /***********************************************************************
1415 * EmbeddedPointerFree [internal]
1417 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1418 unsigned char *pMemory
,
1419 PFORMAT_STRING pFormat
)
1421 unsigned rep
, count
, stride
;
1424 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1425 if (*pFormat
!= RPC_FC_PP
) return;
1428 while (pFormat
[0] != RPC_FC_END
) {
1429 switch (pFormat
[0]) {
1431 FIXME("unknown repeat type %d\n", pFormat
[0]);
1432 case RPC_FC_NO_REPEAT
:
1438 case RPC_FC_FIXED_REPEAT
:
1439 rep
= *(const WORD
*)&pFormat
[2];
1440 stride
= *(const WORD
*)&pFormat
[4];
1441 count
= *(const WORD
*)&pFormat
[8];
1444 case RPC_FC_VARIABLE_REPEAT
:
1445 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1446 stride
= *(const WORD
*)&pFormat
[2];
1447 count
= *(const WORD
*)&pFormat
[6];
1451 for (i
= 0; i
< rep
; i
++) {
1452 PFORMAT_STRING info
= pFormat
;
1453 unsigned char *membase
= pMemory
+ (i
* stride
);
1456 for (u
=0; u
<count
; u
++,info
+=8) {
1457 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1458 unsigned char *saved_memory
= pStubMsg
->Memory
;
1460 pStubMsg
->Memory
= pMemory
;
1461 PointerFree(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1462 pStubMsg
->Memory
= saved_memory
;
1465 pFormat
+= 8 * count
;
1469 /***********************************************************************
1470 * NdrPointerMarshall [RPCRT4.@]
1472 unsigned char * WINAPI
NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1473 unsigned char *pMemory
,
1474 PFORMAT_STRING pFormat
)
1476 unsigned char *Buffer
;
1478 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1480 /* Increment the buffer here instead of in PointerMarshall,
1481 * as that is used by embedded pointers which already handle the incrementing
1482 * the buffer, and shouldn't write any additional pointer data to the wire */
1483 if (*pFormat
!= RPC_FC_RP
)
1485 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
1486 Buffer
= pStubMsg
->Buffer
;
1487 safe_buffer_increment(pStubMsg
, 4);
1490 Buffer
= pStubMsg
->Buffer
;
1492 PointerMarshall(pStubMsg
, Buffer
, pMemory
, pFormat
);
1497 /***********************************************************************
1498 * NdrPointerUnmarshall [RPCRT4.@]
1500 unsigned char * WINAPI
NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1501 unsigned char **ppMemory
,
1502 PFORMAT_STRING pFormat
,
1503 unsigned char fMustAlloc
)
1505 unsigned char *Buffer
;
1507 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1509 if (*pFormat
== RPC_FC_RP
)
1511 Buffer
= pStubMsg
->Buffer
;
1512 /* Do the NULL ref pointer check here because embedded pointers can be
1513 * NULL if the type the pointer is embedded in was allocated rather than
1514 * being passed in by the client */
1515 if (pStubMsg
->IsClient
&& !*ppMemory
)
1517 ERR("NULL ref pointer is not allowed\n");
1518 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
1523 /* Increment the buffer here instead of in PointerUnmarshall,
1524 * as that is used by embedded pointers which already handle the incrementing
1525 * the buffer, and shouldn't read any additional pointer data from the
1527 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1528 Buffer
= pStubMsg
->Buffer
;
1529 safe_buffer_increment(pStubMsg
, 4);
1532 PointerUnmarshall(pStubMsg
, Buffer
, ppMemory
, *ppMemory
, pFormat
, fMustAlloc
);
1537 /***********************************************************************
1538 * NdrPointerBufferSize [RPCRT4.@]
1540 void WINAPI
NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1541 unsigned char *pMemory
,
1542 PFORMAT_STRING pFormat
)
1544 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1546 /* Increment the buffer length here instead of in PointerBufferSize,
1547 * as that is used by embedded pointers which already handle the buffer
1548 * length, and shouldn't write anything more to the wire */
1549 if (*pFormat
!= RPC_FC_RP
)
1551 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
1552 safe_buffer_length_increment(pStubMsg
, 4);
1555 PointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1558 /***********************************************************************
1559 * NdrPointerMemorySize [RPCRT4.@]
1561 ULONG WINAPI
NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1562 PFORMAT_STRING pFormat
)
1564 unsigned char *Buffer
= pStubMsg
->Buffer
;
1565 if (*pFormat
!= RPC_FC_RP
)
1567 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1568 safe_buffer_increment(pStubMsg
, 4);
1570 ALIGN_LENGTH(pStubMsg
->MemorySize
, sizeof(void *));
1571 return PointerMemorySize(pStubMsg
, Buffer
, pFormat
);
1574 /***********************************************************************
1575 * NdrPointerFree [RPCRT4.@]
1577 void WINAPI
NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1578 unsigned char *pMemory
,
1579 PFORMAT_STRING pFormat
)
1581 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1582 PointerFree(pStubMsg
, pMemory
, pFormat
);
1585 /***********************************************************************
1586 * NdrSimpleTypeMarshall [RPCRT4.@]
1588 void WINAPI
NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1589 unsigned char FormatChar
)
1591 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &FormatChar
);
1594 /***********************************************************************
1595 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1597 * Unmarshall a base type.
1600 * Doesn't check that the buffer is long enough before copying, so the caller
1603 void WINAPI
NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1604 unsigned char FormatChar
)
1606 #define BASE_TYPE_UNMARSHALL(type) \
1607 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
1608 TRACE("pMemory: %p\n", pMemory); \
1609 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1610 pStubMsg->Buffer += sizeof(type);
1618 BASE_TYPE_UNMARSHALL(UCHAR
);
1619 TRACE("value: 0x%02x\n", *pMemory
);
1624 BASE_TYPE_UNMARSHALL(USHORT
);
1625 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
1629 case RPC_FC_ERROR_STATUS_T
:
1631 BASE_TYPE_UNMARSHALL(ULONG
);
1632 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
1635 BASE_TYPE_UNMARSHALL(float);
1636 TRACE("value: %f\n", *(float *)pMemory
);
1639 BASE_TYPE_UNMARSHALL(double);
1640 TRACE("value: %f\n", *(double *)pMemory
);
1643 BASE_TYPE_UNMARSHALL(ULONGLONG
);
1644 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
1647 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
1648 TRACE("pMemory: %p\n", pMemory
);
1649 /* 16-bits on the wire, but int in memory */
1650 *(UINT
*)pMemory
= *(USHORT
*)pStubMsg
->Buffer
;
1651 pStubMsg
->Buffer
+= sizeof(USHORT
);
1652 TRACE("value: 0x%08x\n", *(UINT
*)pMemory
);
1657 FIXME("Unhandled base type: 0x%02x\n", FormatChar
);
1659 #undef BASE_TYPE_UNMARSHALL
1662 /***********************************************************************
1663 * NdrSimpleStructMarshall [RPCRT4.@]
1665 unsigned char * WINAPI
NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1666 unsigned char *pMemory
,
1667 PFORMAT_STRING pFormat
)
1669 unsigned size
= *(const WORD
*)(pFormat
+2);
1670 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1672 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pFormat
[1] + 1);
1674 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1675 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
1677 if (pFormat
[0] != RPC_FC_STRUCT
)
1678 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
+4);
1683 /***********************************************************************
1684 * NdrSimpleStructUnmarshall [RPCRT4.@]
1686 unsigned char * WINAPI
NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1687 unsigned char **ppMemory
,
1688 PFORMAT_STRING pFormat
,
1689 unsigned char fMustAlloc
)
1691 unsigned size
= *(const WORD
*)(pFormat
+2);
1692 unsigned char *saved_buffer
;
1693 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1695 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1698 *ppMemory
= NdrAllocate(pStubMsg
, size
);
1701 if (!pStubMsg
->IsClient
&& !*ppMemory
)
1702 /* for servers, we just point straight into the RPC buffer */
1703 *ppMemory
= pStubMsg
->Buffer
;
1706 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1707 safe_buffer_increment(pStubMsg
, size
);
1708 if (pFormat
[0] == RPC_FC_PSTRUCT
)
1709 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
+4, fMustAlloc
);
1711 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
1712 if (*ppMemory
!= saved_buffer
)
1713 memcpy(*ppMemory
, saved_buffer
, size
);
1718 /***********************************************************************
1719 * NdrSimpleStructBufferSize [RPCRT4.@]
1721 void WINAPI
NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1722 unsigned char *pMemory
,
1723 PFORMAT_STRING pFormat
)
1725 unsigned size
= *(const WORD
*)(pFormat
+2);
1726 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1728 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
1730 safe_buffer_length_increment(pStubMsg
, size
);
1731 if (pFormat
[0] != RPC_FC_STRUCT
)
1732 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
+4);
1735 /***********************************************************************
1736 * NdrSimpleStructMemorySize [RPCRT4.@]
1738 ULONG WINAPI
NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1739 PFORMAT_STRING pFormat
)
1741 unsigned short size
= *(const WORD
*)(pFormat
+2);
1743 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1745 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1746 pStubMsg
->MemorySize
+= size
;
1747 safe_buffer_increment(pStubMsg
, size
);
1749 if (pFormat
[0] != RPC_FC_STRUCT
)
1750 EmbeddedPointerMemorySize(pStubMsg
, pFormat
+4);
1751 return pStubMsg
->MemorySize
;
1754 /***********************************************************************
1755 * NdrSimpleStructFree [RPCRT4.@]
1757 void WINAPI
NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
1758 unsigned char *pMemory
,
1759 PFORMAT_STRING pFormat
)
1761 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1762 if (pFormat
[0] != RPC_FC_STRUCT
)
1763 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
+4);
1768 static inline void array_compute_and_size_conformance(
1769 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1770 PFORMAT_STRING pFormat
)
1775 ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1776 SizeConformance(pStubMsg
);
1778 case RPC_FC_CVARRAY
:
1779 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, 0);
1780 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
1781 SizeConformance(pStubMsg
);
1783 case RPC_FC_C_CSTRING
:
1784 case RPC_FC_C_WSTRING
:
1785 if (fc
== RPC_FC_C_CSTRING
)
1787 TRACE("string=%s\n", debugstr_a((const char *)pMemory
));
1788 pStubMsg
->ActualCount
= strlen((const char *)pMemory
)+1;
1792 TRACE("string=%s\n", debugstr_w((LPCWSTR
)pMemory
));
1793 pStubMsg
->ActualCount
= strlenW((LPCWSTR
)pMemory
)+1;
1796 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
1797 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
1799 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
1801 SizeConformance(pStubMsg
);
1804 ERR("unknown array format 0x%x\n", fc
);
1805 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1809 static inline void array_buffer_size(
1810 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1811 PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
1815 unsigned char alignment
;
1820 esize
= *(const WORD
*)(pFormat
+2);
1821 alignment
= pFormat
[1] + 1;
1823 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1825 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
1827 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
1828 /* conformance value plus array */
1829 safe_buffer_length_increment(pStubMsg
, size
);
1832 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1834 case RPC_FC_CVARRAY
:
1835 esize
= *(const WORD
*)(pFormat
+2);
1836 alignment
= pFormat
[1] + 1;
1838 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1839 pFormat
= SkipConformance(pStubMsg
, pFormat
);
1841 SizeVariance(pStubMsg
);
1843 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
1845 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1846 safe_buffer_length_increment(pStubMsg
, size
);
1849 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1851 case RPC_FC_C_CSTRING
:
1852 case RPC_FC_C_WSTRING
:
1853 if (fc
== RPC_FC_C_CSTRING
)
1858 SizeVariance(pStubMsg
);
1860 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1861 safe_buffer_length_increment(pStubMsg
, size
);
1864 ERR("unknown array format 0x%x\n", fc
);
1865 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1869 static inline void array_compute_and_write_conformance(
1870 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1871 PFORMAT_STRING pFormat
)
1876 ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1877 WriteConformance(pStubMsg
);
1879 case RPC_FC_CVARRAY
:
1880 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, 0);
1881 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
1882 WriteConformance(pStubMsg
);
1884 case RPC_FC_C_CSTRING
:
1885 case RPC_FC_C_WSTRING
:
1886 if (fc
== RPC_FC_C_CSTRING
)
1888 TRACE("string=%s\n", debugstr_a((const char *)pMemory
));
1889 pStubMsg
->ActualCount
= strlen((const char *)pMemory
)+1;
1893 TRACE("string=%s\n", debugstr_w((LPCWSTR
)pMemory
));
1894 pStubMsg
->ActualCount
= strlenW((LPCWSTR
)pMemory
)+1;
1896 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
1897 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
1899 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
1900 pStubMsg
->Offset
= 0;
1901 WriteConformance(pStubMsg
);
1904 ERR("unknown array format 0x%x\n", fc
);
1905 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1909 static inline void array_write_variance_and_marshall(
1910 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1911 PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
1915 unsigned char alignment
;
1920 esize
= *(const WORD
*)(pFormat
+2);
1921 alignment
= pFormat
[1] + 1;
1923 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1925 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
1927 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
1929 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1930 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
1933 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
1935 case RPC_FC_CVARRAY
:
1936 esize
= *(const WORD
*)(pFormat
+2);
1937 alignment
= pFormat
[1] + 1;
1940 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1942 pFormat
= SkipConformance(pStubMsg
, pFormat
);
1944 WriteVariance(pStubMsg
);
1946 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
1948 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1951 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1952 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, size
);
1955 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
1957 case RPC_FC_C_CSTRING
:
1958 case RPC_FC_C_WSTRING
:
1959 if (fc
== RPC_FC_C_CSTRING
)
1964 WriteVariance(pStubMsg
);
1966 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1967 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
1970 ERR("unknown array format 0x%x\n", fc
);
1971 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1975 static inline ULONG
array_read_conformance(
1976 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
1983 esize
= *(const WORD
*)(pFormat
+2);
1984 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
1985 return safe_multiply(esize
, pStubMsg
->MaxCount
);
1986 case RPC_FC_CVARRAY
:
1987 esize
= *(const WORD
*)(pFormat
+2);
1988 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
1989 return safe_multiply(esize
, pStubMsg
->MaxCount
);
1990 case RPC_FC_C_CSTRING
:
1991 case RPC_FC_C_WSTRING
:
1992 if (fc
== RPC_FC_C_CSTRING
)
1997 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
1998 ReadConformance(pStubMsg
, pFormat
+ 2);
2000 ReadConformance(pStubMsg
, NULL
);
2001 return safe_multiply(esize
, pStubMsg
->MaxCount
);
2003 ERR("unknown array format 0x%x\n", fc
);
2004 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2008 static inline ULONG
array_read_variance_and_unmarshall(
2009 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char **ppMemory
,
2010 PFORMAT_STRING pFormat
, unsigned char fMustAlloc
,
2011 unsigned char fUseBufferMemoryServer
, unsigned char fUnmarshall
)
2013 ULONG bufsize
, memsize
;
2015 unsigned char alignment
;
2016 unsigned char *saved_buffer
;
2022 esize
= *(const WORD
*)(pFormat
+2);
2023 alignment
= pFormat
[1] + 1;
2025 bufsize
= memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2027 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2029 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2034 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2037 if (fUseBufferMemoryServer
&& !pStubMsg
->IsClient
&& !*ppMemory
)
2038 /* for servers, we just point straight into the RPC buffer */
2039 *ppMemory
= pStubMsg
->Buffer
;
2042 saved_buffer
= pStubMsg
->Buffer
;
2043 safe_buffer_increment(pStubMsg
, bufsize
);
2045 pStubMsg
->BufferMark
= saved_buffer
;
2046 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
2048 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
2049 if (*ppMemory
!= saved_buffer
)
2050 memcpy(*ppMemory
, saved_buffer
, bufsize
);
2053 case RPC_FC_CVARRAY
:
2054 esize
= *(const WORD
*)(pFormat
+2);
2055 alignment
= pFormat
[1] + 1;
2057 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2059 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2061 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2063 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2064 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2068 offset
= pStubMsg
->Offset
;
2070 if (!fMustAlloc
&& !*ppMemory
)
2073 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2074 saved_buffer
= pStubMsg
->Buffer
;
2075 safe_buffer_increment(pStubMsg
, bufsize
);
2077 pStubMsg
->BufferMark
= saved_buffer
;
2078 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
,
2081 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
2084 case RPC_FC_C_CSTRING
:
2085 case RPC_FC_C_WSTRING
:
2086 if (fc
== RPC_FC_C_CSTRING
)
2091 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
2093 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
2095 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2096 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
2097 RpcRaiseException(RPC_S_INVALID_BOUND
);
2099 if (pStubMsg
->Offset
)
2101 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2102 RpcRaiseException(RPC_S_INVALID_BOUND
);
2105 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2106 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2108 validate_string_data(pStubMsg
, bufsize
, esize
);
2113 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2116 if (fUseBufferMemoryServer
&& !pStubMsg
->IsClient
&&
2117 !*ppMemory
&& (pStubMsg
->MaxCount
== pStubMsg
->ActualCount
))
2118 /* if the data in the RPC buffer is big enough, we just point
2119 * straight into it */
2120 *ppMemory
= pStubMsg
->Buffer
;
2121 else if (!*ppMemory
)
2122 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2125 if (*ppMemory
== pStubMsg
->Buffer
)
2126 safe_buffer_increment(pStubMsg
, bufsize
);
2128 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
2130 if (*pFormat
== RPC_FC_C_CSTRING
)
2131 TRACE("string=%s\n", debugstr_a((char*)*ppMemory
));
2133 TRACE("string=%s\n", debugstr_w((LPWSTR
)*ppMemory
));
2137 ERR("unknown array format 0x%x\n", fc
);
2138 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2142 static inline void array_memory_size(
2143 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
,
2144 unsigned char fHasPointers
)
2146 ULONG bufsize
, memsize
;
2148 unsigned char alignment
;
2153 esize
= *(const WORD
*)(pFormat
+2);
2154 alignment
= pFormat
[1] + 1;
2156 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2158 bufsize
= memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2159 pStubMsg
->MemorySize
+= memsize
;
2161 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2163 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2164 safe_buffer_increment(pStubMsg
, bufsize
);
2167 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2169 case RPC_FC_CVARRAY
:
2170 esize
= *(const WORD
*)(pFormat
+2);
2171 alignment
= pFormat
[1] + 1;
2173 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2175 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2177 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2178 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2179 pStubMsg
->MemorySize
+= memsize
;
2181 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2183 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2184 safe_buffer_increment(pStubMsg
, bufsize
);
2187 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2189 case RPC_FC_C_CSTRING
:
2190 case RPC_FC_C_WSTRING
:
2191 if (fc
== RPC_FC_C_CSTRING
)
2196 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
2198 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
2200 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2201 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
2202 RpcRaiseException(RPC_S_INVALID_BOUND
);
2204 if (pStubMsg
->Offset
)
2206 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2207 RpcRaiseException(RPC_S_INVALID_BOUND
);
2210 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2211 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2213 validate_string_data(pStubMsg
, bufsize
, esize
);
2215 safe_buffer_increment(pStubMsg
, bufsize
);
2216 pStubMsg
->MemorySize
+= memsize
;
2219 ERR("unknown array format 0x%x\n", fc
);
2220 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2224 static inline void array_free(
2225 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
,
2226 unsigned char *pMemory
, PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
2231 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2233 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2235 case RPC_FC_CVARRAY
:
2236 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2237 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2239 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2241 case RPC_FC_C_CSTRING
:
2242 case RPC_FC_C_WSTRING
:
2243 /* No embedded pointers so nothing to do */
2246 ERR("unknown array format 0x%x\n", fc
);
2247 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2252 * NdrConformantString:
2254 * What MS calls a ConformantString is, in DCE terminology,
2255 * a Varying-Conformant String.
2257 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2258 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2259 * into unmarshalled string)
2260 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2262 * data: CHARTYPE[maxlen]
2264 * ], where CHARTYPE is the appropriate character type (specified externally)
2268 /***********************************************************************
2269 * NdrConformantStringMarshall [RPCRT4.@]
2271 unsigned char *WINAPI
NdrConformantStringMarshall(MIDL_STUB_MESSAGE
*pStubMsg
,
2272 unsigned char *pszMessage
, PFORMAT_STRING pFormat
)
2274 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg
, pszMessage
, pFormat
);
2276 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2277 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2278 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2281 /* allow compiler to optimise inline function by passing constant into
2282 * these functions */
2283 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2284 array_compute_and_write_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pszMessage
,
2286 array_write_variance_and_marshall(RPC_FC_C_CSTRING
, pStubMsg
, pszMessage
,
2287 pFormat
, TRUE
/* fHasPointers */);
2289 array_compute_and_write_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pszMessage
,
2291 array_write_variance_and_marshall(RPC_FC_C_WSTRING
, pStubMsg
, pszMessage
,
2292 pFormat
, TRUE
/* fHasPointers */);
2298 /***********************************************************************
2299 * NdrConformantStringBufferSize [RPCRT4.@]
2301 void WINAPI
NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2302 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
2304 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2306 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2307 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2308 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2311 /* allow compiler to optimise inline function by passing constant into
2312 * these functions */
2313 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2314 array_compute_and_size_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pMemory
,
2316 array_buffer_size(RPC_FC_C_CSTRING
, pStubMsg
, pMemory
, pFormat
,
2317 TRUE
/* fHasPointers */);
2319 array_compute_and_size_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pMemory
,
2321 array_buffer_size(RPC_FC_C_WSTRING
, pStubMsg
, pMemory
, pFormat
,
2322 TRUE
/* fHasPointers */);
2326 /************************************************************************
2327 * NdrConformantStringMemorySize [RPCRT4.@]
2329 ULONG WINAPI
NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
2330 PFORMAT_STRING pFormat
)
2332 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
2334 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2335 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2336 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2339 /* allow compiler to optimise inline function by passing constant into
2340 * these functions */
2341 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2342 array_read_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
);
2343 array_memory_size(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
,
2344 TRUE
/* fHasPointers */);
2346 array_read_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
);
2347 array_memory_size(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
,
2348 TRUE
/* fHasPointers */);
2351 return pStubMsg
->MemorySize
;
2354 /************************************************************************
2355 * NdrConformantStringUnmarshall [RPCRT4.@]
2357 unsigned char *WINAPI
NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2358 unsigned char** ppMemory
, PFORMAT_STRING pFormat
, unsigned char fMustAlloc
)
2360 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2361 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
2363 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2364 ERR("Unhandled string type: %#x\n", *pFormat
);
2365 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2368 /* allow compiler to optimise inline function by passing constant into
2369 * these functions */
2370 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2371 array_read_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
);
2372 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING
, pStubMsg
, ppMemory
,
2373 pFormat
, fMustAlloc
,
2374 TRUE
/* fUseBufferMemoryServer */,
2375 TRUE
/* fUnmarshall */);
2377 array_read_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
);
2378 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING
, pStubMsg
, ppMemory
,
2379 pFormat
, fMustAlloc
,
2380 TRUE
/* fUseBufferMemoryServer */,
2381 TRUE
/* fUnmarshall */);
2387 /***********************************************************************
2388 * NdrNonConformantStringMarshall [RPCRT4.@]
2390 unsigned char * WINAPI
NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2391 unsigned char *pMemory
,
2392 PFORMAT_STRING pFormat
)
2394 ULONG esize
, size
, maxsize
;
2396 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2398 maxsize
= *(USHORT
*)&pFormat
[2];
2400 if (*pFormat
== RPC_FC_CSTRING
)
2403 const char *str
= (const char *)pMemory
;
2404 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
2406 TRACE("string=%s\n", debugstr_an(str
, i
));
2407 pStubMsg
->ActualCount
= i
+ 1;
2410 else if (*pFormat
== RPC_FC_WSTRING
)
2413 const WCHAR
*str
= (const WCHAR
*)pMemory
;
2414 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
2416 TRACE("string=%s\n", debugstr_wn(str
, i
));
2417 pStubMsg
->ActualCount
= i
+ 1;
2422 ERR("Unhandled string type: %#x\n", *pFormat
);
2423 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2426 pStubMsg
->Offset
= 0;
2427 WriteVariance(pStubMsg
);
2429 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2430 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
2435 /***********************************************************************
2436 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2438 unsigned char * WINAPI
NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2439 unsigned char **ppMemory
,
2440 PFORMAT_STRING pFormat
,
2441 unsigned char fMustAlloc
)
2443 ULONG bufsize
, memsize
, esize
, maxsize
;
2445 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2446 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
2448 maxsize
= *(USHORT
*)&pFormat
[2];
2450 ReadVariance(pStubMsg
, NULL
, maxsize
);
2451 if (pStubMsg
->Offset
)
2453 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2454 RpcRaiseException(RPC_S_INVALID_BOUND
);
2457 if (*pFormat
== RPC_FC_CSTRING
) esize
= 1;
2458 else if (*pFormat
== RPC_FC_WSTRING
) esize
= 2;
2461 ERR("Unhandled string type: %#x\n", *pFormat
);
2462 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2465 memsize
= esize
* maxsize
;
2466 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2468 validate_string_data(pStubMsg
, bufsize
, esize
);
2470 if (!fMustAlloc
&& !*ppMemory
)
2473 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2475 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
2477 if (*pFormat
== RPC_FC_CSTRING
) {
2478 TRACE("string=%s\n", debugstr_an((char*)*ppMemory
, pStubMsg
->ActualCount
));
2480 else if (*pFormat
== RPC_FC_WSTRING
) {
2481 TRACE("string=%s\n", debugstr_wn((LPWSTR
)*ppMemory
, pStubMsg
->ActualCount
));
2487 /***********************************************************************
2488 * NdrNonConformantStringBufferSize [RPCRT4.@]
2490 void WINAPI
NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2491 unsigned char *pMemory
,
2492 PFORMAT_STRING pFormat
)
2494 ULONG esize
, maxsize
;
2496 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2498 maxsize
= *(USHORT
*)&pFormat
[2];
2500 SizeVariance(pStubMsg
);
2502 if (*pFormat
== RPC_FC_CSTRING
)
2505 const char *str
= (const char *)pMemory
;
2506 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
2508 TRACE("string=%s\n", debugstr_an(str
, i
));
2509 pStubMsg
->ActualCount
= i
+ 1;
2512 else if (*pFormat
== RPC_FC_WSTRING
)
2515 const WCHAR
*str
= (const WCHAR
*)pMemory
;
2516 for (i
= 0; i
< maxsize
&& *str
; i
++, str
++)
2518 TRACE("string=%s\n", debugstr_wn(str
, i
));
2519 pStubMsg
->ActualCount
= i
+ 1;
2524 ERR("Unhandled string type: %#x\n", *pFormat
);
2525 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2528 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
2531 /***********************************************************************
2532 * NdrNonConformantStringMemorySize [RPCRT4.@]
2534 ULONG WINAPI
NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2535 PFORMAT_STRING pFormat
)
2537 ULONG bufsize
, memsize
, esize
, maxsize
;
2539 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
2541 maxsize
= *(USHORT
*)&pFormat
[2];
2543 ReadVariance(pStubMsg
, NULL
, maxsize
);
2545 if (pStubMsg
->Offset
)
2547 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2548 RpcRaiseException(RPC_S_INVALID_BOUND
);
2551 if (*pFormat
== RPC_FC_CSTRING
) esize
= 1;
2552 else if (*pFormat
== RPC_FC_WSTRING
) esize
= 2;
2555 ERR("Unhandled string type: %#x\n", *pFormat
);
2556 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2559 memsize
= esize
* maxsize
;
2560 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2562 validate_string_data(pStubMsg
, bufsize
, esize
);
2564 safe_buffer_increment(pStubMsg
, bufsize
);
2565 pStubMsg
->MemorySize
+= memsize
;
2567 return pStubMsg
->MemorySize
;
2572 #include "pshpack1.h"
2576 unsigned char flags_type
; /* flags in upper nibble, type in lower nibble */
2580 #include "poppack.h"
2582 static ULONG
EmbeddedComplexSize(MIDL_STUB_MESSAGE
*pStubMsg
,
2583 PFORMAT_STRING pFormat
)
2587 case RPC_FC_PSTRUCT
:
2588 case RPC_FC_CSTRUCT
:
2589 case RPC_FC_BOGUS_STRUCT
:
2590 case RPC_FC_SMFARRAY
:
2591 case RPC_FC_SMVARRAY
:
2592 case RPC_FC_CSTRING
:
2593 return *(const WORD
*)&pFormat
[2];
2594 case RPC_FC_USER_MARSHAL
:
2595 return *(const WORD
*)&pFormat
[4];
2596 case RPC_FC_RANGE
: {
2597 switch (((const NDR_RANGE
*)pFormat
)->flags_type
& 0xf) {
2602 return sizeof(UCHAR
);
2606 return sizeof(USHORT
);
2610 return sizeof(ULONG
);
2612 return sizeof(float);
2614 return sizeof(double);
2616 return sizeof(ULONGLONG
);
2618 return sizeof(UINT
);
2620 ERR("unknown type 0x%x\n", ((const NDR_RANGE
*)pFormat
)->flags_type
& 0xf);
2621 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2624 case RPC_FC_NON_ENCAPSULATED_UNION
:
2626 if (pStubMsg
->fHasNewCorrDesc
)
2631 pFormat
+= *(const SHORT
*)pFormat
;
2632 return *(const SHORT
*)pFormat
;
2634 return sizeof(void *);
2635 case RPC_FC_WSTRING
:
2636 return *(const WORD
*)&pFormat
[2] * 2;
2638 FIXME("unhandled embedded type %02x\n", *pFormat
);
2644 static ULONG
EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2645 PFORMAT_STRING pFormat
)
2647 NDR_MEMORYSIZE m
= NdrMemorySizer
[*pFormat
& NDR_TABLE_MASK
];
2651 FIXME("no memorysizer for data type=%02x\n", *pFormat
);
2655 return m(pStubMsg
, pFormat
);
2659 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2660 unsigned char *pMemory
,
2661 PFORMAT_STRING pFormat
,
2662 PFORMAT_STRING pPointer
)
2664 PFORMAT_STRING desc
;
2668 while (*pFormat
!= RPC_FC_END
) {
2674 TRACE("byte=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2675 safe_copy_to_buffer(pStubMsg
, pMemory
, 1);
2681 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2682 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
2686 TRACE("enum16=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2687 if (32767 < *(DWORD
*)pMemory
)
2688 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
2689 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
2695 TRACE("long=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2696 safe_copy_to_buffer(pStubMsg
, pMemory
, 4);
2700 TRACE("float=%f <= %p\n", *(float*)pMemory
, pMemory
);
2701 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
2702 pMemory
+= sizeof(float);
2705 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2706 safe_copy_to_buffer(pStubMsg
, pMemory
, 8);
2710 TRACE("double=%f <= %p\n", *(double*)pMemory
, pMemory
);
2711 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
2712 pMemory
+= sizeof(double);
2718 case RPC_FC_POINTER
:
2720 unsigned char *saved_buffer
;
2721 int pointer_buffer_mark_set
= 0;
2722 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
2723 TRACE("pStubMsg->Buffer before %p\n", pStubMsg
->Buffer
);
2724 if (*pFormat
!= RPC_FC_POINTER
)
2726 if (*pPointer
!= RPC_FC_RP
)
2727 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
2728 saved_buffer
= pStubMsg
->Buffer
;
2729 if (pStubMsg
->PointerBufferMark
)
2731 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2732 pStubMsg
->PointerBufferMark
= NULL
;
2733 pointer_buffer_mark_set
= 1;
2735 else if (*pPointer
!= RPC_FC_RP
)
2736 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2737 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char**)pMemory
, pPointer
);
2738 if (pointer_buffer_mark_set
)
2740 STD_OVERFLOW_CHECK(pStubMsg
);
2741 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2742 pStubMsg
->Buffer
= saved_buffer
;
2743 if (*pPointer
!= RPC_FC_RP
)
2744 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2746 TRACE("pStubMsg->Buffer after %p\n", pStubMsg
->Buffer
);
2747 if (*pFormat
== RPC_FC_POINTER
)
2751 pMemory
+= sizeof(void *);
2754 case RPC_FC_ALIGNM2
:
2755 ALIGN_POINTER(pMemory
, 2);
2757 case RPC_FC_ALIGNM4
:
2758 ALIGN_POINTER(pMemory
, 4);
2760 case RPC_FC_ALIGNM8
:
2761 ALIGN_POINTER(pMemory
, 8);
2763 case RPC_FC_STRUCTPAD1
:
2764 case RPC_FC_STRUCTPAD2
:
2765 case RPC_FC_STRUCTPAD3
:
2766 case RPC_FC_STRUCTPAD4
:
2767 case RPC_FC_STRUCTPAD5
:
2768 case RPC_FC_STRUCTPAD6
:
2769 case RPC_FC_STRUCTPAD7
:
2770 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2772 case RPC_FC_EMBEDDED_COMPLEX
:
2773 pMemory
+= pFormat
[1];
2775 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2776 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2777 TRACE("embedded complex (size=%d) <= %p\n", size
, pMemory
);
2778 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
2781 /* for some reason interface pointers aren't generated as
2782 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2783 * they still need the derefencing treatment that pointers are
2785 if (*desc
== RPC_FC_IP
)
2786 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2788 m(pStubMsg
, pMemory
, desc
);
2790 else FIXME("no marshaller for embedded type %02x\n", *desc
);
2797 FIXME("unhandled format 0x%02x\n", *pFormat
);
2805 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2806 unsigned char *pMemory
,
2807 PFORMAT_STRING pFormat
,
2808 PFORMAT_STRING pPointer
,
2809 unsigned char fMustAlloc
)
2811 PFORMAT_STRING desc
;
2815 while (*pFormat
!= RPC_FC_END
) {
2821 safe_copy_from_buffer(pStubMsg
, pMemory
, 1);
2822 TRACE("byte=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2828 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
2829 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2833 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
2834 *(DWORD
*)pMemory
&= 0xffff;
2835 TRACE("enum16=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
2836 if (32767 < *(DWORD
*)pMemory
)
2837 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
2843 safe_copy_from_buffer(pStubMsg
, pMemory
, 4);
2844 TRACE("long=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
2848 safe_copy_from_buffer(pStubMsg
, pMemory
, sizeof(float));
2849 TRACE("float=%f => %p\n", *(float*)pMemory
, pMemory
);
2850 pMemory
+= sizeof(float);
2853 safe_copy_from_buffer(pStubMsg
, pMemory
, 8);
2854 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2858 safe_copy_from_buffer(pStubMsg
, pMemory
, sizeof(double));
2859 TRACE("double=%f => %p\n", *(double*)pMemory
, pMemory
);
2860 pMemory
+= sizeof(double);
2866 case RPC_FC_POINTER
:
2868 unsigned char *saved_buffer
;
2869 int pointer_buffer_mark_set
= 0;
2870 TRACE("pointer => %p\n", pMemory
);
2871 if (*pFormat
!= RPC_FC_POINTER
)
2873 if (*pPointer
!= RPC_FC_RP
)
2874 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2875 saved_buffer
= pStubMsg
->Buffer
;
2876 if (pStubMsg
->PointerBufferMark
)
2878 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2879 pStubMsg
->PointerBufferMark
= NULL
;
2880 pointer_buffer_mark_set
= 1;
2882 else if (*pPointer
!= RPC_FC_RP
)
2883 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2885 PointerUnmarshall(pStubMsg
, saved_buffer
, (unsigned char**)pMemory
, *(unsigned char**)pMemory
, pPointer
, fMustAlloc
);
2886 if (pointer_buffer_mark_set
)
2888 STD_OVERFLOW_CHECK(pStubMsg
);
2889 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2890 pStubMsg
->Buffer
= saved_buffer
;
2891 if (*pPointer
!= RPC_FC_RP
)
2892 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2894 if (*pFormat
== RPC_FC_POINTER
)
2898 pMemory
+= sizeof(void *);
2901 case RPC_FC_ALIGNM2
:
2902 ALIGN_POINTER_CLEAR(pMemory
, 2);
2904 case RPC_FC_ALIGNM4
:
2905 ALIGN_POINTER_CLEAR(pMemory
, 4);
2907 case RPC_FC_ALIGNM8
:
2908 ALIGN_POINTER_CLEAR(pMemory
, 8);
2910 case RPC_FC_STRUCTPAD1
:
2911 case RPC_FC_STRUCTPAD2
:
2912 case RPC_FC_STRUCTPAD3
:
2913 case RPC_FC_STRUCTPAD4
:
2914 case RPC_FC_STRUCTPAD5
:
2915 case RPC_FC_STRUCTPAD6
:
2916 case RPC_FC_STRUCTPAD7
:
2917 memset(pMemory
, 0, *pFormat
- RPC_FC_STRUCTPAD1
+ 1);
2918 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2920 case RPC_FC_EMBEDDED_COMPLEX
:
2921 pMemory
+= pFormat
[1];
2923 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2924 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2925 TRACE("embedded complex (size=%d) => %p\n", size
, pMemory
);
2927 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
2928 * since the type is part of the memory block that is encompassed by
2929 * the whole complex type. Memory is forced to allocate when pointers
2930 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
2931 * clearing the memory we pass in to the unmarshaller */
2932 memset(pMemory
, 0, size
);
2933 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
2936 /* for some reason interface pointers aren't generated as
2937 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2938 * they still need the derefencing treatment that pointers are
2940 if (*desc
== RPC_FC_IP
)
2941 m(pStubMsg
, (unsigned char **)pMemory
, desc
, FALSE
);
2943 m(pStubMsg
, &pMemory
, desc
, FALSE
);
2945 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
2952 FIXME("unhandled format %d\n", *pFormat
);
2960 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2961 unsigned char *pMemory
,
2962 PFORMAT_STRING pFormat
,
2963 PFORMAT_STRING pPointer
)
2965 PFORMAT_STRING desc
;
2969 while (*pFormat
!= RPC_FC_END
) {
2975 safe_buffer_length_increment(pStubMsg
, 1);
2981 safe_buffer_length_increment(pStubMsg
, 2);
2985 safe_buffer_length_increment(pStubMsg
, 2);
2992 safe_buffer_length_increment(pStubMsg
, 4);
2997 safe_buffer_length_increment(pStubMsg
, 8);
3004 case RPC_FC_POINTER
:
3005 if (*pFormat
!= RPC_FC_POINTER
)
3007 if (!pStubMsg
->IgnoreEmbeddedPointers
)
3009 int saved_buffer_length
= pStubMsg
->BufferLength
;
3010 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3011 pStubMsg
->PointerLength
= 0;
3012 if(!pStubMsg
->BufferLength
)
3013 ERR("BufferLength == 0??\n");
3014 PointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
3015 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3016 pStubMsg
->BufferLength
= saved_buffer_length
;
3018 if (*pPointer
!= RPC_FC_RP
)
3020 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
3021 safe_buffer_length_increment(pStubMsg
, 4);
3023 if (*pFormat
== RPC_FC_POINTER
)
3027 pMemory
+= sizeof(void*);
3029 case RPC_FC_ALIGNM2
:
3030 ALIGN_POINTER(pMemory
, 2);
3032 case RPC_FC_ALIGNM4
:
3033 ALIGN_POINTER(pMemory
, 4);
3035 case RPC_FC_ALIGNM8
:
3036 ALIGN_POINTER(pMemory
, 8);
3038 case RPC_FC_STRUCTPAD1
:
3039 case RPC_FC_STRUCTPAD2
:
3040 case RPC_FC_STRUCTPAD3
:
3041 case RPC_FC_STRUCTPAD4
:
3042 case RPC_FC_STRUCTPAD5
:
3043 case RPC_FC_STRUCTPAD6
:
3044 case RPC_FC_STRUCTPAD7
:
3045 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3047 case RPC_FC_EMBEDDED_COMPLEX
:
3048 pMemory
+= pFormat
[1];
3050 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3051 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3052 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
3055 /* for some reason interface pointers aren't generated as
3056 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3057 * they still need the derefencing treatment that pointers are
3059 if (*desc
== RPC_FC_IP
)
3060 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
3062 m(pStubMsg
, pMemory
, desc
);
3064 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
3071 FIXME("unhandled format 0x%02x\n", *pFormat
);
3079 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
3080 unsigned char *pMemory
,
3081 PFORMAT_STRING pFormat
,
3082 PFORMAT_STRING pPointer
)
3084 PFORMAT_STRING desc
;
3088 while (*pFormat
!= RPC_FC_END
) {
3116 case RPC_FC_POINTER
:
3117 if (*pFormat
!= RPC_FC_POINTER
)
3119 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
3120 if (*pFormat
== RPC_FC_POINTER
)
3124 pMemory
+= sizeof(void *);
3126 case RPC_FC_ALIGNM2
:
3127 ALIGN_POINTER(pMemory
, 2);
3129 case RPC_FC_ALIGNM4
:
3130 ALIGN_POINTER(pMemory
, 4);
3132 case RPC_FC_ALIGNM8
:
3133 ALIGN_POINTER(pMemory
, 8);
3135 case RPC_FC_STRUCTPAD1
:
3136 case RPC_FC_STRUCTPAD2
:
3137 case RPC_FC_STRUCTPAD3
:
3138 case RPC_FC_STRUCTPAD4
:
3139 case RPC_FC_STRUCTPAD5
:
3140 case RPC_FC_STRUCTPAD6
:
3141 case RPC_FC_STRUCTPAD7
:
3142 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3144 case RPC_FC_EMBEDDED_COMPLEX
:
3145 pMemory
+= pFormat
[1];
3147 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3148 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3149 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
3152 /* for some reason interface pointers aren't generated as
3153 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3154 * they still need the derefencing treatment that pointers are
3156 if (*desc
== RPC_FC_IP
)
3157 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
3159 m(pStubMsg
, pMemory
, desc
);
3167 FIXME("unhandled format 0x%02x\n", *pFormat
);
3175 static ULONG
ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3176 PFORMAT_STRING pFormat
,
3177 PFORMAT_STRING pPointer
)
3179 PFORMAT_STRING desc
;
3182 while (*pFormat
!= RPC_FC_END
) {
3189 safe_buffer_increment(pStubMsg
, 1);
3195 safe_buffer_increment(pStubMsg
, 2);
3199 safe_buffer_increment(pStubMsg
, 2);
3206 safe_buffer_increment(pStubMsg
, 4);
3211 safe_buffer_increment(pStubMsg
, 8);
3217 case RPC_FC_POINTER
:
3219 unsigned char *saved_buffer
;
3220 int pointer_buffer_mark_set
= 0;
3221 if (*pFormat
!= RPC_FC_POINTER
)
3223 if (*pPointer
!= RPC_FC_RP
)
3224 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3225 saved_buffer
= pStubMsg
->Buffer
;
3226 if (pStubMsg
->PointerBufferMark
)
3228 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3229 pStubMsg
->PointerBufferMark
= NULL
;
3230 pointer_buffer_mark_set
= 1;
3232 else if (*pPointer
!= RPC_FC_RP
)
3233 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3235 if (!pStubMsg
->IgnoreEmbeddedPointers
)
3236 PointerMemorySize(pStubMsg
, saved_buffer
, pPointer
);
3237 if (pointer_buffer_mark_set
)
3239 STD_OVERFLOW_CHECK(pStubMsg
);
3240 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3241 pStubMsg
->Buffer
= saved_buffer
;
3242 if (*pPointer
!= RPC_FC_RP
)
3243 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3245 if (*pFormat
== RPC_FC_POINTER
)
3249 size
+= sizeof(void *);
3252 case RPC_FC_ALIGNM2
:
3253 ALIGN_LENGTH(size
, 2);
3255 case RPC_FC_ALIGNM4
:
3256 ALIGN_LENGTH(size
, 4);
3258 case RPC_FC_ALIGNM8
:
3259 ALIGN_LENGTH(size
, 8);
3261 case RPC_FC_STRUCTPAD1
:
3262 case RPC_FC_STRUCTPAD2
:
3263 case RPC_FC_STRUCTPAD3
:
3264 case RPC_FC_STRUCTPAD4
:
3265 case RPC_FC_STRUCTPAD5
:
3266 case RPC_FC_STRUCTPAD6
:
3267 case RPC_FC_STRUCTPAD7
:
3268 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3270 case RPC_FC_EMBEDDED_COMPLEX
:
3273 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3274 size
+= EmbeddedComplexMemorySize(pStubMsg
, desc
);
3280 FIXME("unhandled format 0x%02x\n", *pFormat
);
3288 ULONG
ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
3290 PFORMAT_STRING desc
;
3293 while (*pFormat
!= RPC_FC_END
) {
3321 case RPC_FC_POINTER
:
3322 size
+= sizeof(void *);
3323 if (*pFormat
!= RPC_FC_POINTER
)
3326 case RPC_FC_ALIGNM2
:
3327 ALIGN_LENGTH(size
, 2);
3329 case RPC_FC_ALIGNM4
:
3330 ALIGN_LENGTH(size
, 4);
3332 case RPC_FC_ALIGNM8
:
3333 ALIGN_LENGTH(size
, 8);
3335 case RPC_FC_STRUCTPAD1
:
3336 case RPC_FC_STRUCTPAD2
:
3337 case RPC_FC_STRUCTPAD3
:
3338 case RPC_FC_STRUCTPAD4
:
3339 case RPC_FC_STRUCTPAD5
:
3340 case RPC_FC_STRUCTPAD6
:
3341 case RPC_FC_STRUCTPAD7
:
3342 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3344 case RPC_FC_EMBEDDED_COMPLEX
:
3347 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3348 size
+= EmbeddedComplexSize(pStubMsg
, desc
);
3354 FIXME("unhandled format 0x%02x\n", *pFormat
);
3362 /***********************************************************************
3363 * NdrComplexStructMarshall [RPCRT4.@]
3365 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3366 unsigned char *pMemory
,
3367 PFORMAT_STRING pFormat
)
3369 PFORMAT_STRING conf_array
= NULL
;
3370 PFORMAT_STRING pointer_desc
= NULL
;
3371 unsigned char *OldMemory
= pStubMsg
->Memory
;
3372 int pointer_buffer_mark_set
= 0;
3374 ULONG max_count
= 0;
3377 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3379 if (!pStubMsg
->PointerBufferMark
)
3381 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3382 /* save buffer length */
3383 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
3385 /* get the buffer pointer after complex array data, but before
3387 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
;
3388 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3389 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
3390 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3392 /* save it for use by embedded pointer code later */
3393 pStubMsg
->PointerBufferMark
= (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
;
3394 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->PointerBufferMark
- pStubMsg
->Buffer
));
3395 pointer_buffer_mark_set
= 1;
3397 /* restore the original buffer length */
3398 pStubMsg
->BufferLength
= saved_buffer_length
;
3401 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pFormat
[1] + 1);
3404 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3406 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3409 pStubMsg
->Memory
= pMemory
;
3413 ULONG struct_size
= ComplexStructSize(pStubMsg
, pFormat
);
3414 array_compute_and_write_conformance(conf_array
[0], pStubMsg
,
3415 pMemory
+ struct_size
, conf_array
);
3416 /* these could be changed in ComplexMarshall so save them for later */
3417 max_count
= pStubMsg
->MaxCount
;
3418 count
= pStubMsg
->ActualCount
;
3419 offset
= pStubMsg
->Offset
;
3422 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3426 pStubMsg
->MaxCount
= max_count
;
3427 pStubMsg
->ActualCount
= count
;
3428 pStubMsg
->Offset
= offset
;
3429 array_write_variance_and_marshall(conf_array
[0], pStubMsg
, pMemory
,
3430 conf_array
, TRUE
/* fHasPointers */);
3433 pStubMsg
->Memory
= OldMemory
;
3435 if (pointer_buffer_mark_set
)
3437 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3438 pStubMsg
->PointerBufferMark
= NULL
;
3441 STD_OVERFLOW_CHECK(pStubMsg
);
3446 /***********************************************************************
3447 * NdrComplexStructUnmarshall [RPCRT4.@]
3449 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3450 unsigned char **ppMemory
,
3451 PFORMAT_STRING pFormat
,
3452 unsigned char fMustAlloc
)
3454 unsigned size
= *(const WORD
*)(pFormat
+2);
3455 PFORMAT_STRING conf_array
= NULL
;
3456 PFORMAT_STRING pointer_desc
= NULL
;
3457 unsigned char *pMemory
;
3458 int pointer_buffer_mark_set
= 0;
3460 ULONG max_count
= 0;
3462 ULONG array_size
= 0;
3464 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3466 if (!pStubMsg
->PointerBufferMark
)
3468 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3469 /* save buffer pointer */
3470 unsigned char *saved_buffer
= pStubMsg
->Buffer
;
3472 /* get the buffer pointer after complex array data, but before
3474 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3475 NdrComplexStructMemorySize(pStubMsg
, pFormat
);
3476 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3478 /* save it for use by embedded pointer code later */
3479 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3480 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->PointerBufferMark
- saved_buffer
));
3481 pointer_buffer_mark_set
= 1;
3483 /* restore the original buffer */
3484 pStubMsg
->Buffer
= saved_buffer
;
3487 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
3490 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3492 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3497 array_size
= array_read_conformance(conf_array
[0], pStubMsg
, conf_array
);
3500 /* these could be changed in ComplexMarshall so save them for later */
3501 max_count
= pStubMsg
->MaxCount
;
3502 count
= pStubMsg
->ActualCount
;
3503 offset
= pStubMsg
->Offset
;
3506 if (!fMustAlloc
&& !*ppMemory
)
3509 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3511 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
, fMustAlloc
);
3515 pStubMsg
->MaxCount
= max_count
;
3516 pStubMsg
->ActualCount
= count
;
3517 pStubMsg
->Offset
= offset
;
3519 memset(pMemory
, 0, array_size
);
3520 array_read_variance_and_unmarshall(conf_array
[0], pStubMsg
, &pMemory
,
3522 FALSE
/* fUseBufferMemoryServer */,
3523 TRUE
/* fUnmarshall */);
3526 if (pointer_buffer_mark_set
)
3528 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3529 pStubMsg
->PointerBufferMark
= NULL
;
3535 /***********************************************************************
3536 * NdrComplexStructBufferSize [RPCRT4.@]
3538 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3539 unsigned char *pMemory
,
3540 PFORMAT_STRING pFormat
)
3542 PFORMAT_STRING conf_array
= NULL
;
3543 PFORMAT_STRING pointer_desc
= NULL
;
3544 unsigned char *OldMemory
= pStubMsg
->Memory
;
3545 int pointer_length_set
= 0;
3547 ULONG max_count
= 0;
3550 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3552 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
3554 if(!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
3556 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3557 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
3559 /* get the buffer length after complex struct data, but before
3561 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3562 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
3563 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3565 /* save it for use by embedded pointer code later */
3566 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3567 pointer_length_set
= 1;
3568 TRACE("difference = 0x%x\n", pStubMsg
->PointerLength
- saved_buffer_length
);
3570 /* restore the original buffer length */
3571 pStubMsg
->BufferLength
= saved_buffer_length
;
3575 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3577 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3580 pStubMsg
->Memory
= pMemory
;
3584 ULONG struct_size
= ComplexStructSize(pStubMsg
, pFormat
);
3585 array_compute_and_size_conformance(conf_array
[0], pStubMsg
, pMemory
+ struct_size
,
3588 /* these could be changed in ComplexMarshall so save them for later */
3589 max_count
= pStubMsg
->MaxCount
;
3590 count
= pStubMsg
->ActualCount
;
3591 offset
= pStubMsg
->Offset
;
3594 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3598 pStubMsg
->MaxCount
= max_count
;
3599 pStubMsg
->ActualCount
= count
;
3600 pStubMsg
->Offset
= offset
;
3601 array_buffer_size(conf_array
[0], pStubMsg
, pMemory
, conf_array
,
3602 TRUE
/* fHasPointers */);
3605 pStubMsg
->Memory
= OldMemory
;
3607 if(pointer_length_set
)
3609 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3610 pStubMsg
->PointerLength
= 0;
3615 /***********************************************************************
3616 * NdrComplexStructMemorySize [RPCRT4.@]
3618 ULONG WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3619 PFORMAT_STRING pFormat
)
3621 unsigned size
= *(const WORD
*)(pFormat
+2);
3622 PFORMAT_STRING conf_array
= NULL
;
3623 PFORMAT_STRING pointer_desc
= NULL
;
3625 ULONG max_count
= 0;
3628 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3630 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
3633 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3635 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3640 array_read_conformance(conf_array
[0], pStubMsg
, conf_array
);
3642 /* these could be changed in ComplexStructMemorySize so save them for
3644 max_count
= pStubMsg
->MaxCount
;
3645 count
= pStubMsg
->ActualCount
;
3646 offset
= pStubMsg
->Offset
;
3649 ComplexStructMemorySize(pStubMsg
, pFormat
, pointer_desc
);
3653 pStubMsg
->MaxCount
= max_count
;
3654 pStubMsg
->ActualCount
= count
;
3655 pStubMsg
->Offset
= offset
;
3656 array_memory_size(conf_array
[0], pStubMsg
, conf_array
,
3657 TRUE
/* fHasPointers */);
3663 /***********************************************************************
3664 * NdrComplexStructFree [RPCRT4.@]
3666 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3667 unsigned char *pMemory
,
3668 PFORMAT_STRING pFormat
)
3670 PFORMAT_STRING conf_array
= NULL
;
3671 PFORMAT_STRING pointer_desc
= NULL
;
3672 unsigned char *OldMemory
= pStubMsg
->Memory
;
3674 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3677 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3679 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3682 pStubMsg
->Memory
= pMemory
;
3684 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3687 array_free(conf_array
[0], pStubMsg
, pMemory
, conf_array
,
3688 TRUE
/* fHasPointers */);
3690 pStubMsg
->Memory
= OldMemory
;
3693 /***********************************************************************
3694 * NdrConformantArrayMarshall [RPCRT4.@]
3696 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3697 unsigned char *pMemory
,
3698 PFORMAT_STRING pFormat
)
3700 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3701 if (pFormat
[0] != RPC_FC_CARRAY
)
3703 ERR("invalid format = 0x%x\n", pFormat
[0]);
3704 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3707 array_compute_and_write_conformance(RPC_FC_CARRAY
, pStubMsg
, pMemory
,
3709 array_write_variance_and_marshall(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3710 TRUE
/* fHasPointers */);
3715 /***********************************************************************
3716 * NdrConformantArrayUnmarshall [RPCRT4.@]
3718 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3719 unsigned char **ppMemory
,
3720 PFORMAT_STRING pFormat
,
3721 unsigned char fMustAlloc
)
3723 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3724 if (pFormat
[0] != RPC_FC_CARRAY
)
3726 ERR("invalid format = 0x%x\n", pFormat
[0]);
3727 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3730 array_read_conformance(RPC_FC_CARRAY
, pStubMsg
, pFormat
);
3731 array_read_variance_and_unmarshall(RPC_FC_CARRAY
, pStubMsg
, ppMemory
, pFormat
,
3733 TRUE
/* fUseBufferMemoryServer */,
3734 TRUE
/* fUnmarshall */);
3739 /***********************************************************************
3740 * NdrConformantArrayBufferSize [RPCRT4.@]
3742 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3743 unsigned char *pMemory
,
3744 PFORMAT_STRING pFormat
)
3746 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3747 if (pFormat
[0] != RPC_FC_CARRAY
)
3749 ERR("invalid format = 0x%x\n", pFormat
[0]);
3750 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3753 array_compute_and_size_conformance(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
);
3754 array_buffer_size(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3755 TRUE
/* fHasPointers */);
3758 /***********************************************************************
3759 * NdrConformantArrayMemorySize [RPCRT4.@]
3761 ULONG WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3762 PFORMAT_STRING pFormat
)
3764 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3765 if (pFormat
[0] != RPC_FC_CARRAY
)
3767 ERR("invalid format = 0x%x\n", pFormat
[0]);
3768 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3771 array_read_conformance(RPC_FC_CARRAY
, pStubMsg
, pFormat
);
3772 array_memory_size(RPC_FC_CARRAY
, pStubMsg
, pFormat
, TRUE
/* fHasPointers */);
3774 return pStubMsg
->MemorySize
;
3777 /***********************************************************************
3778 * NdrConformantArrayFree [RPCRT4.@]
3780 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3781 unsigned char *pMemory
,
3782 PFORMAT_STRING pFormat
)
3784 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3785 if (pFormat
[0] != RPC_FC_CARRAY
)
3787 ERR("invalid format = 0x%x\n", pFormat
[0]);
3788 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3791 array_free(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3792 TRUE
/* fHasPointers */);
3796 /***********************************************************************
3797 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3799 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
3800 unsigned char* pMemory
,
3801 PFORMAT_STRING pFormat
)
3803 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3805 if (pFormat
[0] != RPC_FC_CVARRAY
)
3807 ERR("invalid format type %x\n", pFormat
[0]);
3808 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3812 array_compute_and_write_conformance(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
3814 array_write_variance_and_marshall(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
3815 pFormat
, TRUE
/* fHasPointers */);
3821 /***********************************************************************
3822 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
3824 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
3825 unsigned char** ppMemory
,
3826 PFORMAT_STRING pFormat
,
3827 unsigned char fMustAlloc
)
3829 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3831 if (pFormat
[0] != RPC_FC_CVARRAY
)
3833 ERR("invalid format type %x\n", pFormat
[0]);
3834 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3838 array_read_conformance(RPC_FC_CVARRAY
, pStubMsg
, pFormat
);
3839 array_read_variance_and_unmarshall(RPC_FC_CVARRAY
, pStubMsg
, ppMemory
,
3840 pFormat
, fMustAlloc
,
3841 TRUE
/* fUseBufferMemoryServer */,
3842 TRUE
/* fUnmarshall */);
3848 /***********************************************************************
3849 * NdrConformantVaryingArrayFree [RPCRT4.@]
3851 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
3852 unsigned char* pMemory
,
3853 PFORMAT_STRING pFormat
)
3855 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3857 if (pFormat
[0] != RPC_FC_CVARRAY
)
3859 ERR("invalid format type %x\n", pFormat
[0]);
3860 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3864 array_free(RPC_FC_CVARRAY
, pStubMsg
, pMemory
, pFormat
,
3865 TRUE
/* fHasPointers */);
3869 /***********************************************************************
3870 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
3872 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
3873 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
3875 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3877 if (pFormat
[0] != RPC_FC_CVARRAY
)
3879 ERR("invalid format type %x\n", pFormat
[0]);
3880 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3884 array_compute_and_size_conformance(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
3886 array_buffer_size(RPC_FC_CVARRAY
, pStubMsg
, pMemory
, pFormat
,
3887 TRUE
/* fHasPointers */);
3891 /***********************************************************************
3892 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
3894 ULONG WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
3895 PFORMAT_STRING pFormat
)
3897 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
3899 if (pFormat
[0] != RPC_FC_CVARRAY
)
3901 ERR("invalid format type %x\n", pFormat
[0]);
3902 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3903 return pStubMsg
->MemorySize
;
3906 array_read_conformance(RPC_FC_CVARRAY
, pStubMsg
, pFormat
);
3907 array_memory_size(RPC_FC_CVARRAY
, pStubMsg
, pFormat
,
3908 TRUE
/* fHasPointers */);
3910 return pStubMsg
->MemorySize
;
3914 /***********************************************************************
3915 * NdrComplexArrayMarshall [RPCRT4.@]
3917 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3918 unsigned char *pMemory
,
3919 PFORMAT_STRING pFormat
)
3921 ULONG i
, count
, def
;
3922 BOOL variance_present
;
3923 unsigned char alignment
;
3924 int pointer_buffer_mark_set
= 0;
3926 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3928 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3930 ERR("invalid format type %x\n", pFormat
[0]);
3931 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3935 alignment
= pFormat
[1] + 1;
3937 if (!pStubMsg
->PointerBufferMark
)
3939 /* save buffer fields that may be changed by buffer sizer functions
3940 * and that may be needed later on */
3941 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3942 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
3943 ULONG_PTR saved_max_count
= pStubMsg
->MaxCount
;
3944 ULONG saved_offset
= pStubMsg
->Offset
;
3945 ULONG saved_actual_count
= pStubMsg
->ActualCount
;
3947 /* get the buffer pointer after complex array data, but before
3949 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
;
3950 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3951 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
3952 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3954 /* save it for use by embedded pointer code later */
3955 pStubMsg
->PointerBufferMark
= (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
;
3956 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
));
3957 pointer_buffer_mark_set
= 1;
3959 /* restore fields */
3960 pStubMsg
->ActualCount
= saved_actual_count
;
3961 pStubMsg
->Offset
= saved_offset
;
3962 pStubMsg
->MaxCount
= saved_max_count
;
3963 pStubMsg
->BufferLength
= saved_buffer_length
;
3966 def
= *(const WORD
*)&pFormat
[2];
3969 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3970 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3972 variance_present
= IsConformanceOrVariancePresent(pFormat
);
3973 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3974 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3976 WriteConformance(pStubMsg
);
3977 if (variance_present
)
3978 WriteVariance(pStubMsg
);
3980 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
3982 count
= pStubMsg
->ActualCount
;
3983 for (i
= 0; i
< count
; i
++)
3984 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
3986 STD_OVERFLOW_CHECK(pStubMsg
);
3988 if (pointer_buffer_mark_set
)
3990 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3991 pStubMsg
->PointerBufferMark
= NULL
;
3997 /***********************************************************************
3998 * NdrComplexArrayUnmarshall [RPCRT4.@]
4000 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4001 unsigned char **ppMemory
,
4002 PFORMAT_STRING pFormat
,
4003 unsigned char fMustAlloc
)
4005 ULONG i
, count
, size
;
4006 unsigned char alignment
;
4007 unsigned char *pMemory
;
4008 unsigned char *saved_buffer
;
4009 int pointer_buffer_mark_set
= 0;
4010 int saved_ignore_embedded
;
4012 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4014 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4016 ERR("invalid format type %x\n", pFormat
[0]);
4017 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4021 alignment
= pFormat
[1] + 1;
4023 saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
4024 /* save buffer pointer */
4025 saved_buffer
= pStubMsg
->Buffer
;
4026 /* get the buffer pointer after complex array data, but before
4028 pStubMsg
->IgnoreEmbeddedPointers
= 1;
4029 pStubMsg
->MemorySize
= 0;
4030 NdrComplexArrayMemorySize(pStubMsg
, pFormat
);
4031 size
= pStubMsg
->MemorySize
;
4032 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
4034 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->Buffer
- saved_buffer
));
4035 if (!pStubMsg
->PointerBufferMark
)
4037 /* save it for use by embedded pointer code later */
4038 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4039 pointer_buffer_mark_set
= 1;
4041 /* restore the original buffer */
4042 pStubMsg
->Buffer
= saved_buffer
;
4046 pFormat
= ReadConformance(pStubMsg
, pFormat
);
4047 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
4049 if (!fMustAlloc
&& !*ppMemory
)
4052 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4054 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4056 pMemory
= *ppMemory
;
4057 count
= pStubMsg
->ActualCount
;
4058 for (i
= 0; i
< count
; i
++)
4059 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
, fMustAlloc
);
4061 if (pointer_buffer_mark_set
)
4063 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4064 pStubMsg
->PointerBufferMark
= NULL
;
4070 /***********************************************************************
4071 * NdrComplexArrayBufferSize [RPCRT4.@]
4073 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4074 unsigned char *pMemory
,
4075 PFORMAT_STRING pFormat
)
4077 ULONG i
, count
, def
;
4078 unsigned char alignment
;
4079 BOOL variance_present
;
4080 int pointer_length_set
= 0;
4082 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4084 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4086 ERR("invalid format type %x\n", pFormat
[0]);
4087 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4091 alignment
= pFormat
[1] + 1;
4093 if (!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
4095 /* save buffer fields that may be changed by buffer sizer functions
4096 * and that may be needed later on */
4097 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
4098 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
4099 ULONG_PTR saved_max_count
= pStubMsg
->MaxCount
;
4100 ULONG saved_offset
= pStubMsg
->Offset
;
4101 ULONG saved_actual_count
= pStubMsg
->ActualCount
;
4103 /* get the buffer pointer after complex array data, but before
4105 pStubMsg
->IgnoreEmbeddedPointers
= 1;
4106 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
4107 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
4109 /* save it for use by embedded pointer code later */
4110 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4111 pointer_length_set
= 1;
4113 /* restore fields */
4114 pStubMsg
->ActualCount
= saved_actual_count
;
4115 pStubMsg
->Offset
= saved_offset
;
4116 pStubMsg
->MaxCount
= saved_max_count
;
4117 pStubMsg
->BufferLength
= saved_buffer_length
;
4119 def
= *(const WORD
*)&pFormat
[2];
4122 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
4123 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
4124 SizeConformance(pStubMsg
);
4126 variance_present
= IsConformanceOrVariancePresent(pFormat
);
4127 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
4128 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
4130 if (variance_present
)
4131 SizeVariance(pStubMsg
);
4133 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
4135 count
= pStubMsg
->ActualCount
;
4136 for (i
= 0; i
< count
; i
++)
4137 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
4139 if(pointer_length_set
)
4141 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4142 pStubMsg
->PointerLength
= 0;
4146 /***********************************************************************
4147 * NdrComplexArrayMemorySize [RPCRT4.@]
4149 ULONG WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4150 PFORMAT_STRING pFormat
)
4152 ULONG i
, count
, esize
, SavedMemorySize
, MemorySize
;
4153 unsigned char alignment
;
4155 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
4157 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4159 ERR("invalid format type %x\n", pFormat
[0]);
4160 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4164 alignment
= pFormat
[1] + 1;
4168 pFormat
= ReadConformance(pStubMsg
, pFormat
);
4169 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
4171 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4173 SavedMemorySize
= pStubMsg
->MemorySize
;
4175 esize
= ComplexStructSize(pStubMsg
, pFormat
);
4177 MemorySize
= safe_multiply(pStubMsg
->MaxCount
, esize
);
4179 count
= pStubMsg
->ActualCount
;
4180 for (i
= 0; i
< count
; i
++)
4181 ComplexStructMemorySize(pStubMsg
, pFormat
, NULL
);
4183 pStubMsg
->MemorySize
= SavedMemorySize
;
4185 pStubMsg
->MemorySize
+= MemorySize
;
4189 /***********************************************************************
4190 * NdrComplexArrayFree [RPCRT4.@]
4192 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4193 unsigned char *pMemory
,
4194 PFORMAT_STRING pFormat
)
4196 ULONG i
, count
, def
;
4198 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4200 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4202 ERR("invalid format type %x\n", pFormat
[0]);
4203 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4207 def
= *(const WORD
*)&pFormat
[2];
4210 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
4211 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
4213 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
4214 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
4216 count
= pStubMsg
->ActualCount
;
4217 for (i
= 0; i
< count
; i
++)
4218 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
4221 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg
,
4222 USER_MARSHAL_CB_TYPE cbtype
, PFORMAT_STRING pFormat
,
4223 USER_MARSHAL_CB
*umcb
)
4225 umcb
->Flags
= MAKELONG(pStubMsg
->dwDestContext
,
4226 pStubMsg
->RpcMsg
->DataRepresentation
);
4227 umcb
->pStubMsg
= pStubMsg
;
4228 umcb
->pReserve
= NULL
;
4229 umcb
->Signature
= USER_MARSHAL_CB_SIGNATURE
;
4230 umcb
->CBType
= cbtype
;
4231 umcb
->pFormat
= pFormat
;
4232 umcb
->pTypeFormat
= NULL
/* FIXME */;
4235 #define USER_MARSHAL_PTR_PREFIX \
4236 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4237 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4239 /***********************************************************************
4240 * NdrUserMarshalMarshall [RPCRT4.@]
4242 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4243 unsigned char *pMemory
,
4244 PFORMAT_STRING pFormat
)
4246 unsigned flags
= pFormat
[1];
4247 unsigned index
= *(const WORD
*)&pFormat
[2];
4248 unsigned char *saved_buffer
= NULL
;
4249 USER_MARSHAL_CB umcb
;
4251 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4252 TRACE("index=%d\n", index
);
4254 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_MARSHALL
, pFormat
, &umcb
);
4256 if (flags
& USER_MARSHAL_POINTER
)
4258 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
4259 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, USER_MARSHAL_PTR_PREFIX
);
4260 pStubMsg
->Buffer
+= 4;
4261 if (pStubMsg
->PointerBufferMark
)
4263 saved_buffer
= pStubMsg
->Buffer
;
4264 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4265 pStubMsg
->PointerBufferMark
= NULL
;
4267 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 8);
4270 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4273 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
4274 &umcb
.Flags
, pStubMsg
->Buffer
, pMemory
);
4278 STD_OVERFLOW_CHECK(pStubMsg
);
4279 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4280 pStubMsg
->Buffer
= saved_buffer
;
4283 STD_OVERFLOW_CHECK(pStubMsg
);
4288 /***********************************************************************
4289 * NdrUserMarshalUnmarshall [RPCRT4.@]
4291 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4292 unsigned char **ppMemory
,
4293 PFORMAT_STRING pFormat
,
4294 unsigned char fMustAlloc
)
4296 unsigned flags
= pFormat
[1];
4297 unsigned index
= *(const WORD
*)&pFormat
[2];
4298 DWORD memsize
= *(const WORD
*)&pFormat
[4];
4299 unsigned char *saved_buffer
= NULL
;
4300 USER_MARSHAL_CB umcb
;
4302 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4303 TRACE("index=%d\n", index
);
4305 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_UNMARSHALL
, pFormat
, &umcb
);
4307 if (flags
& USER_MARSHAL_POINTER
)
4309 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4310 /* skip pointer prefix */
4311 pStubMsg
->Buffer
+= 4;
4312 if (pStubMsg
->PointerBufferMark
)
4314 saved_buffer
= pStubMsg
->Buffer
;
4315 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4316 pStubMsg
->PointerBufferMark
= NULL
;
4318 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
4321 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4323 if (!fMustAlloc
&& !*ppMemory
)
4327 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
4328 memset(*ppMemory
, 0, memsize
);
4332 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
4333 &umcb
.Flags
, pStubMsg
->Buffer
, *ppMemory
);
4337 STD_OVERFLOW_CHECK(pStubMsg
);
4338 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4339 pStubMsg
->Buffer
= saved_buffer
;
4345 /***********************************************************************
4346 * NdrUserMarshalBufferSize [RPCRT4.@]
4348 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4349 unsigned char *pMemory
,
4350 PFORMAT_STRING pFormat
)
4352 unsigned flags
= pFormat
[1];
4353 unsigned index
= *(const WORD
*)&pFormat
[2];
4354 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
4355 USER_MARSHAL_CB umcb
;
4356 ULONG saved_buffer_length
= 0;
4358 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4359 TRACE("index=%d\n", index
);
4361 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_BUFFER_SIZE
, pFormat
, &umcb
);
4363 if (flags
& USER_MARSHAL_POINTER
)
4365 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
4366 /* skip pointer prefix */
4367 safe_buffer_length_increment(pStubMsg
, 4);
4368 if (pStubMsg
->IgnoreEmbeddedPointers
)
4370 if (pStubMsg
->PointerLength
)
4372 saved_buffer_length
= pStubMsg
->BufferLength
;
4373 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4374 pStubMsg
->PointerLength
= 0;
4376 ALIGN_LENGTH(pStubMsg
->BufferLength
, 8);
4379 ALIGN_LENGTH(pStubMsg
->BufferLength
, (flags
& 0xf) + 1);
4382 TRACE("size=%d\n", bufsize
);
4383 safe_buffer_length_increment(pStubMsg
, bufsize
);
4386 pStubMsg
->BufferLength
=
4387 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
4388 &umcb
.Flags
, pStubMsg
->BufferLength
, pMemory
);
4390 if (saved_buffer_length
)
4392 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4393 pStubMsg
->BufferLength
= saved_buffer_length
;
4398 /***********************************************************************
4399 * NdrUserMarshalMemorySize [RPCRT4.@]
4401 ULONG WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4402 PFORMAT_STRING pFormat
)
4404 unsigned flags
= pFormat
[1];
4405 unsigned index
= *(const WORD
*)&pFormat
[2];
4406 DWORD memsize
= *(const WORD
*)&pFormat
[4];
4407 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
4409 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
4410 TRACE("index=%d\n", index
);
4412 pStubMsg
->MemorySize
+= memsize
;
4414 if (flags
& USER_MARSHAL_POINTER
)
4416 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4417 /* skip pointer prefix */
4418 pStubMsg
->Buffer
+= 4;
4419 if (pStubMsg
->IgnoreEmbeddedPointers
)
4420 return pStubMsg
->MemorySize
;
4421 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
4424 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4427 FIXME("not implemented for varying buffer size\n");
4429 pStubMsg
->Buffer
+= bufsize
;
4431 return pStubMsg
->MemorySize
;
4434 /***********************************************************************
4435 * NdrUserMarshalFree [RPCRT4.@]
4437 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
4438 unsigned char *pMemory
,
4439 PFORMAT_STRING pFormat
)
4441 /* unsigned flags = pFormat[1]; */
4442 unsigned index
= *(const WORD
*)&pFormat
[2];
4443 USER_MARSHAL_CB umcb
;
4445 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4446 TRACE("index=%d\n", index
);
4448 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_FREE
, pFormat
, &umcb
);
4450 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
4451 &umcb
.Flags
, pMemory
);
4454 /***********************************************************************
4455 * NdrGetUserMarshalInfo [RPCRT4.@]
4457 RPC_STATUS RPC_ENTRY
NdrGetUserMarshalInfo(ULONG
*flags
, ULONG level
, NDR_USER_MARSHAL_INFO
*umi
)
4459 USER_MARSHAL_CB
*umcb
= CONTAINING_RECORD(flags
, USER_MARSHAL_CB
, Flags
);
4461 TRACE("(%p,%u,%p)\n", flags
, level
, umi
);
4464 return RPC_S_INVALID_ARG
;
4466 memset(&umi
->u1
.Level1
, 0, sizeof(umi
->u1
.Level1
));
4467 umi
->InformationLevel
= level
;
4469 if (umcb
->Signature
!= USER_MARSHAL_CB_SIGNATURE
)
4470 return RPC_S_INVALID_ARG
;
4472 umi
->u1
.Level1
.pfnAllocate
= umcb
->pStubMsg
->pfnAllocate
;
4473 umi
->u1
.Level1
.pfnFree
= umcb
->pStubMsg
->pfnFree
;
4474 umi
->u1
.Level1
.pRpcChannelBuffer
= umcb
->pStubMsg
->pRpcChannelBuffer
;
4476 switch (umcb
->CBType
)
4478 case USER_MARSHAL_CB_MARSHALL
:
4479 case USER_MARSHAL_CB_UNMARSHALL
:
4481 RPC_MESSAGE
*msg
= umcb
->pStubMsg
->RpcMsg
;
4482 unsigned char *buffer_start
= msg
->Buffer
;
4483 unsigned char *buffer_end
=
4484 (unsigned char *)msg
->Buffer
+ msg
->BufferLength
;
4486 if (umcb
->pStubMsg
->Buffer
< buffer_start
||
4487 umcb
->pStubMsg
->Buffer
> buffer_end
)
4488 return ERROR_INVALID_USER_BUFFER
;
4490 umi
->u1
.Level1
.Buffer
= umcb
->pStubMsg
->Buffer
;
4491 umi
->u1
.Level1
.BufferSize
= buffer_end
- umcb
->pStubMsg
->Buffer
;
4494 case USER_MARSHAL_CB_BUFFER_SIZE
:
4495 case USER_MARSHAL_CB_FREE
:
4498 WARN("unrecognised CBType %d\n", umcb
->CBType
);
4504 /***********************************************************************
4505 * NdrClearOutParameters [RPCRT4.@]
4507 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
4508 PFORMAT_STRING pFormat
,
4511 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
4514 /***********************************************************************
4515 * NdrConvert [RPCRT4.@]
4517 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
4519 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
4520 /* FIXME: since this stub doesn't do any converting, the proper behavior
4521 is to raise an exception */
4524 /***********************************************************************
4525 * NdrConvert2 [RPCRT4.@]
4527 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, LONG NumberParams
)
4529 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4530 pStubMsg
, pFormat
, NumberParams
);
4531 /* FIXME: since this stub doesn't do any converting, the proper behavior
4532 is to raise an exception */
4535 #include "pshpack1.h"
4536 typedef struct _NDR_CSTRUCT_FORMAT
4539 unsigned char alignment
;
4540 unsigned short memory_size
;
4541 short offset_to_array_description
;
4542 } NDR_CSTRUCT_FORMAT
, NDR_CVSTRUCT_FORMAT
;
4543 #include "poppack.h"
4545 /***********************************************************************
4546 * NdrConformantStructMarshall [RPCRT4.@]
4548 unsigned char * WINAPI
NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4549 unsigned char *pMemory
,
4550 PFORMAT_STRING pFormat
)
4552 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4553 PFORMAT_STRING pCArrayFormat
;
4554 ULONG esize
, bufsize
;
4556 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4558 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4559 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4561 ERR("invalid format type %x\n", pCStructFormat
->type
);
4562 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4566 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4567 pCStructFormat
->offset_to_array_description
;
4568 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4570 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4571 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4574 esize
= *(const WORD
*)(pCArrayFormat
+2);
4576 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4577 pCArrayFormat
+ 4, 0);
4579 WriteConformance(pStubMsg
);
4581 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4583 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4585 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4586 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4588 ERR("integer overflow of memory_size %u with bufsize %u\n",
4589 pCStructFormat
->memory_size
, bufsize
);
4590 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4592 /* copy constant sized part of struct */
4593 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4594 safe_copy_to_buffer(pStubMsg
, pMemory
, pCStructFormat
->memory_size
+ bufsize
);
4596 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4597 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4602 /***********************************************************************
4603 * NdrConformantStructUnmarshall [RPCRT4.@]
4605 unsigned char * WINAPI
NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4606 unsigned char **ppMemory
,
4607 PFORMAT_STRING pFormat
,
4608 unsigned char fMustAlloc
)
4610 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4611 PFORMAT_STRING pCArrayFormat
;
4612 ULONG esize
, bufsize
;
4613 unsigned char *saved_buffer
;
4615 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4617 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4618 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4620 ERR("invalid format type %x\n", pCStructFormat
->type
);
4621 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4624 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4625 pCStructFormat
->offset_to_array_description
;
4626 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4628 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4629 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4632 esize
= *(const WORD
*)(pCArrayFormat
+2);
4634 pCArrayFormat
= ReadConformance(pStubMsg
, pCArrayFormat
+ 4);
4636 ALIGN_POINTER(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4638 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4640 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4641 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4643 ERR("integer overflow of memory_size %u with bufsize %u\n",
4644 pCStructFormat
->memory_size
, bufsize
);
4645 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4650 SIZE_T size
= pCStructFormat
->memory_size
+ bufsize
;
4651 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4655 if (!pStubMsg
->IsClient
&& !*ppMemory
)
4656 /* for servers, we just point straight into the RPC buffer */
4657 *ppMemory
= pStubMsg
->Buffer
;
4660 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4661 safe_buffer_increment(pStubMsg
, pCStructFormat
->memory_size
+ bufsize
);
4662 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4663 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4665 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
4666 if (*ppMemory
!= saved_buffer
)
4667 memcpy(*ppMemory
, saved_buffer
, pCStructFormat
->memory_size
+ bufsize
);
4672 /***********************************************************************
4673 * NdrConformantStructBufferSize [RPCRT4.@]
4675 void WINAPI
NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4676 unsigned char *pMemory
,
4677 PFORMAT_STRING pFormat
)
4679 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4680 PFORMAT_STRING pCArrayFormat
;
4683 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4685 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4686 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4688 ERR("invalid format type %x\n", pCStructFormat
->type
);
4689 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4692 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4693 pCStructFormat
->offset_to_array_description
;
4694 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4696 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4697 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4700 esize
= *(const WORD
*)(pCArrayFormat
+2);
4702 pCArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
, pCArrayFormat
+4, 0);
4703 SizeConformance(pStubMsg
);
4705 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCStructFormat
->alignment
+ 1);
4707 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4709 safe_buffer_length_increment(pStubMsg
, pCStructFormat
->memory_size
);
4710 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
4712 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4713 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4716 /***********************************************************************
4717 * NdrConformantStructMemorySize [RPCRT4.@]
4719 ULONG WINAPI
NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4720 PFORMAT_STRING pFormat
)
4726 /***********************************************************************
4727 * NdrConformantStructFree [RPCRT4.@]
4729 void WINAPI
NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
4730 unsigned char *pMemory
,
4731 PFORMAT_STRING pFormat
)
4733 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4734 PFORMAT_STRING pCArrayFormat
;
4736 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4738 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4739 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4741 ERR("invalid format type %x\n", pCStructFormat
->type
);
4742 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4746 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4747 pCStructFormat
->offset_to_array_description
;
4748 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4750 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4751 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4755 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4756 pCArrayFormat
+ 4, 0);
4758 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4760 /* copy constant sized part of struct */
4761 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4763 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4764 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4767 /***********************************************************************
4768 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4770 unsigned char * WINAPI
NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4771 unsigned char *pMemory
,
4772 PFORMAT_STRING pFormat
)
4774 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4775 PFORMAT_STRING pCVArrayFormat
;
4777 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4779 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4780 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4782 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4783 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4787 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4788 pCVStructFormat
->offset_to_array_description
;
4790 array_compute_and_write_conformance(*pCVArrayFormat
, pStubMsg
,
4791 pMemory
+ pCVStructFormat
->memory_size
,
4794 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4796 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4798 /* write constant sized part */
4799 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4800 safe_copy_to_buffer(pStubMsg
, pMemory
, pCVStructFormat
->memory_size
);
4802 array_write_variance_and_marshall(*pCVArrayFormat
, pStubMsg
,
4803 pMemory
+ pCVStructFormat
->memory_size
,
4804 pCVArrayFormat
, FALSE
/* fHasPointers */);
4806 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4811 /***********************************************************************
4812 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4814 unsigned char * WINAPI
NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4815 unsigned char **ppMemory
,
4816 PFORMAT_STRING pFormat
,
4817 unsigned char fMustAlloc
)
4819 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4820 PFORMAT_STRING pCVArrayFormat
;
4821 ULONG memsize
, bufsize
;
4822 unsigned char *saved_buffer
, *saved_array_buffer
;
4824 unsigned char *array_memory
;
4826 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4828 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4829 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4831 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4832 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4836 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4837 pCVStructFormat
->offset_to_array_description
;
4839 memsize
= array_read_conformance(*pCVArrayFormat
, pStubMsg
,
4842 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4844 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4846 /* work out how much memory to allocate if we need to do so */
4847 if (!fMustAlloc
&& !*ppMemory
)
4851 SIZE_T size
= pCVStructFormat
->memory_size
+ memsize
;
4852 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4855 /* mark the start of the constant data */
4856 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4857 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4859 array_memory
= *ppMemory
+ pCVStructFormat
->memory_size
;
4860 bufsize
= array_read_variance_and_unmarshall(*pCVArrayFormat
, pStubMsg
,
4861 &array_memory
, pCVArrayFormat
,
4862 FALSE
/* fMustAlloc */,
4863 FALSE
/* fUseServerBufferMemory */,
4864 FALSE
/* fUnmarshall */);
4866 /* save offset in case unmarshalling pointers changes it */
4867 offset
= pStubMsg
->Offset
;
4869 /* mark the start of the array data */
4870 saved_array_buffer
= pStubMsg
->Buffer
;
4871 safe_buffer_increment(pStubMsg
, bufsize
);
4873 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4875 /* copy the constant data */
4876 memcpy(*ppMemory
, saved_buffer
, pCVStructFormat
->memory_size
);
4877 /* copy the array data */
4878 TRACE("copying %p to %p\n", saved_array_buffer
, *ppMemory
+ pCVStructFormat
->memory_size
);
4879 memcpy(*ppMemory
+ pCVStructFormat
->memory_size
+ offset
,
4880 saved_array_buffer
, bufsize
);
4882 if (*pCVArrayFormat
== RPC_FC_C_CSTRING
)
4883 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory
+ pCVStructFormat
->memory_size
)));
4884 else if (*pCVArrayFormat
== RPC_FC_C_WSTRING
)
4885 TRACE("string=%s\n", debugstr_w((WCHAR
*)(*ppMemory
+ pCVStructFormat
->memory_size
)));
4890 /***********************************************************************
4891 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
4893 void WINAPI
NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4894 unsigned char *pMemory
,
4895 PFORMAT_STRING pFormat
)
4897 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4898 PFORMAT_STRING pCVArrayFormat
;
4900 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4902 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4903 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4905 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4906 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4910 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4911 pCVStructFormat
->offset_to_array_description
;
4912 array_compute_and_size_conformance(*pCVArrayFormat
, pStubMsg
,
4913 pMemory
+ pCVStructFormat
->memory_size
,
4916 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCVStructFormat
->alignment
+ 1);
4918 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4920 safe_buffer_length_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4922 array_buffer_size(*pCVArrayFormat
, pStubMsg
,
4923 pMemory
+ pCVStructFormat
->memory_size
, pCVArrayFormat
,
4924 FALSE
/* fHasPointers */);
4926 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4929 /***********************************************************************
4930 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4932 ULONG WINAPI
NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4933 PFORMAT_STRING pFormat
)
4935 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4936 PFORMAT_STRING pCVArrayFormat
;
4938 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4940 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4941 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4943 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4944 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4948 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4949 pCVStructFormat
->offset_to_array_description
;
4950 array_read_conformance(*pCVArrayFormat
, pStubMsg
, pCVArrayFormat
);
4952 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4954 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4956 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4957 array_memory_size(*pCVArrayFormat
, pStubMsg
, pCVArrayFormat
,
4958 FALSE
/* fHasPointers */);
4960 pStubMsg
->MemorySize
+= pCVStructFormat
->memory_size
;
4962 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4964 return pStubMsg
->MemorySize
;
4967 /***********************************************************************
4968 * NdrConformantVaryingStructFree [RPCRT4.@]
4970 void WINAPI
NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
4971 unsigned char *pMemory
,
4972 PFORMAT_STRING pFormat
)
4974 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4975 PFORMAT_STRING pCVArrayFormat
;
4977 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4979 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4980 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4982 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4983 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4987 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4988 pCVStructFormat
->offset_to_array_description
;
4989 array_free(*pCVArrayFormat
, pStubMsg
,
4990 pMemory
+ pCVStructFormat
->memory_size
, pCVArrayFormat
,
4991 FALSE
/* fHasPointers */);
4993 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4995 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4998 #include "pshpack1.h"
5002 unsigned char alignment
;
5003 unsigned short total_size
;
5004 } NDR_SMFARRAY_FORMAT
;
5009 unsigned char alignment
;
5011 } NDR_LGFARRAY_FORMAT
;
5012 #include "poppack.h"
5014 /***********************************************************************
5015 * NdrFixedArrayMarshall [RPCRT4.@]
5017 unsigned char * WINAPI
NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5018 unsigned char *pMemory
,
5019 PFORMAT_STRING pFormat
)
5021 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5024 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5026 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5027 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5029 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5030 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5034 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
5036 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5038 total_size
= pSmFArrayFormat
->total_size
;
5039 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5043 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5044 total_size
= pLgFArrayFormat
->total_size
;
5045 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5048 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5049 safe_copy_to_buffer(pStubMsg
, pMemory
, total_size
);
5051 pFormat
= EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
5056 /***********************************************************************
5057 * NdrFixedArrayUnmarshall [RPCRT4.@]
5059 unsigned char * WINAPI
NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5060 unsigned char **ppMemory
,
5061 PFORMAT_STRING pFormat
,
5062 unsigned char fMustAlloc
)
5064 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5066 unsigned char *saved_buffer
;
5068 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5070 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5071 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5073 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5074 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5078 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
5080 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5082 total_size
= pSmFArrayFormat
->total_size
;
5083 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5087 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5088 total_size
= pLgFArrayFormat
->total_size
;
5089 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5093 *ppMemory
= NdrAllocate(pStubMsg
, total_size
);
5096 if (!pStubMsg
->IsClient
&& !*ppMemory
)
5097 /* for servers, we just point straight into the RPC buffer */
5098 *ppMemory
= pStubMsg
->Buffer
;
5101 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5102 safe_buffer_increment(pStubMsg
, total_size
);
5103 pFormat
= EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
5105 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
5106 if (*ppMemory
!= saved_buffer
)
5107 memcpy(*ppMemory
, saved_buffer
, total_size
);
5112 /***********************************************************************
5113 * NdrFixedArrayBufferSize [RPCRT4.@]
5115 void WINAPI
NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5116 unsigned char *pMemory
,
5117 PFORMAT_STRING pFormat
)
5119 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5122 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5124 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5125 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5127 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5128 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5132 ALIGN_LENGTH(pStubMsg
->BufferLength
, pSmFArrayFormat
->alignment
+ 1);
5134 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5136 total_size
= pSmFArrayFormat
->total_size
;
5137 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5141 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5142 total_size
= pLgFArrayFormat
->total_size
;
5143 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5145 safe_buffer_length_increment(pStubMsg
, total_size
);
5147 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5150 /***********************************************************************
5151 * NdrFixedArrayMemorySize [RPCRT4.@]
5153 ULONG WINAPI
NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5154 PFORMAT_STRING pFormat
)
5156 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5159 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5161 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5162 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5164 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5165 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5169 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
5171 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5173 total_size
= pSmFArrayFormat
->total_size
;
5174 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5178 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5179 total_size
= pLgFArrayFormat
->total_size
;
5180 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5182 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5183 safe_buffer_increment(pStubMsg
, total_size
);
5184 pStubMsg
->MemorySize
+= total_size
;
5186 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5191 /***********************************************************************
5192 * NdrFixedArrayFree [RPCRT4.@]
5194 void WINAPI
NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
5195 unsigned char *pMemory
,
5196 PFORMAT_STRING pFormat
)
5198 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5200 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5202 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5203 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5205 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5206 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5210 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5211 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5214 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5215 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5218 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5221 /***********************************************************************
5222 * NdrVaryingArrayMarshall [RPCRT4.@]
5224 unsigned char * WINAPI
NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5225 unsigned char *pMemory
,
5226 PFORMAT_STRING pFormat
)
5228 unsigned char alignment
;
5229 DWORD elements
, esize
;
5232 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5234 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5235 (pFormat
[0] != RPC_FC_LGVARRAY
))
5237 ERR("invalid format type %x\n", pFormat
[0]);
5238 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5242 alignment
= pFormat
[1] + 1;
5244 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5247 pFormat
+= sizeof(WORD
);
5248 elements
= *(const WORD
*)pFormat
;
5249 pFormat
+= sizeof(WORD
);
5254 pFormat
+= sizeof(DWORD
);
5255 elements
= *(const DWORD
*)pFormat
;
5256 pFormat
+= sizeof(DWORD
);
5259 esize
= *(const WORD
*)pFormat
;
5260 pFormat
+= sizeof(WORD
);
5262 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5263 if ((pStubMsg
->ActualCount
> elements
) ||
5264 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5266 RpcRaiseException(RPC_S_INVALID_BOUND
);
5270 WriteVariance(pStubMsg
);
5272 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
5274 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
5275 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5276 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
5278 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
5283 /***********************************************************************
5284 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5286 unsigned char * WINAPI
NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5287 unsigned char **ppMemory
,
5288 PFORMAT_STRING pFormat
,
5289 unsigned char fMustAlloc
)
5291 unsigned char alignment
;
5292 DWORD size
, elements
, esize
;
5294 unsigned char *saved_buffer
;
5297 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5299 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5300 (pFormat
[0] != RPC_FC_LGVARRAY
))
5302 ERR("invalid format type %x\n", pFormat
[0]);
5303 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5307 alignment
= pFormat
[1] + 1;
5309 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5312 size
= *(const WORD
*)pFormat
;
5313 pFormat
+= sizeof(WORD
);
5314 elements
= *(const WORD
*)pFormat
;
5315 pFormat
+= sizeof(WORD
);
5320 size
= *(const DWORD
*)pFormat
;
5321 pFormat
+= sizeof(DWORD
);
5322 elements
= *(const DWORD
*)pFormat
;
5323 pFormat
+= sizeof(DWORD
);
5326 esize
= *(const WORD
*)pFormat
;
5327 pFormat
+= sizeof(WORD
);
5329 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
5331 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
5333 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
5334 offset
= pStubMsg
->Offset
;
5336 if (!fMustAlloc
&& !*ppMemory
)
5339 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5340 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5341 safe_buffer_increment(pStubMsg
, bufsize
);
5343 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
5345 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
5350 /***********************************************************************
5351 * NdrVaryingArrayBufferSize [RPCRT4.@]
5353 void WINAPI
NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5354 unsigned char *pMemory
,
5355 PFORMAT_STRING pFormat
)
5357 unsigned char alignment
;
5358 DWORD elements
, esize
;
5360 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5362 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5363 (pFormat
[0] != RPC_FC_LGVARRAY
))
5365 ERR("invalid format type %x\n", pFormat
[0]);
5366 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5370 alignment
= pFormat
[1] + 1;
5372 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5375 pFormat
+= sizeof(WORD
);
5376 elements
= *(const WORD
*)pFormat
;
5377 pFormat
+= sizeof(WORD
);
5382 pFormat
+= sizeof(DWORD
);
5383 elements
= *(const DWORD
*)pFormat
;
5384 pFormat
+= sizeof(DWORD
);
5387 esize
= *(const WORD
*)pFormat
;
5388 pFormat
+= sizeof(WORD
);
5390 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5391 if ((pStubMsg
->ActualCount
> elements
) ||
5392 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5394 RpcRaiseException(RPC_S_INVALID_BOUND
);
5398 SizeVariance(pStubMsg
);
5400 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
5402 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
5404 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5407 /***********************************************************************
5408 * NdrVaryingArrayMemorySize [RPCRT4.@]
5410 ULONG WINAPI
NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5411 PFORMAT_STRING pFormat
)
5413 unsigned char alignment
;
5414 DWORD size
, elements
, esize
;
5416 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5418 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5419 (pFormat
[0] != RPC_FC_LGVARRAY
))
5421 ERR("invalid format type %x\n", pFormat
[0]);
5422 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5426 alignment
= pFormat
[1] + 1;
5428 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5431 size
= *(const WORD
*)pFormat
;
5432 pFormat
+= sizeof(WORD
);
5433 elements
= *(const WORD
*)pFormat
;
5434 pFormat
+= sizeof(WORD
);
5439 size
= *(const DWORD
*)pFormat
;
5440 pFormat
+= sizeof(DWORD
);
5441 elements
= *(const DWORD
*)pFormat
;
5442 pFormat
+= sizeof(DWORD
);
5445 esize
= *(const WORD
*)pFormat
;
5446 pFormat
+= sizeof(WORD
);
5448 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
5450 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
5452 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
5453 pStubMsg
->MemorySize
+= size
;
5455 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5457 return pStubMsg
->MemorySize
;
5460 /***********************************************************************
5461 * NdrVaryingArrayFree [RPCRT4.@]
5463 void WINAPI
NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
5464 unsigned char *pMemory
,
5465 PFORMAT_STRING pFormat
)
5469 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5471 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5472 (pFormat
[0] != RPC_FC_LGVARRAY
))
5474 ERR("invalid format type %x\n", pFormat
[0]);
5475 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5479 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5482 pFormat
+= sizeof(WORD
);
5483 elements
= *(const WORD
*)pFormat
;
5484 pFormat
+= sizeof(WORD
);
5489 pFormat
+= sizeof(DWORD
);
5490 elements
= *(const DWORD
*)pFormat
;
5491 pFormat
+= sizeof(DWORD
);
5494 pFormat
+= sizeof(WORD
);
5496 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5497 if ((pStubMsg
->ActualCount
> elements
) ||
5498 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5500 RpcRaiseException(RPC_S_INVALID_BOUND
);
5504 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5507 static ULONG
get_discriminant(unsigned char fc
, const unsigned char *pMemory
)
5520 return *(const USHORT
*)pMemory
;
5524 return *(const ULONG
*)pMemory
;
5526 FIXME("Unhandled base type: 0x%02x\n", fc
);
5531 static PFORMAT_STRING
get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg
,
5533 PFORMAT_STRING pFormat
)
5535 unsigned short num_arms
, arm
, type
;
5537 num_arms
= *(const SHORT
*)pFormat
& 0x0fff;
5539 for(arm
= 0; arm
< num_arms
; arm
++)
5541 if(discriminant
== *(const ULONG
*)pFormat
)
5549 type
= *(const unsigned short*)pFormat
;
5550 TRACE("type %04x\n", type
);
5551 if(arm
== num_arms
) /* default arm extras */
5555 ERR("no arm for 0x%x and no default case\n", discriminant
);
5556 RpcRaiseException(RPC_S_INVALID_TAG
);
5561 TRACE("falling back to empty default case for 0x%x\n", discriminant
);
5568 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
, ULONG discriminant
, PFORMAT_STRING pFormat
)
5570 unsigned short type
;
5574 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5578 type
= *(const unsigned short*)pFormat
;
5579 if((type
& 0xff00) == 0x8000)
5581 unsigned char basetype
= LOBYTE(type
);
5582 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &basetype
);
5586 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5587 NDR_MARSHALL m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
5590 unsigned char *saved_buffer
= NULL
;
5591 int pointer_buffer_mark_set
= 0;
5598 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
5599 saved_buffer
= pStubMsg
->Buffer
;
5600 if (pStubMsg
->PointerBufferMark
)
5602 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5603 pStubMsg
->PointerBufferMark
= NULL
;
5604 pointer_buffer_mark_set
= 1;
5607 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
5609 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char **)pMemory
, desc
);
5610 if (pointer_buffer_mark_set
)
5612 STD_OVERFLOW_CHECK(pStubMsg
);
5613 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5614 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5616 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5617 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
5618 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5620 pStubMsg
->Buffer
= saved_buffer
+ 4;
5624 m(pStubMsg
, pMemory
, desc
);
5627 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5632 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5633 unsigned char **ppMemory
,
5635 PFORMAT_STRING pFormat
,
5636 unsigned char fMustAlloc
)
5638 unsigned short type
;
5642 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5646 type
= *(const unsigned short*)pFormat
;
5647 if((type
& 0xff00) == 0x8000)
5649 unsigned char basetype
= LOBYTE(type
);
5650 return NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &basetype
, FALSE
);
5654 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5655 NDR_UNMARSHALL m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
5658 unsigned char *saved_buffer
= NULL
;
5659 int pointer_buffer_mark_set
= 0;
5666 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5667 saved_buffer
= pStubMsg
->Buffer
;
5668 if (pStubMsg
->PointerBufferMark
)
5670 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5671 pStubMsg
->PointerBufferMark
= NULL
;
5672 pointer_buffer_mark_set
= 1;
5675 pStubMsg
->Buffer
+= 4; /* for pointer ID */
5677 if (saved_buffer
+ 4 > pStubMsg
->BufferEnd
)
5679 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5680 saved_buffer
, pStubMsg
->BufferEnd
);
5681 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5684 PointerUnmarshall(pStubMsg
, saved_buffer
, *(unsigned char ***)ppMemory
, **(unsigned char ***)ppMemory
, desc
, fMustAlloc
);
5685 if (pointer_buffer_mark_set
)
5687 STD_OVERFLOW_CHECK(pStubMsg
);
5688 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5689 pStubMsg
->Buffer
= saved_buffer
+ 4;
5693 m(pStubMsg
, ppMemory
, desc
, fMustAlloc
);
5696 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5701 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg
,
5702 unsigned char *pMemory
,
5704 PFORMAT_STRING pFormat
)
5706 unsigned short type
;
5710 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5714 type
= *(const unsigned short*)pFormat
;
5715 if((type
& 0xff00) == 0x8000)
5717 unsigned char basetype
= LOBYTE(type
);
5718 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &basetype
);
5722 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5723 NDR_BUFFERSIZE m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
5732 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
5733 safe_buffer_length_increment(pStubMsg
, 4); /* for pointer ID */
5734 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5736 int saved_buffer_length
= pStubMsg
->BufferLength
;
5737 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
5738 pStubMsg
->PointerLength
= 0;
5739 if(!pStubMsg
->BufferLength
)
5740 ERR("BufferLength == 0??\n");
5741 PointerBufferSize(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5742 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
5743 pStubMsg
->BufferLength
= saved_buffer_length
;
5747 m(pStubMsg
, pMemory
, desc
);
5750 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
5754 static ULONG
union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg
,
5756 PFORMAT_STRING pFormat
)
5758 unsigned short type
, size
;
5760 size
= *(const unsigned short*)pFormat
;
5761 pStubMsg
->Memory
+= size
;
5764 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5768 type
= *(const unsigned short*)pFormat
;
5769 if((type
& 0xff00) == 0x8000)
5771 return NdrBaseTypeMemorySize(pStubMsg
, pFormat
);
5775 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5776 NDR_MEMORYSIZE m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
5777 unsigned char *saved_buffer
;
5786 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5787 saved_buffer
= pStubMsg
->Buffer
;
5788 safe_buffer_increment(pStubMsg
, 4);
5789 ALIGN_LENGTH(pStubMsg
->MemorySize
, sizeof(void *));
5790 pStubMsg
->MemorySize
+= sizeof(void *);
5791 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5792 PointerMemorySize(pStubMsg
, saved_buffer
, pFormat
);
5795 return m(pStubMsg
, desc
);
5798 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5801 TRACE("size %d\n", size
);
5805 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg
,
5806 unsigned char *pMemory
,
5808 PFORMAT_STRING pFormat
)
5810 unsigned short type
;
5814 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5818 type
= *(const unsigned short*)pFormat
;
5819 if((type
& 0xff00) != 0x8000)
5821 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5822 NDR_FREE m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
5831 PointerFree(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5834 m(pStubMsg
, pMemory
, desc
);
5840 /***********************************************************************
5841 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5843 unsigned char * WINAPI
NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5844 unsigned char *pMemory
,
5845 PFORMAT_STRING pFormat
)
5847 unsigned char switch_type
;
5848 unsigned char increment
;
5851 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5854 switch_type
= *pFormat
& 0xf;
5855 increment
= (*pFormat
& 0xf0) >> 4;
5858 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, increment
);
5860 switch_value
= get_discriminant(switch_type
, pMemory
);
5861 TRACE("got switch value 0x%x\n", switch_value
);
5863 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &switch_type
);
5864 pMemory
+= increment
;
5866 return union_arm_marshall(pStubMsg
, pMemory
, switch_value
, pFormat
);
5869 /***********************************************************************
5870 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5872 unsigned char * WINAPI
NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5873 unsigned char **ppMemory
,
5874 PFORMAT_STRING pFormat
,
5875 unsigned char fMustAlloc
)
5877 unsigned char switch_type
;
5878 unsigned char increment
;
5880 unsigned short size
;
5881 unsigned char *pMemoryArm
;
5883 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5886 switch_type
= *pFormat
& 0xf;
5887 increment
= (*pFormat
& 0xf0) >> 4;
5890 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
5891 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
5892 TRACE("got switch value 0x%x\n", switch_value
);
5894 size
= *(const unsigned short*)pFormat
+ increment
;
5895 if (!fMustAlloc
&& !*ppMemory
)
5898 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5900 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
5901 * since the arm is part of the memory block that is encompassed by
5902 * the whole union. Memory is forced to allocate when pointers
5903 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
5904 * clearing the memory we pass in to the unmarshaller */
5906 memset(*ppMemory
, 0, size
);
5908 NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &switch_type
, FALSE
);
5909 pMemoryArm
= *ppMemory
+ increment
;
5911 return union_arm_unmarshall(pStubMsg
, &pMemoryArm
, switch_value
, pFormat
, FALSE
);
5914 /***********************************************************************
5915 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5917 void WINAPI
NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5918 unsigned char *pMemory
,
5919 PFORMAT_STRING pFormat
)
5921 unsigned char switch_type
;
5922 unsigned char increment
;
5925 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5928 switch_type
= *pFormat
& 0xf;
5929 increment
= (*pFormat
& 0xf0) >> 4;
5932 ALIGN_LENGTH(pStubMsg
->BufferLength
, increment
);
5933 switch_value
= get_discriminant(switch_type
, pMemory
);
5934 TRACE("got switch value 0x%x\n", switch_value
);
5936 /* Add discriminant size */
5937 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&switch_value
, &switch_type
);
5938 pMemory
+= increment
;
5940 union_arm_buffer_size(pStubMsg
, pMemory
, switch_value
, pFormat
);
5943 /***********************************************************************
5944 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5946 ULONG WINAPI
NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5947 PFORMAT_STRING pFormat
)
5949 unsigned char switch_type
;
5950 unsigned char increment
;
5953 switch_type
= *pFormat
& 0xf;
5954 increment
= (*pFormat
& 0xf0) >> 4;
5957 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
5958 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
5959 TRACE("got switch value 0x%x\n", switch_value
);
5961 pStubMsg
->Memory
+= increment
;
5963 return increment
+ union_arm_memory_size(pStubMsg
, switch_value
, pFormat
+ *(const SHORT
*)pFormat
);
5966 /***********************************************************************
5967 * NdrEncapsulatedUnionFree [RPCRT4.@]
5969 void WINAPI
NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
5970 unsigned char *pMemory
,
5971 PFORMAT_STRING pFormat
)
5973 unsigned char switch_type
;
5974 unsigned char increment
;
5977 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5980 switch_type
= *pFormat
& 0xf;
5981 increment
= (*pFormat
& 0xf0) >> 4;
5984 switch_value
= get_discriminant(switch_type
, pMemory
);
5985 TRACE("got switch value 0x%x\n", switch_value
);
5987 pMemory
+= increment
;
5989 union_arm_free(pStubMsg
, pMemory
, switch_value
, pFormat
);
5992 /***********************************************************************
5993 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5995 unsigned char * WINAPI
NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5996 unsigned char *pMemory
,
5997 PFORMAT_STRING pFormat
)
5999 unsigned char switch_type
;
6001 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6004 switch_type
= *pFormat
;
6007 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6008 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6009 /* Marshall discriminant */
6010 NdrBaseTypeMarshall(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
6012 return union_arm_marshall(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6015 static LONG
unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg
,
6016 PFORMAT_STRING
*ppFormat
)
6018 LONG discriminant
= 0;
6028 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
6037 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
6038 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
6046 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
6047 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
6052 FIXME("Unhandled base type: 0x%02x\n", **ppFormat
);
6056 if (pStubMsg
->fHasNewCorrDesc
)
6060 return discriminant
;
6063 /**********************************************************************
6064 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
6066 unsigned char * WINAPI
NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6067 unsigned char **ppMemory
,
6068 PFORMAT_STRING pFormat
,
6069 unsigned char fMustAlloc
)
6072 unsigned short size
;
6074 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
6077 /* Unmarshall discriminant */
6078 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
6079 TRACE("unmarshalled discriminant %x\n", discriminant
);
6081 pFormat
+= *(const SHORT
*)pFormat
;
6083 size
= *(const unsigned short*)pFormat
;
6085 if (!fMustAlloc
&& !*ppMemory
)
6088 *ppMemory
= NdrAllocate(pStubMsg
, size
);
6090 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6091 * since the arm is part of the memory block that is encompassed by
6092 * the whole union. Memory is forced to allocate when pointers
6093 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6094 * clearing the memory we pass in to the unmarshaller */
6096 memset(*ppMemory
, 0, size
);
6098 return union_arm_unmarshall(pStubMsg
, ppMemory
, discriminant
, pFormat
, FALSE
);
6101 /***********************************************************************
6102 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
6104 void WINAPI
NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6105 unsigned char *pMemory
,
6106 PFORMAT_STRING pFormat
)
6108 unsigned char switch_type
;
6110 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6113 switch_type
= *pFormat
;
6116 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6117 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6118 /* Add discriminant size */
6119 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
6121 union_arm_buffer_size(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6124 /***********************************************************************
6125 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
6127 ULONG WINAPI
NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6128 PFORMAT_STRING pFormat
)
6133 /* Unmarshall discriminant */
6134 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
6135 TRACE("unmarshalled discriminant 0x%x\n", discriminant
);
6137 return union_arm_memory_size(pStubMsg
, discriminant
, pFormat
+ *(const SHORT
*)pFormat
);
6140 /***********************************************************************
6141 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6143 void WINAPI
NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
6144 unsigned char *pMemory
,
6145 PFORMAT_STRING pFormat
)
6147 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6151 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6152 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6154 union_arm_free(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6157 /***********************************************************************
6158 * NdrByteCountPointerMarshall [RPCRT4.@]
6160 unsigned char * WINAPI
NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6161 unsigned char *pMemory
,
6162 PFORMAT_STRING pFormat
)
6168 /***********************************************************************
6169 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6171 unsigned char * WINAPI
NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6172 unsigned char **ppMemory
,
6173 PFORMAT_STRING pFormat
,
6174 unsigned char fMustAlloc
)
6180 /***********************************************************************
6181 * NdrByteCountPointerBufferSize [RPCRT4.@]
6183 void WINAPI
NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6184 unsigned char *pMemory
,
6185 PFORMAT_STRING pFormat
)
6190 /***********************************************************************
6191 * NdrByteCountPointerMemorySize [internal]
6193 static ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6194 PFORMAT_STRING pFormat
)
6200 /***********************************************************************
6201 * NdrByteCountPointerFree [RPCRT4.@]
6203 void WINAPI
NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
6204 unsigned char *pMemory
,
6205 PFORMAT_STRING pFormat
)
6210 /***********************************************************************
6211 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6213 unsigned char * WINAPI
NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6214 unsigned char *pMemory
,
6215 PFORMAT_STRING pFormat
)
6221 /***********************************************************************
6222 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6224 unsigned char * WINAPI
NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6225 unsigned char **ppMemory
,
6226 PFORMAT_STRING pFormat
,
6227 unsigned char fMustAlloc
)
6233 /***********************************************************************
6234 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6236 void WINAPI
NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6237 unsigned char *pMemory
,
6238 PFORMAT_STRING pFormat
)
6243 /***********************************************************************
6244 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6246 ULONG WINAPI
NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6247 PFORMAT_STRING pFormat
)
6253 /***********************************************************************
6254 * NdrXmitOrRepAsFree [RPCRT4.@]
6256 void WINAPI
NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg
,
6257 unsigned char *pMemory
,
6258 PFORMAT_STRING pFormat
)
6263 /***********************************************************************
6264 * NdrRangeMarshall [internal]
6266 static unsigned char *WINAPI
NdrRangeMarshall(
6267 PMIDL_STUB_MESSAGE pStubMsg
,
6268 unsigned char *pMemory
,
6269 PFORMAT_STRING pFormat
)
6271 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
6272 unsigned char base_type
;
6274 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6276 if (pRange
->type
!= RPC_FC_RANGE
)
6278 ERR("invalid format type %x\n", pRange
->type
);
6279 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6283 base_type
= pRange
->flags_type
& 0xf;
6285 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &base_type
);
6288 /***********************************************************************
6289 * NdrRangeUnmarshall [RPCRT4.@]
6291 unsigned char *WINAPI
NdrRangeUnmarshall(
6292 PMIDL_STUB_MESSAGE pStubMsg
,
6293 unsigned char **ppMemory
,
6294 PFORMAT_STRING pFormat
,
6295 unsigned char fMustAlloc
)
6297 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
6298 unsigned char base_type
;
6300 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6302 if (pRange
->type
!= RPC_FC_RANGE
)
6304 ERR("invalid format type %x\n", pRange
->type
);
6305 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6308 base_type
= pRange
->flags_type
& 0xf;
6310 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6311 base_type
, pRange
->low_value
, pRange
->high_value
);
6313 #define RANGE_UNMARSHALL(mem_type, wire_type, format_spec) \
6316 ALIGN_POINTER(pStubMsg->Buffer, sizeof(wire_type)); \
6317 if (!fMustAlloc && !*ppMemory) \
6318 fMustAlloc = TRUE; \
6320 *ppMemory = NdrAllocate(pStubMsg, sizeof(mem_type)); \
6321 if (pStubMsg->Buffer + sizeof(wire_type) > pStubMsg->BufferEnd) \
6323 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6324 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6325 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6327 if ((*(wire_type *)pStubMsg->Buffer < (mem_type)pRange->low_value) || \
6328 (*(wire_type *)pStubMsg->Buffer > (mem_type)pRange->high_value)) \
6330 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6331 *(wire_type *)pStubMsg->Buffer, (mem_type)pRange->low_value, \
6332 (mem_type)pRange->high_value); \
6333 RpcRaiseException(RPC_S_INVALID_BOUND); \
6336 TRACE("*ppMemory: %p\n", *ppMemory); \
6337 **(mem_type **)ppMemory = *(wire_type *)pStubMsg->Buffer; \
6338 pStubMsg->Buffer += sizeof(wire_type); \
6345 RANGE_UNMARSHALL(UCHAR
, UCHAR
, "%d");
6346 TRACE("value: 0x%02x\n", **ppMemory
);
6350 RANGE_UNMARSHALL(CHAR
, CHAR
, "%u");
6351 TRACE("value: 0x%02x\n", **ppMemory
);
6353 case RPC_FC_WCHAR
: /* FIXME: valid? */
6355 RANGE_UNMARSHALL(USHORT
, USHORT
, "%u");
6356 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6359 RANGE_UNMARSHALL(SHORT
, SHORT
, "%d");
6360 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6364 RANGE_UNMARSHALL(LONG
, LONG
, "%d");
6365 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6368 RANGE_UNMARSHALL(ULONG
, ULONG
, "%u");
6369 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6372 RANGE_UNMARSHALL(UINT
, USHORT
, "%u");
6373 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
6379 ERR("invalid range base type: 0x%02x\n", base_type
);
6380 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6386 /***********************************************************************
6387 * NdrRangeBufferSize [internal]
6389 static void WINAPI
NdrRangeBufferSize(
6390 PMIDL_STUB_MESSAGE pStubMsg
,
6391 unsigned char *pMemory
,
6392 PFORMAT_STRING pFormat
)
6394 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
6395 unsigned char base_type
;
6397 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6399 if (pRange
->type
!= RPC_FC_RANGE
)
6401 ERR("invalid format type %x\n", pRange
->type
);
6402 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6404 base_type
= pRange
->flags_type
& 0xf;
6406 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &base_type
);
6409 /***********************************************************************
6410 * NdrRangeMemorySize [internal]
6412 static ULONG WINAPI
NdrRangeMemorySize(
6413 PMIDL_STUB_MESSAGE pStubMsg
,
6414 PFORMAT_STRING pFormat
)
6416 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
6417 unsigned char base_type
;
6419 if (pRange
->type
!= RPC_FC_RANGE
)
6421 ERR("invalid format type %x\n", pRange
->type
);
6422 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6425 base_type
= pRange
->flags_type
& 0xf;
6427 return NdrBaseTypeMemorySize(pStubMsg
, &base_type
);
6430 /***********************************************************************
6431 * NdrRangeFree [internal]
6433 static void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6434 unsigned char *pMemory
,
6435 PFORMAT_STRING pFormat
)
6437 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6442 /***********************************************************************
6443 * NdrBaseTypeMarshall [internal]
6445 static unsigned char *WINAPI
NdrBaseTypeMarshall(
6446 PMIDL_STUB_MESSAGE pStubMsg
,
6447 unsigned char *pMemory
,
6448 PFORMAT_STRING pFormat
)
6450 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6458 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(UCHAR
));
6459 TRACE("value: 0x%02x\n", *pMemory
);
6464 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(USHORT
));
6465 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(USHORT
));
6466 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
6470 case RPC_FC_ERROR_STATUS_T
:
6472 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(ULONG
));
6473 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONG
));
6474 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
6477 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(float));
6478 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
6481 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(double));
6482 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
6485 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(ULONGLONG
));
6486 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONGLONG
));
6487 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
6490 /* only 16-bits on the wire, so do a sanity check */
6491 if (*(UINT
*)pMemory
> SHRT_MAX
)
6492 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
6493 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(USHORT
));
6494 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6495 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6496 *(USHORT
*)pStubMsg
->Buffer
= *(UINT
*)pMemory
;
6497 pStubMsg
->Buffer
+= sizeof(USHORT
);
6498 TRACE("value: 0x%04x\n", *(UINT
*)pMemory
);
6503 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6506 /* FIXME: what is the correct return value? */
6510 /***********************************************************************
6511 * NdrBaseTypeUnmarshall [internal]
6513 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(
6514 PMIDL_STUB_MESSAGE pStubMsg
,
6515 unsigned char **ppMemory
,
6516 PFORMAT_STRING pFormat
,
6517 unsigned char fMustAlloc
)
6519 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6521 #define BASE_TYPE_UNMARSHALL(type) \
6522 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6523 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6525 *ppMemory = pStubMsg->Buffer; \
6526 TRACE("*ppMemory: %p\n", *ppMemory); \
6527 safe_buffer_increment(pStubMsg, sizeof(type)); \
6532 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6533 TRACE("*ppMemory: %p\n", *ppMemory); \
6534 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6543 BASE_TYPE_UNMARSHALL(UCHAR
);
6544 TRACE("value: 0x%02x\n", **ppMemory
);
6549 BASE_TYPE_UNMARSHALL(USHORT
);
6550 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6554 case RPC_FC_ERROR_STATUS_T
:
6556 BASE_TYPE_UNMARSHALL(ULONG
);
6557 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6560 BASE_TYPE_UNMARSHALL(float);
6561 TRACE("value: %f\n", **(float **)ppMemory
);
6564 BASE_TYPE_UNMARSHALL(double);
6565 TRACE("value: %f\n", **(double **)ppMemory
);
6568 BASE_TYPE_UNMARSHALL(ULONGLONG
);
6569 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG
**)ppMemory
));
6572 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
6573 if (!fMustAlloc
&& !*ppMemory
)
6576 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT
));
6577 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > pStubMsg
->BufferEnd
)
6578 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6579 TRACE("*ppMemory: %p\n", *ppMemory
);
6580 /* 16-bits on the wire, but int in memory */
6581 **(UINT
**)ppMemory
= *(USHORT
*)pStubMsg
->Buffer
;
6582 pStubMsg
->Buffer
+= sizeof(USHORT
);
6583 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
6588 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6590 #undef BASE_TYPE_UNMARSHALL
6592 /* FIXME: what is the correct return value? */
6597 /***********************************************************************
6598 * NdrBaseTypeBufferSize [internal]
6600 static void WINAPI
NdrBaseTypeBufferSize(
6601 PMIDL_STUB_MESSAGE pStubMsg
,
6602 unsigned char *pMemory
,
6603 PFORMAT_STRING pFormat
)
6605 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6613 safe_buffer_length_increment(pStubMsg
, sizeof(UCHAR
));
6619 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(USHORT
));
6620 safe_buffer_length_increment(pStubMsg
, sizeof(USHORT
));
6625 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONG
));
6626 safe_buffer_length_increment(pStubMsg
, sizeof(ULONG
));
6629 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(float));
6630 safe_buffer_length_increment(pStubMsg
, sizeof(float));
6633 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(double));
6634 safe_buffer_length_increment(pStubMsg
, sizeof(double));
6637 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONGLONG
));
6638 safe_buffer_length_increment(pStubMsg
, sizeof(ULONGLONG
));
6640 case RPC_FC_ERROR_STATUS_T
:
6641 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(error_status_t
));
6642 safe_buffer_length_increment(pStubMsg
, sizeof(error_status_t
));
6647 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6651 /***********************************************************************
6652 * NdrBaseTypeMemorySize [internal]
6654 static ULONG WINAPI
NdrBaseTypeMemorySize(
6655 PMIDL_STUB_MESSAGE pStubMsg
,
6656 PFORMAT_STRING pFormat
)
6658 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg
, *pFormat
);
6666 safe_buffer_increment(pStubMsg
, sizeof(UCHAR
));
6667 pStubMsg
->MemorySize
+= sizeof(UCHAR
);
6668 return sizeof(UCHAR
);
6672 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
6673 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6674 ALIGN_LENGTH(pStubMsg
->MemorySize
, sizeof(USHORT
));
6675 pStubMsg
->MemorySize
+= sizeof(USHORT
);
6676 return sizeof(USHORT
);
6680 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
6681 safe_buffer_increment(pStubMsg
, sizeof(ULONG
));
6682 ALIGN_LENGTH(pStubMsg
->MemorySize
, sizeof(ULONG
));
6683 pStubMsg
->MemorySize
+= sizeof(ULONG
);
6684 return sizeof(ULONG
);
6686 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(float));
6687 safe_buffer_increment(pStubMsg
, sizeof(float));
6688 ALIGN_LENGTH(pStubMsg
->MemorySize
, sizeof(float));
6689 pStubMsg
->MemorySize
+= sizeof(float);
6690 return sizeof(float);
6692 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(double));
6693 safe_buffer_increment(pStubMsg
, sizeof(double));
6694 ALIGN_LENGTH(pStubMsg
->MemorySize
, sizeof(double));
6695 pStubMsg
->MemorySize
+= sizeof(double);
6696 return sizeof(double);
6698 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONGLONG
));
6699 safe_buffer_increment(pStubMsg
, sizeof(ULONGLONG
));
6700 ALIGN_LENGTH(pStubMsg
->MemorySize
, sizeof(ULONGLONG
));
6701 pStubMsg
->MemorySize
+= sizeof(ULONGLONG
);
6702 return sizeof(ULONGLONG
);
6703 case RPC_FC_ERROR_STATUS_T
:
6704 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(error_status_t
));
6705 safe_buffer_increment(pStubMsg
, sizeof(error_status_t
));
6706 ALIGN_LENGTH(pStubMsg
->MemorySize
, sizeof(error_status_t
));
6707 pStubMsg
->MemorySize
+= sizeof(error_status_t
);
6708 return sizeof(error_status_t
);
6710 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
6711 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6712 ALIGN_LENGTH(pStubMsg
->MemorySize
, sizeof(UINT
));
6713 pStubMsg
->MemorySize
+= sizeof(UINT
);
6714 return sizeof(UINT
);
6716 ALIGN_LENGTH(pStubMsg
->MemorySize
, sizeof(void *));
6717 pStubMsg
->MemorySize
+= sizeof(void *);
6718 return sizeof(void *);
6720 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6725 /***********************************************************************
6726 * NdrBaseTypeFree [internal]
6728 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6729 unsigned char *pMemory
,
6730 PFORMAT_STRING pFormat
)
6732 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6737 /***********************************************************************
6738 * NdrContextHandleBufferSize [internal]
6740 static void WINAPI
NdrContextHandleBufferSize(
6741 PMIDL_STUB_MESSAGE pStubMsg
,
6742 unsigned char *pMemory
,
6743 PFORMAT_STRING pFormat
)
6745 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6747 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6749 ERR("invalid format type %x\n", *pFormat
);
6750 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6752 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
6753 safe_buffer_length_increment(pStubMsg
, cbNDRContext
);
6756 /***********************************************************************
6757 * NdrContextHandleMarshall [internal]
6759 static unsigned char *WINAPI
NdrContextHandleMarshall(
6760 PMIDL_STUB_MESSAGE pStubMsg
,
6761 unsigned char *pMemory
,
6762 PFORMAT_STRING pFormat
)
6764 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6766 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6768 ERR("invalid format type %x\n", *pFormat
);
6769 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6771 TRACE("flags: 0x%02x\n", pFormat
[1]);
6773 if (pStubMsg
->IsClient
)
6775 if (pFormat
[1] & HANDLE_PARAM_IS_VIA_PTR
)
6776 NdrClientContextMarshall(pStubMsg
, *(NDR_CCONTEXT
**)pMemory
, FALSE
);
6778 NdrClientContextMarshall(pStubMsg
, pMemory
, FALSE
);
6782 NDR_SCONTEXT ctxt
= NDRSContextFromValue(pMemory
);
6783 NDR_RUNDOWN rundown
= pStubMsg
->StubDesc
->apfnNdrRundownRoutines
[pFormat
[2]];
6784 NdrServerContextNewMarshall(pStubMsg
, ctxt
, rundown
, pFormat
);
6790 /***********************************************************************
6791 * NdrContextHandleUnmarshall [internal]
6793 static unsigned char *WINAPI
NdrContextHandleUnmarshall(
6794 PMIDL_STUB_MESSAGE pStubMsg
,
6795 unsigned char **ppMemory
,
6796 PFORMAT_STRING pFormat
,
6797 unsigned char fMustAlloc
)
6799 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg
,
6800 ppMemory
, pFormat
, fMustAlloc
? "TRUE": "FALSE");
6802 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6804 ERR("invalid format type %x\n", *pFormat
);
6805 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6807 TRACE("flags: 0x%02x\n", pFormat
[1]);
6809 if (pStubMsg
->IsClient
)
6811 /* [out]-only or [ret] param */
6812 if ((pFormat
[1] & (HANDLE_PARAM_IS_IN
|HANDLE_PARAM_IS_OUT
)) == HANDLE_PARAM_IS_OUT
)
6813 **(NDR_CCONTEXT
**)ppMemory
= NULL
;
6814 NdrClientContextUnmarshall(pStubMsg
, *(NDR_CCONTEXT
**)ppMemory
, pStubMsg
->RpcMsg
->Handle
);
6819 ctxt
= NdrServerContextNewUnmarshall(pStubMsg
, pFormat
);
6820 if (pFormat
[1] & HANDLE_PARAM_IS_VIA_PTR
)
6821 *(void **)ppMemory
= NDRSContextValue(ctxt
);
6823 *(void **)ppMemory
= *NDRSContextValue(ctxt
);
6829 /***********************************************************************
6830 * NdrClientContextMarshall [RPCRT4.@]
6832 void WINAPI
NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6833 NDR_CCONTEXT ContextHandle
,
6836 TRACE("(%p, %p, %d)\n", pStubMsg
, ContextHandle
, fCheck
);
6838 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
6840 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6842 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6843 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6844 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6847 /* FIXME: what does fCheck do? */
6848 NDRCContextMarshall(ContextHandle
,
6851 pStubMsg
->Buffer
+= cbNDRContext
;
6854 /***********************************************************************
6855 * NdrClientContextUnmarshall [RPCRT4.@]
6857 void WINAPI
NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6858 NDR_CCONTEXT
* pContextHandle
,
6859 RPC_BINDING_HANDLE BindHandle
)
6861 TRACE("(%p, %p, %p)\n", pStubMsg
, pContextHandle
, BindHandle
);
6863 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6865 if (pStubMsg
->Buffer
+ cbNDRContext
> pStubMsg
->BufferEnd
)
6866 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6868 NDRCContextUnmarshall(pContextHandle
,
6871 pStubMsg
->RpcMsg
->DataRepresentation
);
6873 pStubMsg
->Buffer
+= cbNDRContext
;
6876 void WINAPI
NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6877 NDR_SCONTEXT ContextHandle
,
6878 NDR_RUNDOWN RundownRoutine
)
6880 TRACE("(%p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
);
6882 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6884 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6886 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6887 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6888 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6891 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
6892 pStubMsg
->Buffer
, RundownRoutine
, NULL
,
6893 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
6894 pStubMsg
->Buffer
+= cbNDRContext
;
6897 NDR_SCONTEXT WINAPI
NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
)
6899 NDR_SCONTEXT ContextHandle
;
6901 TRACE("(%p)\n", pStubMsg
);
6903 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6905 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6907 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6908 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6909 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6912 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
6914 pStubMsg
->RpcMsg
->DataRepresentation
,
6915 NULL
, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
6916 pStubMsg
->Buffer
+= cbNDRContext
;
6918 return ContextHandle
;
6921 void WINAPI
NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg
,
6922 unsigned char* pMemory
,
6923 PFORMAT_STRING pFormat
)
6925 FIXME("(%p, %p, %p): stub\n", pStubMsg
, pMemory
, pFormat
);
6928 NDR_SCONTEXT WINAPI
NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg
,
6929 PFORMAT_STRING pFormat
)
6931 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6932 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6934 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
6936 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
6937 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
6938 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
6939 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
6940 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
6942 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
6943 if_id
= &sif
->InterfaceId
;
6946 return NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
, NULL
,
6947 pStubMsg
->RpcMsg
->DataRepresentation
, if_id
,
6951 void WINAPI
NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6952 NDR_SCONTEXT ContextHandle
,
6953 NDR_RUNDOWN RundownRoutine
,
6954 PFORMAT_STRING pFormat
)
6956 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6957 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6959 TRACE("(%p, %p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
, pFormat
);
6961 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6963 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6965 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6966 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6967 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6970 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
6971 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
6972 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
6973 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
6974 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
6976 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
6977 if_id
= &sif
->InterfaceId
;
6980 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
6981 pStubMsg
->Buffer
, RundownRoutine
, if_id
, flags
);
6982 pStubMsg
->Buffer
+= cbNDRContext
;
6985 NDR_SCONTEXT WINAPI
NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6986 PFORMAT_STRING pFormat
)
6988 NDR_SCONTEXT ContextHandle
;
6989 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
6990 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
6992 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
6994 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6996 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6998 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6999 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7000 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7003 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
7004 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
7005 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
7006 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
7007 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
7009 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
7010 if_id
= &sif
->InterfaceId
;
7013 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
7015 pStubMsg
->RpcMsg
->DataRepresentation
,
7017 pStubMsg
->Buffer
+= cbNDRContext
;
7019 return ContextHandle
;
7022 /***********************************************************************
7023 * NdrCorrelationInitialize [RPCRT4.@]
7025 * Initializes correlation validity checking.
7028 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7029 * pMemory [I] Pointer to memory to use as a cache.
7030 * CacheSize [I] Size of the memory pointed to by pMemory.
7031 * Flags [I] Reserved. Set to zero.
7036 void WINAPI
NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg
, void *pMemory
, ULONG CacheSize
, ULONG Flags
)
7038 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg
, pMemory
, CacheSize
, Flags
);
7039 pStubMsg
->fHasNewCorrDesc
= TRUE
;
7042 /***********************************************************************
7043 * NdrCorrelationPass [RPCRT4.@]
7045 * Performs correlation validity checking.
7048 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7053 void WINAPI
NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg
)
7055 FIXME("(%p): stub\n", pStubMsg
);
7058 /***********************************************************************
7059 * NdrCorrelationFree [RPCRT4.@]
7061 * Frees any resources used while unmarshalling parameters that need
7062 * correlation validity checking.
7065 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7070 void WINAPI
NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg
)
7072 FIXME("(%p): stub\n", pStubMsg
);