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
36 #define NONAMELESSUNION
45 #include "wine/unicode.h"
46 #include "wine/debug.h"
48 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
51 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
52 (*((UINT32 *)(pchar)) = (uint32))
54 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
55 (*((UINT32 *)(pchar)))
57 /* these would work for i386 too, but less efficient */
58 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
59 (*(pchar) = LOBYTE(LOWORD(uint32)), \
60 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
61 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
62 *((pchar)+3) = HIBYTE(HIWORD(uint32)))
64 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
66 MAKEWORD(*(pchar), *((pchar)+1)), \
67 MAKEWORD(*((pchar)+2), *((pchar)+3))))
70 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
71 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
72 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
73 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
74 *(pchar) = HIBYTE(HIWORD(uint32)))
76 #define BIG_ENDIAN_UINT32_READ(pchar) \
78 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
79 MAKEWORD(*((pchar)+1), *(pchar))))
81 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
82 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
83 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
84 # define NDR_LOCAL_UINT32_READ(pchar) \
85 BIG_ENDIAN_UINT32_READ(pchar)
87 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
88 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
89 # define NDR_LOCAL_UINT32_READ(pchar) \
90 LITTLE_ENDIAN_UINT32_READ(pchar)
93 static inline void align_length( ULONG
*len
, unsigned int align
)
95 *len
= (*len
+ align
- 1) & ~(align
- 1);
98 static inline void align_pointer( unsigned char **ptr
, unsigned int align
)
100 ULONG_PTR mask
= align
- 1;
101 *ptr
= (unsigned char *)(((ULONG_PTR
)*ptr
+ mask
) & ~mask
);
104 static inline void align_pointer_clear( unsigned char **ptr
, unsigned int align
)
106 ULONG_PTR mask
= align
- 1;
107 memset( *ptr
, 0, (align
- (ULONG_PTR
)*ptr
) & mask
);
108 *ptr
= (unsigned char *)(((ULONG_PTR
)*ptr
+ mask
) & ~mask
);
111 #define STD_OVERFLOW_CHECK(_Msg) do { \
112 TRACE("buffer=%d/%d\n", (ULONG)(_Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer), _Msg->BufferLength); \
113 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
114 ERR("buffer overflow %d bytes\n", (ULONG)(_Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength))); \
117 #define NDR_POINTER_ID_BASE 0x20000
118 #define NDR_POINTER_ID(pStubMsg) (NDR_POINTER_ID_BASE + ((pStubMsg)->UniquePtrCount++) * 4)
119 #define NDR_TABLE_SIZE 128
120 #define NDR_TABLE_MASK 127
122 #define NDRSContextFromValue(user_context) (NDR_SCONTEXT)((char *)(user_context) - (char *)NDRSContextValue((NDR_SCONTEXT)NULL))
124 static unsigned char *WINAPI
NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
125 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
126 static void WINAPI
NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
127 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
128 static ULONG WINAPI
NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
130 static unsigned char *WINAPI
NdrContextHandleMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
131 static void WINAPI
NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
132 static unsigned char *WINAPI
NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
134 static unsigned char *WINAPI
NdrRangeMarshall(PMIDL_STUB_MESSAGE
,unsigned char *, PFORMAT_STRING
);
135 static void WINAPI
NdrRangeBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
136 static ULONG WINAPI
NdrRangeMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
137 static void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
139 static ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
141 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
142 unsigned char *pMemory
,
143 PFORMAT_STRING pFormat
,
144 PFORMAT_STRING pPointer
);
145 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
146 unsigned char *pMemory
,
147 PFORMAT_STRING pFormat
,
148 PFORMAT_STRING pPointer
);
149 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
150 unsigned char *pMemory
,
151 PFORMAT_STRING pFormat
,
152 PFORMAT_STRING pPointer
,
153 unsigned char fMustAlloc
);
154 static ULONG
ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
155 PFORMAT_STRING pFormat
,
156 PFORMAT_STRING pPointer
);
157 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
158 unsigned char *pMemory
,
159 PFORMAT_STRING pFormat
,
160 PFORMAT_STRING pPointer
);
162 const NDR_MARSHALL NdrMarshaller
[NDR_TABLE_SIZE
] = {
164 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
165 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
166 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
167 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
171 NdrPointerMarshall
, NdrPointerMarshall
,
172 NdrPointerMarshall
, NdrPointerMarshall
,
174 NdrSimpleStructMarshall
, NdrSimpleStructMarshall
,
175 NdrConformantStructMarshall
, NdrConformantStructMarshall
,
176 NdrConformantVaryingStructMarshall
,
177 NdrComplexStructMarshall
,
179 NdrConformantArrayMarshall
,
180 NdrConformantVaryingArrayMarshall
,
181 NdrFixedArrayMarshall
, NdrFixedArrayMarshall
,
182 NdrVaryingArrayMarshall
, NdrVaryingArrayMarshall
,
183 NdrComplexArrayMarshall
,
185 NdrConformantStringMarshall
, 0, 0,
186 NdrConformantStringMarshall
,
187 NdrNonConformantStringMarshall
, 0, 0, 0,
189 NdrEncapsulatedUnionMarshall
,
190 NdrNonEncapsulatedUnionMarshall
,
191 NdrByteCountPointerMarshall
,
192 NdrXmitOrRepAsMarshall
, NdrXmitOrRepAsMarshall
,
194 NdrInterfacePointerMarshall
,
196 NdrContextHandleMarshall
,
199 NdrUserMarshalMarshall
,
206 const NDR_UNMARSHALL NdrUnmarshaller
[NDR_TABLE_SIZE
] = {
208 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
209 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
210 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
211 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
213 NdrBaseTypeUnmarshall
,
215 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
216 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
218 NdrSimpleStructUnmarshall
, NdrSimpleStructUnmarshall
,
219 NdrConformantStructUnmarshall
, NdrConformantStructUnmarshall
,
220 NdrConformantVaryingStructUnmarshall
,
221 NdrComplexStructUnmarshall
,
223 NdrConformantArrayUnmarshall
,
224 NdrConformantVaryingArrayUnmarshall
,
225 NdrFixedArrayUnmarshall
, NdrFixedArrayUnmarshall
,
226 NdrVaryingArrayUnmarshall
, NdrVaryingArrayUnmarshall
,
227 NdrComplexArrayUnmarshall
,
229 NdrConformantStringUnmarshall
, 0, 0,
230 NdrConformantStringUnmarshall
,
231 NdrNonConformantStringUnmarshall
, 0, 0, 0,
233 NdrEncapsulatedUnionUnmarshall
,
234 NdrNonEncapsulatedUnionUnmarshall
,
235 NdrByteCountPointerUnmarshall
,
236 NdrXmitOrRepAsUnmarshall
, NdrXmitOrRepAsUnmarshall
,
238 NdrInterfacePointerUnmarshall
,
240 NdrContextHandleUnmarshall
,
243 NdrUserMarshalUnmarshall
,
247 NdrBaseTypeUnmarshall
,
248 NdrBaseTypeUnmarshall
250 const NDR_BUFFERSIZE NdrBufferSizer
[NDR_TABLE_SIZE
] = {
252 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
253 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
254 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
255 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
257 NdrBaseTypeBufferSize
,
259 NdrPointerBufferSize
, NdrPointerBufferSize
,
260 NdrPointerBufferSize
, NdrPointerBufferSize
,
262 NdrSimpleStructBufferSize
, NdrSimpleStructBufferSize
,
263 NdrConformantStructBufferSize
, NdrConformantStructBufferSize
,
264 NdrConformantVaryingStructBufferSize
,
265 NdrComplexStructBufferSize
,
267 NdrConformantArrayBufferSize
,
268 NdrConformantVaryingArrayBufferSize
,
269 NdrFixedArrayBufferSize
, NdrFixedArrayBufferSize
,
270 NdrVaryingArrayBufferSize
, NdrVaryingArrayBufferSize
,
271 NdrComplexArrayBufferSize
,
273 NdrConformantStringBufferSize
, 0, 0,
274 NdrConformantStringBufferSize
,
275 NdrNonConformantStringBufferSize
, 0, 0, 0,
277 NdrEncapsulatedUnionBufferSize
,
278 NdrNonEncapsulatedUnionBufferSize
,
279 NdrByteCountPointerBufferSize
,
280 NdrXmitOrRepAsBufferSize
, NdrXmitOrRepAsBufferSize
,
282 NdrInterfacePointerBufferSize
,
284 NdrContextHandleBufferSize
,
287 NdrUserMarshalBufferSize
,
291 NdrBaseTypeBufferSize
,
292 NdrBaseTypeBufferSize
294 const NDR_MEMORYSIZE NdrMemorySizer
[NDR_TABLE_SIZE
] = {
296 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
297 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
298 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
299 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
301 NdrBaseTypeMemorySize
,
303 NdrPointerMemorySize
, NdrPointerMemorySize
,
304 NdrPointerMemorySize
, NdrPointerMemorySize
,
306 NdrSimpleStructMemorySize
, NdrSimpleStructMemorySize
,
307 NdrConformantStructMemorySize
, NdrConformantStructMemorySize
,
308 NdrConformantVaryingStructMemorySize
,
309 NdrComplexStructMemorySize
,
311 NdrConformantArrayMemorySize
,
312 NdrConformantVaryingArrayMemorySize
,
313 NdrFixedArrayMemorySize
, NdrFixedArrayMemorySize
,
314 NdrVaryingArrayMemorySize
, NdrVaryingArrayMemorySize
,
315 NdrComplexArrayMemorySize
,
317 NdrConformantStringMemorySize
, 0, 0,
318 NdrConformantStringMemorySize
,
319 NdrNonConformantStringMemorySize
, 0, 0, 0,
321 NdrEncapsulatedUnionMemorySize
,
322 NdrNonEncapsulatedUnionMemorySize
,
323 NdrByteCountPointerMemorySize
,
324 NdrXmitOrRepAsMemorySize
, NdrXmitOrRepAsMemorySize
,
326 NdrInterfacePointerMemorySize
,
331 NdrUserMarshalMemorySize
,
335 NdrBaseTypeMemorySize
,
336 NdrBaseTypeMemorySize
338 const NDR_FREE NdrFreer
[NDR_TABLE_SIZE
] = {
340 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
341 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
342 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
343 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
347 NdrPointerFree
, NdrPointerFree
,
348 NdrPointerFree
, NdrPointerFree
,
350 NdrSimpleStructFree
, NdrSimpleStructFree
,
351 NdrConformantStructFree
, NdrConformantStructFree
,
352 NdrConformantVaryingStructFree
,
353 NdrComplexStructFree
,
355 NdrConformantArrayFree
,
356 NdrConformantVaryingArrayFree
,
357 NdrFixedArrayFree
, NdrFixedArrayFree
,
358 NdrVaryingArrayFree
, NdrVaryingArrayFree
,
364 NdrEncapsulatedUnionFree
,
365 NdrNonEncapsulatedUnionFree
,
367 NdrXmitOrRepAsFree
, NdrXmitOrRepAsFree
,
369 NdrInterfacePointerFree
,
382 typedef struct _NDR_MEMORY_LIST
387 struct _NDR_MEMORY_LIST
*next
;
390 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
392 /***********************************************************************
393 * NdrAllocate [RPCRT4.@]
395 * Allocates a block of memory using pStubMsg->pfnAllocate.
398 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
399 * len [I] Size of memory block to allocate.
402 * The memory block of size len that was allocated.
405 * The memory block is always 8-byte aligned.
406 * If the function is unable to allocate memory an RPC_X_NO_MEMORY
407 * exception is raised.
409 void * WINAPI
NdrAllocate(MIDL_STUB_MESSAGE
*pStubMsg
, SIZE_T len
)
414 NDR_MEMORY_LIST
*mem_list
;
416 aligned_len
= (len
+ 7) & ~7;
417 adjusted_len
= aligned_len
+ sizeof(NDR_MEMORY_LIST
);
418 /* check for overflow */
419 if (adjusted_len
< len
)
421 ERR("overflow of adjusted_len %ld, len %ld\n", adjusted_len
, len
);
422 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
425 p
= pStubMsg
->pfnAllocate(adjusted_len
);
426 if (!p
) RpcRaiseException(RPC_X_NO_MEMORY
);
428 mem_list
= (NDR_MEMORY_LIST
*)((char *)p
+ aligned_len
);
429 mem_list
->magic
= MEML_MAGIC
;
430 mem_list
->size
= aligned_len
;
431 mem_list
->reserved
= 0;
432 mem_list
->next
= pStubMsg
->pMemoryList
;
433 pStubMsg
->pMemoryList
= mem_list
;
439 static void NdrFree(MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *Pointer
)
441 TRACE("(%p, %p)\n", pStubMsg
, Pointer
);
443 pStubMsg
->pfnFree(Pointer
);
446 static inline BOOL
IsConformanceOrVariancePresent(PFORMAT_STRING pFormat
)
448 return (*(const ULONG
*)pFormat
!= -1);
451 static inline PFORMAT_STRING
SkipConformance(const PMIDL_STUB_MESSAGE pStubMsg
, const PFORMAT_STRING pFormat
)
453 return pFormat
+ 4 + pStubMsg
->CorrDespIncrement
;
456 static PFORMAT_STRING
ReadConformance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
)
458 align_pointer(&pStubMsg
->Buffer
, 4);
459 if (pStubMsg
->Buffer
+ 4 > pStubMsg
->BufferEnd
)
460 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
461 pStubMsg
->MaxCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
462 pStubMsg
->Buffer
+= 4;
463 TRACE("unmarshalled conformance is %ld\n", pStubMsg
->MaxCount
);
464 return SkipConformance(pStubMsg
, pFormat
);
467 static inline PFORMAT_STRING
ReadVariance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
, ULONG MaxValue
)
469 if (pFormat
&& !IsConformanceOrVariancePresent(pFormat
))
471 pStubMsg
->Offset
= 0;
472 pStubMsg
->ActualCount
= pStubMsg
->MaxCount
;
476 align_pointer(&pStubMsg
->Buffer
, 4);
477 if (pStubMsg
->Buffer
+ 8 > pStubMsg
->BufferEnd
)
478 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
479 pStubMsg
->Offset
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
480 pStubMsg
->Buffer
+= 4;
481 TRACE("offset is %d\n", pStubMsg
->Offset
);
482 pStubMsg
->ActualCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
483 pStubMsg
->Buffer
+= 4;
484 TRACE("variance is %d\n", pStubMsg
->ActualCount
);
486 if ((pStubMsg
->ActualCount
> MaxValue
) ||
487 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> MaxValue
))
489 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
490 pStubMsg
->ActualCount
, pStubMsg
->Offset
, MaxValue
);
491 RpcRaiseException(RPC_S_INVALID_BOUND
);
496 return SkipConformance(pStubMsg
, pFormat
);
499 /* writes the conformance value to the buffer */
500 static inline void WriteConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
502 align_pointer_clear(&pStubMsg
->Buffer
, 4);
503 if (pStubMsg
->Buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
504 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
505 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->MaxCount
);
506 pStubMsg
->Buffer
+= 4;
509 /* writes the variance values to the buffer */
510 static inline void WriteVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
512 align_pointer_clear(&pStubMsg
->Buffer
, 4);
513 if (pStubMsg
->Buffer
+ 8 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
514 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
515 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->Offset
);
516 pStubMsg
->Buffer
+= 4;
517 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->ActualCount
);
518 pStubMsg
->Buffer
+= 4;
521 /* requests buffer space for the conformance value */
522 static inline void SizeConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
524 align_length(&pStubMsg
->BufferLength
, 4);
525 if (pStubMsg
->BufferLength
+ 4 < pStubMsg
->BufferLength
)
526 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
527 pStubMsg
->BufferLength
+= 4;
530 /* requests buffer space for the variance values */
531 static inline void SizeVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
533 align_length(&pStubMsg
->BufferLength
, 4);
534 if (pStubMsg
->BufferLength
+ 8 < pStubMsg
->BufferLength
)
535 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
536 pStubMsg
->BufferLength
+= 8;
539 PFORMAT_STRING
ComputeConformanceOrVariance(
540 MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *pMemory
,
541 PFORMAT_STRING pFormat
, ULONG_PTR def
, ULONG_PTR
*pCount
)
543 BYTE dtype
= pFormat
[0] & 0xf;
544 short ofs
= *(const short *)&pFormat
[2];
548 if (!IsConformanceOrVariancePresent(pFormat
)) {
549 /* null descriptor */
554 switch (pFormat
[0] & 0xf0) {
555 case FC_NORMAL_CONFORMANCE
:
556 TRACE("normal conformance, ofs=%d\n", ofs
);
559 case FC_POINTER_CONFORMANCE
:
560 TRACE("pointer conformance, ofs=%d\n", ofs
);
561 ptr
= pStubMsg
->Memory
;
563 case FC_TOP_LEVEL_CONFORMANCE
:
564 TRACE("toplevel conformance, ofs=%d\n", ofs
);
565 if (pStubMsg
->StackTop
) {
566 ptr
= pStubMsg
->StackTop
;
569 /* -Os mode, *pCount is already set */
573 case FC_CONSTANT_CONFORMANCE
:
574 data
= ofs
| ((DWORD
)pFormat
[1] << 16);
575 TRACE("constant conformance, val=%ld\n", data
);
578 case FC_TOP_LEVEL_MULTID_CONFORMANCE
:
579 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs
);
580 if (pStubMsg
->StackTop
) {
581 ptr
= pStubMsg
->StackTop
;
589 FIXME("unknown conformance type %x, expect crash.\n", pFormat
[0] & 0xf0);
593 switch (pFormat
[1]) {
595 ptr
= *(LPVOID
*)((char *)ptr
+ ofs
);
599 unsigned char *old_stack_top
= pStubMsg
->StackTop
;
600 ULONG_PTR max_count
, old_max_count
= pStubMsg
->MaxCount
;
602 pStubMsg
->StackTop
= ptr
;
604 /* ofs is index into StubDesc->apfnExprEval */
605 TRACE("callback conformance into apfnExprEval[%d]\n", ofs
);
606 pStubMsg
->StubDesc
->apfnExprEval
[ofs
](pStubMsg
);
608 pStubMsg
->StackTop
= old_stack_top
;
610 /* the callback function always stores the computed value in MaxCount */
611 max_count
= pStubMsg
->MaxCount
;
612 pStubMsg
->MaxCount
= old_max_count
;
617 ptr
= (char *)ptr
+ ofs
;
630 data
= *(USHORT
*)ptr
;
641 data
= *(ULONGLONG
*)ptr
;
644 FIXME("unknown conformance data type %x\n", dtype
);
647 TRACE("dereferenced data type %x at %p, got %ld\n", dtype
, ptr
, data
);
650 switch (pFormat
[1]) {
651 case FC_DEREFERENCE
: /* already handled */
668 FIXME("unknown conformance op %d\n", pFormat
[1]);
673 TRACE("resulting conformance is %ld\n", *pCount
);
675 return SkipConformance(pStubMsg
, pFormat
);
678 static inline PFORMAT_STRING
SkipVariance(PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
680 return SkipConformance( pStubMsg
, pFormat
);
683 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
684 * the result overflows 32-bits */
685 static inline ULONG
safe_multiply(ULONG a
, ULONG b
)
687 ULONGLONG ret
= (ULONGLONG
)a
* b
;
688 if (ret
> 0xffffffff)
690 RpcRaiseException(RPC_S_INVALID_BOUND
);
696 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
698 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
699 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
700 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
701 pStubMsg
->Buffer
+= size
;
704 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
706 if (pStubMsg
->BufferLength
+ size
< pStubMsg
->BufferLength
) /* integer overflow of pStubMsg->BufferSize */
708 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
709 pStubMsg
->BufferLength
, size
);
710 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
712 pStubMsg
->BufferLength
+= size
;
715 /* copies data from the buffer, checking that there is enough data in the buffer
717 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, void *p
, ULONG size
)
719 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
720 (pStubMsg
->Buffer
+ size
> pStubMsg
->BufferEnd
))
722 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
723 pStubMsg
->Buffer
, pStubMsg
->BufferEnd
, size
);
724 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
726 if (p
== pStubMsg
->Buffer
)
727 ERR("pointer is the same as the buffer\n");
728 memcpy(p
, pStubMsg
->Buffer
, size
);
729 pStubMsg
->Buffer
+= size
;
732 /* copies data to the buffer, checking that there is enough space to do so */
733 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, const void *p
, ULONG size
)
735 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
736 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
738 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
739 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
,
741 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
743 memcpy(pStubMsg
->Buffer
, p
, size
);
744 pStubMsg
->Buffer
+= size
;
747 /* verify that string data sitting in the buffer is valid and safe to
749 static void validate_string_data(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG bufsize
, ULONG esize
)
753 /* verify the buffer is safe to access */
754 if ((pStubMsg
->Buffer
+ bufsize
< pStubMsg
->Buffer
) ||
755 (pStubMsg
->Buffer
+ bufsize
> pStubMsg
->BufferEnd
))
757 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize
,
758 pStubMsg
->BufferEnd
, pStubMsg
->Buffer
);
759 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
762 /* strings must always have null terminating bytes */
765 ERR("invalid string length of %d\n", bufsize
/ esize
);
766 RpcRaiseException(RPC_S_INVALID_BOUND
);
769 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
770 if (pStubMsg
->Buffer
[i
] != 0)
772 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
773 i
, pStubMsg
->Buffer
[i
]);
774 RpcRaiseException(RPC_S_INVALID_BOUND
);
778 static inline void dump_pointer_attr(unsigned char attr
)
780 if (attr
& FC_ALLOCATE_ALL_NODES
)
781 TRACE(" FC_ALLOCATE_ALL_NODES");
782 if (attr
& FC_DONT_FREE
)
783 TRACE(" FC_DONT_FREE");
784 if (attr
& FC_ALLOCED_ON_STACK
)
785 TRACE(" FC_ALLOCED_ON_STACK");
786 if (attr
& FC_SIMPLE_POINTER
)
787 TRACE(" FC_SIMPLE_POINTER");
788 if (attr
& FC_POINTER_DEREF
)
789 TRACE(" FC_POINTER_DEREF");
793 /***********************************************************************
794 * PointerMarshall [internal]
796 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
797 unsigned char *Buffer
,
798 unsigned char *Pointer
,
799 PFORMAT_STRING pFormat
)
801 unsigned type
= pFormat
[0], attr
= pFormat
[1];
805 BOOL pointer_needs_marshaling
;
807 TRACE("(%p,%p,%p,%p)\n", pStubMsg
, Buffer
, Pointer
, pFormat
);
808 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
810 if (attr
& FC_SIMPLE_POINTER
) desc
= pFormat
;
811 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
814 case FC_RP
: /* ref pointer (always non-null) */
817 ERR("NULL ref pointer is not allowed\n");
818 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
820 pointer_needs_marshaling
= TRUE
;
822 case FC_UP
: /* unique pointer */
823 case FC_OP
: /* object pointer - same as unique here */
825 pointer_needs_marshaling
= TRUE
;
827 pointer_needs_marshaling
= FALSE
;
828 pointer_id
= Pointer
? NDR_POINTER_ID(pStubMsg
) : 0;
829 TRACE("writing 0x%08x to buffer\n", pointer_id
);
830 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
833 pointer_needs_marshaling
= !NdrFullPointerQueryPointer(
834 pStubMsg
->FullPtrXlatTables
, Pointer
, 1, &pointer_id
);
835 TRACE("writing 0x%08x to buffer\n", pointer_id
);
836 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
839 FIXME("unhandled ptr type=%02x\n", type
);
840 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
844 TRACE("calling marshaller for type 0x%x\n", (int)*desc
);
846 if (pointer_needs_marshaling
) {
847 if (attr
& FC_POINTER_DEREF
) {
848 Pointer
= *(unsigned char**)Pointer
;
849 TRACE("deref => %p\n", Pointer
);
851 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
852 if (m
) m(pStubMsg
, Pointer
, desc
);
853 else FIXME("no marshaller for data type=%02x\n", *desc
);
856 STD_OVERFLOW_CHECK(pStubMsg
);
859 /***********************************************************************
860 * PointerUnmarshall [internal]
862 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
863 unsigned char *Buffer
,
864 unsigned char **pPointer
,
865 unsigned char *pSrcPointer
,
866 PFORMAT_STRING pFormat
,
867 unsigned char fMustAlloc
)
869 unsigned type
= pFormat
[0], attr
= pFormat
[1];
872 DWORD pointer_id
= 0;
873 BOOL pointer_needs_unmarshaling
;
875 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg
, Buffer
, pPointer
, pSrcPointer
, pFormat
, fMustAlloc
);
876 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
878 if (attr
& FC_SIMPLE_POINTER
) desc
= pFormat
;
879 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
882 case FC_RP
: /* ref pointer (always non-null) */
883 pointer_needs_unmarshaling
= TRUE
;
885 case FC_UP
: /* unique pointer */
886 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
887 TRACE("pointer_id is 0x%08x\n", pointer_id
);
889 pointer_needs_unmarshaling
= TRUE
;
892 pointer_needs_unmarshaling
= FALSE
;
895 case FC_OP
: /* object pointer - we must free data before overwriting it */
896 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
897 TRACE("pointer_id is 0x%08x\n", pointer_id
);
898 if (!fMustAlloc
&& pSrcPointer
)
900 FIXME("free object pointer %p\n", pSrcPointer
);
904 pointer_needs_unmarshaling
= TRUE
;
908 pointer_needs_unmarshaling
= FALSE
;
912 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
913 TRACE("pointer_id is 0x%08x\n", pointer_id
);
914 pointer_needs_unmarshaling
= !NdrFullPointerQueryRefId(
915 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, (void **)pPointer
);
918 FIXME("unhandled ptr type=%02x\n", type
);
919 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
923 if (pointer_needs_unmarshaling
) {
924 unsigned char **current_ptr
= pPointer
;
925 if (pStubMsg
->IsClient
) {
927 /* if we aren't forcing allocation of memory then try to use the existing
928 * (source) pointer to unmarshall the data into so that [in,out]
929 * parameters behave correctly. it doesn't matter if the parameter is
930 * [out] only since in that case the pointer will be NULL. we force
931 * allocation when the source pointer is NULL here instead of in the type
932 * unmarshalling routine for the benefit of the deref code below */
935 TRACE("setting *pPointer to %p\n", pSrcPointer
);
936 *pPointer
= pSrcPointer
;
942 /* the memory in a stub is never initialised, so we have to work out here
943 * whether we have to initialise it so we can use the optimisation of
944 * setting the pointer to the buffer, if possible, or set fMustAlloc to
946 if (attr
& FC_POINTER_DEREF
) {
953 if (attr
& FC_ALLOCATE_ALL_NODES
)
954 FIXME("FC_ALLOCATE_ALL_NODES not implemented\n");
956 if (attr
& FC_POINTER_DEREF
) {
958 unsigned char *base_ptr_val
= NdrAllocate(pStubMsg
, sizeof(void *));
959 *pPointer
= base_ptr_val
;
960 current_ptr
= (unsigned char **)base_ptr_val
;
962 current_ptr
= *(unsigned char***)current_ptr
;
963 TRACE("deref => %p\n", current_ptr
);
964 if (!fMustAlloc
&& !*current_ptr
) fMustAlloc
= TRUE
;
966 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
967 if (m
) m(pStubMsg
, current_ptr
, desc
, fMustAlloc
);
968 else FIXME("no unmarshaller for data type=%02x\n", *desc
);
971 NdrFullPointerInsertRefId(pStubMsg
->FullPtrXlatTables
, pointer_id
,
975 TRACE("pointer=%p\n", *pPointer
);
978 /***********************************************************************
979 * PointerBufferSize [internal]
981 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
982 unsigned char *Pointer
,
983 PFORMAT_STRING pFormat
)
985 unsigned type
= pFormat
[0], attr
= pFormat
[1];
988 BOOL pointer_needs_sizing
;
991 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
992 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
994 if (attr
& FC_SIMPLE_POINTER
) desc
= pFormat
;
995 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
998 case FC_RP
: /* ref pointer (always non-null) */
1001 ERR("NULL ref pointer is not allowed\n");
1002 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
1007 /* NULL pointer has no further representation */
1012 pointer_needs_sizing
= !NdrFullPointerQueryPointer(
1013 pStubMsg
->FullPtrXlatTables
, Pointer
, 0, &pointer_id
);
1014 if (!pointer_needs_sizing
)
1018 FIXME("unhandled ptr type=%02x\n", type
);
1019 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1023 if (attr
& FC_POINTER_DEREF
) {
1024 Pointer
= *(unsigned char**)Pointer
;
1025 TRACE("deref => %p\n", Pointer
);
1028 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
1029 if (m
) m(pStubMsg
, Pointer
, desc
);
1030 else FIXME("no buffersizer for data type=%02x\n", *desc
);
1033 /***********************************************************************
1034 * PointerMemorySize [internal]
1036 static ULONG
PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1037 unsigned char *Buffer
, PFORMAT_STRING pFormat
)
1039 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1040 PFORMAT_STRING desc
;
1042 DWORD pointer_id
= 0;
1043 BOOL pointer_needs_sizing
;
1045 TRACE("(%p,%p,%p)\n", pStubMsg
, Buffer
, pFormat
);
1046 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1048 if (attr
& FC_SIMPLE_POINTER
) desc
= pFormat
;
1049 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1052 case FC_RP
: /* ref pointer (always non-null) */
1053 pointer_needs_sizing
= TRUE
;
1055 case FC_UP
: /* unique pointer */
1056 case FC_OP
: /* object pointer - we must free data before overwriting it */
1057 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1058 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1060 pointer_needs_sizing
= TRUE
;
1062 pointer_needs_sizing
= FALSE
;
1067 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1068 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1069 pointer_needs_sizing
= !NdrFullPointerQueryRefId(
1070 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, &pointer
);
1074 FIXME("unhandled ptr type=%02x\n", type
);
1075 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1079 if (attr
& FC_POINTER_DEREF
) {
1080 align_length(&pStubMsg
->MemorySize
, sizeof(void*));
1081 pStubMsg
->MemorySize
+= sizeof(void*);
1085 if (pointer_needs_sizing
) {
1086 m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
1087 if (m
) m(pStubMsg
, desc
);
1088 else FIXME("no memorysizer for data type=%02x\n", *desc
);
1091 return pStubMsg
->MemorySize
;
1094 /***********************************************************************
1095 * PointerFree [internal]
1097 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1098 unsigned char *Pointer
,
1099 PFORMAT_STRING pFormat
)
1101 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1102 PFORMAT_STRING desc
;
1104 unsigned char *current_pointer
= Pointer
;
1106 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1107 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1108 if (attr
& FC_DONT_FREE
) return;
1110 if (attr
& FC_SIMPLE_POINTER
) desc
= pFormat
;
1111 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1113 if (!Pointer
) return;
1115 if (type
== FC_FP
) {
1116 int pointer_needs_freeing
= NdrFullPointerFree(
1117 pStubMsg
->FullPtrXlatTables
, Pointer
);
1118 if (!pointer_needs_freeing
)
1122 if (attr
& FC_POINTER_DEREF
) {
1123 current_pointer
= *(unsigned char**)Pointer
;
1124 TRACE("deref => %p\n", current_pointer
);
1127 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
1128 if (m
) m(pStubMsg
, current_pointer
, desc
);
1130 /* this check stops us from trying to free buffer memory. we don't have to
1131 * worry about clients, since they won't call this function.
1132 * we don't have to check for the buffer being reallocated because
1133 * BufferStart and BufferEnd won't be reset when allocating memory for
1134 * sending the response. we don't have to check for the new buffer here as
1135 * it won't be used a type memory, only for buffer memory */
1136 if (Pointer
>= pStubMsg
->BufferStart
&& Pointer
<= pStubMsg
->BufferEnd
)
1139 if (attr
& FC_ALLOCED_ON_STACK
) {
1140 TRACE("not freeing stack ptr %p\n", Pointer
);
1143 TRACE("freeing %p\n", Pointer
);
1144 NdrFree(pStubMsg
, Pointer
);
1147 TRACE("not freeing %p\n", Pointer
);
1150 /***********************************************************************
1151 * EmbeddedPointerMarshall
1153 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1154 unsigned char *pMemory
,
1155 PFORMAT_STRING pFormat
)
1157 unsigned char *Mark
= pStubMsg
->BufferMark
;
1158 unsigned rep
, count
, stride
;
1160 unsigned char *saved_buffer
= NULL
;
1162 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1164 if (*pFormat
!= FC_PP
) return NULL
;
1167 if (pStubMsg
->PointerBufferMark
)
1169 saved_buffer
= pStubMsg
->Buffer
;
1170 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1171 pStubMsg
->PointerBufferMark
= NULL
;
1174 while (pFormat
[0] != FC_END
) {
1175 switch (pFormat
[0]) {
1177 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat
[0]);
1185 case FC_FIXED_REPEAT
:
1186 rep
= *(const WORD
*)&pFormat
[2];
1187 stride
= *(const WORD
*)&pFormat
[4];
1188 count
= *(const WORD
*)&pFormat
[8];
1191 case FC_VARIABLE_REPEAT
:
1192 rep
= (pFormat
[1] == FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1193 stride
= *(const WORD
*)&pFormat
[2];
1194 count
= *(const WORD
*)&pFormat
[6];
1198 for (i
= 0; i
< rep
; i
++) {
1199 PFORMAT_STRING info
= pFormat
;
1200 unsigned char *membase
= pMemory
+ (i
* stride
);
1201 unsigned char *bufbase
= Mark
+ (i
* stride
);
1204 for (u
=0; u
<count
; u
++,info
+=8) {
1205 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1206 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1207 unsigned char *saved_memory
= pStubMsg
->Memory
;
1209 pStubMsg
->Memory
= membase
;
1210 PointerMarshall(pStubMsg
, bufptr
, *(unsigned char**)memptr
, info
+4);
1211 pStubMsg
->Memory
= saved_memory
;
1214 pFormat
+= 8 * count
;
1219 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1220 pStubMsg
->Buffer
= saved_buffer
;
1223 STD_OVERFLOW_CHECK(pStubMsg
);
1228 /***********************************************************************
1229 * EmbeddedPointerUnmarshall
1231 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1232 unsigned char *pDstBuffer
,
1233 unsigned char *pSrcMemoryPtrs
,
1234 PFORMAT_STRING pFormat
,
1235 unsigned char fMustAlloc
)
1237 unsigned char *Mark
= pStubMsg
->BufferMark
;
1238 unsigned rep
, count
, stride
;
1240 unsigned char *saved_buffer
= NULL
;
1242 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg
, pDstBuffer
, pSrcMemoryPtrs
, pFormat
, fMustAlloc
);
1244 if (*pFormat
!= FC_PP
) return NULL
;
1247 if (pStubMsg
->PointerBufferMark
)
1249 saved_buffer
= pStubMsg
->Buffer
;
1250 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1251 pStubMsg
->PointerBufferMark
= NULL
;
1254 while (pFormat
[0] != FC_END
) {
1255 TRACE("pFormat[0] = 0x%x\n", pFormat
[0]);
1256 switch (pFormat
[0]) {
1258 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat
[0]);
1266 case FC_FIXED_REPEAT
:
1267 rep
= *(const WORD
*)&pFormat
[2];
1268 stride
= *(const WORD
*)&pFormat
[4];
1269 count
= *(const WORD
*)&pFormat
[8];
1272 case FC_VARIABLE_REPEAT
:
1273 rep
= (pFormat
[1] == FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1274 stride
= *(const WORD
*)&pFormat
[2];
1275 count
= *(const WORD
*)&pFormat
[6];
1279 for (i
= 0; i
< rep
; i
++) {
1280 PFORMAT_STRING info
= pFormat
;
1281 unsigned char *bufdstbase
= pDstBuffer
+ (i
* stride
);
1282 unsigned char *memsrcbase
= pSrcMemoryPtrs
+ (i
* stride
);
1283 unsigned char *bufbase
= Mark
+ (i
* stride
);
1286 for (u
=0; u
<count
; u
++,info
+=8) {
1287 unsigned char **bufdstptr
= (unsigned char **)(bufdstbase
+ *(const SHORT
*)&info
[2]);
1288 unsigned char **memsrcptr
= (unsigned char **)(memsrcbase
+ *(const SHORT
*)&info
[0]);
1289 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1290 PointerUnmarshall(pStubMsg
, bufptr
, bufdstptr
, *memsrcptr
, info
+4, fMustAlloc
);
1293 pFormat
+= 8 * count
;
1298 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1299 pStubMsg
->Buffer
= saved_buffer
;
1305 /***********************************************************************
1306 * EmbeddedPointerBufferSize
1308 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1309 unsigned char *pMemory
,
1310 PFORMAT_STRING pFormat
)
1312 unsigned rep
, count
, stride
;
1314 ULONG saved_buffer_length
= 0;
1316 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1318 if (pStubMsg
->IgnoreEmbeddedPointers
) return;
1320 if (*pFormat
!= FC_PP
) return;
1323 if (pStubMsg
->PointerLength
)
1325 saved_buffer_length
= pStubMsg
->BufferLength
;
1326 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
1327 pStubMsg
->PointerLength
= 0;
1330 while (pFormat
[0] != FC_END
) {
1331 switch (pFormat
[0]) {
1333 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat
[0]);
1341 case FC_FIXED_REPEAT
:
1342 rep
= *(const WORD
*)&pFormat
[2];
1343 stride
= *(const WORD
*)&pFormat
[4];
1344 count
= *(const WORD
*)&pFormat
[8];
1347 case FC_VARIABLE_REPEAT
:
1348 rep
= (pFormat
[1] == FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1349 stride
= *(const WORD
*)&pFormat
[2];
1350 count
= *(const WORD
*)&pFormat
[6];
1354 for (i
= 0; i
< rep
; i
++) {
1355 PFORMAT_STRING info
= pFormat
;
1356 unsigned char *membase
= pMemory
+ (i
* stride
);
1359 for (u
=0; u
<count
; u
++,info
+=8) {
1360 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1361 unsigned char *saved_memory
= pStubMsg
->Memory
;
1363 pStubMsg
->Memory
= membase
;
1364 PointerBufferSize(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1365 pStubMsg
->Memory
= saved_memory
;
1368 pFormat
+= 8 * count
;
1371 if (saved_buffer_length
)
1373 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
1374 pStubMsg
->BufferLength
= saved_buffer_length
;
1378 /***********************************************************************
1379 * EmbeddedPointerMemorySize [internal]
1381 static ULONG
EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1382 PFORMAT_STRING pFormat
)
1384 unsigned char *Mark
= pStubMsg
->BufferMark
;
1385 unsigned rep
, count
, stride
;
1387 unsigned char *saved_buffer
= NULL
;
1389 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1391 if (pStubMsg
->IgnoreEmbeddedPointers
) return 0;
1393 if (pStubMsg
->PointerBufferMark
)
1395 saved_buffer
= pStubMsg
->Buffer
;
1396 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1397 pStubMsg
->PointerBufferMark
= NULL
;
1400 if (*pFormat
!= FC_PP
) return 0;
1403 while (pFormat
[0] != FC_END
) {
1404 switch (pFormat
[0]) {
1406 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat
[0]);
1414 case FC_FIXED_REPEAT
:
1415 rep
= *(const WORD
*)&pFormat
[2];
1416 stride
= *(const WORD
*)&pFormat
[4];
1417 count
= *(const WORD
*)&pFormat
[8];
1420 case FC_VARIABLE_REPEAT
:
1421 rep
= (pFormat
[1] == FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1422 stride
= *(const WORD
*)&pFormat
[2];
1423 count
= *(const WORD
*)&pFormat
[6];
1427 for (i
= 0; i
< rep
; i
++) {
1428 PFORMAT_STRING info
= pFormat
;
1429 unsigned char *bufbase
= Mark
+ (i
* stride
);
1431 for (u
=0; u
<count
; u
++,info
+=8) {
1432 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1433 PointerMemorySize(pStubMsg
, bufptr
, info
+4);
1436 pFormat
+= 8 * count
;
1441 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1442 pStubMsg
->Buffer
= saved_buffer
;
1448 /***********************************************************************
1449 * EmbeddedPointerFree [internal]
1451 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1452 unsigned char *pMemory
,
1453 PFORMAT_STRING pFormat
)
1455 unsigned rep
, count
, stride
;
1458 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1459 if (*pFormat
!= FC_PP
) return;
1462 while (pFormat
[0] != FC_END
) {
1463 switch (pFormat
[0]) {
1465 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat
[0]);
1473 case FC_FIXED_REPEAT
:
1474 rep
= *(const WORD
*)&pFormat
[2];
1475 stride
= *(const WORD
*)&pFormat
[4];
1476 count
= *(const WORD
*)&pFormat
[8];
1479 case FC_VARIABLE_REPEAT
:
1480 rep
= (pFormat
[1] == FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1481 stride
= *(const WORD
*)&pFormat
[2];
1482 count
= *(const WORD
*)&pFormat
[6];
1486 for (i
= 0; i
< rep
; i
++) {
1487 PFORMAT_STRING info
= pFormat
;
1488 unsigned char *membase
= pMemory
+ (i
* stride
);
1491 for (u
=0; u
<count
; u
++,info
+=8) {
1492 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1493 unsigned char *saved_memory
= pStubMsg
->Memory
;
1495 pStubMsg
->Memory
= membase
;
1496 PointerFree(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1497 pStubMsg
->Memory
= saved_memory
;
1500 pFormat
+= 8 * count
;
1504 /***********************************************************************
1505 * NdrPointerMarshall [RPCRT4.@]
1507 unsigned char * WINAPI
NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1508 unsigned char *pMemory
,
1509 PFORMAT_STRING pFormat
)
1511 unsigned char *Buffer
;
1513 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1515 /* Increment the buffer here instead of in PointerMarshall,
1516 * as that is used by embedded pointers which already handle the incrementing
1517 * the buffer, and shouldn't write any additional pointer data to the wire */
1518 if (*pFormat
!= FC_RP
)
1520 align_pointer_clear(&pStubMsg
->Buffer
, 4);
1521 Buffer
= pStubMsg
->Buffer
;
1522 safe_buffer_increment(pStubMsg
, 4);
1525 Buffer
= pStubMsg
->Buffer
;
1527 PointerMarshall(pStubMsg
, Buffer
, pMemory
, pFormat
);
1532 /***********************************************************************
1533 * NdrPointerUnmarshall [RPCRT4.@]
1535 unsigned char * WINAPI
NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1536 unsigned char **ppMemory
,
1537 PFORMAT_STRING pFormat
,
1538 unsigned char fMustAlloc
)
1540 unsigned char *Buffer
;
1542 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1544 if (*pFormat
== FC_RP
)
1546 Buffer
= pStubMsg
->Buffer
;
1547 /* Do the NULL ref pointer check here because embedded pointers can be
1548 * NULL if the type the pointer is embedded in was allocated rather than
1549 * being passed in by the client */
1550 if (pStubMsg
->IsClient
&& !*ppMemory
)
1552 ERR("NULL ref pointer is not allowed\n");
1553 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
1558 /* Increment the buffer here instead of in PointerUnmarshall,
1559 * as that is used by embedded pointers which already handle the incrementing
1560 * the buffer, and shouldn't read any additional pointer data from the
1562 align_pointer(&pStubMsg
->Buffer
, 4);
1563 Buffer
= pStubMsg
->Buffer
;
1564 safe_buffer_increment(pStubMsg
, 4);
1567 PointerUnmarshall(pStubMsg
, Buffer
, ppMemory
, *ppMemory
, pFormat
, fMustAlloc
);
1572 /***********************************************************************
1573 * NdrPointerBufferSize [RPCRT4.@]
1575 void WINAPI
NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1576 unsigned char *pMemory
,
1577 PFORMAT_STRING pFormat
)
1579 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1581 /* Increment the buffer length here instead of in PointerBufferSize,
1582 * as that is used by embedded pointers which already handle the buffer
1583 * length, and shouldn't write anything more to the wire */
1584 if (*pFormat
!= FC_RP
)
1586 align_length(&pStubMsg
->BufferLength
, 4);
1587 safe_buffer_length_increment(pStubMsg
, 4);
1590 PointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1593 /***********************************************************************
1594 * NdrPointerMemorySize [RPCRT4.@]
1596 ULONG WINAPI
NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1597 PFORMAT_STRING pFormat
)
1599 unsigned char *Buffer
= pStubMsg
->Buffer
;
1600 if (*pFormat
!= FC_RP
)
1602 align_pointer(&pStubMsg
->Buffer
, 4);
1603 safe_buffer_increment(pStubMsg
, 4);
1605 align_length(&pStubMsg
->MemorySize
, sizeof(void *));
1606 return PointerMemorySize(pStubMsg
, Buffer
, pFormat
);
1609 /***********************************************************************
1610 * NdrPointerFree [RPCRT4.@]
1612 void WINAPI
NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1613 unsigned char *pMemory
,
1614 PFORMAT_STRING pFormat
)
1616 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1617 PointerFree(pStubMsg
, pMemory
, pFormat
);
1620 /***********************************************************************
1621 * NdrSimpleTypeMarshall [RPCRT4.@]
1623 void WINAPI
NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1624 unsigned char FormatChar
)
1626 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &FormatChar
);
1629 /***********************************************************************
1630 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1632 * Unmarshall a base type.
1635 * Doesn't check that the buffer is long enough before copying, so the caller
1638 void WINAPI
NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1639 unsigned char FormatChar
)
1641 #define BASE_TYPE_UNMARSHALL(type) \
1642 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
1643 TRACE("pMemory: %p\n", pMemory); \
1644 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1645 pStubMsg->Buffer += sizeof(type);
1653 BASE_TYPE_UNMARSHALL(UCHAR
);
1654 TRACE("value: 0x%02x\n", *pMemory
);
1659 BASE_TYPE_UNMARSHALL(USHORT
);
1660 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
1664 case FC_ERROR_STATUS_T
:
1666 BASE_TYPE_UNMARSHALL(ULONG
);
1667 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
1670 BASE_TYPE_UNMARSHALL(float);
1671 TRACE("value: %f\n", *(float *)pMemory
);
1674 BASE_TYPE_UNMARSHALL(double);
1675 TRACE("value: %f\n", *(double *)pMemory
);
1678 BASE_TYPE_UNMARSHALL(ULONGLONG
);
1679 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
1682 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
1683 TRACE("pMemory: %p\n", pMemory
);
1684 /* 16-bits on the wire, but int in memory */
1685 *(UINT
*)pMemory
= *(USHORT
*)pStubMsg
->Buffer
;
1686 pStubMsg
->Buffer
+= sizeof(USHORT
);
1687 TRACE("value: 0x%08x\n", *(UINT
*)pMemory
);
1690 align_pointer(&pStubMsg
->Buffer
, sizeof(INT
));
1691 /* 32-bits on the wire, but int_ptr in memory */
1692 *(INT_PTR
*)pMemory
= *(INT
*)pStubMsg
->Buffer
;
1693 pStubMsg
->Buffer
+= sizeof(INT
);
1694 TRACE("value: 0x%08lx\n", *(INT_PTR
*)pMemory
);
1697 align_pointer(&pStubMsg
->Buffer
, sizeof(UINT
));
1698 /* 32-bits on the wire, but int_ptr in memory */
1699 *(UINT_PTR
*)pMemory
= *(UINT
*)pStubMsg
->Buffer
;
1700 pStubMsg
->Buffer
+= sizeof(UINT
);
1701 TRACE("value: 0x%08lx\n", *(UINT_PTR
*)pMemory
);
1706 FIXME("Unhandled base type: 0x%02x\n", FormatChar
);
1708 #undef BASE_TYPE_UNMARSHALL
1711 /***********************************************************************
1712 * NdrSimpleStructMarshall [RPCRT4.@]
1714 unsigned char * WINAPI
NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1715 unsigned char *pMemory
,
1716 PFORMAT_STRING pFormat
)
1718 unsigned size
= *(const WORD
*)(pFormat
+2);
1719 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1721 align_pointer_clear(&pStubMsg
->Buffer
, pFormat
[1] + 1);
1723 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1724 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
1726 if (pFormat
[0] != FC_STRUCT
)
1727 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
+4);
1732 /***********************************************************************
1733 * NdrSimpleStructUnmarshall [RPCRT4.@]
1735 unsigned char * WINAPI
NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1736 unsigned char **ppMemory
,
1737 PFORMAT_STRING pFormat
,
1738 unsigned char fMustAlloc
)
1740 unsigned size
= *(const WORD
*)(pFormat
+2);
1741 unsigned char *saved_buffer
;
1742 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1744 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
1747 *ppMemory
= NdrAllocate(pStubMsg
, size
);
1750 if (!pStubMsg
->IsClient
&& !*ppMemory
)
1751 /* for servers, we just point straight into the RPC buffer */
1752 *ppMemory
= pStubMsg
->Buffer
;
1755 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1756 safe_buffer_increment(pStubMsg
, size
);
1757 if (pFormat
[0] == FC_PSTRUCT
)
1758 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
+4, fMustAlloc
);
1760 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
1761 if (*ppMemory
!= saved_buffer
)
1762 memcpy(*ppMemory
, saved_buffer
, size
);
1767 /***********************************************************************
1768 * NdrSimpleStructBufferSize [RPCRT4.@]
1770 void WINAPI
NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1771 unsigned char *pMemory
,
1772 PFORMAT_STRING pFormat
)
1774 unsigned size
= *(const WORD
*)(pFormat
+2);
1775 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1777 align_length(&pStubMsg
->BufferLength
, pFormat
[1] + 1);
1779 safe_buffer_length_increment(pStubMsg
, size
);
1780 if (pFormat
[0] != FC_STRUCT
)
1781 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
+4);
1784 /***********************************************************************
1785 * NdrSimpleStructMemorySize [RPCRT4.@]
1787 ULONG WINAPI
NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1788 PFORMAT_STRING pFormat
)
1790 unsigned short size
= *(const WORD
*)(pFormat
+2);
1792 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1794 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
1795 pStubMsg
->MemorySize
+= size
;
1796 safe_buffer_increment(pStubMsg
, size
);
1798 if (pFormat
[0] != FC_STRUCT
)
1799 EmbeddedPointerMemorySize(pStubMsg
, pFormat
+4);
1800 return pStubMsg
->MemorySize
;
1803 /***********************************************************************
1804 * NdrSimpleStructFree [RPCRT4.@]
1806 void WINAPI
NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
1807 unsigned char *pMemory
,
1808 PFORMAT_STRING pFormat
)
1810 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1811 if (pFormat
[0] != FC_STRUCT
)
1812 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
+4);
1817 static inline void array_compute_and_size_conformance(
1818 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1819 PFORMAT_STRING pFormat
)
1826 ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1827 SizeConformance(pStubMsg
);
1830 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, 0);
1831 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
1832 SizeConformance(pStubMsg
);
1836 if (fc
== FC_C_CSTRING
)
1838 TRACE("string=%s\n", debugstr_a((const char *)pMemory
));
1839 pStubMsg
->ActualCount
= strlen((const char *)pMemory
)+1;
1843 TRACE("string=%s\n", debugstr_w((LPCWSTR
)pMemory
));
1844 pStubMsg
->ActualCount
= strlenW((LPCWSTR
)pMemory
)+1;
1847 if (pFormat
[1] == FC_STRING_SIZED
)
1848 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
1850 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
1852 SizeConformance(pStubMsg
);
1854 case FC_BOGUS_ARRAY
:
1855 count
= *(const WORD
*)(pFormat
+ 2);
1857 if (IsConformanceOrVariancePresent(pFormat
)) SizeConformance(pStubMsg
);
1858 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, count
);
1859 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
1862 ERR("unknown array format 0x%x\n", fc
);
1863 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1867 static inline void array_buffer_size(
1868 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1869 PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
1873 unsigned char alignment
;
1878 esize
= *(const WORD
*)(pFormat
+2);
1879 alignment
= pFormat
[1] + 1;
1881 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1883 align_length(&pStubMsg
->BufferLength
, alignment
);
1885 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
1886 /* conformance value plus array */
1887 safe_buffer_length_increment(pStubMsg
, size
);
1890 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1893 esize
= *(const WORD
*)(pFormat
+2);
1894 alignment
= pFormat
[1] + 1;
1896 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1897 pFormat
= SkipVariance(pStubMsg
, pFormat
);
1899 SizeVariance(pStubMsg
);
1901 align_length(&pStubMsg
->BufferLength
, alignment
);
1903 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1904 safe_buffer_length_increment(pStubMsg
, size
);
1907 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1911 if (fc
== FC_C_CSTRING
)
1916 SizeVariance(pStubMsg
);
1918 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1919 safe_buffer_length_increment(pStubMsg
, size
);
1921 case FC_BOGUS_ARRAY
:
1922 alignment
= pFormat
[1] + 1;
1923 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1924 if (IsConformanceOrVariancePresent(pFormat
)) SizeVariance(pStubMsg
);
1925 pFormat
= SkipVariance(pStubMsg
, pFormat
);
1927 align_length(&pStubMsg
->BufferLength
, alignment
);
1929 size
= pStubMsg
->ActualCount
;
1930 for (i
= 0; i
< size
; i
++)
1931 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
1934 ERR("unknown array format 0x%x\n", fc
);
1935 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1939 static inline void array_compute_and_write_conformance(
1940 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1941 PFORMAT_STRING pFormat
)
1944 BOOL conformance_present
;
1949 ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1950 WriteConformance(pStubMsg
);
1953 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, 0);
1954 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
1955 WriteConformance(pStubMsg
);
1959 if (fc
== FC_C_CSTRING
)
1961 TRACE("string=%s\n", debugstr_a((const char *)pMemory
));
1962 pStubMsg
->ActualCount
= strlen((const char *)pMemory
)+1;
1966 TRACE("string=%s\n", debugstr_w((LPCWSTR
)pMemory
));
1967 pStubMsg
->ActualCount
= strlenW((LPCWSTR
)pMemory
)+1;
1969 if (pFormat
[1] == FC_STRING_SIZED
)
1970 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
1972 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
1973 pStubMsg
->Offset
= 0;
1974 WriteConformance(pStubMsg
);
1976 case FC_BOGUS_ARRAY
:
1977 def
= *(const WORD
*)(pFormat
+ 2);
1979 conformance_present
= IsConformanceOrVariancePresent(pFormat
);
1980 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
1981 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
1982 if (conformance_present
) WriteConformance(pStubMsg
);
1985 ERR("unknown array format 0x%x\n", fc
);
1986 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1990 static inline void array_write_variance_and_marshall(
1991 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1992 PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
1996 unsigned char alignment
;
2001 esize
= *(const WORD
*)(pFormat
+2);
2002 alignment
= pFormat
[1] + 1;
2004 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2006 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
2008 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2010 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2011 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
2014 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2017 esize
= *(const WORD
*)(pFormat
+2);
2018 alignment
= pFormat
[1] + 1;
2020 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2021 pFormat
= SkipVariance(pStubMsg
, pFormat
);
2023 WriteVariance(pStubMsg
);
2025 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
2027 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2030 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2031 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, size
);
2034 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2038 if (fc
== FC_C_CSTRING
)
2043 WriteVariance(pStubMsg
);
2045 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2046 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
2048 case FC_BOGUS_ARRAY
:
2049 alignment
= pFormat
[1] + 1;
2050 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2051 if (IsConformanceOrVariancePresent(pFormat
)) WriteVariance(pStubMsg
);
2052 pFormat
= SkipVariance(pStubMsg
, pFormat
);
2054 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
2056 size
= pStubMsg
->ActualCount
;
2057 for (i
= 0; i
< size
; i
++)
2058 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
2061 ERR("unknown array format 0x%x\n", fc
);
2062 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2066 static inline ULONG
array_read_conformance(
2067 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
2074 esize
= *(const WORD
*)(pFormat
+2);
2075 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2076 return safe_multiply(esize
, pStubMsg
->MaxCount
);
2078 esize
= *(const WORD
*)(pFormat
+2);
2079 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2080 return safe_multiply(esize
, pStubMsg
->MaxCount
);
2083 if (fc
== FC_C_CSTRING
)
2088 if (pFormat
[1] == FC_STRING_SIZED
)
2089 ReadConformance(pStubMsg
, pFormat
+ 2);
2091 ReadConformance(pStubMsg
, NULL
);
2092 return safe_multiply(esize
, pStubMsg
->MaxCount
);
2093 case FC_BOGUS_ARRAY
:
2094 def
= *(const WORD
*)(pFormat
+ 2);
2096 if (IsConformanceOrVariancePresent(pFormat
)) pFormat
= ReadConformance(pStubMsg
, pFormat
);
2099 pStubMsg
->MaxCount
= def
;
2100 pFormat
= SkipConformance( pStubMsg
, pFormat
);
2102 pFormat
= SkipVariance( pStubMsg
, pFormat
);
2104 esize
= ComplexStructSize(pStubMsg
, pFormat
);
2105 return safe_multiply(pStubMsg
->MaxCount
, esize
);
2107 ERR("unknown array format 0x%x\n", fc
);
2108 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2112 static inline ULONG
array_read_variance_and_unmarshall(
2113 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char **ppMemory
,
2114 PFORMAT_STRING pFormat
, unsigned char fMustAlloc
,
2115 unsigned char fUseBufferMemoryServer
, unsigned char fUnmarshall
)
2117 ULONG bufsize
, memsize
;
2119 unsigned char alignment
;
2120 unsigned char *saved_buffer
, *pMemory
;
2121 ULONG i
, offset
, count
;
2126 esize
= *(const WORD
*)(pFormat
+2);
2127 alignment
= pFormat
[1] + 1;
2129 bufsize
= memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2131 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2133 align_pointer(&pStubMsg
->Buffer
, alignment
);
2138 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2141 if (fUseBufferMemoryServer
&& !pStubMsg
->IsClient
&& !*ppMemory
)
2142 /* for servers, we just point straight into the RPC buffer */
2143 *ppMemory
= pStubMsg
->Buffer
;
2146 saved_buffer
= pStubMsg
->Buffer
;
2147 safe_buffer_increment(pStubMsg
, bufsize
);
2149 pStubMsg
->BufferMark
= saved_buffer
;
2150 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
2152 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
2153 if (*ppMemory
!= saved_buffer
)
2154 memcpy(*ppMemory
, saved_buffer
, bufsize
);
2158 esize
= *(const WORD
*)(pFormat
+2);
2159 alignment
= pFormat
[1] + 1;
2161 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2163 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2165 align_pointer(&pStubMsg
->Buffer
, alignment
);
2167 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2168 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2172 offset
= pStubMsg
->Offset
;
2174 if (!fMustAlloc
&& !*ppMemory
)
2177 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2178 saved_buffer
= pStubMsg
->Buffer
;
2179 safe_buffer_increment(pStubMsg
, bufsize
);
2181 pStubMsg
->BufferMark
= saved_buffer
;
2182 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
,
2185 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
2190 if (fc
== FC_C_CSTRING
)
2195 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
2197 if (pFormat
[1] != FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
2199 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2200 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
2201 RpcRaiseException(RPC_S_INVALID_BOUND
);
2203 if (pStubMsg
->Offset
)
2205 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2206 RpcRaiseException(RPC_S_INVALID_BOUND
);
2209 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2210 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2212 validate_string_data(pStubMsg
, bufsize
, esize
);
2217 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2220 if (fUseBufferMemoryServer
&& !pStubMsg
->IsClient
&&
2221 !*ppMemory
&& (pStubMsg
->MaxCount
== pStubMsg
->ActualCount
))
2222 /* if the data in the RPC buffer is big enough, we just point
2223 * straight into it */
2224 *ppMemory
= pStubMsg
->Buffer
;
2225 else if (!*ppMemory
)
2226 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2229 if (*ppMemory
== pStubMsg
->Buffer
)
2230 safe_buffer_increment(pStubMsg
, bufsize
);
2232 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
2234 if (*pFormat
== FC_C_CSTRING
)
2235 TRACE("string=%s\n", debugstr_a((char*)*ppMemory
));
2237 TRACE("string=%s\n", debugstr_w((LPWSTR
)*ppMemory
));
2241 case FC_BOGUS_ARRAY
:
2242 alignment
= pFormat
[1] + 1;
2243 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2244 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2246 esize
= ComplexStructSize(pStubMsg
, pFormat
);
2247 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2249 assert( fUnmarshall
);
2251 if (!fMustAlloc
&& !*ppMemory
)
2254 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2256 align_pointer(&pStubMsg
->Buffer
, alignment
);
2257 saved_buffer
= pStubMsg
->Buffer
;
2259 pMemory
= *ppMemory
;
2260 count
= pStubMsg
->ActualCount
;
2261 for (i
= 0; i
< count
; i
++)
2262 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
, fMustAlloc
);
2263 return pStubMsg
->Buffer
- saved_buffer
;
2266 ERR("unknown array format 0x%x\n", fc
);
2267 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2271 static inline void array_memory_size(
2272 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
,
2273 unsigned char fHasPointers
)
2275 ULONG i
, count
, SavedMemorySize
;
2276 ULONG bufsize
, memsize
;
2278 unsigned char alignment
;
2283 esize
= *(const WORD
*)(pFormat
+2);
2284 alignment
= pFormat
[1] + 1;
2286 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2288 bufsize
= memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2289 pStubMsg
->MemorySize
+= memsize
;
2291 align_pointer(&pStubMsg
->Buffer
, alignment
);
2293 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2294 safe_buffer_increment(pStubMsg
, bufsize
);
2297 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2300 esize
= *(const WORD
*)(pFormat
+2);
2301 alignment
= pFormat
[1] + 1;
2303 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2305 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2307 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2308 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2309 pStubMsg
->MemorySize
+= memsize
;
2311 align_pointer(&pStubMsg
->Buffer
, alignment
);
2313 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2314 safe_buffer_increment(pStubMsg
, bufsize
);
2317 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2321 if (fc
== FC_C_CSTRING
)
2326 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
2328 if (pFormat
[1] != FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
2330 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2331 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
2332 RpcRaiseException(RPC_S_INVALID_BOUND
);
2334 if (pStubMsg
->Offset
)
2336 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2337 RpcRaiseException(RPC_S_INVALID_BOUND
);
2340 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2341 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2343 validate_string_data(pStubMsg
, bufsize
, esize
);
2345 safe_buffer_increment(pStubMsg
, bufsize
);
2346 pStubMsg
->MemorySize
+= memsize
;
2348 case FC_BOGUS_ARRAY
:
2349 alignment
= pFormat
[1] + 1;
2350 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2351 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2353 align_pointer(&pStubMsg
->Buffer
, alignment
);
2355 SavedMemorySize
= pStubMsg
->MemorySize
;
2357 esize
= ComplexStructSize(pStubMsg
, pFormat
);
2358 memsize
= safe_multiply(pStubMsg
->MaxCount
, esize
);
2360 count
= pStubMsg
->ActualCount
;
2361 for (i
= 0; i
< count
; i
++)
2362 ComplexStructMemorySize(pStubMsg
, pFormat
, NULL
);
2364 pStubMsg
->MemorySize
= SavedMemorySize
+ memsize
;
2367 ERR("unknown array format 0x%x\n", fc
);
2368 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2372 static inline void array_free(
2373 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
,
2374 unsigned char *pMemory
, PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
2381 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2383 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2386 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2387 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2389 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2393 /* No embedded pointers so nothing to do */
2395 case FC_BOGUS_ARRAY
:
2396 count
= *(const WORD
*)(pFormat
+ 2);
2397 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, count
);
2398 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
2400 count
= pStubMsg
->ActualCount
;
2401 for (i
= 0; i
< count
; i
++)
2402 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
2405 ERR("unknown array format 0x%x\n", fc
);
2406 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2411 * NdrConformantString:
2413 * What MS calls a ConformantString is, in DCE terminology,
2414 * a Varying-Conformant String.
2416 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2417 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2418 * into unmarshalled string)
2419 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2421 * data: CHARTYPE[maxlen]
2423 * ], where CHARTYPE is the appropriate character type (specified externally)
2427 /***********************************************************************
2428 * NdrConformantStringMarshall [RPCRT4.@]
2430 unsigned char *WINAPI
NdrConformantStringMarshall(MIDL_STUB_MESSAGE
*pStubMsg
,
2431 unsigned char *pszMessage
, PFORMAT_STRING pFormat
)
2433 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg
, pszMessage
, pFormat
);
2435 if (pFormat
[0] != FC_C_CSTRING
&& pFormat
[0] != FC_C_WSTRING
) {
2436 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2437 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2440 /* allow compiler to optimise inline function by passing constant into
2441 * these functions */
2442 if (pFormat
[0] == FC_C_CSTRING
) {
2443 array_compute_and_write_conformance(FC_C_CSTRING
, pStubMsg
, pszMessage
,
2445 array_write_variance_and_marshall(FC_C_CSTRING
, pStubMsg
, pszMessage
,
2446 pFormat
, TRUE
/* fHasPointers */);
2448 array_compute_and_write_conformance(FC_C_WSTRING
, pStubMsg
, pszMessage
,
2450 array_write_variance_and_marshall(FC_C_WSTRING
, pStubMsg
, pszMessage
,
2451 pFormat
, TRUE
/* fHasPointers */);
2457 /***********************************************************************
2458 * NdrConformantStringBufferSize [RPCRT4.@]
2460 void WINAPI
NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2461 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
2463 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2465 if (pFormat
[0] != FC_C_CSTRING
&& pFormat
[0] != FC_C_WSTRING
) {
2466 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2467 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2470 /* allow compiler to optimise inline function by passing constant into
2471 * these functions */
2472 if (pFormat
[0] == FC_C_CSTRING
) {
2473 array_compute_and_size_conformance(FC_C_CSTRING
, pStubMsg
, pMemory
,
2475 array_buffer_size(FC_C_CSTRING
, pStubMsg
, pMemory
, pFormat
,
2476 TRUE
/* fHasPointers */);
2478 array_compute_and_size_conformance(FC_C_WSTRING
, pStubMsg
, pMemory
,
2480 array_buffer_size(FC_C_WSTRING
, pStubMsg
, pMemory
, pFormat
,
2481 TRUE
/* fHasPointers */);
2485 /************************************************************************
2486 * NdrConformantStringMemorySize [RPCRT4.@]
2488 ULONG WINAPI
NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
2489 PFORMAT_STRING pFormat
)
2491 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
2493 if (pFormat
[0] != FC_C_CSTRING
&& pFormat
[0] != FC_C_WSTRING
) {
2494 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2495 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2498 /* allow compiler to optimise inline function by passing constant into
2499 * these functions */
2500 if (pFormat
[0] == FC_C_CSTRING
) {
2501 array_read_conformance(FC_C_CSTRING
, pStubMsg
, pFormat
);
2502 array_memory_size(FC_C_CSTRING
, pStubMsg
, pFormat
,
2503 TRUE
/* fHasPointers */);
2505 array_read_conformance(FC_C_WSTRING
, pStubMsg
, pFormat
);
2506 array_memory_size(FC_C_WSTRING
, pStubMsg
, pFormat
,
2507 TRUE
/* fHasPointers */);
2510 return pStubMsg
->MemorySize
;
2513 /************************************************************************
2514 * NdrConformantStringUnmarshall [RPCRT4.@]
2516 unsigned char *WINAPI
NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2517 unsigned char** ppMemory
, PFORMAT_STRING pFormat
, unsigned char fMustAlloc
)
2519 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2520 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
2522 if (pFormat
[0] != FC_C_CSTRING
&& pFormat
[0] != FC_C_WSTRING
) {
2523 ERR("Unhandled string type: %#x\n", *pFormat
);
2524 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2527 /* allow compiler to optimise inline function by passing constant into
2528 * these functions */
2529 if (pFormat
[0] == FC_C_CSTRING
) {
2530 array_read_conformance(FC_C_CSTRING
, pStubMsg
, pFormat
);
2531 array_read_variance_and_unmarshall(FC_C_CSTRING
, pStubMsg
, ppMemory
,
2532 pFormat
, fMustAlloc
,
2533 TRUE
/* fUseBufferMemoryServer */,
2534 TRUE
/* fUnmarshall */);
2536 array_read_conformance(FC_C_WSTRING
, pStubMsg
, pFormat
);
2537 array_read_variance_and_unmarshall(FC_C_WSTRING
, pStubMsg
, ppMemory
,
2538 pFormat
, fMustAlloc
,
2539 TRUE
/* fUseBufferMemoryServer */,
2540 TRUE
/* fUnmarshall */);
2546 /***********************************************************************
2547 * NdrNonConformantStringMarshall [RPCRT4.@]
2549 unsigned char * WINAPI
NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2550 unsigned char *pMemory
,
2551 PFORMAT_STRING pFormat
)
2553 ULONG esize
, size
, maxsize
;
2555 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2557 maxsize
= *(const USHORT
*)&pFormat
[2];
2559 if (*pFormat
== FC_CSTRING
)
2562 const char *str
= (const char *)pMemory
;
2563 while (i
< maxsize
&& str
[i
]) i
++;
2564 TRACE("string=%s\n", debugstr_an(str
, i
));
2565 pStubMsg
->ActualCount
= i
+ 1;
2568 else if (*pFormat
== FC_WSTRING
)
2571 const WCHAR
*str
= (const WCHAR
*)pMemory
;
2572 while (i
< maxsize
&& str
[i
]) i
++;
2573 TRACE("string=%s\n", debugstr_wn(str
, i
));
2574 pStubMsg
->ActualCount
= i
+ 1;
2579 ERR("Unhandled string type: %#x\n", *pFormat
);
2580 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2583 pStubMsg
->Offset
= 0;
2584 WriteVariance(pStubMsg
);
2586 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2587 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
2592 /***********************************************************************
2593 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2595 unsigned char * WINAPI
NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2596 unsigned char **ppMemory
,
2597 PFORMAT_STRING pFormat
,
2598 unsigned char fMustAlloc
)
2600 ULONG bufsize
, memsize
, esize
, maxsize
;
2602 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2603 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
2605 maxsize
= *(const USHORT
*)&pFormat
[2];
2607 ReadVariance(pStubMsg
, NULL
, maxsize
);
2608 if (pStubMsg
->Offset
)
2610 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2611 RpcRaiseException(RPC_S_INVALID_BOUND
);
2614 if (*pFormat
== FC_CSTRING
) esize
= 1;
2615 else if (*pFormat
== FC_WSTRING
) esize
= 2;
2618 ERR("Unhandled string type: %#x\n", *pFormat
);
2619 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2622 memsize
= esize
* maxsize
;
2623 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2625 validate_string_data(pStubMsg
, bufsize
, esize
);
2627 if (!fMustAlloc
&& !*ppMemory
)
2630 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2632 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
2634 if (*pFormat
== FC_CSTRING
) {
2635 TRACE("string=%s\n", debugstr_an((char*)*ppMemory
, pStubMsg
->ActualCount
));
2637 else if (*pFormat
== FC_WSTRING
) {
2638 TRACE("string=%s\n", debugstr_wn((LPWSTR
)*ppMemory
, pStubMsg
->ActualCount
));
2644 /***********************************************************************
2645 * NdrNonConformantStringBufferSize [RPCRT4.@]
2647 void WINAPI
NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2648 unsigned char *pMemory
,
2649 PFORMAT_STRING pFormat
)
2651 ULONG esize
, maxsize
;
2653 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2655 maxsize
= *(const USHORT
*)&pFormat
[2];
2657 SizeVariance(pStubMsg
);
2659 if (*pFormat
== FC_CSTRING
)
2662 const char *str
= (const char *)pMemory
;
2663 while (i
< maxsize
&& str
[i
]) i
++;
2664 TRACE("string=%s\n", debugstr_an(str
, i
));
2665 pStubMsg
->ActualCount
= i
+ 1;
2668 else if (*pFormat
== FC_WSTRING
)
2671 const WCHAR
*str
= (const WCHAR
*)pMemory
;
2672 while (i
< maxsize
&& str
[i
]) i
++;
2673 TRACE("string=%s\n", debugstr_wn(str
, i
));
2674 pStubMsg
->ActualCount
= i
+ 1;
2679 ERR("Unhandled string type: %#x\n", *pFormat
);
2680 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2683 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
2686 /***********************************************************************
2687 * NdrNonConformantStringMemorySize [RPCRT4.@]
2689 ULONG WINAPI
NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2690 PFORMAT_STRING pFormat
)
2692 ULONG bufsize
, memsize
, esize
, maxsize
;
2694 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
2696 maxsize
= *(const USHORT
*)&pFormat
[2];
2698 ReadVariance(pStubMsg
, NULL
, maxsize
);
2700 if (pStubMsg
->Offset
)
2702 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2703 RpcRaiseException(RPC_S_INVALID_BOUND
);
2706 if (*pFormat
== FC_CSTRING
) esize
= 1;
2707 else if (*pFormat
== FC_WSTRING
) esize
= 2;
2710 ERR("Unhandled string type: %#x\n", *pFormat
);
2711 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2714 memsize
= esize
* maxsize
;
2715 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2717 validate_string_data(pStubMsg
, bufsize
, esize
);
2719 safe_buffer_increment(pStubMsg
, bufsize
);
2720 pStubMsg
->MemorySize
+= memsize
;
2722 return pStubMsg
->MemorySize
;
2727 #include "pshpack1.h"
2731 unsigned char flags_type
; /* flags in upper nibble, type in lower nibble */
2735 #include "poppack.h"
2737 static ULONG
EmbeddedComplexSize(MIDL_STUB_MESSAGE
*pStubMsg
,
2738 PFORMAT_STRING pFormat
)
2744 case FC_BOGUS_STRUCT
:
2748 return *(const WORD
*)&pFormat
[2];
2749 case FC_USER_MARSHAL
:
2750 return *(const WORD
*)&pFormat
[4];
2752 switch (((const NDR_RANGE
*)pFormat
)->flags_type
& 0xf) {
2757 return sizeof(UCHAR
);
2761 return sizeof(USHORT
);
2767 return sizeof(ULONG
);
2769 return sizeof(float);
2771 return sizeof(double);
2773 return sizeof(ULONGLONG
);
2775 return sizeof(UINT
);
2777 ERR("unknown type 0x%x\n", ((const NDR_RANGE
*)pFormat
)->flags_type
& 0xf);
2778 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2781 case FC_NON_ENCAPSULATED_UNION
:
2783 pFormat
= SkipConformance(pStubMsg
, pFormat
);
2784 pFormat
+= *(const SHORT
*)pFormat
;
2785 return *(const SHORT
*)pFormat
;
2787 return sizeof(void *);
2789 return *(const WORD
*)&pFormat
[2] * 2;
2791 FIXME("unhandled embedded type %02x\n", *pFormat
);
2797 static ULONG
EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2798 PFORMAT_STRING pFormat
)
2800 NDR_MEMORYSIZE m
= NdrMemorySizer
[*pFormat
& NDR_TABLE_MASK
];
2804 FIXME("no memorysizer for data type=%02x\n", *pFormat
);
2808 return m(pStubMsg
, pFormat
);
2812 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2813 unsigned char *pMemory
,
2814 PFORMAT_STRING pFormat
,
2815 PFORMAT_STRING pPointer
)
2817 PFORMAT_STRING desc
;
2821 while (*pFormat
!= FC_END
) {
2827 TRACE("byte=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2828 safe_copy_to_buffer(pStubMsg
, pMemory
, 1);
2834 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2835 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
2840 USHORT val
= *(DWORD
*)pMemory
;
2841 TRACE("enum16=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2842 if (32767 < *(DWORD
*)pMemory
)
2843 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
2844 safe_copy_to_buffer(pStubMsg
, &val
, 2);
2851 TRACE("long=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2852 safe_copy_to_buffer(pStubMsg
, pMemory
, 4);
2858 UINT val
= *(UINT_PTR
*)pMemory
;
2859 TRACE("int3264=%ld <= %p\n", *(UINT_PTR
*)pMemory
, pMemory
);
2860 safe_copy_to_buffer(pStubMsg
, &val
, sizeof(UINT
));
2861 pMemory
+= sizeof(UINT_PTR
);
2865 TRACE("float=%f <= %p\n", *(float*)pMemory
, pMemory
);
2866 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
2867 pMemory
+= sizeof(float);
2870 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2871 safe_copy_to_buffer(pStubMsg
, pMemory
, 8);
2875 TRACE("double=%f <= %p\n", *(double*)pMemory
, pMemory
);
2876 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
2877 pMemory
+= sizeof(double);
2885 unsigned char *saved_buffer
;
2886 BOOL pointer_buffer_mark_set
= FALSE
;
2887 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
2888 TRACE("pStubMsg->Buffer before %p\n", pStubMsg
->Buffer
);
2889 if (*pFormat
!= FC_POINTER
)
2891 if (*pPointer
!= FC_RP
)
2892 align_pointer_clear(&pStubMsg
->Buffer
, 4);
2893 saved_buffer
= pStubMsg
->Buffer
;
2894 if (pStubMsg
->PointerBufferMark
)
2896 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2897 pStubMsg
->PointerBufferMark
= NULL
;
2898 pointer_buffer_mark_set
= TRUE
;
2900 else if (*pPointer
!= FC_RP
)
2901 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2902 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char**)pMemory
, pPointer
);
2903 if (pointer_buffer_mark_set
)
2905 STD_OVERFLOW_CHECK(pStubMsg
);
2906 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2907 pStubMsg
->Buffer
= saved_buffer
;
2908 if (*pPointer
!= FC_RP
)
2909 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2911 TRACE("pStubMsg->Buffer after %p\n", pStubMsg
->Buffer
);
2912 if (*pFormat
== FC_POINTER
)
2916 pMemory
+= sizeof(void *);
2920 align_pointer(&pMemory
, 2);
2923 align_pointer(&pMemory
, 4);
2926 align_pointer(&pMemory
, 8);
2935 pMemory
+= *pFormat
- FC_STRUCTPAD1
+ 1;
2937 case FC_EMBEDDED_COMPLEX
:
2938 pMemory
+= pFormat
[1];
2940 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2941 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2942 TRACE("embedded complex (size=%d) <= %p\n", size
, pMemory
);
2943 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
2946 /* for some reason interface pointers aren't generated as
2947 * FC_POINTER, but instead as FC_EMBEDDED_COMPLEX, yet
2948 * they still need the dereferencing treatment that pointers are
2951 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2953 m(pStubMsg
, pMemory
, desc
);
2955 else FIXME("no marshaller for embedded type %02x\n", *desc
);
2962 FIXME("unhandled format 0x%02x\n", *pFormat
);
2970 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2971 unsigned char *pMemory
,
2972 PFORMAT_STRING pFormat
,
2973 PFORMAT_STRING pPointer
,
2974 unsigned char fMustAlloc
)
2976 PFORMAT_STRING desc
;
2980 while (*pFormat
!= FC_END
) {
2986 safe_copy_from_buffer(pStubMsg
, pMemory
, 1);
2987 TRACE("byte=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2993 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
2994 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
3000 safe_copy_from_buffer(pStubMsg
, &val
, 2);
3001 *(DWORD
*)pMemory
= val
;
3002 TRACE("enum16=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
3003 if (32767 < *(DWORD
*)pMemory
)
3004 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
3011 safe_copy_from_buffer(pStubMsg
, pMemory
, 4);
3012 TRACE("long=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
3018 safe_copy_from_buffer(pStubMsg
, &val
, 4);
3019 *(INT_PTR
*)pMemory
= val
;
3020 TRACE("int3264=%ld => %p\n", *(INT_PTR
*)pMemory
, pMemory
);
3021 pMemory
+= sizeof(INT_PTR
);
3027 safe_copy_from_buffer(pStubMsg
, &val
, 4);
3028 *(UINT_PTR
*)pMemory
= val
;
3029 TRACE("uint3264=%ld => %p\n", *(UINT_PTR
*)pMemory
, pMemory
);
3030 pMemory
+= sizeof(UINT_PTR
);
3034 safe_copy_from_buffer(pStubMsg
, pMemory
, sizeof(float));
3035 TRACE("float=%f => %p\n", *(float*)pMemory
, pMemory
);
3036 pMemory
+= sizeof(float);
3039 safe_copy_from_buffer(pStubMsg
, pMemory
, 8);
3040 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
3044 safe_copy_from_buffer(pStubMsg
, pMemory
, sizeof(double));
3045 TRACE("double=%f => %p\n", *(double*)pMemory
, pMemory
);
3046 pMemory
+= sizeof(double);
3054 unsigned char *saved_buffer
;
3055 BOOL pointer_buffer_mark_set
= FALSE
;
3056 TRACE("pointer => %p\n", pMemory
);
3057 if (*pFormat
!= FC_POINTER
)
3059 if (*pPointer
!= FC_RP
)
3060 align_pointer(&pStubMsg
->Buffer
, 4);
3061 saved_buffer
= pStubMsg
->Buffer
;
3062 if (pStubMsg
->PointerBufferMark
)
3064 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3065 pStubMsg
->PointerBufferMark
= NULL
;
3066 pointer_buffer_mark_set
= TRUE
;
3068 else if (*pPointer
!= FC_RP
)
3069 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3071 PointerUnmarshall(pStubMsg
, saved_buffer
, (unsigned char**)pMemory
, *(unsigned char**)pMemory
, pPointer
, fMustAlloc
);
3072 if (pointer_buffer_mark_set
)
3074 STD_OVERFLOW_CHECK(pStubMsg
);
3075 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3076 pStubMsg
->Buffer
= saved_buffer
;
3077 if (*pPointer
!= FC_RP
)
3078 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3080 if (*pFormat
== FC_POINTER
)
3084 pMemory
+= sizeof(void *);
3088 align_pointer_clear(&pMemory
, 2);
3091 align_pointer_clear(&pMemory
, 4);
3094 align_pointer_clear(&pMemory
, 8);
3103 memset(pMemory
, 0, *pFormat
- FC_STRUCTPAD1
+ 1);
3104 pMemory
+= *pFormat
- FC_STRUCTPAD1
+ 1;
3106 case FC_EMBEDDED_COMPLEX
:
3107 pMemory
+= pFormat
[1];
3109 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3110 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3111 TRACE("embedded complex (size=%d) => %p\n", size
, pMemory
);
3113 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
3114 * since the type is part of the memory block that is encompassed by
3115 * the whole complex type. Memory is forced to allocate when pointers
3116 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
3117 * clearing the memory we pass in to the unmarshaller */
3118 memset(pMemory
, 0, size
);
3119 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
3122 /* for some reason interface pointers aren't generated as
3123 * FC_POINTER, but instead as FC_EMBEDDED_COMPLEX, yet
3124 * they still need the dereferencing treatment that pointers are
3127 m(pStubMsg
, (unsigned char **)pMemory
, desc
, FALSE
);
3129 m(pStubMsg
, &pMemory
, desc
, FALSE
);
3131 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
3138 FIXME("unhandled format %d\n", *pFormat
);
3146 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3147 unsigned char *pMemory
,
3148 PFORMAT_STRING pFormat
,
3149 PFORMAT_STRING pPointer
)
3151 PFORMAT_STRING desc
;
3155 while (*pFormat
!= FC_END
) {
3161 safe_buffer_length_increment(pStubMsg
, 1);
3167 safe_buffer_length_increment(pStubMsg
, 2);
3171 safe_buffer_length_increment(pStubMsg
, 2);
3178 safe_buffer_length_increment(pStubMsg
, 4);
3183 safe_buffer_length_increment(pStubMsg
, 4);
3184 pMemory
+= sizeof(INT_PTR
);
3188 safe_buffer_length_increment(pStubMsg
, 8);
3196 if (*pFormat
!= FC_POINTER
)
3198 if (!pStubMsg
->IgnoreEmbeddedPointers
)
3200 int saved_buffer_length
= pStubMsg
->BufferLength
;
3201 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3202 pStubMsg
->PointerLength
= 0;
3203 if(!pStubMsg
->BufferLength
)
3204 ERR("BufferLength == 0??\n");
3205 PointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
3206 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3207 pStubMsg
->BufferLength
= saved_buffer_length
;
3209 if (*pPointer
!= FC_RP
)
3211 align_length(&pStubMsg
->BufferLength
, 4);
3212 safe_buffer_length_increment(pStubMsg
, 4);
3214 if (*pFormat
== FC_POINTER
)
3218 pMemory
+= sizeof(void*);
3221 align_pointer(&pMemory
, 2);
3224 align_pointer(&pMemory
, 4);
3227 align_pointer(&pMemory
, 8);
3236 pMemory
+= *pFormat
- FC_STRUCTPAD1
+ 1;
3238 case FC_EMBEDDED_COMPLEX
:
3239 pMemory
+= pFormat
[1];
3241 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3242 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3243 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
3246 /* for some reason interface pointers aren't generated as
3247 * FC_POINTER, but instead as FC_EMBEDDED_COMPLEX, yet
3248 * they still need the dereferencing treatment that pointers are
3251 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
3253 m(pStubMsg
, pMemory
, desc
);
3255 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
3262 FIXME("unhandled format 0x%02x\n", *pFormat
);
3270 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
3271 unsigned char *pMemory
,
3272 PFORMAT_STRING pFormat
,
3273 PFORMAT_STRING pPointer
)
3275 PFORMAT_STRING desc
;
3279 while (*pFormat
!= FC_END
) {
3301 pMemory
+= sizeof(INT_PTR
);
3312 if (*pFormat
!= FC_POINTER
)
3314 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
3315 if (*pFormat
== FC_POINTER
)
3319 pMemory
+= sizeof(void *);
3322 align_pointer(&pMemory
, 2);
3325 align_pointer(&pMemory
, 4);
3328 align_pointer(&pMemory
, 8);
3337 pMemory
+= *pFormat
- FC_STRUCTPAD1
+ 1;
3339 case FC_EMBEDDED_COMPLEX
:
3340 pMemory
+= pFormat
[1];
3342 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3343 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3344 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
3347 /* for some reason interface pointers aren't generated as
3348 * FC_POINTER, but instead as FC_EMBEDDED_COMPLEX, yet
3349 * they still need the dereferencing treatment that pointers are
3352 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
3354 m(pStubMsg
, pMemory
, desc
);
3362 FIXME("unhandled format 0x%02x\n", *pFormat
);
3370 static ULONG
ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3371 PFORMAT_STRING pFormat
,
3372 PFORMAT_STRING pPointer
)
3374 PFORMAT_STRING desc
;
3377 while (*pFormat
!= FC_END
) {
3384 safe_buffer_increment(pStubMsg
, 1);
3390 safe_buffer_increment(pStubMsg
, 2);
3394 safe_buffer_increment(pStubMsg
, 2);
3401 safe_buffer_increment(pStubMsg
, 4);
3405 size
+= sizeof(INT_PTR
);
3406 safe_buffer_increment(pStubMsg
, 4);
3411 safe_buffer_increment(pStubMsg
, 8);
3419 unsigned char *saved_buffer
;
3420 BOOL pointer_buffer_mark_set
= FALSE
;
3421 if (*pFormat
!= FC_POINTER
)
3423 if (*pPointer
!= FC_RP
)
3424 align_pointer(&pStubMsg
->Buffer
, 4);
3425 saved_buffer
= pStubMsg
->Buffer
;
3426 if (pStubMsg
->PointerBufferMark
)
3428 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3429 pStubMsg
->PointerBufferMark
= NULL
;
3430 pointer_buffer_mark_set
= TRUE
;
3432 else if (*pPointer
!= FC_RP
)
3433 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3435 if (!pStubMsg
->IgnoreEmbeddedPointers
)
3436 PointerMemorySize(pStubMsg
, saved_buffer
, pPointer
);
3437 if (pointer_buffer_mark_set
)
3439 STD_OVERFLOW_CHECK(pStubMsg
);
3440 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3441 pStubMsg
->Buffer
= saved_buffer
;
3442 if (*pPointer
!= FC_RP
)
3443 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3445 if (*pFormat
== FC_POINTER
)
3449 size
+= sizeof(void *);
3453 align_length(&size
, 2);
3456 align_length(&size
, 4);
3459 align_length(&size
, 8);
3468 size
+= *pFormat
- FC_STRUCTPAD1
+ 1;
3470 case FC_EMBEDDED_COMPLEX
:
3473 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3474 size
+= EmbeddedComplexMemorySize(pStubMsg
, desc
);
3480 FIXME("unhandled format 0x%02x\n", *pFormat
);
3488 ULONG
ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
3490 PFORMAT_STRING desc
;
3493 while (*pFormat
!= FC_END
) {
3515 size
+= sizeof(INT_PTR
);
3526 size
+= sizeof(void *);
3527 if (*pFormat
!= FC_POINTER
)
3531 align_length(&size
, 2);
3534 align_length(&size
, 4);
3537 align_length(&size
, 8);
3546 size
+= *pFormat
- FC_STRUCTPAD1
+ 1;
3548 case FC_EMBEDDED_COMPLEX
:
3551 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3552 size
+= EmbeddedComplexSize(pStubMsg
, desc
);
3558 FIXME("unhandled format 0x%02x\n", *pFormat
);
3566 /***********************************************************************
3567 * NdrComplexStructMarshall [RPCRT4.@]
3569 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3570 unsigned char *pMemory
,
3571 PFORMAT_STRING pFormat
)
3573 PFORMAT_STRING conf_array
= NULL
;
3574 PFORMAT_STRING pointer_desc
= NULL
;
3575 unsigned char *OldMemory
= pStubMsg
->Memory
;
3576 BOOL pointer_buffer_mark_set
= FALSE
;
3578 ULONG max_count
= 0;
3581 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3583 if (!pStubMsg
->PointerBufferMark
)
3585 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3586 /* save buffer length */
3587 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
3589 /* get the buffer pointer after complex array data, but before
3591 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
;
3592 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3593 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
3594 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3596 /* save it for use by embedded pointer code later */
3597 pStubMsg
->PointerBufferMark
= (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
;
3598 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->PointerBufferMark
- pStubMsg
->Buffer
));
3599 pointer_buffer_mark_set
= TRUE
;
3601 /* restore the original buffer length */
3602 pStubMsg
->BufferLength
= saved_buffer_length
;
3605 align_pointer_clear(&pStubMsg
->Buffer
, pFormat
[1] + 1);
3608 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3610 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3613 pStubMsg
->Memory
= pMemory
;
3617 ULONG struct_size
= ComplexStructSize(pStubMsg
, pFormat
);
3618 array_compute_and_write_conformance(conf_array
[0], pStubMsg
,
3619 pMemory
+ struct_size
, conf_array
);
3620 /* these could be changed in ComplexMarshall so save them for later */
3621 max_count
= pStubMsg
->MaxCount
;
3622 count
= pStubMsg
->ActualCount
;
3623 offset
= pStubMsg
->Offset
;
3626 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3630 pStubMsg
->MaxCount
= max_count
;
3631 pStubMsg
->ActualCount
= count
;
3632 pStubMsg
->Offset
= offset
;
3633 array_write_variance_and_marshall(conf_array
[0], pStubMsg
, pMemory
,
3634 conf_array
, TRUE
/* fHasPointers */);
3637 pStubMsg
->Memory
= OldMemory
;
3639 if (pointer_buffer_mark_set
)
3641 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3642 pStubMsg
->PointerBufferMark
= NULL
;
3645 STD_OVERFLOW_CHECK(pStubMsg
);
3650 /***********************************************************************
3651 * NdrComplexStructUnmarshall [RPCRT4.@]
3653 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3654 unsigned char **ppMemory
,
3655 PFORMAT_STRING pFormat
,
3656 unsigned char fMustAlloc
)
3658 unsigned size
= *(const WORD
*)(pFormat
+2);
3659 PFORMAT_STRING conf_array
= NULL
;
3660 PFORMAT_STRING pointer_desc
= NULL
;
3661 unsigned char *pMemory
;
3662 BOOL pointer_buffer_mark_set
= FALSE
;
3664 ULONG max_count
= 0;
3666 ULONG array_size
= 0;
3668 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3670 if (!pStubMsg
->PointerBufferMark
)
3672 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3673 /* save buffer pointer */
3674 unsigned char *saved_buffer
= pStubMsg
->Buffer
;
3676 /* get the buffer pointer after complex array data, but before
3678 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3679 NdrComplexStructMemorySize(pStubMsg
, pFormat
);
3680 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3682 /* save it for use by embedded pointer code later */
3683 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3684 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->PointerBufferMark
- saved_buffer
));
3685 pointer_buffer_mark_set
= TRUE
;
3687 /* restore the original buffer */
3688 pStubMsg
->Buffer
= saved_buffer
;
3691 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
3694 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3696 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3701 array_size
= array_read_conformance(conf_array
[0], pStubMsg
, conf_array
);
3704 /* these could be changed in ComplexMarshall so save them for later */
3705 max_count
= pStubMsg
->MaxCount
;
3706 count
= pStubMsg
->ActualCount
;
3707 offset
= pStubMsg
->Offset
;
3710 if (!fMustAlloc
&& !*ppMemory
)
3713 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3715 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
, fMustAlloc
);
3719 pStubMsg
->MaxCount
= max_count
;
3720 pStubMsg
->ActualCount
= count
;
3721 pStubMsg
->Offset
= offset
;
3723 memset(pMemory
, 0, array_size
);
3724 array_read_variance_and_unmarshall(conf_array
[0], pStubMsg
, &pMemory
,
3726 FALSE
/* fUseBufferMemoryServer */,
3727 TRUE
/* fUnmarshall */);
3730 if (pointer_buffer_mark_set
)
3732 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3733 pStubMsg
->PointerBufferMark
= NULL
;
3739 /***********************************************************************
3740 * NdrComplexStructBufferSize [RPCRT4.@]
3742 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3743 unsigned char *pMemory
,
3744 PFORMAT_STRING pFormat
)
3746 PFORMAT_STRING conf_array
= NULL
;
3747 PFORMAT_STRING pointer_desc
= NULL
;
3748 unsigned char *OldMemory
= pStubMsg
->Memory
;
3749 int pointer_length_set
= 0;
3751 ULONG max_count
= 0;
3754 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3756 align_length(&pStubMsg
->BufferLength
, pFormat
[1] + 1);
3758 if(!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
3760 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3761 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
3763 /* get the buffer length after complex struct data, but before
3765 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3766 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
3767 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3769 /* save it for use by embedded pointer code later */
3770 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3771 pointer_length_set
= 1;
3772 TRACE("difference = 0x%x\n", pStubMsg
->PointerLength
- saved_buffer_length
);
3774 /* restore the original buffer length */
3775 pStubMsg
->BufferLength
= saved_buffer_length
;
3779 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3781 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3784 pStubMsg
->Memory
= pMemory
;
3788 ULONG struct_size
= ComplexStructSize(pStubMsg
, pFormat
);
3789 array_compute_and_size_conformance(conf_array
[0], pStubMsg
, pMemory
+ struct_size
,
3792 /* these could be changed in ComplexMarshall so save them for later */
3793 max_count
= pStubMsg
->MaxCount
;
3794 count
= pStubMsg
->ActualCount
;
3795 offset
= pStubMsg
->Offset
;
3798 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3802 pStubMsg
->MaxCount
= max_count
;
3803 pStubMsg
->ActualCount
= count
;
3804 pStubMsg
->Offset
= offset
;
3805 array_buffer_size(conf_array
[0], pStubMsg
, pMemory
, conf_array
,
3806 TRUE
/* fHasPointers */);
3809 pStubMsg
->Memory
= OldMemory
;
3811 if(pointer_length_set
)
3813 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3814 pStubMsg
->PointerLength
= 0;
3819 /***********************************************************************
3820 * NdrComplexStructMemorySize [RPCRT4.@]
3822 ULONG WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3823 PFORMAT_STRING pFormat
)
3825 unsigned size
= *(const WORD
*)(pFormat
+2);
3826 PFORMAT_STRING conf_array
= NULL
;
3827 PFORMAT_STRING pointer_desc
= NULL
;
3829 ULONG max_count
= 0;
3832 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3834 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
3837 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3839 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3844 array_read_conformance(conf_array
[0], pStubMsg
, conf_array
);
3846 /* these could be changed in ComplexStructMemorySize so save them for
3848 max_count
= pStubMsg
->MaxCount
;
3849 count
= pStubMsg
->ActualCount
;
3850 offset
= pStubMsg
->Offset
;
3853 ComplexStructMemorySize(pStubMsg
, pFormat
, pointer_desc
);
3857 pStubMsg
->MaxCount
= max_count
;
3858 pStubMsg
->ActualCount
= count
;
3859 pStubMsg
->Offset
= offset
;
3860 array_memory_size(conf_array
[0], pStubMsg
, conf_array
,
3861 TRUE
/* fHasPointers */);
3867 /***********************************************************************
3868 * NdrComplexStructFree [RPCRT4.@]
3870 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3871 unsigned char *pMemory
,
3872 PFORMAT_STRING pFormat
)
3874 PFORMAT_STRING conf_array
= NULL
;
3875 PFORMAT_STRING pointer_desc
= NULL
;
3876 unsigned char *OldMemory
= pStubMsg
->Memory
;
3878 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3881 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3883 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3886 pStubMsg
->Memory
= pMemory
;
3888 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3891 array_free(conf_array
[0], pStubMsg
, pMemory
, conf_array
,
3892 TRUE
/* fHasPointers */);
3894 pStubMsg
->Memory
= OldMemory
;
3897 /***********************************************************************
3898 * NdrConformantArrayMarshall [RPCRT4.@]
3900 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3901 unsigned char *pMemory
,
3902 PFORMAT_STRING pFormat
)
3904 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3905 if (pFormat
[0] != FC_CARRAY
)
3907 ERR("invalid format = 0x%x\n", pFormat
[0]);
3908 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3911 array_compute_and_write_conformance(FC_CARRAY
, pStubMsg
, pMemory
,
3913 array_write_variance_and_marshall(FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3914 TRUE
/* fHasPointers */);
3919 /***********************************************************************
3920 * NdrConformantArrayUnmarshall [RPCRT4.@]
3922 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3923 unsigned char **ppMemory
,
3924 PFORMAT_STRING pFormat
,
3925 unsigned char fMustAlloc
)
3927 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3928 if (pFormat
[0] != FC_CARRAY
)
3930 ERR("invalid format = 0x%x\n", pFormat
[0]);
3931 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3934 array_read_conformance(FC_CARRAY
, pStubMsg
, pFormat
);
3935 array_read_variance_and_unmarshall(FC_CARRAY
, pStubMsg
, ppMemory
, pFormat
,
3937 TRUE
/* fUseBufferMemoryServer */,
3938 TRUE
/* fUnmarshall */);
3943 /***********************************************************************
3944 * NdrConformantArrayBufferSize [RPCRT4.@]
3946 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3947 unsigned char *pMemory
,
3948 PFORMAT_STRING pFormat
)
3950 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3951 if (pFormat
[0] != FC_CARRAY
)
3953 ERR("invalid format = 0x%x\n", pFormat
[0]);
3954 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3957 array_compute_and_size_conformance(FC_CARRAY
, pStubMsg
, pMemory
, pFormat
);
3958 array_buffer_size(FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3959 TRUE
/* fHasPointers */);
3962 /***********************************************************************
3963 * NdrConformantArrayMemorySize [RPCRT4.@]
3965 ULONG WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3966 PFORMAT_STRING pFormat
)
3968 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3969 if (pFormat
[0] != FC_CARRAY
)
3971 ERR("invalid format = 0x%x\n", pFormat
[0]);
3972 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3975 array_read_conformance(FC_CARRAY
, pStubMsg
, pFormat
);
3976 array_memory_size(FC_CARRAY
, pStubMsg
, pFormat
, TRUE
/* fHasPointers */);
3978 return pStubMsg
->MemorySize
;
3981 /***********************************************************************
3982 * NdrConformantArrayFree [RPCRT4.@]
3984 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3985 unsigned char *pMemory
,
3986 PFORMAT_STRING pFormat
)
3988 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3989 if (pFormat
[0] != FC_CARRAY
)
3991 ERR("invalid format = 0x%x\n", pFormat
[0]);
3992 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3995 array_free(FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3996 TRUE
/* fHasPointers */);
4000 /***********************************************************************
4001 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
4003 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
4004 unsigned char* pMemory
,
4005 PFORMAT_STRING pFormat
)
4007 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4009 if (pFormat
[0] != FC_CVARRAY
)
4011 ERR("invalid format type %x\n", pFormat
[0]);
4012 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4016 array_compute_and_write_conformance(FC_CVARRAY
, pStubMsg
, pMemory
,
4018 array_write_variance_and_marshall(FC_CVARRAY
, pStubMsg
, pMemory
,
4019 pFormat
, TRUE
/* fHasPointers */);
4025 /***********************************************************************
4026 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
4028 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
4029 unsigned char** ppMemory
,
4030 PFORMAT_STRING pFormat
,
4031 unsigned char fMustAlloc
)
4033 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4035 if (pFormat
[0] != FC_CVARRAY
)
4037 ERR("invalid format type %x\n", pFormat
[0]);
4038 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4042 array_read_conformance(FC_CVARRAY
, pStubMsg
, pFormat
);
4043 array_read_variance_and_unmarshall(FC_CVARRAY
, pStubMsg
, ppMemory
,
4044 pFormat
, fMustAlloc
,
4045 TRUE
/* fUseBufferMemoryServer */,
4046 TRUE
/* fUnmarshall */);
4052 /***********************************************************************
4053 * NdrConformantVaryingArrayFree [RPCRT4.@]
4055 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
4056 unsigned char* pMemory
,
4057 PFORMAT_STRING pFormat
)
4059 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4061 if (pFormat
[0] != FC_CVARRAY
)
4063 ERR("invalid format type %x\n", pFormat
[0]);
4064 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4068 array_free(FC_CVARRAY
, pStubMsg
, pMemory
, pFormat
,
4069 TRUE
/* fHasPointers */);
4073 /***********************************************************************
4074 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
4076 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
4077 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
4079 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4081 if (pFormat
[0] != FC_CVARRAY
)
4083 ERR("invalid format type %x\n", pFormat
[0]);
4084 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4088 array_compute_and_size_conformance(FC_CVARRAY
, pStubMsg
, pMemory
,
4090 array_buffer_size(FC_CVARRAY
, pStubMsg
, pMemory
, pFormat
,
4091 TRUE
/* fHasPointers */);
4095 /***********************************************************************
4096 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
4098 ULONG WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
4099 PFORMAT_STRING pFormat
)
4101 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4103 if (pFormat
[0] != FC_CVARRAY
)
4105 ERR("invalid format type %x\n", pFormat
[0]);
4106 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4107 return pStubMsg
->MemorySize
;
4110 array_read_conformance(FC_CVARRAY
, pStubMsg
, pFormat
);
4111 array_memory_size(FC_CVARRAY
, pStubMsg
, pFormat
,
4112 TRUE
/* fHasPointers */);
4114 return pStubMsg
->MemorySize
;
4118 /***********************************************************************
4119 * NdrComplexArrayMarshall [RPCRT4.@]
4121 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4122 unsigned char *pMemory
,
4123 PFORMAT_STRING pFormat
)
4125 BOOL pointer_buffer_mark_set
= FALSE
;
4127 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4129 if (pFormat
[0] != FC_BOGUS_ARRAY
)
4131 ERR("invalid format type %x\n", pFormat
[0]);
4132 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4136 if (!pStubMsg
->PointerBufferMark
)
4138 /* save buffer fields that may be changed by buffer sizer functions
4139 * and that may be needed later on */
4140 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
4141 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
4142 ULONG_PTR saved_max_count
= pStubMsg
->MaxCount
;
4143 ULONG saved_offset
= pStubMsg
->Offset
;
4144 ULONG saved_actual_count
= pStubMsg
->ActualCount
;
4146 /* get the buffer pointer after complex array data, but before
4148 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
;
4149 pStubMsg
->IgnoreEmbeddedPointers
= 1;
4150 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
4151 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
4153 /* save it for use by embedded pointer code later */
4154 pStubMsg
->PointerBufferMark
= (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
;
4155 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
));
4156 pointer_buffer_mark_set
= TRUE
;
4158 /* restore fields */
4159 pStubMsg
->ActualCount
= saved_actual_count
;
4160 pStubMsg
->Offset
= saved_offset
;
4161 pStubMsg
->MaxCount
= saved_max_count
;
4162 pStubMsg
->BufferLength
= saved_buffer_length
;
4165 array_compute_and_write_conformance(FC_BOGUS_ARRAY
, pStubMsg
, pMemory
, pFormat
);
4166 array_write_variance_and_marshall(FC_BOGUS_ARRAY
, pStubMsg
,
4167 pMemory
, pFormat
, TRUE
/* fHasPointers */);
4169 STD_OVERFLOW_CHECK(pStubMsg
);
4171 if (pointer_buffer_mark_set
)
4173 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4174 pStubMsg
->PointerBufferMark
= NULL
;
4180 /***********************************************************************
4181 * NdrComplexArrayUnmarshall [RPCRT4.@]
4183 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4184 unsigned char **ppMemory
,
4185 PFORMAT_STRING pFormat
,
4186 unsigned char fMustAlloc
)
4188 unsigned char *saved_buffer
;
4189 BOOL pointer_buffer_mark_set
= FALSE
;
4190 int saved_ignore_embedded
;
4192 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4194 if (pFormat
[0] != FC_BOGUS_ARRAY
)
4196 ERR("invalid format type %x\n", pFormat
[0]);
4197 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4201 saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
4202 /* save buffer pointer */
4203 saved_buffer
= pStubMsg
->Buffer
;
4204 /* get the buffer pointer after complex array data, but before
4206 pStubMsg
->IgnoreEmbeddedPointers
= 1;
4207 pStubMsg
->MemorySize
= 0;
4208 NdrComplexArrayMemorySize(pStubMsg
, pFormat
);
4209 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
4211 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->Buffer
- saved_buffer
));
4212 if (!pStubMsg
->PointerBufferMark
)
4214 /* save it for use by embedded pointer code later */
4215 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4216 pointer_buffer_mark_set
= TRUE
;
4218 /* restore the original buffer */
4219 pStubMsg
->Buffer
= saved_buffer
;
4221 array_read_conformance(FC_BOGUS_ARRAY
, pStubMsg
, pFormat
);
4222 array_read_variance_and_unmarshall(FC_BOGUS_ARRAY
, pStubMsg
, ppMemory
, pFormat
, fMustAlloc
,
4223 TRUE
/* fUseBufferMemoryServer */, TRUE
/* fUnmarshall */);
4225 if (pointer_buffer_mark_set
)
4227 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4228 pStubMsg
->PointerBufferMark
= NULL
;
4234 /***********************************************************************
4235 * NdrComplexArrayBufferSize [RPCRT4.@]
4237 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4238 unsigned char *pMemory
,
4239 PFORMAT_STRING pFormat
)
4241 int pointer_length_set
= 0;
4243 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4245 if (pFormat
[0] != FC_BOGUS_ARRAY
)
4247 ERR("invalid format type %x\n", pFormat
[0]);
4248 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4252 if (!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
4254 /* save buffer fields that may be changed by buffer sizer functions
4255 * and that may be needed later on */
4256 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
4257 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
4258 ULONG_PTR saved_max_count
= pStubMsg
->MaxCount
;
4259 ULONG saved_offset
= pStubMsg
->Offset
;
4260 ULONG saved_actual_count
= pStubMsg
->ActualCount
;
4262 /* get the buffer pointer after complex array data, but before
4264 pStubMsg
->IgnoreEmbeddedPointers
= 1;
4265 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
4266 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
4268 /* save it for use by embedded pointer code later */
4269 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4270 pointer_length_set
= 1;
4272 /* restore fields */
4273 pStubMsg
->ActualCount
= saved_actual_count
;
4274 pStubMsg
->Offset
= saved_offset
;
4275 pStubMsg
->MaxCount
= saved_max_count
;
4276 pStubMsg
->BufferLength
= saved_buffer_length
;
4279 array_compute_and_size_conformance(FC_BOGUS_ARRAY
, pStubMsg
, pMemory
, pFormat
);
4280 array_buffer_size(FC_BOGUS_ARRAY
, pStubMsg
, pMemory
, pFormat
, TRUE
/* fHasPointers */);
4282 if(pointer_length_set
)
4284 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4285 pStubMsg
->PointerLength
= 0;
4289 /***********************************************************************
4290 * NdrComplexArrayMemorySize [RPCRT4.@]
4292 ULONG WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4293 PFORMAT_STRING pFormat
)
4295 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
4297 if (pFormat
[0] != FC_BOGUS_ARRAY
)
4299 ERR("invalid format type %x\n", pFormat
[0]);
4300 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4304 array_read_conformance(FC_BOGUS_ARRAY
, pStubMsg
, pFormat
);
4305 array_memory_size(FC_BOGUS_ARRAY
, pStubMsg
, pFormat
, TRUE
/* fHasPointers */);
4306 return pStubMsg
->MemorySize
;
4309 /***********************************************************************
4310 * NdrComplexArrayFree [RPCRT4.@]
4312 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4313 unsigned char *pMemory
,
4314 PFORMAT_STRING pFormat
)
4316 ULONG i
, count
, def
;
4318 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4320 if (pFormat
[0] != FC_BOGUS_ARRAY
)
4322 ERR("invalid format type %x\n", pFormat
[0]);
4323 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4327 def
= *(const WORD
*)&pFormat
[2];
4330 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
4331 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
4333 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
4334 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
4336 count
= pStubMsg
->ActualCount
;
4337 for (i
= 0; i
< count
; i
++)
4338 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
4341 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg
,
4342 USER_MARSHAL_CB_TYPE cbtype
, PFORMAT_STRING pFormat
,
4343 USER_MARSHAL_CB
*umcb
)
4345 umcb
->Flags
= MAKELONG(pStubMsg
->dwDestContext
,
4346 pStubMsg
->RpcMsg
->DataRepresentation
);
4347 umcb
->pStubMsg
= pStubMsg
;
4348 umcb
->pReserve
= NULL
;
4349 umcb
->Signature
= USER_MARSHAL_CB_SIGNATURE
;
4350 umcb
->CBType
= cbtype
;
4351 umcb
->pFormat
= pFormat
;
4352 umcb
->pTypeFormat
= NULL
/* FIXME */;
4355 #define USER_MARSHAL_PTR_PREFIX \
4356 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4357 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4359 /***********************************************************************
4360 * NdrUserMarshalMarshall [RPCRT4.@]
4362 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4363 unsigned char *pMemory
,
4364 PFORMAT_STRING pFormat
)
4366 unsigned flags
= pFormat
[1];
4367 unsigned index
= *(const WORD
*)&pFormat
[2];
4368 unsigned char *saved_buffer
= NULL
;
4369 USER_MARSHAL_CB umcb
;
4371 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4372 TRACE("index=%d\n", index
);
4374 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_MARSHALL
, pFormat
, &umcb
);
4376 if (flags
& USER_MARSHAL_POINTER
)
4378 align_pointer_clear(&pStubMsg
->Buffer
, 4);
4379 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, USER_MARSHAL_PTR_PREFIX
);
4380 pStubMsg
->Buffer
+= 4;
4381 if (pStubMsg
->PointerBufferMark
)
4383 saved_buffer
= pStubMsg
->Buffer
;
4384 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4385 pStubMsg
->PointerBufferMark
= NULL
;
4387 align_pointer_clear(&pStubMsg
->Buffer
, 8);
4390 align_pointer_clear(&pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4393 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
4394 &umcb
.Flags
, pStubMsg
->Buffer
, pMemory
);
4398 STD_OVERFLOW_CHECK(pStubMsg
);
4399 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4400 pStubMsg
->Buffer
= saved_buffer
;
4403 STD_OVERFLOW_CHECK(pStubMsg
);
4408 /***********************************************************************
4409 * NdrUserMarshalUnmarshall [RPCRT4.@]
4411 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4412 unsigned char **ppMemory
,
4413 PFORMAT_STRING pFormat
,
4414 unsigned char fMustAlloc
)
4416 unsigned flags
= pFormat
[1];
4417 unsigned index
= *(const WORD
*)&pFormat
[2];
4418 DWORD memsize
= *(const WORD
*)&pFormat
[4];
4419 unsigned char *saved_buffer
= NULL
;
4420 USER_MARSHAL_CB umcb
;
4422 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4423 TRACE("index=%d\n", index
);
4425 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_UNMARSHALL
, pFormat
, &umcb
);
4427 if (flags
& USER_MARSHAL_POINTER
)
4429 align_pointer(&pStubMsg
->Buffer
, 4);
4430 /* skip pointer prefix */
4431 pStubMsg
->Buffer
+= 4;
4432 if (pStubMsg
->PointerBufferMark
)
4434 saved_buffer
= pStubMsg
->Buffer
;
4435 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4436 pStubMsg
->PointerBufferMark
= NULL
;
4438 align_pointer(&pStubMsg
->Buffer
, 8);
4441 align_pointer(&pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4443 if (!fMustAlloc
&& !*ppMemory
)
4447 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
4448 memset(*ppMemory
, 0, memsize
);
4452 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
4453 &umcb
.Flags
, pStubMsg
->Buffer
, *ppMemory
);
4457 STD_OVERFLOW_CHECK(pStubMsg
);
4458 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4459 pStubMsg
->Buffer
= saved_buffer
;
4465 /***********************************************************************
4466 * NdrUserMarshalBufferSize [RPCRT4.@]
4468 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4469 unsigned char *pMemory
,
4470 PFORMAT_STRING pFormat
)
4472 unsigned flags
= pFormat
[1];
4473 unsigned index
= *(const WORD
*)&pFormat
[2];
4474 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
4475 USER_MARSHAL_CB umcb
;
4476 ULONG saved_buffer_length
= 0;
4478 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4479 TRACE("index=%d\n", index
);
4481 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_BUFFER_SIZE
, pFormat
, &umcb
);
4483 if (flags
& USER_MARSHAL_POINTER
)
4485 align_length(&pStubMsg
->BufferLength
, 4);
4486 /* skip pointer prefix */
4487 safe_buffer_length_increment(pStubMsg
, 4);
4488 if (pStubMsg
->IgnoreEmbeddedPointers
)
4490 if (pStubMsg
->PointerLength
)
4492 saved_buffer_length
= pStubMsg
->BufferLength
;
4493 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4494 pStubMsg
->PointerLength
= 0;
4496 align_length(&pStubMsg
->BufferLength
, 8);
4499 align_length(&pStubMsg
->BufferLength
, (flags
& 0xf) + 1);
4502 TRACE("size=%d\n", bufsize
);
4503 safe_buffer_length_increment(pStubMsg
, bufsize
);
4506 pStubMsg
->BufferLength
=
4507 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
4508 &umcb
.Flags
, pStubMsg
->BufferLength
, pMemory
);
4510 if (saved_buffer_length
)
4512 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4513 pStubMsg
->BufferLength
= saved_buffer_length
;
4518 /***********************************************************************
4519 * NdrUserMarshalMemorySize [RPCRT4.@]
4521 ULONG WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4522 PFORMAT_STRING pFormat
)
4524 unsigned flags
= pFormat
[1];
4525 unsigned index
= *(const WORD
*)&pFormat
[2];
4526 DWORD memsize
= *(const WORD
*)&pFormat
[4];
4527 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
4529 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
4530 TRACE("index=%d\n", index
);
4532 pStubMsg
->MemorySize
+= memsize
;
4534 if (flags
& USER_MARSHAL_POINTER
)
4536 align_pointer(&pStubMsg
->Buffer
, 4);
4537 /* skip pointer prefix */
4538 pStubMsg
->Buffer
+= 4;
4539 if (pStubMsg
->IgnoreEmbeddedPointers
)
4540 return pStubMsg
->MemorySize
;
4541 align_pointer(&pStubMsg
->Buffer
, 8);
4544 align_pointer(&pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4547 FIXME("not implemented for varying buffer size\n");
4549 pStubMsg
->Buffer
+= bufsize
;
4551 return pStubMsg
->MemorySize
;
4554 /***********************************************************************
4555 * NdrUserMarshalFree [RPCRT4.@]
4557 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
4558 unsigned char *pMemory
,
4559 PFORMAT_STRING pFormat
)
4561 /* unsigned flags = pFormat[1]; */
4562 unsigned index
= *(const WORD
*)&pFormat
[2];
4563 USER_MARSHAL_CB umcb
;
4565 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4566 TRACE("index=%d\n", index
);
4568 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_FREE
, pFormat
, &umcb
);
4570 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
4571 &umcb
.Flags
, pMemory
);
4574 /***********************************************************************
4575 * NdrGetUserMarshalInfo [RPCRT4.@]
4577 RPC_STATUS RPC_ENTRY
NdrGetUserMarshalInfo(ULONG
*flags
, ULONG level
, NDR_USER_MARSHAL_INFO
*umi
)
4579 USER_MARSHAL_CB
*umcb
= CONTAINING_RECORD(flags
, USER_MARSHAL_CB
, Flags
);
4581 TRACE("(%p,%u,%p)\n", flags
, level
, umi
);
4584 return RPC_S_INVALID_ARG
;
4586 memset(&umi
->u1
.Level1
, 0, sizeof(umi
->u1
.Level1
));
4587 umi
->InformationLevel
= level
;
4589 if (umcb
->Signature
!= USER_MARSHAL_CB_SIGNATURE
)
4590 return RPC_S_INVALID_ARG
;
4592 umi
->u1
.Level1
.pfnAllocate
= umcb
->pStubMsg
->pfnAllocate
;
4593 umi
->u1
.Level1
.pfnFree
= umcb
->pStubMsg
->pfnFree
;
4594 umi
->u1
.Level1
.pRpcChannelBuffer
= umcb
->pStubMsg
->pRpcChannelBuffer
;
4596 switch (umcb
->CBType
)
4598 case USER_MARSHAL_CB_MARSHALL
:
4599 case USER_MARSHAL_CB_UNMARSHALL
:
4601 RPC_MESSAGE
*msg
= umcb
->pStubMsg
->RpcMsg
;
4602 unsigned char *buffer_start
= msg
->Buffer
;
4603 unsigned char *buffer_end
=
4604 (unsigned char *)msg
->Buffer
+ msg
->BufferLength
;
4606 if (umcb
->pStubMsg
->Buffer
< buffer_start
||
4607 umcb
->pStubMsg
->Buffer
> buffer_end
)
4608 return RPC_X_INVALID_BUFFER
;
4610 umi
->u1
.Level1
.Buffer
= umcb
->pStubMsg
->Buffer
;
4611 umi
->u1
.Level1
.BufferSize
= buffer_end
- umcb
->pStubMsg
->Buffer
;
4614 case USER_MARSHAL_CB_BUFFER_SIZE
:
4615 case USER_MARSHAL_CB_FREE
:
4618 WARN("unrecognised CBType %d\n", umcb
->CBType
);
4624 /***********************************************************************
4625 * NdrClearOutParameters [RPCRT4.@]
4627 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
4628 PFORMAT_STRING pFormat
,
4631 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
4634 /***********************************************************************
4635 * NdrConvert [RPCRT4.@]
4637 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
4639 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
4640 /* FIXME: since this stub doesn't do any converting, the proper behavior
4641 is to raise an exception */
4644 /***********************************************************************
4645 * NdrConvert2 [RPCRT4.@]
4647 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, LONG NumberParams
)
4649 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4650 pStubMsg
, pFormat
, NumberParams
);
4651 /* FIXME: since this stub doesn't do any converting, the proper behavior
4652 is to raise an exception */
4655 #include "pshpack1.h"
4656 typedef struct _NDR_CSTRUCT_FORMAT
4659 unsigned char alignment
;
4660 unsigned short memory_size
;
4661 short offset_to_array_description
;
4662 } NDR_CSTRUCT_FORMAT
, NDR_CVSTRUCT_FORMAT
;
4663 #include "poppack.h"
4665 /***********************************************************************
4666 * NdrConformantStructMarshall [RPCRT4.@]
4668 unsigned char * WINAPI
NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4669 unsigned char *pMemory
,
4670 PFORMAT_STRING pFormat
)
4672 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4673 PFORMAT_STRING pCArrayFormat
;
4674 ULONG esize
, bufsize
;
4676 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4678 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4679 if ((pCStructFormat
->type
!= FC_CPSTRUCT
) && (pCStructFormat
->type
!= FC_CSTRUCT
))
4681 ERR("invalid format type %x\n", pCStructFormat
->type
);
4682 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4686 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4687 pCStructFormat
->offset_to_array_description
;
4688 if (*pCArrayFormat
!= FC_CARRAY
)
4690 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4691 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4694 esize
= *(const WORD
*)(pCArrayFormat
+2);
4696 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4697 pCArrayFormat
+ 4, 0);
4699 WriteConformance(pStubMsg
);
4701 align_pointer_clear(&pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4703 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4705 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4706 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4708 ERR("integer overflow of memory_size %u with bufsize %u\n",
4709 pCStructFormat
->memory_size
, bufsize
);
4710 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4712 /* copy constant sized part of struct */
4713 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4714 safe_copy_to_buffer(pStubMsg
, pMemory
, pCStructFormat
->memory_size
+ bufsize
);
4716 if (pCStructFormat
->type
== FC_CPSTRUCT
)
4717 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4722 /***********************************************************************
4723 * NdrConformantStructUnmarshall [RPCRT4.@]
4725 unsigned char * WINAPI
NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4726 unsigned char **ppMemory
,
4727 PFORMAT_STRING pFormat
,
4728 unsigned char fMustAlloc
)
4730 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4731 PFORMAT_STRING pCArrayFormat
;
4732 ULONG esize
, bufsize
;
4733 unsigned char *saved_buffer
;
4735 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4737 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4738 if ((pCStructFormat
->type
!= FC_CPSTRUCT
) && (pCStructFormat
->type
!= FC_CSTRUCT
))
4740 ERR("invalid format type %x\n", pCStructFormat
->type
);
4741 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4744 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4745 pCStructFormat
->offset_to_array_description
;
4746 if (*pCArrayFormat
!= FC_CARRAY
)
4748 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4749 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4752 esize
= *(const WORD
*)(pCArrayFormat
+2);
4754 pCArrayFormat
= ReadConformance(pStubMsg
, pCArrayFormat
+ 4);
4756 align_pointer(&pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4758 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4760 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4761 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4763 ERR("integer overflow of memory_size %u with bufsize %u\n",
4764 pCStructFormat
->memory_size
, bufsize
);
4765 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4770 SIZE_T size
= pCStructFormat
->memory_size
+ bufsize
;
4771 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4775 if (!pStubMsg
->IsClient
&& !*ppMemory
)
4776 /* for servers, we just point straight into the RPC buffer */
4777 *ppMemory
= pStubMsg
->Buffer
;
4780 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4781 safe_buffer_increment(pStubMsg
, pCStructFormat
->memory_size
+ bufsize
);
4782 if (pCStructFormat
->type
== FC_CPSTRUCT
)
4783 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4785 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
4786 if (*ppMemory
!= saved_buffer
)
4787 memcpy(*ppMemory
, saved_buffer
, pCStructFormat
->memory_size
+ bufsize
);
4792 /***********************************************************************
4793 * NdrConformantStructBufferSize [RPCRT4.@]
4795 void WINAPI
NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4796 unsigned char *pMemory
,
4797 PFORMAT_STRING pFormat
)
4799 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4800 PFORMAT_STRING pCArrayFormat
;
4803 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4805 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4806 if ((pCStructFormat
->type
!= FC_CPSTRUCT
) && (pCStructFormat
->type
!= FC_CSTRUCT
))
4808 ERR("invalid format type %x\n", pCStructFormat
->type
);
4809 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4812 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4813 pCStructFormat
->offset_to_array_description
;
4814 if (*pCArrayFormat
!= FC_CARRAY
)
4816 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4817 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4820 esize
= *(const WORD
*)(pCArrayFormat
+2);
4822 pCArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
, pCArrayFormat
+4, 0);
4823 SizeConformance(pStubMsg
);
4825 align_length(&pStubMsg
->BufferLength
, pCStructFormat
->alignment
+ 1);
4827 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4829 safe_buffer_length_increment(pStubMsg
, pCStructFormat
->memory_size
);
4830 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
4832 if (pCStructFormat
->type
== FC_CPSTRUCT
)
4833 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4836 /***********************************************************************
4837 * NdrConformantStructMemorySize [RPCRT4.@]
4839 ULONG WINAPI
NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4840 PFORMAT_STRING pFormat
)
4846 /***********************************************************************
4847 * NdrConformantStructFree [RPCRT4.@]
4849 void WINAPI
NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
4850 unsigned char *pMemory
,
4851 PFORMAT_STRING pFormat
)
4853 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4854 PFORMAT_STRING pCArrayFormat
;
4856 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4858 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4859 if ((pCStructFormat
->type
!= FC_CPSTRUCT
) && (pCStructFormat
->type
!= FC_CSTRUCT
))
4861 ERR("invalid format type %x\n", pCStructFormat
->type
);
4862 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4866 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4867 pCStructFormat
->offset_to_array_description
;
4868 if (*pCArrayFormat
!= FC_CARRAY
)
4870 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4871 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4875 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4876 pCArrayFormat
+ 4, 0);
4878 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4880 /* copy constant sized part of struct */
4881 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4883 if (pCStructFormat
->type
== FC_CPSTRUCT
)
4884 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4887 /***********************************************************************
4888 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4890 unsigned char * WINAPI
NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4891 unsigned char *pMemory
,
4892 PFORMAT_STRING pFormat
)
4894 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4895 PFORMAT_STRING pCVArrayFormat
;
4897 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4899 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4900 if (pCVStructFormat
->type
!= FC_CVSTRUCT
)
4902 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4903 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4907 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4908 pCVStructFormat
->offset_to_array_description
;
4910 array_compute_and_write_conformance(*pCVArrayFormat
, pStubMsg
,
4911 pMemory
+ pCVStructFormat
->memory_size
,
4914 align_pointer_clear(&pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4916 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4918 /* write constant sized part */
4919 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4920 safe_copy_to_buffer(pStubMsg
, pMemory
, pCVStructFormat
->memory_size
);
4922 array_write_variance_and_marshall(*pCVArrayFormat
, pStubMsg
,
4923 pMemory
+ pCVStructFormat
->memory_size
,
4924 pCVArrayFormat
, FALSE
/* fHasPointers */);
4926 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4931 /***********************************************************************
4932 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4934 unsigned char * WINAPI
NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4935 unsigned char **ppMemory
,
4936 PFORMAT_STRING pFormat
,
4937 unsigned char fMustAlloc
)
4939 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4940 PFORMAT_STRING pCVArrayFormat
;
4941 ULONG memsize
, bufsize
;
4942 unsigned char *saved_buffer
, *saved_array_buffer
;
4944 unsigned char *array_memory
;
4946 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4948 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4949 if (pCVStructFormat
->type
!= FC_CVSTRUCT
)
4951 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4952 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4956 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4957 pCVStructFormat
->offset_to_array_description
;
4959 memsize
= array_read_conformance(*pCVArrayFormat
, pStubMsg
,
4962 align_pointer(&pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4964 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4966 /* work out how much memory to allocate if we need to do so */
4967 if (!fMustAlloc
&& !*ppMemory
)
4971 SIZE_T size
= pCVStructFormat
->memory_size
+ memsize
;
4972 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4975 /* mark the start of the constant data */
4976 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4977 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4979 array_memory
= *ppMemory
+ pCVStructFormat
->memory_size
;
4980 bufsize
= array_read_variance_and_unmarshall(*pCVArrayFormat
, pStubMsg
,
4981 &array_memory
, pCVArrayFormat
,
4982 FALSE
/* fMustAlloc */,
4983 FALSE
/* fUseServerBufferMemory */,
4984 FALSE
/* fUnmarshall */);
4986 /* save offset in case unmarshalling pointers changes it */
4987 offset
= pStubMsg
->Offset
;
4989 /* mark the start of the array data */
4990 saved_array_buffer
= pStubMsg
->Buffer
;
4991 safe_buffer_increment(pStubMsg
, bufsize
);
4993 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4995 /* copy the constant data */
4996 memcpy(*ppMemory
, saved_buffer
, pCVStructFormat
->memory_size
);
4997 /* copy the array data */
4998 TRACE("copying %p to %p\n", saved_array_buffer
, *ppMemory
+ pCVStructFormat
->memory_size
);
4999 memcpy(*ppMemory
+ pCVStructFormat
->memory_size
+ offset
,
5000 saved_array_buffer
, bufsize
);
5002 if (*pCVArrayFormat
== FC_C_CSTRING
)
5003 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory
+ pCVStructFormat
->memory_size
)));
5004 else if (*pCVArrayFormat
== FC_C_WSTRING
)
5005 TRACE("string=%s\n", debugstr_w((WCHAR
*)(*ppMemory
+ pCVStructFormat
->memory_size
)));
5010 /***********************************************************************
5011 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
5013 void WINAPI
NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5014 unsigned char *pMemory
,
5015 PFORMAT_STRING pFormat
)
5017 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
5018 PFORMAT_STRING pCVArrayFormat
;
5020 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5022 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
5023 if (pCVStructFormat
->type
!= FC_CVSTRUCT
)
5025 ERR("invalid format type %x\n", pCVStructFormat
->type
);
5026 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5030 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
5031 pCVStructFormat
->offset_to_array_description
;
5032 array_compute_and_size_conformance(*pCVArrayFormat
, pStubMsg
,
5033 pMemory
+ pCVStructFormat
->memory_size
,
5036 align_length(&pStubMsg
->BufferLength
, pCVStructFormat
->alignment
+ 1);
5038 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
5040 safe_buffer_length_increment(pStubMsg
, pCVStructFormat
->memory_size
);
5042 array_buffer_size(*pCVArrayFormat
, pStubMsg
,
5043 pMemory
+ pCVStructFormat
->memory_size
, pCVArrayFormat
,
5044 FALSE
/* fHasPointers */);
5046 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5049 /***********************************************************************
5050 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
5052 ULONG WINAPI
NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5053 PFORMAT_STRING pFormat
)
5055 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
5056 PFORMAT_STRING pCVArrayFormat
;
5058 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5060 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
5061 if (pCVStructFormat
->type
!= FC_CVSTRUCT
)
5063 ERR("invalid format type %x\n", pCVStructFormat
->type
);
5064 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5068 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
5069 pCVStructFormat
->offset_to_array_description
;
5070 array_read_conformance(*pCVArrayFormat
, pStubMsg
, pCVArrayFormat
);
5072 align_pointer(&pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
5074 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
5076 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
5077 array_memory_size(*pCVArrayFormat
, pStubMsg
, pCVArrayFormat
,
5078 FALSE
/* fHasPointers */);
5080 pStubMsg
->MemorySize
+= pCVStructFormat
->memory_size
;
5082 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5084 return pStubMsg
->MemorySize
;
5087 /***********************************************************************
5088 * NdrConformantVaryingStructFree [RPCRT4.@]
5090 void WINAPI
NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
5091 unsigned char *pMemory
,
5092 PFORMAT_STRING pFormat
)
5094 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
5095 PFORMAT_STRING pCVArrayFormat
;
5097 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5099 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
5100 if (pCVStructFormat
->type
!= FC_CVSTRUCT
)
5102 ERR("invalid format type %x\n", pCVStructFormat
->type
);
5103 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5107 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
5108 pCVStructFormat
->offset_to_array_description
;
5109 array_free(*pCVArrayFormat
, pStubMsg
,
5110 pMemory
+ pCVStructFormat
->memory_size
, pCVArrayFormat
,
5111 FALSE
/* fHasPointers */);
5113 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
5115 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5118 #include "pshpack1.h"
5122 unsigned char alignment
;
5123 unsigned short total_size
;
5124 } NDR_SMFARRAY_FORMAT
;
5129 unsigned char alignment
;
5131 } NDR_LGFARRAY_FORMAT
;
5132 #include "poppack.h"
5134 /***********************************************************************
5135 * NdrFixedArrayMarshall [RPCRT4.@]
5137 unsigned char * WINAPI
NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5138 unsigned char *pMemory
,
5139 PFORMAT_STRING pFormat
)
5141 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5144 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5146 if ((pSmFArrayFormat
->type
!= FC_SMFARRAY
) &&
5147 (pSmFArrayFormat
->type
!= FC_LGFARRAY
))
5149 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5150 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5154 align_pointer_clear(&pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
5156 if (pSmFArrayFormat
->type
== FC_SMFARRAY
)
5158 total_size
= pSmFArrayFormat
->total_size
;
5159 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5163 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5164 total_size
= pLgFArrayFormat
->total_size
;
5165 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5168 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5169 safe_copy_to_buffer(pStubMsg
, pMemory
, total_size
);
5171 pFormat
= EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
5176 /***********************************************************************
5177 * NdrFixedArrayUnmarshall [RPCRT4.@]
5179 unsigned char * WINAPI
NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5180 unsigned char **ppMemory
,
5181 PFORMAT_STRING pFormat
,
5182 unsigned char fMustAlloc
)
5184 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5186 unsigned char *saved_buffer
;
5188 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5190 if ((pSmFArrayFormat
->type
!= FC_SMFARRAY
) &&
5191 (pSmFArrayFormat
->type
!= FC_LGFARRAY
))
5193 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5194 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5198 align_pointer(&pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
5200 if (pSmFArrayFormat
->type
== FC_SMFARRAY
)
5202 total_size
= pSmFArrayFormat
->total_size
;
5203 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5207 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5208 total_size
= pLgFArrayFormat
->total_size
;
5209 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5213 *ppMemory
= NdrAllocate(pStubMsg
, total_size
);
5216 if (!pStubMsg
->IsClient
&& !*ppMemory
)
5217 /* for servers, we just point straight into the RPC buffer */
5218 *ppMemory
= pStubMsg
->Buffer
;
5221 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5222 safe_buffer_increment(pStubMsg
, total_size
);
5223 pFormat
= EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
5225 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
5226 if (*ppMemory
!= saved_buffer
)
5227 memcpy(*ppMemory
, saved_buffer
, total_size
);
5232 /***********************************************************************
5233 * NdrFixedArrayBufferSize [RPCRT4.@]
5235 void WINAPI
NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5236 unsigned char *pMemory
,
5237 PFORMAT_STRING pFormat
)
5239 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5242 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5244 if ((pSmFArrayFormat
->type
!= FC_SMFARRAY
) &&
5245 (pSmFArrayFormat
->type
!= FC_LGFARRAY
))
5247 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5248 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5252 align_length(&pStubMsg
->BufferLength
, pSmFArrayFormat
->alignment
+ 1);
5254 if (pSmFArrayFormat
->type
== FC_SMFARRAY
)
5256 total_size
= pSmFArrayFormat
->total_size
;
5257 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5261 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5262 total_size
= pLgFArrayFormat
->total_size
;
5263 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5265 safe_buffer_length_increment(pStubMsg
, total_size
);
5267 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5270 /***********************************************************************
5271 * NdrFixedArrayMemorySize [RPCRT4.@]
5273 ULONG WINAPI
NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5274 PFORMAT_STRING pFormat
)
5276 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5279 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5281 if ((pSmFArrayFormat
->type
!= FC_SMFARRAY
) &&
5282 (pSmFArrayFormat
->type
!= FC_LGFARRAY
))
5284 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5285 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5289 align_pointer(&pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
5291 if (pSmFArrayFormat
->type
== FC_SMFARRAY
)
5293 total_size
= pSmFArrayFormat
->total_size
;
5294 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5298 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5299 total_size
= pLgFArrayFormat
->total_size
;
5300 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5302 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5303 safe_buffer_increment(pStubMsg
, total_size
);
5304 pStubMsg
->MemorySize
+= total_size
;
5306 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5311 /***********************************************************************
5312 * NdrFixedArrayFree [RPCRT4.@]
5314 void WINAPI
NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
5315 unsigned char *pMemory
,
5316 PFORMAT_STRING pFormat
)
5318 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5320 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5322 if ((pSmFArrayFormat
->type
!= FC_SMFARRAY
) &&
5323 (pSmFArrayFormat
->type
!= FC_LGFARRAY
))
5325 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5326 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5330 if (pSmFArrayFormat
->type
== FC_SMFARRAY
)
5331 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5334 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5335 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5338 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5341 /***********************************************************************
5342 * NdrVaryingArrayMarshall [RPCRT4.@]
5344 unsigned char * WINAPI
NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5345 unsigned char *pMemory
,
5346 PFORMAT_STRING pFormat
)
5348 unsigned char alignment
;
5349 DWORD elements
, esize
;
5352 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5354 if ((pFormat
[0] != FC_SMVARRAY
) &&
5355 (pFormat
[0] != FC_LGVARRAY
))
5357 ERR("invalid format type %x\n", pFormat
[0]);
5358 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5362 alignment
= pFormat
[1] + 1;
5364 if (pFormat
[0] == FC_SMVARRAY
)
5367 pFormat
+= sizeof(WORD
);
5368 elements
= *(const WORD
*)pFormat
;
5369 pFormat
+= sizeof(WORD
);
5374 pFormat
+= sizeof(DWORD
);
5375 elements
= *(const DWORD
*)pFormat
;
5376 pFormat
+= sizeof(DWORD
);
5379 esize
= *(const WORD
*)pFormat
;
5380 pFormat
+= sizeof(WORD
);
5382 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5383 if ((pStubMsg
->ActualCount
> elements
) ||
5384 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5386 RpcRaiseException(RPC_S_INVALID_BOUND
);
5390 WriteVariance(pStubMsg
);
5392 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
5394 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
5395 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5396 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
5398 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
5403 /***********************************************************************
5404 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5406 unsigned char * WINAPI
NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5407 unsigned char **ppMemory
,
5408 PFORMAT_STRING pFormat
,
5409 unsigned char fMustAlloc
)
5411 unsigned char alignment
;
5412 DWORD size
, elements
, esize
;
5414 unsigned char *saved_buffer
;
5417 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5419 if ((pFormat
[0] != FC_SMVARRAY
) &&
5420 (pFormat
[0] != FC_LGVARRAY
))
5422 ERR("invalid format type %x\n", pFormat
[0]);
5423 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5427 alignment
= pFormat
[1] + 1;
5429 if (pFormat
[0] == FC_SMVARRAY
)
5432 size
= *(const WORD
*)pFormat
;
5433 pFormat
+= sizeof(WORD
);
5434 elements
= *(const WORD
*)pFormat
;
5435 pFormat
+= sizeof(WORD
);
5440 size
= *(const DWORD
*)pFormat
;
5441 pFormat
+= sizeof(DWORD
);
5442 elements
= *(const DWORD
*)pFormat
;
5443 pFormat
+= sizeof(DWORD
);
5446 esize
= *(const WORD
*)pFormat
;
5447 pFormat
+= sizeof(WORD
);
5449 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
5451 align_pointer(&pStubMsg
->Buffer
, alignment
);
5453 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
5454 offset
= pStubMsg
->Offset
;
5456 if (!fMustAlloc
&& !*ppMemory
)
5459 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5460 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5461 safe_buffer_increment(pStubMsg
, bufsize
);
5463 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
5465 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
5470 /***********************************************************************
5471 * NdrVaryingArrayBufferSize [RPCRT4.@]
5473 void WINAPI
NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5474 unsigned char *pMemory
,
5475 PFORMAT_STRING pFormat
)
5477 unsigned char alignment
;
5478 DWORD elements
, esize
;
5480 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5482 if ((pFormat
[0] != FC_SMVARRAY
) &&
5483 (pFormat
[0] != FC_LGVARRAY
))
5485 ERR("invalid format type %x\n", pFormat
[0]);
5486 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5490 alignment
= pFormat
[1] + 1;
5492 if (pFormat
[0] == FC_SMVARRAY
)
5495 pFormat
+= sizeof(WORD
);
5496 elements
= *(const WORD
*)pFormat
;
5497 pFormat
+= sizeof(WORD
);
5502 pFormat
+= sizeof(DWORD
);
5503 elements
= *(const DWORD
*)pFormat
;
5504 pFormat
+= sizeof(DWORD
);
5507 esize
= *(const WORD
*)pFormat
;
5508 pFormat
+= sizeof(WORD
);
5510 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5511 if ((pStubMsg
->ActualCount
> elements
) ||
5512 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5514 RpcRaiseException(RPC_S_INVALID_BOUND
);
5518 SizeVariance(pStubMsg
);
5520 align_length(&pStubMsg
->BufferLength
, alignment
);
5522 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
5524 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5527 /***********************************************************************
5528 * NdrVaryingArrayMemorySize [RPCRT4.@]
5530 ULONG WINAPI
NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5531 PFORMAT_STRING pFormat
)
5533 unsigned char alignment
;
5534 DWORD size
, elements
, esize
;
5536 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5538 if ((pFormat
[0] != FC_SMVARRAY
) &&
5539 (pFormat
[0] != FC_LGVARRAY
))
5541 ERR("invalid format type %x\n", pFormat
[0]);
5542 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5546 alignment
= pFormat
[1] + 1;
5548 if (pFormat
[0] == FC_SMVARRAY
)
5551 size
= *(const WORD
*)pFormat
;
5552 pFormat
+= sizeof(WORD
);
5553 elements
= *(const WORD
*)pFormat
;
5554 pFormat
+= sizeof(WORD
);
5559 size
= *(const DWORD
*)pFormat
;
5560 pFormat
+= sizeof(DWORD
);
5561 elements
= *(const DWORD
*)pFormat
;
5562 pFormat
+= sizeof(DWORD
);
5565 esize
= *(const WORD
*)pFormat
;
5566 pFormat
+= sizeof(WORD
);
5568 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
5570 align_pointer(&pStubMsg
->Buffer
, alignment
);
5572 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
5573 pStubMsg
->MemorySize
+= size
;
5575 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5577 return pStubMsg
->MemorySize
;
5580 /***********************************************************************
5581 * NdrVaryingArrayFree [RPCRT4.@]
5583 void WINAPI
NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
5584 unsigned char *pMemory
,
5585 PFORMAT_STRING pFormat
)
5589 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5591 if ((pFormat
[0] != FC_SMVARRAY
) &&
5592 (pFormat
[0] != FC_LGVARRAY
))
5594 ERR("invalid format type %x\n", pFormat
[0]);
5595 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5599 if (pFormat
[0] == FC_SMVARRAY
)
5602 pFormat
+= sizeof(WORD
);
5603 elements
= *(const WORD
*)pFormat
;
5604 pFormat
+= sizeof(WORD
);
5609 pFormat
+= sizeof(DWORD
);
5610 elements
= *(const DWORD
*)pFormat
;
5611 pFormat
+= sizeof(DWORD
);
5614 pFormat
+= sizeof(WORD
);
5616 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5617 if ((pStubMsg
->ActualCount
> elements
) ||
5618 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5620 RpcRaiseException(RPC_S_INVALID_BOUND
);
5624 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5627 static ULONG
get_discriminant(unsigned char fc
, const unsigned char *pMemory
)
5640 return *(const USHORT
*)pMemory
;
5644 return *(const ULONG
*)pMemory
;
5647 return *(const ULONG_PTR
*)pMemory
;
5649 FIXME("Unhandled base type: 0x%02x\n", fc
);
5654 static PFORMAT_STRING
get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg
,
5656 PFORMAT_STRING pFormat
)
5658 unsigned short num_arms
, arm
, type
;
5660 num_arms
= *(const SHORT
*)pFormat
& 0x0fff;
5662 for(arm
= 0; arm
< num_arms
; arm
++)
5664 if(discriminant
== *(const ULONG
*)pFormat
)
5672 type
= *(const unsigned short*)pFormat
;
5673 TRACE("type %04x\n", type
);
5674 if(arm
== num_arms
) /* default arm extras */
5678 ERR("no arm for 0x%x and no default case\n", discriminant
);
5679 RpcRaiseException(RPC_S_INVALID_TAG
);
5684 TRACE("falling back to empty default case for 0x%x\n", discriminant
);
5691 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
, ULONG discriminant
, PFORMAT_STRING pFormat
)
5693 unsigned short type
;
5697 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5701 type
= *(const unsigned short*)pFormat
;
5702 if((type
& 0xff00) == 0x8000)
5704 unsigned char basetype
= LOBYTE(type
);
5705 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &basetype
);
5709 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5710 NDR_MARSHALL m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
5713 unsigned char *saved_buffer
= NULL
;
5714 BOOL pointer_buffer_mark_set
= FALSE
;
5721 align_pointer_clear(&pStubMsg
->Buffer
, 4);
5722 saved_buffer
= pStubMsg
->Buffer
;
5723 if (pStubMsg
->PointerBufferMark
)
5725 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5726 pStubMsg
->PointerBufferMark
= NULL
;
5727 pointer_buffer_mark_set
= TRUE
;
5730 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
5732 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char **)pMemory
, desc
);
5733 if (pointer_buffer_mark_set
)
5735 STD_OVERFLOW_CHECK(pStubMsg
);
5736 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5737 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5739 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5740 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
5741 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5743 pStubMsg
->Buffer
= saved_buffer
+ 4;
5747 /* must be dereferenced first */
5748 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5751 m(pStubMsg
, pMemory
, desc
);
5755 FIXME("no marshaller for embedded type %02x\n", *desc
);
5760 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5761 unsigned char **ppMemory
,
5763 PFORMAT_STRING pFormat
,
5764 unsigned char fMustAlloc
)
5766 unsigned short type
;
5770 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5774 type
= *(const unsigned short*)pFormat
;
5775 if((type
& 0xff00) == 0x8000)
5777 unsigned char basetype
= LOBYTE(type
);
5778 return NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &basetype
, FALSE
);
5782 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5783 NDR_UNMARSHALL m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
5786 unsigned char *saved_buffer
= NULL
;
5787 BOOL pointer_buffer_mark_set
= FALSE
;
5794 align_pointer(&pStubMsg
->Buffer
, 4);
5795 saved_buffer
= pStubMsg
->Buffer
;
5796 if (pStubMsg
->PointerBufferMark
)
5798 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5799 pStubMsg
->PointerBufferMark
= NULL
;
5800 pointer_buffer_mark_set
= TRUE
;
5803 pStubMsg
->Buffer
+= 4; /* for pointer ID */
5805 if (saved_buffer
+ 4 > pStubMsg
->BufferEnd
)
5807 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5808 saved_buffer
, pStubMsg
->BufferEnd
);
5809 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5812 PointerUnmarshall(pStubMsg
, saved_buffer
, *(unsigned char ***)ppMemory
, **(unsigned char ***)ppMemory
, desc
, fMustAlloc
);
5813 if (pointer_buffer_mark_set
)
5815 STD_OVERFLOW_CHECK(pStubMsg
);
5816 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5817 pStubMsg
->Buffer
= saved_buffer
+ 4;
5821 /* must be dereferenced first */
5822 m(pStubMsg
, *(unsigned char ***)ppMemory
, desc
, fMustAlloc
);
5825 m(pStubMsg
, ppMemory
, desc
, fMustAlloc
);
5829 FIXME("no marshaller for embedded type %02x\n", *desc
);
5834 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg
,
5835 unsigned char *pMemory
,
5837 PFORMAT_STRING pFormat
)
5839 unsigned short type
;
5843 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5847 type
= *(const unsigned short*)pFormat
;
5848 if((type
& 0xff00) == 0x8000)
5850 unsigned char basetype
= LOBYTE(type
);
5851 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &basetype
);
5855 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5856 NDR_BUFFERSIZE m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
5865 align_length(&pStubMsg
->BufferLength
, 4);
5866 safe_buffer_length_increment(pStubMsg
, 4); /* for pointer ID */
5867 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5869 int saved_buffer_length
= pStubMsg
->BufferLength
;
5870 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
5871 pStubMsg
->PointerLength
= 0;
5872 if(!pStubMsg
->BufferLength
)
5873 ERR("BufferLength == 0??\n");
5874 PointerBufferSize(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5875 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
5876 pStubMsg
->BufferLength
= saved_buffer_length
;
5880 /* must be dereferenced first */
5881 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5884 m(pStubMsg
, pMemory
, desc
);
5888 FIXME("no buffersizer for embedded type %02x\n", *desc
);
5892 static ULONG
union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg
,
5894 PFORMAT_STRING pFormat
)
5896 unsigned short type
, size
;
5898 size
= *(const unsigned short*)pFormat
;
5899 pStubMsg
->Memory
+= size
;
5902 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5906 type
= *(const unsigned short*)pFormat
;
5907 if((type
& 0xff00) == 0x8000)
5909 return NdrBaseTypeMemorySize(pStubMsg
, pFormat
);
5913 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5914 NDR_MEMORYSIZE m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
5915 unsigned char *saved_buffer
;
5924 align_pointer(&pStubMsg
->Buffer
, 4);
5925 saved_buffer
= pStubMsg
->Buffer
;
5926 safe_buffer_increment(pStubMsg
, 4);
5927 align_length(&pStubMsg
->MemorySize
, sizeof(void *));
5928 pStubMsg
->MemorySize
+= sizeof(void *);
5929 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5930 PointerMemorySize(pStubMsg
, saved_buffer
, pFormat
);
5933 return m(pStubMsg
, desc
);
5937 FIXME("no marshaller for embedded type %02x\n", *desc
);
5940 TRACE("size %d\n", size
);
5944 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg
,
5945 unsigned char *pMemory
,
5947 PFORMAT_STRING pFormat
)
5949 unsigned short type
;
5953 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5957 type
= *(const unsigned short*)pFormat
;
5958 if((type
& 0xff00) != 0x8000)
5960 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5961 NDR_FREE m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
5970 PointerFree(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5973 /* must be dereferenced first */
5974 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5977 m(pStubMsg
, pMemory
, desc
);
5983 /***********************************************************************
5984 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5986 unsigned char * WINAPI
NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5987 unsigned char *pMemory
,
5988 PFORMAT_STRING pFormat
)
5990 unsigned char switch_type
;
5991 unsigned char increment
;
5994 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5997 switch_type
= *pFormat
& 0xf;
5998 increment
= (*pFormat
& 0xf0) >> 4;
6001 align_pointer_clear(&pStubMsg
->Buffer
, increment
);
6003 switch_value
= get_discriminant(switch_type
, pMemory
);
6004 TRACE("got switch value 0x%x\n", switch_value
);
6006 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &switch_type
);
6007 pMemory
+= increment
;
6009 return union_arm_marshall(pStubMsg
, pMemory
, switch_value
, pFormat
);
6012 /***********************************************************************
6013 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
6015 unsigned char * WINAPI
NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6016 unsigned char **ppMemory
,
6017 PFORMAT_STRING pFormat
,
6018 unsigned char fMustAlloc
)
6020 unsigned char switch_type
;
6021 unsigned char increment
;
6023 unsigned short size
;
6024 unsigned char *pMemoryArm
;
6026 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
6029 switch_type
= *pFormat
& 0xf;
6030 increment
= (*pFormat
& 0xf0) >> 4;
6033 align_pointer(&pStubMsg
->Buffer
, increment
);
6034 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
6035 TRACE("got switch value 0x%x\n", switch_value
);
6037 size
= *(const unsigned short*)pFormat
+ increment
;
6038 if (!fMustAlloc
&& !*ppMemory
)
6041 *ppMemory
= NdrAllocate(pStubMsg
, size
);
6043 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6044 * since the arm is part of the memory block that is encompassed by
6045 * the whole union. Memory is forced to allocate when pointers
6046 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6047 * clearing the memory we pass in to the unmarshaller */
6049 memset(*ppMemory
, 0, size
);
6051 NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &switch_type
, FALSE
);
6052 pMemoryArm
= *ppMemory
+ increment
;
6054 return union_arm_unmarshall(pStubMsg
, &pMemoryArm
, switch_value
, pFormat
, FALSE
);
6057 /***********************************************************************
6058 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
6060 void WINAPI
NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6061 unsigned char *pMemory
,
6062 PFORMAT_STRING pFormat
)
6064 unsigned char switch_type
;
6065 unsigned char increment
;
6068 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6071 switch_type
= *pFormat
& 0xf;
6072 increment
= (*pFormat
& 0xf0) >> 4;
6075 align_length(&pStubMsg
->BufferLength
, increment
);
6076 switch_value
= get_discriminant(switch_type
, pMemory
);
6077 TRACE("got switch value 0x%x\n", switch_value
);
6079 /* Add discriminant size */
6080 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&switch_value
, &switch_type
);
6081 pMemory
+= increment
;
6083 union_arm_buffer_size(pStubMsg
, pMemory
, switch_value
, pFormat
);
6086 /***********************************************************************
6087 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
6089 ULONG WINAPI
NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6090 PFORMAT_STRING pFormat
)
6092 unsigned char switch_type
;
6093 unsigned char increment
;
6096 switch_type
= *pFormat
& 0xf;
6097 increment
= (*pFormat
& 0xf0) >> 4;
6100 align_pointer(&pStubMsg
->Buffer
, increment
);
6101 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
6102 TRACE("got switch value 0x%x\n", switch_value
);
6104 pStubMsg
->Memory
+= increment
;
6106 return increment
+ union_arm_memory_size(pStubMsg
, switch_value
, pFormat
+ *(const SHORT
*)pFormat
);
6109 /***********************************************************************
6110 * NdrEncapsulatedUnionFree [RPCRT4.@]
6112 void WINAPI
NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
6113 unsigned char *pMemory
,
6114 PFORMAT_STRING pFormat
)
6116 unsigned char switch_type
;
6117 unsigned char increment
;
6120 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6123 switch_type
= *pFormat
& 0xf;
6124 increment
= (*pFormat
& 0xf0) >> 4;
6127 switch_value
= get_discriminant(switch_type
, pMemory
);
6128 TRACE("got switch value 0x%x\n", switch_value
);
6130 pMemory
+= increment
;
6132 union_arm_free(pStubMsg
, pMemory
, switch_value
, pFormat
);
6135 /***********************************************************************
6136 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
6138 unsigned char * WINAPI
NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6139 unsigned char *pMemory
,
6140 PFORMAT_STRING pFormat
)
6142 unsigned char switch_type
;
6144 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6147 switch_type
= *pFormat
;
6150 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6151 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6152 /* Marshall discriminant */
6153 NdrBaseTypeMarshall(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
6155 return union_arm_marshall(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6158 static LONG
unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg
,
6159 PFORMAT_STRING
*ppFormat
)
6161 LONG discriminant
= 0;
6171 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
6181 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6182 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
6190 align_pointer(&pStubMsg
->Buffer
, sizeof(ULONG
));
6191 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
6196 FIXME("Unhandled base type: 0x%02x\n", **ppFormat
);
6200 *ppFormat
= SkipConformance(pStubMsg
, *ppFormat
);
6201 return discriminant
;
6204 /**********************************************************************
6205 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
6207 unsigned char * WINAPI
NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6208 unsigned char **ppMemory
,
6209 PFORMAT_STRING pFormat
,
6210 unsigned char fMustAlloc
)
6213 unsigned short size
;
6215 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
6218 /* Unmarshall discriminant */
6219 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
6220 TRACE("unmarshalled discriminant %x\n", discriminant
);
6222 pFormat
+= *(const SHORT
*)pFormat
;
6224 size
= *(const unsigned short*)pFormat
;
6226 if (!fMustAlloc
&& !*ppMemory
)
6229 *ppMemory
= NdrAllocate(pStubMsg
, size
);
6231 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6232 * since the arm is part of the memory block that is encompassed by
6233 * the whole union. Memory is forced to allocate when pointers
6234 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6235 * clearing the memory we pass in to the unmarshaller */
6237 memset(*ppMemory
, 0, size
);
6239 return union_arm_unmarshall(pStubMsg
, ppMemory
, discriminant
, pFormat
, FALSE
);
6242 /***********************************************************************
6243 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
6245 void WINAPI
NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6246 unsigned char *pMemory
,
6247 PFORMAT_STRING pFormat
)
6249 unsigned char switch_type
;
6251 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6254 switch_type
= *pFormat
;
6257 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6258 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6259 /* Add discriminant size */
6260 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
6262 union_arm_buffer_size(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6265 /***********************************************************************
6266 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
6268 ULONG WINAPI
NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6269 PFORMAT_STRING pFormat
)
6274 /* Unmarshall discriminant */
6275 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
6276 TRACE("unmarshalled discriminant 0x%x\n", discriminant
);
6278 return union_arm_memory_size(pStubMsg
, discriminant
, pFormat
+ *(const SHORT
*)pFormat
);
6281 /***********************************************************************
6282 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6284 void WINAPI
NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
6285 unsigned char *pMemory
,
6286 PFORMAT_STRING pFormat
)
6288 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6292 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6293 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6295 union_arm_free(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6298 /***********************************************************************
6299 * NdrByteCountPointerMarshall [RPCRT4.@]
6301 unsigned char * WINAPI
NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6302 unsigned char *pMemory
,
6303 PFORMAT_STRING pFormat
)
6309 /***********************************************************************
6310 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6312 unsigned char * WINAPI
NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6313 unsigned char **ppMemory
,
6314 PFORMAT_STRING pFormat
,
6315 unsigned char fMustAlloc
)
6321 /***********************************************************************
6322 * NdrByteCountPointerBufferSize [RPCRT4.@]
6324 void WINAPI
NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6325 unsigned char *pMemory
,
6326 PFORMAT_STRING pFormat
)
6331 /***********************************************************************
6332 * NdrByteCountPointerMemorySize [internal]
6334 static ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6335 PFORMAT_STRING pFormat
)
6341 /***********************************************************************
6342 * NdrByteCountPointerFree [RPCRT4.@]
6344 void WINAPI
NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
6345 unsigned char *pMemory
,
6346 PFORMAT_STRING pFormat
)
6351 /***********************************************************************
6352 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6354 unsigned char * WINAPI
NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6355 unsigned char *pMemory
,
6356 PFORMAT_STRING pFormat
)
6362 /***********************************************************************
6363 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6365 unsigned char * WINAPI
NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6366 unsigned char **ppMemory
,
6367 PFORMAT_STRING pFormat
,
6368 unsigned char fMustAlloc
)
6374 /***********************************************************************
6375 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6377 void WINAPI
NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6378 unsigned char *pMemory
,
6379 PFORMAT_STRING pFormat
)
6384 /***********************************************************************
6385 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6387 ULONG WINAPI
NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6388 PFORMAT_STRING pFormat
)
6394 /***********************************************************************
6395 * NdrXmitOrRepAsFree [RPCRT4.@]
6397 void WINAPI
NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg
,
6398 unsigned char *pMemory
,
6399 PFORMAT_STRING pFormat
)
6404 /***********************************************************************
6405 * NdrRangeMarshall [internal]
6407 static unsigned char *WINAPI
NdrRangeMarshall(
6408 PMIDL_STUB_MESSAGE pStubMsg
,
6409 unsigned char *pMemory
,
6410 PFORMAT_STRING pFormat
)
6412 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6413 unsigned char base_type
;
6415 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6417 if (pRange
->type
!= FC_RANGE
)
6419 ERR("invalid format type %x\n", pRange
->type
);
6420 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6424 base_type
= pRange
->flags_type
& 0xf;
6426 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &base_type
);
6429 /***********************************************************************
6430 * NdrRangeUnmarshall [RPCRT4.@]
6432 unsigned char *WINAPI
NdrRangeUnmarshall(
6433 PMIDL_STUB_MESSAGE pStubMsg
,
6434 unsigned char **ppMemory
,
6435 PFORMAT_STRING pFormat
,
6436 unsigned char fMustAlloc
)
6438 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6439 unsigned char base_type
;
6441 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6443 if (pRange
->type
!= FC_RANGE
)
6445 ERR("invalid format type %x\n", pRange
->type
);
6446 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6449 base_type
= pRange
->flags_type
& 0xf;
6451 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6452 base_type
, pRange
->low_value
, pRange
->high_value
);
6454 #define RANGE_UNMARSHALL(mem_type, wire_type, format_spec) \
6457 align_pointer(&pStubMsg->Buffer, sizeof(wire_type)); \
6458 if (!fMustAlloc && !*ppMemory) \
6459 fMustAlloc = TRUE; \
6461 *ppMemory = NdrAllocate(pStubMsg, sizeof(mem_type)); \
6462 if (pStubMsg->Buffer + sizeof(wire_type) > pStubMsg->BufferEnd) \
6464 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6465 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6466 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6468 if ((*(wire_type *)pStubMsg->Buffer < (mem_type)pRange->low_value) || \
6469 (*(wire_type *)pStubMsg->Buffer > (mem_type)pRange->high_value)) \
6471 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6472 *(wire_type *)pStubMsg->Buffer, (mem_type)pRange->low_value, \
6473 (mem_type)pRange->high_value); \
6474 RpcRaiseException(RPC_S_INVALID_BOUND); \
6477 TRACE("*ppMemory: %p\n", *ppMemory); \
6478 **(mem_type **)ppMemory = *(wire_type *)pStubMsg->Buffer; \
6479 pStubMsg->Buffer += sizeof(wire_type); \
6486 RANGE_UNMARSHALL(UCHAR
, UCHAR
, "%d");
6487 TRACE("value: 0x%02x\n", **ppMemory
);
6491 RANGE_UNMARSHALL(CHAR
, CHAR
, "%u");
6492 TRACE("value: 0x%02x\n", **ppMemory
);
6494 case FC_WCHAR
: /* FIXME: valid? */
6496 RANGE_UNMARSHALL(USHORT
, USHORT
, "%u");
6497 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6500 RANGE_UNMARSHALL(SHORT
, SHORT
, "%d");
6501 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6505 RANGE_UNMARSHALL(LONG
, LONG
, "%d");
6506 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6509 RANGE_UNMARSHALL(ULONG
, ULONG
, "%u");
6510 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6513 RANGE_UNMARSHALL(UINT
, USHORT
, "%u");
6514 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
6520 ERR("invalid range base type: 0x%02x\n", base_type
);
6521 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6527 /***********************************************************************
6528 * NdrRangeBufferSize [internal]
6530 static void WINAPI
NdrRangeBufferSize(
6531 PMIDL_STUB_MESSAGE pStubMsg
,
6532 unsigned char *pMemory
,
6533 PFORMAT_STRING pFormat
)
6535 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6536 unsigned char base_type
;
6538 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6540 if (pRange
->type
!= FC_RANGE
)
6542 ERR("invalid format type %x\n", pRange
->type
);
6543 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6545 base_type
= pRange
->flags_type
& 0xf;
6547 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &base_type
);
6550 /***********************************************************************
6551 * NdrRangeMemorySize [internal]
6553 static ULONG WINAPI
NdrRangeMemorySize(
6554 PMIDL_STUB_MESSAGE pStubMsg
,
6555 PFORMAT_STRING pFormat
)
6557 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6558 unsigned char base_type
;
6560 if (pRange
->type
!= FC_RANGE
)
6562 ERR("invalid format type %x\n", pRange
->type
);
6563 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6566 base_type
= pRange
->flags_type
& 0xf;
6568 return NdrBaseTypeMemorySize(pStubMsg
, &base_type
);
6571 /***********************************************************************
6572 * NdrRangeFree [internal]
6574 static void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6575 unsigned char *pMemory
,
6576 PFORMAT_STRING pFormat
)
6578 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6583 /***********************************************************************
6584 * NdrBaseTypeMarshall [internal]
6586 static unsigned char *WINAPI
NdrBaseTypeMarshall(
6587 PMIDL_STUB_MESSAGE pStubMsg
,
6588 unsigned char *pMemory
,
6589 PFORMAT_STRING pFormat
)
6591 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6599 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(UCHAR
));
6600 TRACE("value: 0x%02x\n", *pMemory
);
6605 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(USHORT
));
6606 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(USHORT
));
6607 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
6611 case FC_ERROR_STATUS_T
:
6613 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(ULONG
));
6614 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONG
));
6615 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
6618 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(float));
6619 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
6622 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(double));
6623 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
6626 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(ULONGLONG
));
6627 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONGLONG
));
6628 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
6632 USHORT val
= *(UINT
*)pMemory
;
6633 /* only 16-bits on the wire, so do a sanity check */
6634 if (*(UINT
*)pMemory
> SHRT_MAX
)
6635 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
6636 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(USHORT
));
6637 safe_copy_to_buffer(pStubMsg
, &val
, sizeof(val
));
6638 TRACE("value: 0x%04x\n", *(UINT
*)pMemory
);
6644 UINT val
= *(UINT_PTR
*)pMemory
;
6645 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(UINT
));
6646 safe_copy_to_buffer(pStubMsg
, &val
, sizeof(val
));
6652 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6655 /* FIXME: what is the correct return value? */
6659 /***********************************************************************
6660 * NdrBaseTypeUnmarshall [internal]
6662 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(
6663 PMIDL_STUB_MESSAGE pStubMsg
,
6664 unsigned char **ppMemory
,
6665 PFORMAT_STRING pFormat
,
6666 unsigned char fMustAlloc
)
6668 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6670 #define BASE_TYPE_UNMARSHALL(type) do { \
6671 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
6672 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6674 *ppMemory = pStubMsg->Buffer; \
6675 TRACE("*ppMemory: %p\n", *ppMemory); \
6676 safe_buffer_increment(pStubMsg, sizeof(type)); \
6681 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6682 TRACE("*ppMemory: %p\n", *ppMemory); \
6683 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6693 BASE_TYPE_UNMARSHALL(UCHAR
);
6694 TRACE("value: 0x%02x\n", **ppMemory
);
6699 BASE_TYPE_UNMARSHALL(USHORT
);
6700 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6704 case FC_ERROR_STATUS_T
:
6706 BASE_TYPE_UNMARSHALL(ULONG
);
6707 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6710 BASE_TYPE_UNMARSHALL(float);
6711 TRACE("value: %f\n", **(float **)ppMemory
);
6714 BASE_TYPE_UNMARSHALL(double);
6715 TRACE("value: %f\n", **(double **)ppMemory
);
6718 BASE_TYPE_UNMARSHALL(ULONGLONG
);
6719 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG
**)ppMemory
));
6724 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6725 if (!fMustAlloc
&& !*ppMemory
)
6728 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT
));
6729 safe_copy_from_buffer(pStubMsg
, &val
, sizeof(USHORT
));
6730 /* 16-bits on the wire, but int in memory */
6731 **(UINT
**)ppMemory
= val
;
6732 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
6736 if (sizeof(INT_PTR
) == sizeof(INT
)) BASE_TYPE_UNMARSHALL(INT
);
6740 align_pointer(&pStubMsg
->Buffer
, sizeof(INT
));
6741 if (!fMustAlloc
&& !*ppMemory
)
6744 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(INT_PTR
));
6745 safe_copy_from_buffer(pStubMsg
, &val
, sizeof(INT
));
6746 **(INT_PTR
**)ppMemory
= val
;
6747 TRACE("value: 0x%08lx\n", **(INT_PTR
**)ppMemory
);
6751 if (sizeof(UINT_PTR
) == sizeof(UINT
)) BASE_TYPE_UNMARSHALL(UINT
);
6755 align_pointer(&pStubMsg
->Buffer
, sizeof(UINT
));
6756 if (!fMustAlloc
&& !*ppMemory
)
6759 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT_PTR
));
6760 safe_copy_from_buffer(pStubMsg
, &val
, sizeof(UINT
));
6761 **(UINT_PTR
**)ppMemory
= val
;
6762 TRACE("value: 0x%08lx\n", **(UINT_PTR
**)ppMemory
);
6768 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6770 #undef BASE_TYPE_UNMARSHALL
6772 /* FIXME: what is the correct return value? */
6777 /***********************************************************************
6778 * NdrBaseTypeBufferSize [internal]
6780 static void WINAPI
NdrBaseTypeBufferSize(
6781 PMIDL_STUB_MESSAGE pStubMsg
,
6782 unsigned char *pMemory
,
6783 PFORMAT_STRING pFormat
)
6785 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6793 safe_buffer_length_increment(pStubMsg
, sizeof(UCHAR
));
6799 align_length(&pStubMsg
->BufferLength
, sizeof(USHORT
));
6800 safe_buffer_length_increment(pStubMsg
, sizeof(USHORT
));
6807 align_length(&pStubMsg
->BufferLength
, sizeof(ULONG
));
6808 safe_buffer_length_increment(pStubMsg
, sizeof(ULONG
));
6811 align_length(&pStubMsg
->BufferLength
, sizeof(float));
6812 safe_buffer_length_increment(pStubMsg
, sizeof(float));
6815 align_length(&pStubMsg
->BufferLength
, sizeof(double));
6816 safe_buffer_length_increment(pStubMsg
, sizeof(double));
6819 align_length(&pStubMsg
->BufferLength
, sizeof(ULONGLONG
));
6820 safe_buffer_length_increment(pStubMsg
, sizeof(ULONGLONG
));
6822 case FC_ERROR_STATUS_T
:
6823 align_length(&pStubMsg
->BufferLength
, sizeof(error_status_t
));
6824 safe_buffer_length_increment(pStubMsg
, sizeof(error_status_t
));
6829 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6833 /***********************************************************************
6834 * NdrBaseTypeMemorySize [internal]
6836 static ULONG WINAPI
NdrBaseTypeMemorySize(
6837 PMIDL_STUB_MESSAGE pStubMsg
,
6838 PFORMAT_STRING pFormat
)
6840 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg
, *pFormat
);
6848 safe_buffer_increment(pStubMsg
, sizeof(UCHAR
));
6849 pStubMsg
->MemorySize
+= sizeof(UCHAR
);
6850 return sizeof(UCHAR
);
6854 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6855 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6856 align_length(&pStubMsg
->MemorySize
, sizeof(USHORT
));
6857 pStubMsg
->MemorySize
+= sizeof(USHORT
);
6858 return sizeof(USHORT
);
6862 align_pointer(&pStubMsg
->Buffer
, sizeof(ULONG
));
6863 safe_buffer_increment(pStubMsg
, sizeof(ULONG
));
6864 align_length(&pStubMsg
->MemorySize
, sizeof(ULONG
));
6865 pStubMsg
->MemorySize
+= sizeof(ULONG
);
6866 return sizeof(ULONG
);
6868 align_pointer(&pStubMsg
->Buffer
, sizeof(float));
6869 safe_buffer_increment(pStubMsg
, sizeof(float));
6870 align_length(&pStubMsg
->MemorySize
, sizeof(float));
6871 pStubMsg
->MemorySize
+= sizeof(float);
6872 return sizeof(float);
6874 align_pointer(&pStubMsg
->Buffer
, sizeof(double));
6875 safe_buffer_increment(pStubMsg
, sizeof(double));
6876 align_length(&pStubMsg
->MemorySize
, sizeof(double));
6877 pStubMsg
->MemorySize
+= sizeof(double);
6878 return sizeof(double);
6880 align_pointer(&pStubMsg
->Buffer
, sizeof(ULONGLONG
));
6881 safe_buffer_increment(pStubMsg
, sizeof(ULONGLONG
));
6882 align_length(&pStubMsg
->MemorySize
, sizeof(ULONGLONG
));
6883 pStubMsg
->MemorySize
+= sizeof(ULONGLONG
);
6884 return sizeof(ULONGLONG
);
6885 case FC_ERROR_STATUS_T
:
6886 align_pointer(&pStubMsg
->Buffer
, sizeof(error_status_t
));
6887 safe_buffer_increment(pStubMsg
, sizeof(error_status_t
));
6888 align_length(&pStubMsg
->MemorySize
, sizeof(error_status_t
));
6889 pStubMsg
->MemorySize
+= sizeof(error_status_t
);
6890 return sizeof(error_status_t
);
6892 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6893 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6894 align_length(&pStubMsg
->MemorySize
, sizeof(UINT
));
6895 pStubMsg
->MemorySize
+= sizeof(UINT
);
6896 return sizeof(UINT
);
6899 align_pointer(&pStubMsg
->Buffer
, sizeof(UINT
));
6900 safe_buffer_increment(pStubMsg
, sizeof(UINT
));
6901 align_length(&pStubMsg
->MemorySize
, sizeof(UINT_PTR
));
6902 pStubMsg
->MemorySize
+= sizeof(UINT_PTR
);
6903 return sizeof(UINT_PTR
);
6905 align_length(&pStubMsg
->MemorySize
, sizeof(void *));
6906 pStubMsg
->MemorySize
+= sizeof(void *);
6907 return sizeof(void *);
6909 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6914 /***********************************************************************
6915 * NdrBaseTypeFree [internal]
6917 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6918 unsigned char *pMemory
,
6919 PFORMAT_STRING pFormat
)
6921 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6926 /***********************************************************************
6927 * NdrContextHandleBufferSize [internal]
6929 static void WINAPI
NdrContextHandleBufferSize(
6930 PMIDL_STUB_MESSAGE pStubMsg
,
6931 unsigned char *pMemory
,
6932 PFORMAT_STRING pFormat
)
6934 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6936 if (*pFormat
!= FC_BIND_CONTEXT
)
6938 ERR("invalid format type %x\n", *pFormat
);
6939 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6941 align_length(&pStubMsg
->BufferLength
, 4);
6942 safe_buffer_length_increment(pStubMsg
, cbNDRContext
);
6945 /***********************************************************************
6946 * NdrContextHandleMarshall [internal]
6948 static unsigned char *WINAPI
NdrContextHandleMarshall(
6949 PMIDL_STUB_MESSAGE pStubMsg
,
6950 unsigned char *pMemory
,
6951 PFORMAT_STRING pFormat
)
6953 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6955 if (*pFormat
!= FC_BIND_CONTEXT
)
6957 ERR("invalid format type %x\n", *pFormat
);
6958 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6960 TRACE("flags: 0x%02x\n", pFormat
[1]);
6962 if (pStubMsg
->IsClient
)
6964 if (pFormat
[1] & HANDLE_PARAM_IS_VIA_PTR
)
6965 NdrClientContextMarshall(pStubMsg
, *(NDR_CCONTEXT
**)pMemory
, FALSE
);
6967 NdrClientContextMarshall(pStubMsg
, pMemory
, FALSE
);
6971 NDR_SCONTEXT ctxt
= NDRSContextFromValue(pMemory
);
6972 NDR_RUNDOWN rundown
= pStubMsg
->StubDesc
->apfnNdrRundownRoutines
[pFormat
[2]];
6973 NdrServerContextNewMarshall(pStubMsg
, ctxt
, rundown
, pFormat
);
6979 /***********************************************************************
6980 * NdrContextHandleUnmarshall [internal]
6982 static unsigned char *WINAPI
NdrContextHandleUnmarshall(
6983 PMIDL_STUB_MESSAGE pStubMsg
,
6984 unsigned char **ppMemory
,
6985 PFORMAT_STRING pFormat
,
6986 unsigned char fMustAlloc
)
6988 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg
,
6989 ppMemory
, pFormat
, fMustAlloc
? "TRUE": "FALSE");
6991 if (*pFormat
!= FC_BIND_CONTEXT
)
6993 ERR("invalid format type %x\n", *pFormat
);
6994 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6996 TRACE("flags: 0x%02x\n", pFormat
[1]);
6998 if (pStubMsg
->IsClient
)
7000 /* [out]-only or [ret] param */
7001 if ((pFormat
[1] & (HANDLE_PARAM_IS_IN
|HANDLE_PARAM_IS_OUT
)) == HANDLE_PARAM_IS_OUT
)
7002 **(NDR_CCONTEXT
**)ppMemory
= NULL
;
7003 NdrClientContextUnmarshall(pStubMsg
, *(NDR_CCONTEXT
**)ppMemory
, pStubMsg
->RpcMsg
->Handle
);
7008 ctxt
= NdrServerContextNewUnmarshall(pStubMsg
, pFormat
);
7009 if (pFormat
[1] & HANDLE_PARAM_IS_VIA_PTR
)
7010 *(void **)ppMemory
= NDRSContextValue(ctxt
);
7012 *(void **)ppMemory
= *NDRSContextValue(ctxt
);
7018 /***********************************************************************
7019 * NdrClientContextMarshall [RPCRT4.@]
7021 void WINAPI
NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7022 NDR_CCONTEXT ContextHandle
,
7025 TRACE("(%p, %p, %d)\n", pStubMsg
, ContextHandle
, fCheck
);
7027 align_pointer_clear(&pStubMsg
->Buffer
, 4);
7029 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7031 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7032 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7033 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7036 /* FIXME: what does fCheck do? */
7037 NDRCContextMarshall(ContextHandle
,
7040 pStubMsg
->Buffer
+= cbNDRContext
;
7043 /***********************************************************************
7044 * NdrClientContextUnmarshall [RPCRT4.@]
7046 void WINAPI
NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7047 NDR_CCONTEXT
* pContextHandle
,
7048 RPC_BINDING_HANDLE BindHandle
)
7050 TRACE("(%p, %p, %p)\n", pStubMsg
, pContextHandle
, BindHandle
);
7052 align_pointer(&pStubMsg
->Buffer
, 4);
7054 if (pStubMsg
->Buffer
+ cbNDRContext
> pStubMsg
->BufferEnd
)
7055 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7057 NDRCContextUnmarshall(pContextHandle
,
7060 pStubMsg
->RpcMsg
->DataRepresentation
);
7062 pStubMsg
->Buffer
+= cbNDRContext
;
7065 void WINAPI
NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7066 NDR_SCONTEXT ContextHandle
,
7067 NDR_RUNDOWN RundownRoutine
)
7069 TRACE("(%p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
);
7071 align_pointer(&pStubMsg
->Buffer
, 4);
7073 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7075 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7076 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7077 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7080 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
7081 pStubMsg
->Buffer
, RundownRoutine
, NULL
,
7082 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
7083 pStubMsg
->Buffer
+= cbNDRContext
;
7086 NDR_SCONTEXT WINAPI
NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
)
7088 NDR_SCONTEXT ContextHandle
;
7090 TRACE("(%p)\n", pStubMsg
);
7092 align_pointer(&pStubMsg
->Buffer
, 4);
7094 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7096 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7097 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7098 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7101 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
7103 pStubMsg
->RpcMsg
->DataRepresentation
,
7104 NULL
, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
7105 pStubMsg
->Buffer
+= cbNDRContext
;
7107 return ContextHandle
;
7110 void WINAPI
NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg
,
7111 unsigned char* pMemory
,
7112 PFORMAT_STRING pFormat
)
7114 FIXME("(%p, %p, %p): stub\n", pStubMsg
, pMemory
, pFormat
);
7117 NDR_SCONTEXT WINAPI
NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg
,
7118 PFORMAT_STRING pFormat
)
7120 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
7121 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
7123 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
7125 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
7126 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
7127 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NOSERIALIZE
)
7128 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
7129 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
7131 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
7132 if_id
= &sif
->InterfaceId
;
7135 return NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
, NULL
,
7136 pStubMsg
->RpcMsg
->DataRepresentation
, if_id
,
7140 void WINAPI
NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7141 NDR_SCONTEXT ContextHandle
,
7142 NDR_RUNDOWN RundownRoutine
,
7143 PFORMAT_STRING pFormat
)
7145 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
7146 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
7148 TRACE("(%p, %p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
, pFormat
);
7150 align_pointer(&pStubMsg
->Buffer
, 4);
7152 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7154 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7155 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7156 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7159 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
7160 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
7161 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NOSERIALIZE
)
7162 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
7163 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
7165 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
7166 if_id
= &sif
->InterfaceId
;
7169 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
7170 pStubMsg
->Buffer
, RundownRoutine
, if_id
, flags
);
7171 pStubMsg
->Buffer
+= cbNDRContext
;
7174 NDR_SCONTEXT WINAPI
NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7175 PFORMAT_STRING pFormat
)
7177 NDR_SCONTEXT ContextHandle
;
7178 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
7179 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
7181 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
7183 align_pointer(&pStubMsg
->Buffer
, 4);
7185 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7187 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7188 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7189 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7192 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
7193 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
7194 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NOSERIALIZE
)
7195 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
7196 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
7198 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
7199 if_id
= &sif
->InterfaceId
;
7202 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
7204 pStubMsg
->RpcMsg
->DataRepresentation
,
7206 pStubMsg
->Buffer
+= cbNDRContext
;
7208 return ContextHandle
;
7211 /***********************************************************************
7212 * NdrCorrelationInitialize [RPCRT4.@]
7214 * Initializes correlation validity checking.
7217 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7218 * pMemory [I] Pointer to memory to use as a cache.
7219 * CacheSize [I] Size of the memory pointed to by pMemory.
7220 * Flags [I] Reserved. Set to zero.
7225 void WINAPI
NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg
, void *pMemory
, ULONG CacheSize
, ULONG Flags
)
7227 FIXME("(%p, %p, %d, 0x%x): semi-stub\n", pStubMsg
, pMemory
, CacheSize
, Flags
);
7229 if (pStubMsg
->CorrDespIncrement
== 0)
7230 pStubMsg
->CorrDespIncrement
= 2; /* size of the normal (non-range) /robust payload */
7232 pStubMsg
->fHasNewCorrDesc
= TRUE
;
7235 /***********************************************************************
7236 * NdrCorrelationPass [RPCRT4.@]
7238 * Performs correlation validity checking.
7241 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7246 void WINAPI
NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg
)
7248 FIXME("(%p): stub\n", pStubMsg
);
7251 /***********************************************************************
7252 * NdrCorrelationFree [RPCRT4.@]
7254 * Frees any resources used while unmarshalling parameters that need
7255 * correlation validity checking.
7258 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7263 void WINAPI
NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg
)
7265 FIXME("(%p): stub\n", pStubMsg
);