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/rpcfc.h"
48 #include "wine/debug.h"
50 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
53 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
54 (*((UINT32 *)(pchar)) = (uint32))
56 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
57 (*((UINT32 *)(pchar)))
59 /* these would work for i386 too, but less efficient */
60 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
61 (*(pchar) = LOBYTE(LOWORD(uint32)), \
62 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
63 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
64 *((pchar)+3) = HIBYTE(HIWORD(uint32)))
66 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
68 MAKEWORD(*(pchar), *((pchar)+1)), \
69 MAKEWORD(*((pchar)+2), *((pchar)+3))))
72 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
73 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
74 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
75 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
76 *(pchar) = HIBYTE(HIWORD(uint32)))
78 #define BIG_ENDIAN_UINT32_READ(pchar) \
80 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
81 MAKEWORD(*((pchar)+1), *(pchar))))
83 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
84 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
85 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
86 # define NDR_LOCAL_UINT32_READ(pchar) \
87 BIG_ENDIAN_UINT32_READ(pchar)
89 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
90 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
91 # define NDR_LOCAL_UINT32_READ(pchar) \
92 LITTLE_ENDIAN_UINT32_READ(pchar)
95 static inline void align_length( ULONG
*len
, unsigned int align
)
97 *len
= (*len
+ align
- 1) & ~(align
- 1);
100 static inline void align_pointer( unsigned char **ptr
, unsigned int align
)
102 ULONG_PTR mask
= align
- 1;
103 *ptr
= (unsigned char *)(((ULONG_PTR
)*ptr
+ mask
) & ~mask
);
106 static inline void align_pointer_clear( unsigned char **ptr
, unsigned int align
)
108 ULONG_PTR mask
= align
- 1;
109 memset( *ptr
, 0, (align
- (ULONG_PTR
)*ptr
) & mask
);
110 *ptr
= (unsigned char *)(((ULONG_PTR
)*ptr
+ mask
) & ~mask
);
113 #define STD_OVERFLOW_CHECK(_Msg) do { \
114 TRACE("buffer=%d/%d\n", (ULONG)(_Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer), _Msg->BufferLength); \
115 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
116 ERR("buffer overflow %d bytes\n", (ULONG)(_Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength))); \
119 #define NDR_POINTER_ID_BASE 0x20000
120 #define NDR_POINTER_ID(pStubMsg) (NDR_POINTER_ID_BASE + ((pStubMsg)->UniquePtrCount++) * 4)
121 #define NDR_TABLE_SIZE 128
122 #define NDR_TABLE_MASK 127
124 #define NDRSContextFromValue(user_context) (NDR_SCONTEXT)((char *)(user_context) - (char *)NDRSContextValue((NDR_SCONTEXT)NULL))
126 static unsigned char *WINAPI
NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
127 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
128 static void WINAPI
NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
129 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
130 static ULONG WINAPI
NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
132 static unsigned char *WINAPI
NdrContextHandleMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
133 static void WINAPI
NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
134 static unsigned char *WINAPI
NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
136 static unsigned char *WINAPI
NdrRangeMarshall(PMIDL_STUB_MESSAGE
,unsigned char *, PFORMAT_STRING
);
137 static void WINAPI
NdrRangeBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
138 static ULONG WINAPI
NdrRangeMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
139 static void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
141 static ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
143 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
144 unsigned char *pMemory
,
145 PFORMAT_STRING pFormat
,
146 PFORMAT_STRING pPointer
);
147 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
148 unsigned char *pMemory
,
149 PFORMAT_STRING pFormat
,
150 PFORMAT_STRING pPointer
);
151 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
152 unsigned char *pMemory
,
153 PFORMAT_STRING pFormat
,
154 PFORMAT_STRING pPointer
,
155 unsigned char fMustAlloc
);
156 static ULONG
ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
157 PFORMAT_STRING pFormat
,
158 PFORMAT_STRING pPointer
);
159 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
160 unsigned char *pMemory
,
161 PFORMAT_STRING pFormat
,
162 PFORMAT_STRING pPointer
);
164 const NDR_MARSHALL NdrMarshaller
[NDR_TABLE_SIZE
] = {
166 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
167 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
168 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
169 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
173 NdrPointerMarshall
, NdrPointerMarshall
,
174 NdrPointerMarshall
, NdrPointerMarshall
,
176 NdrSimpleStructMarshall
, NdrSimpleStructMarshall
,
177 NdrConformantStructMarshall
, NdrConformantStructMarshall
,
178 NdrConformantVaryingStructMarshall
,
179 NdrComplexStructMarshall
,
181 NdrConformantArrayMarshall
,
182 NdrConformantVaryingArrayMarshall
,
183 NdrFixedArrayMarshall
, NdrFixedArrayMarshall
,
184 NdrVaryingArrayMarshall
, NdrVaryingArrayMarshall
,
185 NdrComplexArrayMarshall
,
187 NdrConformantStringMarshall
, 0, 0,
188 NdrConformantStringMarshall
,
189 NdrNonConformantStringMarshall
, 0, 0, 0,
191 NdrEncapsulatedUnionMarshall
,
192 NdrNonEncapsulatedUnionMarshall
,
193 NdrByteCountPointerMarshall
,
194 NdrXmitOrRepAsMarshall
, NdrXmitOrRepAsMarshall
,
196 NdrInterfacePointerMarshall
,
198 NdrContextHandleMarshall
,
201 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
,
248 const NDR_BUFFERSIZE NdrBufferSizer
[NDR_TABLE_SIZE
] = {
250 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
251 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
252 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
253 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
255 NdrBaseTypeBufferSize
,
257 NdrPointerBufferSize
, NdrPointerBufferSize
,
258 NdrPointerBufferSize
, NdrPointerBufferSize
,
260 NdrSimpleStructBufferSize
, NdrSimpleStructBufferSize
,
261 NdrConformantStructBufferSize
, NdrConformantStructBufferSize
,
262 NdrConformantVaryingStructBufferSize
,
263 NdrComplexStructBufferSize
,
265 NdrConformantArrayBufferSize
,
266 NdrConformantVaryingArrayBufferSize
,
267 NdrFixedArrayBufferSize
, NdrFixedArrayBufferSize
,
268 NdrVaryingArrayBufferSize
, NdrVaryingArrayBufferSize
,
269 NdrComplexArrayBufferSize
,
271 NdrConformantStringBufferSize
, 0, 0,
272 NdrConformantStringBufferSize
,
273 NdrNonConformantStringBufferSize
, 0, 0, 0,
275 NdrEncapsulatedUnionBufferSize
,
276 NdrNonEncapsulatedUnionBufferSize
,
277 NdrByteCountPointerBufferSize
,
278 NdrXmitOrRepAsBufferSize
, NdrXmitOrRepAsBufferSize
,
280 NdrInterfacePointerBufferSize
,
282 NdrContextHandleBufferSize
,
285 NdrUserMarshalBufferSize
,
290 const NDR_MEMORYSIZE NdrMemorySizer
[NDR_TABLE_SIZE
] = {
292 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
293 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
294 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
295 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
297 NdrBaseTypeMemorySize
,
299 NdrPointerMemorySize
, NdrPointerMemorySize
,
300 NdrPointerMemorySize
, NdrPointerMemorySize
,
302 NdrSimpleStructMemorySize
, NdrSimpleStructMemorySize
,
303 NdrConformantStructMemorySize
, NdrConformantStructMemorySize
,
304 NdrConformantVaryingStructMemorySize
,
305 NdrComplexStructMemorySize
,
307 NdrConformantArrayMemorySize
,
308 NdrConformantVaryingArrayMemorySize
,
309 NdrFixedArrayMemorySize
, NdrFixedArrayMemorySize
,
310 NdrVaryingArrayMemorySize
, NdrVaryingArrayMemorySize
,
311 NdrComplexArrayMemorySize
,
313 NdrConformantStringMemorySize
, 0, 0,
314 NdrConformantStringMemorySize
,
315 NdrNonConformantStringMemorySize
, 0, 0, 0,
317 NdrEncapsulatedUnionMemorySize
,
318 NdrNonEncapsulatedUnionMemorySize
,
319 NdrByteCountPointerMemorySize
,
320 NdrXmitOrRepAsMemorySize
, NdrXmitOrRepAsMemorySize
,
322 NdrInterfacePointerMemorySize
,
327 NdrUserMarshalMemorySize
,
332 const NDR_FREE NdrFreer
[NDR_TABLE_SIZE
] = {
334 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
335 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
336 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
337 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
341 NdrPointerFree
, NdrPointerFree
,
342 NdrPointerFree
, NdrPointerFree
,
344 NdrSimpleStructFree
, NdrSimpleStructFree
,
345 NdrConformantStructFree
, NdrConformantStructFree
,
346 NdrConformantVaryingStructFree
,
347 NdrComplexStructFree
,
349 NdrConformantArrayFree
,
350 NdrConformantVaryingArrayFree
,
351 NdrFixedArrayFree
, NdrFixedArrayFree
,
352 NdrVaryingArrayFree
, NdrVaryingArrayFree
,
358 NdrEncapsulatedUnionFree
,
359 NdrNonEncapsulatedUnionFree
,
361 NdrXmitOrRepAsFree
, NdrXmitOrRepAsFree
,
363 NdrInterfacePointerFree
,
374 typedef struct _NDR_MEMORY_LIST
379 struct _NDR_MEMORY_LIST
*next
;
382 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
384 /***********************************************************************
385 * NdrAllocate [RPCRT4.@]
387 * Allocates a block of memory using pStubMsg->pfnAllocate.
390 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
391 * len [I] Size of memory block to allocate.
394 * The memory block of size len that was allocated.
397 * The memory block is always 8-byte aligned.
398 * If the function is unable to allocate memory an ERROR_OUTOFMEMORY
399 * exception is raised.
401 void * WINAPI
NdrAllocate(MIDL_STUB_MESSAGE
*pStubMsg
, SIZE_T len
)
406 NDR_MEMORY_LIST
*mem_list
;
408 aligned_len
= (len
+ 7) & ~7;
409 adjusted_len
= aligned_len
+ sizeof(NDR_MEMORY_LIST
);
410 /* check for overflow */
411 if (adjusted_len
< len
)
413 ERR("overflow of adjusted_len %ld, len %ld\n", adjusted_len
, len
);
414 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
417 p
= pStubMsg
->pfnAllocate(adjusted_len
);
418 if (!p
) RpcRaiseException(ERROR_OUTOFMEMORY
);
420 mem_list
= (NDR_MEMORY_LIST
*)((char *)p
+ aligned_len
);
421 mem_list
->magic
= MEML_MAGIC
;
422 mem_list
->size
= aligned_len
;
423 mem_list
->reserved
= 0;
424 mem_list
->next
= pStubMsg
->pMemoryList
;
425 pStubMsg
->pMemoryList
= mem_list
;
431 static void NdrFree(MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *Pointer
)
433 TRACE("(%p, %p)\n", pStubMsg
, Pointer
);
435 pStubMsg
->pfnFree(Pointer
);
438 static inline BOOL
IsConformanceOrVariancePresent(PFORMAT_STRING pFormat
)
440 return (*(const ULONG
*)pFormat
!= -1);
443 static PFORMAT_STRING
ReadConformance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
)
445 align_pointer(&pStubMsg
->Buffer
, 4);
446 if (pStubMsg
->Buffer
+ 4 > pStubMsg
->BufferEnd
)
447 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
448 pStubMsg
->MaxCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
449 pStubMsg
->Buffer
+= 4;
450 TRACE("unmarshalled conformance is %ld\n", pStubMsg
->MaxCount
);
451 if (pStubMsg
->fHasNewCorrDesc
)
457 static inline PFORMAT_STRING
ReadVariance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
, ULONG MaxValue
)
459 if (pFormat
&& !IsConformanceOrVariancePresent(pFormat
))
461 pStubMsg
->Offset
= 0;
462 pStubMsg
->ActualCount
= pStubMsg
->MaxCount
;
466 align_pointer(&pStubMsg
->Buffer
, 4);
467 if (pStubMsg
->Buffer
+ 8 > pStubMsg
->BufferEnd
)
468 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
469 pStubMsg
->Offset
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
470 pStubMsg
->Buffer
+= 4;
471 TRACE("offset is %d\n", pStubMsg
->Offset
);
472 pStubMsg
->ActualCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
473 pStubMsg
->Buffer
+= 4;
474 TRACE("variance is %d\n", pStubMsg
->ActualCount
);
476 if ((pStubMsg
->ActualCount
> MaxValue
) ||
477 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> MaxValue
))
479 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
480 pStubMsg
->ActualCount
, pStubMsg
->Offset
, MaxValue
);
481 RpcRaiseException(RPC_S_INVALID_BOUND
);
486 if (pStubMsg
->fHasNewCorrDesc
)
492 /* writes the conformance value to the buffer */
493 static inline void WriteConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
495 align_pointer_clear(&pStubMsg
->Buffer
, 4);
496 if (pStubMsg
->Buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
497 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
498 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->MaxCount
);
499 pStubMsg
->Buffer
+= 4;
502 /* writes the variance values to the buffer */
503 static inline void WriteVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
505 align_pointer_clear(&pStubMsg
->Buffer
, 4);
506 if (pStubMsg
->Buffer
+ 8 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
507 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
508 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->Offset
);
509 pStubMsg
->Buffer
+= 4;
510 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->ActualCount
);
511 pStubMsg
->Buffer
+= 4;
514 /* requests buffer space for the conformance value */
515 static inline void SizeConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
517 align_length(&pStubMsg
->BufferLength
, 4);
518 if (pStubMsg
->BufferLength
+ 4 < pStubMsg
->BufferLength
)
519 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
520 pStubMsg
->BufferLength
+= 4;
523 /* requests buffer space for the variance values */
524 static inline void SizeVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
526 align_length(&pStubMsg
->BufferLength
, 4);
527 if (pStubMsg
->BufferLength
+ 8 < pStubMsg
->BufferLength
)
528 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
529 pStubMsg
->BufferLength
+= 8;
532 PFORMAT_STRING
ComputeConformanceOrVariance(
533 MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *pMemory
,
534 PFORMAT_STRING pFormat
, ULONG_PTR def
, ULONG_PTR
*pCount
)
536 BYTE dtype
= pFormat
[0] & 0xf;
537 short ofs
= *(const short *)&pFormat
[2];
541 if (!IsConformanceOrVariancePresent(pFormat
)) {
542 /* null descriptor */
547 switch (pFormat
[0] & 0xf0) {
548 case RPC_FC_NORMAL_CONFORMANCE
:
549 TRACE("normal conformance, ofs=%d\n", ofs
);
552 case RPC_FC_POINTER_CONFORMANCE
:
553 TRACE("pointer conformance, ofs=%d\n", ofs
);
554 ptr
= pStubMsg
->Memory
;
556 case RPC_FC_TOP_LEVEL_CONFORMANCE
:
557 TRACE("toplevel conformance, ofs=%d\n", ofs
);
558 if (pStubMsg
->StackTop
) {
559 ptr
= pStubMsg
->StackTop
;
562 /* -Os mode, *pCount is already set */
566 case RPC_FC_CONSTANT_CONFORMANCE
:
567 data
= ofs
| ((DWORD
)pFormat
[1] << 16);
568 TRACE("constant conformance, val=%d\n", data
);
571 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE
:
572 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs
);
573 if (pStubMsg
->StackTop
) {
574 ptr
= pStubMsg
->StackTop
;
582 FIXME("unknown conformance type %x, expect crash.\n", pFormat
[0] & 0xf0);
586 switch (pFormat
[1]) {
587 case RPC_FC_DEREFERENCE
:
588 ptr
= *(LPVOID
*)((char *)ptr
+ ofs
);
590 case RPC_FC_CALLBACK
:
592 unsigned char *old_stack_top
= pStubMsg
->StackTop
;
593 pStubMsg
->StackTop
= ptr
;
595 /* ofs is index into StubDesc->apfnExprEval */
596 TRACE("callback conformance into apfnExprEval[%d]\n", ofs
);
597 pStubMsg
->StubDesc
->apfnExprEval
[ofs
](pStubMsg
);
599 pStubMsg
->StackTop
= old_stack_top
;
601 /* the callback function always stores the computed value in MaxCount */
602 *pCount
= pStubMsg
->MaxCount
;
606 ptr
= (char *)ptr
+ ofs
;
619 data
= *(USHORT
*)ptr
;
630 FIXME("unknown conformance data type %x\n", dtype
);
633 TRACE("dereferenced data type %x at %p, got %d\n", dtype
, ptr
, data
);
636 switch (pFormat
[1]) {
637 case RPC_FC_DEREFERENCE
: /* already handled */
654 FIXME("unknown conformance op %d\n", pFormat
[1]);
659 TRACE("resulting conformance is %ld\n", *pCount
);
660 if (pStubMsg
->fHasNewCorrDesc
)
666 static inline PFORMAT_STRING
SkipConformance(PMIDL_STUB_MESSAGE pStubMsg
,
667 PFORMAT_STRING pFormat
)
669 if (pStubMsg
->fHasNewCorrDesc
)
676 static inline PFORMAT_STRING
SkipVariance(PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
678 return SkipConformance( pStubMsg
, pFormat
);
681 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
682 * the result overflows 32-bits */
683 static inline ULONG
safe_multiply(ULONG a
, ULONG b
)
685 ULONGLONG ret
= (ULONGLONG
)a
* b
;
686 if (ret
> 0xffffffff)
688 RpcRaiseException(RPC_S_INVALID_BOUND
);
694 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
696 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
697 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
698 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
699 pStubMsg
->Buffer
+= size
;
702 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
704 if (pStubMsg
->BufferLength
+ size
< pStubMsg
->BufferLength
) /* integer overflow of pStubMsg->BufferSize */
706 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
707 pStubMsg
->BufferLength
, size
);
708 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
710 pStubMsg
->BufferLength
+= size
;
713 /* copies data from the buffer, checking that there is enough data in the buffer
715 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, void *p
, ULONG size
)
717 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
718 (pStubMsg
->Buffer
+ size
> pStubMsg
->BufferEnd
))
720 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
721 pStubMsg
->Buffer
, pStubMsg
->BufferEnd
, size
);
722 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
724 if (p
== pStubMsg
->Buffer
)
725 ERR("pointer is the same as the buffer\n");
726 memcpy(p
, pStubMsg
->Buffer
, size
);
727 pStubMsg
->Buffer
+= size
;
730 /* copies data to the buffer, checking that there is enough space to do so */
731 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, const void *p
, ULONG size
)
733 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
734 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
736 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
737 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
,
739 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
741 memcpy(pStubMsg
->Buffer
, p
, size
);
742 pStubMsg
->Buffer
+= size
;
745 /* verify that string data sitting in the buffer is valid and safe to
747 static void validate_string_data(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG bufsize
, ULONG esize
)
751 /* verify the buffer is safe to access */
752 if ((pStubMsg
->Buffer
+ bufsize
< pStubMsg
->Buffer
) ||
753 (pStubMsg
->Buffer
+ bufsize
> pStubMsg
->BufferEnd
))
755 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize
,
756 pStubMsg
->BufferEnd
, pStubMsg
->Buffer
);
757 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
760 /* strings must always have null terminating bytes */
763 ERR("invalid string length of %d\n", bufsize
/ esize
);
764 RpcRaiseException(RPC_S_INVALID_BOUND
);
767 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
768 if (pStubMsg
->Buffer
[i
] != 0)
770 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
771 i
, pStubMsg
->Buffer
[i
]);
772 RpcRaiseException(RPC_S_INVALID_BOUND
);
776 static inline void dump_pointer_attr(unsigned char attr
)
778 if (attr
& RPC_FC_P_ALLOCALLNODES
)
779 TRACE(" RPC_FC_P_ALLOCALLNODES");
780 if (attr
& RPC_FC_P_DONTFREE
)
781 TRACE(" RPC_FC_P_DONTFREE");
782 if (attr
& RPC_FC_P_ONSTACK
)
783 TRACE(" RPC_FC_P_ONSTACK");
784 if (attr
& RPC_FC_P_SIMPLEPOINTER
)
785 TRACE(" RPC_FC_P_SIMPLEPOINTER");
786 if (attr
& RPC_FC_P_DEREF
)
787 TRACE(" RPC_FC_P_DEREF");
791 /***********************************************************************
792 * PointerMarshall [internal]
794 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
795 unsigned char *Buffer
,
796 unsigned char *Pointer
,
797 PFORMAT_STRING pFormat
)
799 unsigned type
= pFormat
[0], attr
= pFormat
[1];
803 int pointer_needs_marshaling
;
805 TRACE("(%p,%p,%p,%p)\n", pStubMsg
, Buffer
, Pointer
, pFormat
);
806 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
808 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
809 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
812 case RPC_FC_RP
: /* ref pointer (always non-null) */
815 ERR("NULL ref pointer is not allowed\n");
816 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
818 pointer_needs_marshaling
= 1;
820 case RPC_FC_UP
: /* unique pointer */
821 case RPC_FC_OP
: /* object pointer - same as unique here */
823 pointer_needs_marshaling
= 1;
825 pointer_needs_marshaling
= 0;
826 pointer_id
= Pointer
? NDR_POINTER_ID(pStubMsg
) : 0;
827 TRACE("writing 0x%08x to buffer\n", pointer_id
);
828 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
831 pointer_needs_marshaling
= !NdrFullPointerQueryPointer(
832 pStubMsg
->FullPtrXlatTables
, Pointer
, 1, &pointer_id
);
833 TRACE("writing 0x%08x to buffer\n", pointer_id
);
834 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
837 FIXME("unhandled ptr type=%02x\n", type
);
838 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
842 TRACE("calling marshaller for type 0x%x\n", (int)*desc
);
844 if (pointer_needs_marshaling
) {
845 if (attr
& RPC_FC_P_DEREF
) {
846 Pointer
= *(unsigned char**)Pointer
;
847 TRACE("deref => %p\n", Pointer
);
849 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
850 if (m
) m(pStubMsg
, Pointer
, desc
);
851 else FIXME("no marshaller for data type=%02x\n", *desc
);
854 STD_OVERFLOW_CHECK(pStubMsg
);
857 /***********************************************************************
858 * PointerUnmarshall [internal]
860 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
861 unsigned char *Buffer
,
862 unsigned char **pPointer
,
863 unsigned char *pSrcPointer
,
864 PFORMAT_STRING pFormat
,
865 unsigned char fMustAlloc
)
867 unsigned type
= pFormat
[0], attr
= pFormat
[1];
870 DWORD pointer_id
= 0;
871 int pointer_needs_unmarshaling
;
873 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg
, Buffer
, pPointer
, pSrcPointer
, pFormat
, fMustAlloc
);
874 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
876 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
877 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
880 case RPC_FC_RP
: /* ref pointer (always non-null) */
881 pointer_needs_unmarshaling
= 1;
883 case RPC_FC_UP
: /* unique pointer */
884 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
885 TRACE("pointer_id is 0x%08x\n", pointer_id
);
887 pointer_needs_unmarshaling
= 1;
890 pointer_needs_unmarshaling
= 0;
893 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
894 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
895 TRACE("pointer_id is 0x%08x\n", pointer_id
);
896 if (!fMustAlloc
&& pSrcPointer
)
898 FIXME("free object pointer %p\n", pSrcPointer
);
902 pointer_needs_unmarshaling
= 1;
906 pointer_needs_unmarshaling
= 0;
910 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
911 TRACE("pointer_id is 0x%08x\n", pointer_id
);
912 pointer_needs_unmarshaling
= !NdrFullPointerQueryRefId(
913 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, (void **)pPointer
);
916 FIXME("unhandled ptr type=%02x\n", type
);
917 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
921 if (pointer_needs_unmarshaling
) {
922 unsigned char *base_ptr_val
= *pPointer
;
923 unsigned char **current_ptr
= pPointer
;
924 if (pStubMsg
->IsClient
) {
926 /* if we aren't forcing allocation of memory then try to use the existing
927 * (source) pointer to unmarshall the data into so that [in,out]
928 * parameters behave correctly. it doesn't matter if the parameter is
929 * [out] only since in that case the pointer will be NULL. we force
930 * allocation when the source pointer is NULL here instead of in the type
931 * unmarshalling routine for the benefit of the deref code below */
934 TRACE("setting *pPointer to %p\n", pSrcPointer
);
935 *pPointer
= base_ptr_val
= pSrcPointer
;
941 /* the memory in a stub is never initialised, so we have to work out here
942 * whether we have to initialise it so we can use the optimisation of
943 * setting the pointer to the buffer, if possible, or set fMustAlloc to
945 if (attr
& RPC_FC_P_DEREF
) {
953 if (attr
& RPC_FC_P_ALLOCALLNODES
)
954 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
956 if (attr
& RPC_FC_P_DEREF
) {
958 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
);
970 if (type
== RPC_FC_FP
)
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 int 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
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
995 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
998 case RPC_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
& RPC_FC_P_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 int 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
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1049 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1052 case RPC_FC_RP
: /* ref pointer (always non-null) */
1053 pointer_needs_sizing
= 1;
1055 case RPC_FC_UP
: /* unique pointer */
1056 case RPC_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
= 1;
1062 pointer_needs_sizing
= 0;
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
& RPC_FC_P_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
& RPC_FC_P_DONTFREE
) return;
1110 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1111 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1113 if (!Pointer
) return;
1115 if (type
== RPC_FC_FP
) {
1116 int pointer_needs_freeing
= NdrFullPointerFree(
1117 pStubMsg
->FullPtrXlatTables
, Pointer
);
1118 if (!pointer_needs_freeing
)
1122 if (attr
& RPC_FC_P_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
& RPC_FC_P_ONSTACK
) {
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
!= RPC_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] != RPC_FC_END
) {
1175 switch (pFormat
[0]) {
1177 FIXME("unknown repeat type %d\n", pFormat
[0]);
1178 case RPC_FC_NO_REPEAT
:
1184 case RPC_FC_FIXED_REPEAT
:
1185 rep
= *(const WORD
*)&pFormat
[2];
1186 stride
= *(const WORD
*)&pFormat
[4];
1187 count
= *(const WORD
*)&pFormat
[8];
1190 case RPC_FC_VARIABLE_REPEAT
:
1191 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1192 stride
= *(const WORD
*)&pFormat
[2];
1193 count
= *(const WORD
*)&pFormat
[6];
1197 for (i
= 0; i
< rep
; i
++) {
1198 PFORMAT_STRING info
= pFormat
;
1199 unsigned char *membase
= pMemory
+ (i
* stride
);
1200 unsigned char *bufbase
= Mark
+ (i
* stride
);
1203 for (u
=0; u
<count
; u
++,info
+=8) {
1204 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1205 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1206 unsigned char *saved_memory
= pStubMsg
->Memory
;
1208 pStubMsg
->Memory
= pMemory
;
1209 PointerMarshall(pStubMsg
, bufptr
, *(unsigned char**)memptr
, info
+4);
1210 pStubMsg
->Memory
= saved_memory
;
1213 pFormat
+= 8 * count
;
1218 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1219 pStubMsg
->Buffer
= saved_buffer
;
1222 STD_OVERFLOW_CHECK(pStubMsg
);
1227 /***********************************************************************
1228 * EmbeddedPointerUnmarshall
1230 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1231 unsigned char *pDstBuffer
,
1232 unsigned char *pSrcMemoryPtrs
,
1233 PFORMAT_STRING pFormat
,
1234 unsigned char fMustAlloc
)
1236 unsigned char *Mark
= pStubMsg
->BufferMark
;
1237 unsigned rep
, count
, stride
;
1239 unsigned char *saved_buffer
= NULL
;
1241 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg
, pDstBuffer
, pSrcMemoryPtrs
, pFormat
, fMustAlloc
);
1243 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1246 if (pStubMsg
->PointerBufferMark
)
1248 saved_buffer
= pStubMsg
->Buffer
;
1249 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1250 pStubMsg
->PointerBufferMark
= NULL
;
1253 while (pFormat
[0] != RPC_FC_END
) {
1254 TRACE("pFormat[0] = 0x%x\n", pFormat
[0]);
1255 switch (pFormat
[0]) {
1257 FIXME("unknown repeat type %d\n", pFormat
[0]);
1258 case RPC_FC_NO_REPEAT
:
1264 case RPC_FC_FIXED_REPEAT
:
1265 rep
= *(const WORD
*)&pFormat
[2];
1266 stride
= *(const WORD
*)&pFormat
[4];
1267 count
= *(const WORD
*)&pFormat
[8];
1270 case RPC_FC_VARIABLE_REPEAT
:
1271 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1272 stride
= *(const WORD
*)&pFormat
[2];
1273 count
= *(const WORD
*)&pFormat
[6];
1277 for (i
= 0; i
< rep
; i
++) {
1278 PFORMAT_STRING info
= pFormat
;
1279 unsigned char *bufdstbase
= pDstBuffer
+ (i
* stride
);
1280 unsigned char *memsrcbase
= pSrcMemoryPtrs
+ (i
* stride
);
1281 unsigned char *bufbase
= Mark
+ (i
* stride
);
1284 for (u
=0; u
<count
; u
++,info
+=8) {
1285 unsigned char **bufdstptr
= (unsigned char **)(bufdstbase
+ *(const SHORT
*)&info
[2]);
1286 unsigned char **memsrcptr
= (unsigned char **)(memsrcbase
+ *(const SHORT
*)&info
[0]);
1287 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1288 PointerUnmarshall(pStubMsg
, bufptr
, bufdstptr
, *memsrcptr
, info
+4, fMustAlloc
);
1291 pFormat
+= 8 * count
;
1296 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1297 pStubMsg
->Buffer
= saved_buffer
;
1303 /***********************************************************************
1304 * EmbeddedPointerBufferSize
1306 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1307 unsigned char *pMemory
,
1308 PFORMAT_STRING pFormat
)
1310 unsigned rep
, count
, stride
;
1312 ULONG saved_buffer_length
= 0;
1314 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1316 if (pStubMsg
->IgnoreEmbeddedPointers
) return;
1318 if (*pFormat
!= RPC_FC_PP
) return;
1321 if (pStubMsg
->PointerLength
)
1323 saved_buffer_length
= pStubMsg
->BufferLength
;
1324 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
1325 pStubMsg
->PointerLength
= 0;
1328 while (pFormat
[0] != RPC_FC_END
) {
1329 switch (pFormat
[0]) {
1331 FIXME("unknown repeat type %d\n", pFormat
[0]);
1332 case RPC_FC_NO_REPEAT
:
1338 case RPC_FC_FIXED_REPEAT
:
1339 rep
= *(const WORD
*)&pFormat
[2];
1340 stride
= *(const WORD
*)&pFormat
[4];
1341 count
= *(const WORD
*)&pFormat
[8];
1344 case RPC_FC_VARIABLE_REPEAT
:
1345 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1346 stride
= *(const WORD
*)&pFormat
[2];
1347 count
= *(const WORD
*)&pFormat
[6];
1351 for (i
= 0; i
< rep
; i
++) {
1352 PFORMAT_STRING info
= pFormat
;
1353 unsigned char *membase
= pMemory
+ (i
* stride
);
1356 for (u
=0; u
<count
; u
++,info
+=8) {
1357 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1358 unsigned char *saved_memory
= pStubMsg
->Memory
;
1360 pStubMsg
->Memory
= pMemory
;
1361 PointerBufferSize(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1362 pStubMsg
->Memory
= saved_memory
;
1365 pFormat
+= 8 * count
;
1368 if (saved_buffer_length
)
1370 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
1371 pStubMsg
->BufferLength
= saved_buffer_length
;
1375 /***********************************************************************
1376 * EmbeddedPointerMemorySize [internal]
1378 static ULONG
EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1379 PFORMAT_STRING pFormat
)
1381 unsigned char *Mark
= pStubMsg
->BufferMark
;
1382 unsigned rep
, count
, stride
;
1384 unsigned char *saved_buffer
= NULL
;
1386 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1388 if (pStubMsg
->IgnoreEmbeddedPointers
) return 0;
1390 if (pStubMsg
->PointerBufferMark
)
1392 saved_buffer
= pStubMsg
->Buffer
;
1393 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1394 pStubMsg
->PointerBufferMark
= NULL
;
1397 if (*pFormat
!= RPC_FC_PP
) return 0;
1400 while (pFormat
[0] != RPC_FC_END
) {
1401 switch (pFormat
[0]) {
1403 FIXME("unknown repeat type %d\n", pFormat
[0]);
1404 case RPC_FC_NO_REPEAT
:
1410 case RPC_FC_FIXED_REPEAT
:
1411 rep
= *(const WORD
*)&pFormat
[2];
1412 stride
= *(const WORD
*)&pFormat
[4];
1413 count
= *(const WORD
*)&pFormat
[8];
1416 case RPC_FC_VARIABLE_REPEAT
:
1417 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1418 stride
= *(const WORD
*)&pFormat
[2];
1419 count
= *(const WORD
*)&pFormat
[6];
1423 for (i
= 0; i
< rep
; i
++) {
1424 PFORMAT_STRING info
= pFormat
;
1425 unsigned char *bufbase
= Mark
+ (i
* stride
);
1427 for (u
=0; u
<count
; u
++,info
+=8) {
1428 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1429 PointerMemorySize(pStubMsg
, bufptr
, info
+4);
1432 pFormat
+= 8 * count
;
1437 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1438 pStubMsg
->Buffer
= saved_buffer
;
1444 /***********************************************************************
1445 * EmbeddedPointerFree [internal]
1447 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1448 unsigned char *pMemory
,
1449 PFORMAT_STRING pFormat
)
1451 unsigned rep
, count
, stride
;
1454 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1455 if (*pFormat
!= RPC_FC_PP
) return;
1458 while (pFormat
[0] != RPC_FC_END
) {
1459 switch (pFormat
[0]) {
1461 FIXME("unknown repeat type %d\n", pFormat
[0]);
1462 case RPC_FC_NO_REPEAT
:
1468 case RPC_FC_FIXED_REPEAT
:
1469 rep
= *(const WORD
*)&pFormat
[2];
1470 stride
= *(const WORD
*)&pFormat
[4];
1471 count
= *(const WORD
*)&pFormat
[8];
1474 case RPC_FC_VARIABLE_REPEAT
:
1475 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1476 stride
= *(const WORD
*)&pFormat
[2];
1477 count
= *(const WORD
*)&pFormat
[6];
1481 for (i
= 0; i
< rep
; i
++) {
1482 PFORMAT_STRING info
= pFormat
;
1483 unsigned char *membase
= pMemory
+ (i
* stride
);
1486 for (u
=0; u
<count
; u
++,info
+=8) {
1487 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1488 unsigned char *saved_memory
= pStubMsg
->Memory
;
1490 pStubMsg
->Memory
= pMemory
;
1491 PointerFree(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1492 pStubMsg
->Memory
= saved_memory
;
1495 pFormat
+= 8 * count
;
1499 /***********************************************************************
1500 * NdrPointerMarshall [RPCRT4.@]
1502 unsigned char * WINAPI
NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1503 unsigned char *pMemory
,
1504 PFORMAT_STRING pFormat
)
1506 unsigned char *Buffer
;
1508 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1510 /* Increment the buffer here instead of in PointerMarshall,
1511 * as that is used by embedded pointers which already handle the incrementing
1512 * the buffer, and shouldn't write any additional pointer data to the wire */
1513 if (*pFormat
!= RPC_FC_RP
)
1515 align_pointer_clear(&pStubMsg
->Buffer
, 4);
1516 Buffer
= pStubMsg
->Buffer
;
1517 safe_buffer_increment(pStubMsg
, 4);
1520 Buffer
= pStubMsg
->Buffer
;
1522 PointerMarshall(pStubMsg
, Buffer
, pMemory
, pFormat
);
1527 /***********************************************************************
1528 * NdrPointerUnmarshall [RPCRT4.@]
1530 unsigned char * WINAPI
NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1531 unsigned char **ppMemory
,
1532 PFORMAT_STRING pFormat
,
1533 unsigned char fMustAlloc
)
1535 unsigned char *Buffer
;
1537 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1539 if (*pFormat
== RPC_FC_RP
)
1541 Buffer
= pStubMsg
->Buffer
;
1542 /* Do the NULL ref pointer check here because embedded pointers can be
1543 * NULL if the type the pointer is embedded in was allocated rather than
1544 * being passed in by the client */
1545 if (pStubMsg
->IsClient
&& !*ppMemory
)
1547 ERR("NULL ref pointer is not allowed\n");
1548 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
1553 /* Increment the buffer here instead of in PointerUnmarshall,
1554 * as that is used by embedded pointers which already handle the incrementing
1555 * the buffer, and shouldn't read any additional pointer data from the
1557 align_pointer(&pStubMsg
->Buffer
, 4);
1558 Buffer
= pStubMsg
->Buffer
;
1559 safe_buffer_increment(pStubMsg
, 4);
1562 PointerUnmarshall(pStubMsg
, Buffer
, ppMemory
, *ppMemory
, pFormat
, fMustAlloc
);
1567 /***********************************************************************
1568 * NdrPointerBufferSize [RPCRT4.@]
1570 void WINAPI
NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1571 unsigned char *pMemory
,
1572 PFORMAT_STRING pFormat
)
1574 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1576 /* Increment the buffer length here instead of in PointerBufferSize,
1577 * as that is used by embedded pointers which already handle the buffer
1578 * length, and shouldn't write anything more to the wire */
1579 if (*pFormat
!= RPC_FC_RP
)
1581 align_length(&pStubMsg
->BufferLength
, 4);
1582 safe_buffer_length_increment(pStubMsg
, 4);
1585 PointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1588 /***********************************************************************
1589 * NdrPointerMemorySize [RPCRT4.@]
1591 ULONG WINAPI
NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1592 PFORMAT_STRING pFormat
)
1594 unsigned char *Buffer
= pStubMsg
->Buffer
;
1595 if (*pFormat
!= RPC_FC_RP
)
1597 align_pointer(&pStubMsg
->Buffer
, 4);
1598 safe_buffer_increment(pStubMsg
, 4);
1600 align_length(&pStubMsg
->MemorySize
, sizeof(void *));
1601 return PointerMemorySize(pStubMsg
, Buffer
, pFormat
);
1604 /***********************************************************************
1605 * NdrPointerFree [RPCRT4.@]
1607 void WINAPI
NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1608 unsigned char *pMemory
,
1609 PFORMAT_STRING pFormat
)
1611 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1612 PointerFree(pStubMsg
, pMemory
, pFormat
);
1615 /***********************************************************************
1616 * NdrSimpleTypeMarshall [RPCRT4.@]
1618 void WINAPI
NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1619 unsigned char FormatChar
)
1621 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &FormatChar
);
1624 /***********************************************************************
1625 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1627 * Unmarshall a base type.
1630 * Doesn't check that the buffer is long enough before copying, so the caller
1633 void WINAPI
NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1634 unsigned char FormatChar
)
1636 #define BASE_TYPE_UNMARSHALL(type) \
1637 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
1638 TRACE("pMemory: %p\n", pMemory); \
1639 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1640 pStubMsg->Buffer += sizeof(type);
1648 BASE_TYPE_UNMARSHALL(UCHAR
);
1649 TRACE("value: 0x%02x\n", *pMemory
);
1654 BASE_TYPE_UNMARSHALL(USHORT
);
1655 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
1659 case RPC_FC_ERROR_STATUS_T
:
1661 BASE_TYPE_UNMARSHALL(ULONG
);
1662 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
1665 BASE_TYPE_UNMARSHALL(float);
1666 TRACE("value: %f\n", *(float *)pMemory
);
1669 BASE_TYPE_UNMARSHALL(double);
1670 TRACE("value: %f\n", *(double *)pMemory
);
1673 BASE_TYPE_UNMARSHALL(ULONGLONG
);
1674 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
1677 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
1678 TRACE("pMemory: %p\n", pMemory
);
1679 /* 16-bits on the wire, but int in memory */
1680 *(UINT
*)pMemory
= *(USHORT
*)pStubMsg
->Buffer
;
1681 pStubMsg
->Buffer
+= sizeof(USHORT
);
1682 TRACE("value: 0x%08x\n", *(UINT
*)pMemory
);
1684 case RPC_FC_INT3264
:
1685 align_pointer(&pStubMsg
->Buffer
, sizeof(INT
));
1686 /* 32-bits on the wire, but int_ptr in memory */
1687 *(INT_PTR
*)pMemory
= *(INT
*)pStubMsg
->Buffer
;
1688 pStubMsg
->Buffer
+= sizeof(INT
);
1689 TRACE("value: 0x%08lx\n", *(INT_PTR
*)pMemory
);
1691 case RPC_FC_UINT3264
:
1692 align_pointer(&pStubMsg
->Buffer
, sizeof(UINT
));
1693 /* 32-bits on the wire, but int_ptr in memory */
1694 *(UINT_PTR
*)pMemory
= *(UINT
*)pStubMsg
->Buffer
;
1695 pStubMsg
->Buffer
+= sizeof(UINT
);
1696 TRACE("value: 0x%08lx\n", *(UINT_PTR
*)pMemory
);
1701 FIXME("Unhandled base type: 0x%02x\n", FormatChar
);
1703 #undef BASE_TYPE_UNMARSHALL
1706 /***********************************************************************
1707 * NdrSimpleStructMarshall [RPCRT4.@]
1709 unsigned char * WINAPI
NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1710 unsigned char *pMemory
,
1711 PFORMAT_STRING pFormat
)
1713 unsigned size
= *(const WORD
*)(pFormat
+2);
1714 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1716 align_pointer_clear(&pStubMsg
->Buffer
, pFormat
[1] + 1);
1718 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1719 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
1721 if (pFormat
[0] != RPC_FC_STRUCT
)
1722 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
+4);
1727 /***********************************************************************
1728 * NdrSimpleStructUnmarshall [RPCRT4.@]
1730 unsigned char * WINAPI
NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1731 unsigned char **ppMemory
,
1732 PFORMAT_STRING pFormat
,
1733 unsigned char fMustAlloc
)
1735 unsigned size
= *(const WORD
*)(pFormat
+2);
1736 unsigned char *saved_buffer
;
1737 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1739 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
1742 *ppMemory
= NdrAllocate(pStubMsg
, size
);
1745 if (!pStubMsg
->IsClient
&& !*ppMemory
)
1746 /* for servers, we just point straight into the RPC buffer */
1747 *ppMemory
= pStubMsg
->Buffer
;
1750 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1751 safe_buffer_increment(pStubMsg
, size
);
1752 if (pFormat
[0] == RPC_FC_PSTRUCT
)
1753 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
+4, fMustAlloc
);
1755 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
1756 if (*ppMemory
!= saved_buffer
)
1757 memcpy(*ppMemory
, saved_buffer
, size
);
1762 /***********************************************************************
1763 * NdrSimpleStructBufferSize [RPCRT4.@]
1765 void WINAPI
NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1766 unsigned char *pMemory
,
1767 PFORMAT_STRING pFormat
)
1769 unsigned size
= *(const WORD
*)(pFormat
+2);
1770 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1772 align_length(&pStubMsg
->BufferLength
, pFormat
[1] + 1);
1774 safe_buffer_length_increment(pStubMsg
, size
);
1775 if (pFormat
[0] != RPC_FC_STRUCT
)
1776 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
+4);
1779 /***********************************************************************
1780 * NdrSimpleStructMemorySize [RPCRT4.@]
1782 ULONG WINAPI
NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1783 PFORMAT_STRING pFormat
)
1785 unsigned short size
= *(const WORD
*)(pFormat
+2);
1787 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1789 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
1790 pStubMsg
->MemorySize
+= size
;
1791 safe_buffer_increment(pStubMsg
, size
);
1793 if (pFormat
[0] != RPC_FC_STRUCT
)
1794 EmbeddedPointerMemorySize(pStubMsg
, pFormat
+4);
1795 return pStubMsg
->MemorySize
;
1798 /***********************************************************************
1799 * NdrSimpleStructFree [RPCRT4.@]
1801 void WINAPI
NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
1802 unsigned char *pMemory
,
1803 PFORMAT_STRING pFormat
)
1805 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1806 if (pFormat
[0] != RPC_FC_STRUCT
)
1807 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
+4);
1812 static inline void array_compute_and_size_conformance(
1813 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1814 PFORMAT_STRING pFormat
)
1821 ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1822 SizeConformance(pStubMsg
);
1824 case RPC_FC_CVARRAY
:
1825 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, 0);
1826 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
1827 SizeConformance(pStubMsg
);
1829 case RPC_FC_C_CSTRING
:
1830 case RPC_FC_C_WSTRING
:
1831 if (fc
== RPC_FC_C_CSTRING
)
1833 TRACE("string=%s\n", debugstr_a((const char *)pMemory
));
1834 pStubMsg
->ActualCount
= strlen((const char *)pMemory
)+1;
1838 TRACE("string=%s\n", debugstr_w((LPCWSTR
)pMemory
));
1839 pStubMsg
->ActualCount
= strlenW((LPCWSTR
)pMemory
)+1;
1842 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
1843 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
1845 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
1847 SizeConformance(pStubMsg
);
1849 case RPC_FC_BOGUS_ARRAY
:
1850 count
= *(const WORD
*)(pFormat
+ 2);
1852 if (IsConformanceOrVariancePresent(pFormat
)) SizeConformance(pStubMsg
);
1853 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, count
);
1854 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
1857 ERR("unknown array format 0x%x\n", fc
);
1858 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1862 static inline void array_buffer_size(
1863 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1864 PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
1868 unsigned char alignment
;
1873 esize
= *(const WORD
*)(pFormat
+2);
1874 alignment
= pFormat
[1] + 1;
1876 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1878 align_length(&pStubMsg
->BufferLength
, alignment
);
1880 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
1881 /* conformance value plus array */
1882 safe_buffer_length_increment(pStubMsg
, size
);
1885 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1887 case RPC_FC_CVARRAY
:
1888 esize
= *(const WORD
*)(pFormat
+2);
1889 alignment
= pFormat
[1] + 1;
1891 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1892 pFormat
= SkipVariance(pStubMsg
, pFormat
);
1894 SizeVariance(pStubMsg
);
1896 align_length(&pStubMsg
->BufferLength
, alignment
);
1898 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1899 safe_buffer_length_increment(pStubMsg
, size
);
1902 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1904 case RPC_FC_C_CSTRING
:
1905 case RPC_FC_C_WSTRING
:
1906 if (fc
== RPC_FC_C_CSTRING
)
1911 SizeVariance(pStubMsg
);
1913 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1914 safe_buffer_length_increment(pStubMsg
, size
);
1916 case RPC_FC_BOGUS_ARRAY
:
1917 alignment
= pFormat
[1] + 1;
1918 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1919 if (IsConformanceOrVariancePresent(pFormat
)) SizeVariance(pStubMsg
);
1920 pFormat
= SkipVariance(pStubMsg
, pFormat
);
1922 align_length(&pStubMsg
->BufferLength
, alignment
);
1924 size
= pStubMsg
->ActualCount
;
1925 for (i
= 0; i
< size
; i
++)
1926 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
1929 ERR("unknown array format 0x%x\n", fc
);
1930 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1934 static inline void array_compute_and_write_conformance(
1935 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1936 PFORMAT_STRING pFormat
)
1939 BOOL conformance_present
;
1944 ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1945 WriteConformance(pStubMsg
);
1947 case RPC_FC_CVARRAY
:
1948 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, 0);
1949 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
1950 WriteConformance(pStubMsg
);
1952 case RPC_FC_C_CSTRING
:
1953 case RPC_FC_C_WSTRING
:
1954 if (fc
== RPC_FC_C_CSTRING
)
1956 TRACE("string=%s\n", debugstr_a((const char *)pMemory
));
1957 pStubMsg
->ActualCount
= strlen((const char *)pMemory
)+1;
1961 TRACE("string=%s\n", debugstr_w((LPCWSTR
)pMemory
));
1962 pStubMsg
->ActualCount
= strlenW((LPCWSTR
)pMemory
)+1;
1964 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
1965 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
1967 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
1968 pStubMsg
->Offset
= 0;
1969 WriteConformance(pStubMsg
);
1971 case RPC_FC_BOGUS_ARRAY
:
1972 def
= *(const WORD
*)(pFormat
+ 2);
1974 conformance_present
= IsConformanceOrVariancePresent(pFormat
);
1975 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
1976 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
1977 if (conformance_present
) WriteConformance(pStubMsg
);
1980 ERR("unknown array format 0x%x\n", fc
);
1981 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1985 static inline void array_write_variance_and_marshall(
1986 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1987 PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
1991 unsigned char alignment
;
1996 esize
= *(const WORD
*)(pFormat
+2);
1997 alignment
= pFormat
[1] + 1;
1999 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2001 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
2003 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2005 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2006 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
2009 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2011 case RPC_FC_CVARRAY
:
2012 esize
= *(const WORD
*)(pFormat
+2);
2013 alignment
= pFormat
[1] + 1;
2015 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2016 pFormat
= SkipVariance(pStubMsg
, pFormat
);
2018 WriteVariance(pStubMsg
);
2020 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
2022 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2025 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2026 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, size
);
2029 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2031 case RPC_FC_C_CSTRING
:
2032 case RPC_FC_C_WSTRING
:
2033 if (fc
== RPC_FC_C_CSTRING
)
2038 WriteVariance(pStubMsg
);
2040 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2041 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
2043 case RPC_FC_BOGUS_ARRAY
:
2044 alignment
= pFormat
[1] + 1;
2045 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2046 if (IsConformanceOrVariancePresent(pFormat
)) WriteVariance(pStubMsg
);
2047 pFormat
= SkipVariance(pStubMsg
, pFormat
);
2049 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
2051 size
= pStubMsg
->ActualCount
;
2052 for (i
= 0; i
< size
; i
++)
2053 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
2056 ERR("unknown array format 0x%x\n", fc
);
2057 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2061 static inline ULONG
array_read_conformance(
2062 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
2069 esize
= *(const WORD
*)(pFormat
+2);
2070 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2071 return safe_multiply(esize
, pStubMsg
->MaxCount
);
2072 case RPC_FC_CVARRAY
:
2073 esize
= *(const WORD
*)(pFormat
+2);
2074 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2075 return safe_multiply(esize
, pStubMsg
->MaxCount
);
2076 case RPC_FC_C_CSTRING
:
2077 case RPC_FC_C_WSTRING
:
2078 if (fc
== RPC_FC_C_CSTRING
)
2083 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
2084 ReadConformance(pStubMsg
, pFormat
+ 2);
2086 ReadConformance(pStubMsg
, NULL
);
2087 return safe_multiply(esize
, pStubMsg
->MaxCount
);
2088 case RPC_FC_BOGUS_ARRAY
:
2089 def
= *(const WORD
*)(pFormat
+ 2);
2091 if (IsConformanceOrVariancePresent(pFormat
)) pFormat
= ReadConformance(pStubMsg
, pFormat
);
2094 pStubMsg
->MaxCount
= def
;
2095 pFormat
= SkipConformance( pStubMsg
, pFormat
);
2097 pFormat
= SkipVariance( pStubMsg
, pFormat
);
2099 esize
= ComplexStructSize(pStubMsg
, pFormat
);
2100 return safe_multiply(pStubMsg
->MaxCount
, esize
);
2102 ERR("unknown array format 0x%x\n", fc
);
2103 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2107 static inline ULONG
array_read_variance_and_unmarshall(
2108 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char **ppMemory
,
2109 PFORMAT_STRING pFormat
, unsigned char fMustAlloc
,
2110 unsigned char fUseBufferMemoryServer
, unsigned char fUnmarshall
)
2112 ULONG bufsize
, memsize
;
2114 unsigned char alignment
;
2115 unsigned char *saved_buffer
, *pMemory
;
2116 ULONG i
, offset
, count
;
2121 esize
= *(const WORD
*)(pFormat
+2);
2122 alignment
= pFormat
[1] + 1;
2124 bufsize
= memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2126 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2128 align_pointer(&pStubMsg
->Buffer
, alignment
);
2133 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2136 if (fUseBufferMemoryServer
&& !pStubMsg
->IsClient
&& !*ppMemory
)
2137 /* for servers, we just point straight into the RPC buffer */
2138 *ppMemory
= pStubMsg
->Buffer
;
2141 saved_buffer
= pStubMsg
->Buffer
;
2142 safe_buffer_increment(pStubMsg
, bufsize
);
2144 pStubMsg
->BufferMark
= saved_buffer
;
2145 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
2147 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
2148 if (*ppMemory
!= saved_buffer
)
2149 memcpy(*ppMemory
, saved_buffer
, bufsize
);
2152 case RPC_FC_CVARRAY
:
2153 esize
= *(const WORD
*)(pFormat
+2);
2154 alignment
= pFormat
[1] + 1;
2156 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2158 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2160 align_pointer(&pStubMsg
->Buffer
, alignment
);
2162 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2163 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2167 offset
= pStubMsg
->Offset
;
2169 if (!fMustAlloc
&& !*ppMemory
)
2172 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2173 saved_buffer
= pStubMsg
->Buffer
;
2174 safe_buffer_increment(pStubMsg
, bufsize
);
2176 pStubMsg
->BufferMark
= saved_buffer
;
2177 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
,
2180 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
2183 case RPC_FC_C_CSTRING
:
2184 case RPC_FC_C_WSTRING
:
2185 if (fc
== RPC_FC_C_CSTRING
)
2190 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
2192 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
2194 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2195 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
2196 RpcRaiseException(RPC_S_INVALID_BOUND
);
2198 if (pStubMsg
->Offset
)
2200 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2201 RpcRaiseException(RPC_S_INVALID_BOUND
);
2204 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2205 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2207 validate_string_data(pStubMsg
, bufsize
, esize
);
2212 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2215 if (fUseBufferMemoryServer
&& !pStubMsg
->IsClient
&&
2216 !*ppMemory
&& (pStubMsg
->MaxCount
== pStubMsg
->ActualCount
))
2217 /* if the data in the RPC buffer is big enough, we just point
2218 * straight into it */
2219 *ppMemory
= pStubMsg
->Buffer
;
2220 else if (!*ppMemory
)
2221 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2224 if (*ppMemory
== pStubMsg
->Buffer
)
2225 safe_buffer_increment(pStubMsg
, bufsize
);
2227 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
2229 if (*pFormat
== RPC_FC_C_CSTRING
)
2230 TRACE("string=%s\n", debugstr_a((char*)*ppMemory
));
2232 TRACE("string=%s\n", debugstr_w((LPWSTR
)*ppMemory
));
2236 case RPC_FC_BOGUS_ARRAY
:
2237 alignment
= pFormat
[1] + 1;
2238 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2239 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2241 esize
= ComplexStructSize(pStubMsg
, pFormat
);
2242 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2244 assert( fUnmarshall
);
2246 if (!fMustAlloc
&& !*ppMemory
)
2249 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2251 align_pointer(&pStubMsg
->Buffer
, alignment
);
2252 saved_buffer
= pStubMsg
->Buffer
;
2254 pMemory
= *ppMemory
;
2255 count
= pStubMsg
->ActualCount
;
2256 for (i
= 0; i
< count
; i
++)
2257 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
, fMustAlloc
);
2258 return pStubMsg
->Buffer
- saved_buffer
;
2261 ERR("unknown array format 0x%x\n", fc
);
2262 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2266 static inline void array_memory_size(
2267 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
,
2268 unsigned char fHasPointers
)
2270 ULONG i
, count
, SavedMemorySize
;
2271 ULONG bufsize
, memsize
;
2273 unsigned char alignment
;
2278 esize
= *(const WORD
*)(pFormat
+2);
2279 alignment
= pFormat
[1] + 1;
2281 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2283 bufsize
= memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2284 pStubMsg
->MemorySize
+= memsize
;
2286 align_pointer(&pStubMsg
->Buffer
, alignment
);
2288 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2289 safe_buffer_increment(pStubMsg
, bufsize
);
2292 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2294 case RPC_FC_CVARRAY
:
2295 esize
= *(const WORD
*)(pFormat
+2);
2296 alignment
= pFormat
[1] + 1;
2298 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2300 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2302 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2303 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2304 pStubMsg
->MemorySize
+= memsize
;
2306 align_pointer(&pStubMsg
->Buffer
, alignment
);
2308 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2309 safe_buffer_increment(pStubMsg
, bufsize
);
2312 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2314 case RPC_FC_C_CSTRING
:
2315 case RPC_FC_C_WSTRING
:
2316 if (fc
== RPC_FC_C_CSTRING
)
2321 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
2323 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
2325 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2326 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
2327 RpcRaiseException(RPC_S_INVALID_BOUND
);
2329 if (pStubMsg
->Offset
)
2331 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2332 RpcRaiseException(RPC_S_INVALID_BOUND
);
2335 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2336 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2338 validate_string_data(pStubMsg
, bufsize
, esize
);
2340 safe_buffer_increment(pStubMsg
, bufsize
);
2341 pStubMsg
->MemorySize
+= memsize
;
2343 case RPC_FC_BOGUS_ARRAY
:
2344 alignment
= pFormat
[1] + 1;
2345 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2346 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2348 align_pointer(&pStubMsg
->Buffer
, alignment
);
2350 SavedMemorySize
= pStubMsg
->MemorySize
;
2352 esize
= ComplexStructSize(pStubMsg
, pFormat
);
2353 memsize
= safe_multiply(pStubMsg
->MaxCount
, esize
);
2355 count
= pStubMsg
->ActualCount
;
2356 for (i
= 0; i
< count
; i
++)
2357 ComplexStructMemorySize(pStubMsg
, pFormat
, NULL
);
2359 pStubMsg
->MemorySize
= SavedMemorySize
+ memsize
;
2362 ERR("unknown array format 0x%x\n", fc
);
2363 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2367 static inline void array_free(
2368 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
,
2369 unsigned char *pMemory
, PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
2376 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2378 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2380 case RPC_FC_CVARRAY
:
2381 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2382 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2384 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2386 case RPC_FC_C_CSTRING
:
2387 case RPC_FC_C_WSTRING
:
2388 /* No embedded pointers so nothing to do */
2390 case RPC_FC_BOGUS_ARRAY
:
2391 count
= *(const WORD
*)(pFormat
+ 2);
2392 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, count
);
2393 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
2395 count
= pStubMsg
->ActualCount
;
2396 for (i
= 0; i
< count
; i
++)
2397 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
2400 ERR("unknown array format 0x%x\n", fc
);
2401 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2406 * NdrConformantString:
2408 * What MS calls a ConformantString is, in DCE terminology,
2409 * a Varying-Conformant String.
2411 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2412 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2413 * into unmarshalled string)
2414 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2416 * data: CHARTYPE[maxlen]
2418 * ], where CHARTYPE is the appropriate character type (specified externally)
2422 /***********************************************************************
2423 * NdrConformantStringMarshall [RPCRT4.@]
2425 unsigned char *WINAPI
NdrConformantStringMarshall(MIDL_STUB_MESSAGE
*pStubMsg
,
2426 unsigned char *pszMessage
, PFORMAT_STRING pFormat
)
2428 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg
, pszMessage
, pFormat
);
2430 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2431 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2432 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2435 /* allow compiler to optimise inline function by passing constant into
2436 * these functions */
2437 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2438 array_compute_and_write_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pszMessage
,
2440 array_write_variance_and_marshall(RPC_FC_C_CSTRING
, pStubMsg
, pszMessage
,
2441 pFormat
, TRUE
/* fHasPointers */);
2443 array_compute_and_write_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pszMessage
,
2445 array_write_variance_and_marshall(RPC_FC_C_WSTRING
, pStubMsg
, pszMessage
,
2446 pFormat
, TRUE
/* fHasPointers */);
2452 /***********************************************************************
2453 * NdrConformantStringBufferSize [RPCRT4.@]
2455 void WINAPI
NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2456 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
2458 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2460 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2461 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2462 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2465 /* allow compiler to optimise inline function by passing constant into
2466 * these functions */
2467 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2468 array_compute_and_size_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pMemory
,
2470 array_buffer_size(RPC_FC_C_CSTRING
, pStubMsg
, pMemory
, pFormat
,
2471 TRUE
/* fHasPointers */);
2473 array_compute_and_size_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pMemory
,
2475 array_buffer_size(RPC_FC_C_WSTRING
, pStubMsg
, pMemory
, pFormat
,
2476 TRUE
/* fHasPointers */);
2480 /************************************************************************
2481 * NdrConformantStringMemorySize [RPCRT4.@]
2483 ULONG WINAPI
NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
2484 PFORMAT_STRING pFormat
)
2486 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
2488 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2489 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2490 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2493 /* allow compiler to optimise inline function by passing constant into
2494 * these functions */
2495 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2496 array_read_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
);
2497 array_memory_size(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
,
2498 TRUE
/* fHasPointers */);
2500 array_read_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
);
2501 array_memory_size(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
,
2502 TRUE
/* fHasPointers */);
2505 return pStubMsg
->MemorySize
;
2508 /************************************************************************
2509 * NdrConformantStringUnmarshall [RPCRT4.@]
2511 unsigned char *WINAPI
NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2512 unsigned char** ppMemory
, PFORMAT_STRING pFormat
, unsigned char fMustAlloc
)
2514 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2515 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
2517 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2518 ERR("Unhandled string type: %#x\n", *pFormat
);
2519 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2522 /* allow compiler to optimise inline function by passing constant into
2523 * these functions */
2524 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2525 array_read_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
);
2526 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING
, pStubMsg
, ppMemory
,
2527 pFormat
, fMustAlloc
,
2528 TRUE
/* fUseBufferMemoryServer */,
2529 TRUE
/* fUnmarshall */);
2531 array_read_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
);
2532 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING
, pStubMsg
, ppMemory
,
2533 pFormat
, fMustAlloc
,
2534 TRUE
/* fUseBufferMemoryServer */,
2535 TRUE
/* fUnmarshall */);
2541 /***********************************************************************
2542 * NdrNonConformantStringMarshall [RPCRT4.@]
2544 unsigned char * WINAPI
NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2545 unsigned char *pMemory
,
2546 PFORMAT_STRING pFormat
)
2548 ULONG esize
, size
, maxsize
;
2550 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2552 maxsize
= *(const USHORT
*)&pFormat
[2];
2554 if (*pFormat
== RPC_FC_CSTRING
)
2557 const char *str
= (const char *)pMemory
;
2558 while (i
< maxsize
&& str
[i
]) i
++;
2559 TRACE("string=%s\n", debugstr_an(str
, i
));
2560 pStubMsg
->ActualCount
= i
+ 1;
2563 else if (*pFormat
== RPC_FC_WSTRING
)
2566 const WCHAR
*str
= (const WCHAR
*)pMemory
;
2567 while (i
< maxsize
&& str
[i
]) i
++;
2568 TRACE("string=%s\n", debugstr_wn(str
, i
));
2569 pStubMsg
->ActualCount
= i
+ 1;
2574 ERR("Unhandled string type: %#x\n", *pFormat
);
2575 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2578 pStubMsg
->Offset
= 0;
2579 WriteVariance(pStubMsg
);
2581 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2582 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
2587 /***********************************************************************
2588 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2590 unsigned char * WINAPI
NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2591 unsigned char **ppMemory
,
2592 PFORMAT_STRING pFormat
,
2593 unsigned char fMustAlloc
)
2595 ULONG bufsize
, memsize
, esize
, maxsize
;
2597 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2598 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
2600 maxsize
= *(const USHORT
*)&pFormat
[2];
2602 ReadVariance(pStubMsg
, NULL
, maxsize
);
2603 if (pStubMsg
->Offset
)
2605 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2606 RpcRaiseException(RPC_S_INVALID_BOUND
);
2609 if (*pFormat
== RPC_FC_CSTRING
) esize
= 1;
2610 else if (*pFormat
== RPC_FC_WSTRING
) esize
= 2;
2613 ERR("Unhandled string type: %#x\n", *pFormat
);
2614 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2617 memsize
= esize
* maxsize
;
2618 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2620 validate_string_data(pStubMsg
, bufsize
, esize
);
2622 if (!fMustAlloc
&& !*ppMemory
)
2625 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2627 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
2629 if (*pFormat
== RPC_FC_CSTRING
) {
2630 TRACE("string=%s\n", debugstr_an((char*)*ppMemory
, pStubMsg
->ActualCount
));
2632 else if (*pFormat
== RPC_FC_WSTRING
) {
2633 TRACE("string=%s\n", debugstr_wn((LPWSTR
)*ppMemory
, pStubMsg
->ActualCount
));
2639 /***********************************************************************
2640 * NdrNonConformantStringBufferSize [RPCRT4.@]
2642 void WINAPI
NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2643 unsigned char *pMemory
,
2644 PFORMAT_STRING pFormat
)
2646 ULONG esize
, maxsize
;
2648 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2650 maxsize
= *(const USHORT
*)&pFormat
[2];
2652 SizeVariance(pStubMsg
);
2654 if (*pFormat
== RPC_FC_CSTRING
)
2657 const char *str
= (const char *)pMemory
;
2658 while (i
< maxsize
&& str
[i
]) i
++;
2659 TRACE("string=%s\n", debugstr_an(str
, i
));
2660 pStubMsg
->ActualCount
= i
+ 1;
2663 else if (*pFormat
== RPC_FC_WSTRING
)
2666 const WCHAR
*str
= (const WCHAR
*)pMemory
;
2667 while (i
< maxsize
&& str
[i
]) i
++;
2668 TRACE("string=%s\n", debugstr_wn(str
, i
));
2669 pStubMsg
->ActualCount
= i
+ 1;
2674 ERR("Unhandled string type: %#x\n", *pFormat
);
2675 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2678 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
2681 /***********************************************************************
2682 * NdrNonConformantStringMemorySize [RPCRT4.@]
2684 ULONG WINAPI
NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2685 PFORMAT_STRING pFormat
)
2687 ULONG bufsize
, memsize
, esize
, maxsize
;
2689 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
2691 maxsize
= *(const USHORT
*)&pFormat
[2];
2693 ReadVariance(pStubMsg
, NULL
, maxsize
);
2695 if (pStubMsg
->Offset
)
2697 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2698 RpcRaiseException(RPC_S_INVALID_BOUND
);
2701 if (*pFormat
== RPC_FC_CSTRING
) esize
= 1;
2702 else if (*pFormat
== RPC_FC_WSTRING
) esize
= 2;
2705 ERR("Unhandled string type: %#x\n", *pFormat
);
2706 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2709 memsize
= esize
* maxsize
;
2710 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2712 validate_string_data(pStubMsg
, bufsize
, esize
);
2714 safe_buffer_increment(pStubMsg
, bufsize
);
2715 pStubMsg
->MemorySize
+= memsize
;
2717 return pStubMsg
->MemorySize
;
2722 #include "pshpack1.h"
2726 unsigned char flags_type
; /* flags in upper nibble, type in lower nibble */
2730 #include "poppack.h"
2732 static ULONG
EmbeddedComplexSize(MIDL_STUB_MESSAGE
*pStubMsg
,
2733 PFORMAT_STRING pFormat
)
2737 case RPC_FC_PSTRUCT
:
2738 case RPC_FC_CSTRUCT
:
2739 case RPC_FC_BOGUS_STRUCT
:
2740 case RPC_FC_SMFARRAY
:
2741 case RPC_FC_SMVARRAY
:
2742 case RPC_FC_CSTRING
:
2743 return *(const WORD
*)&pFormat
[2];
2744 case RPC_FC_USER_MARSHAL
:
2745 return *(const WORD
*)&pFormat
[4];
2746 case RPC_FC_RANGE
: {
2747 switch (((const NDR_RANGE
*)pFormat
)->flags_type
& 0xf) {
2752 return sizeof(UCHAR
);
2756 return sizeof(USHORT
);
2760 case RPC_FC_INT3264
:
2761 case RPC_FC_UINT3264
:
2762 return sizeof(ULONG
);
2764 return sizeof(float);
2766 return sizeof(double);
2768 return sizeof(ULONGLONG
);
2770 return sizeof(UINT
);
2772 ERR("unknown type 0x%x\n", ((const NDR_RANGE
*)pFormat
)->flags_type
& 0xf);
2773 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2776 case RPC_FC_NON_ENCAPSULATED_UNION
:
2778 if (pStubMsg
->fHasNewCorrDesc
)
2783 pFormat
+= *(const SHORT
*)pFormat
;
2784 return *(const SHORT
*)pFormat
;
2786 return sizeof(void *);
2787 case RPC_FC_WSTRING
:
2788 return *(const WORD
*)&pFormat
[2] * 2;
2790 FIXME("unhandled embedded type %02x\n", *pFormat
);
2796 static ULONG
EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2797 PFORMAT_STRING pFormat
)
2799 NDR_MEMORYSIZE m
= NdrMemorySizer
[*pFormat
& NDR_TABLE_MASK
];
2803 FIXME("no memorysizer for data type=%02x\n", *pFormat
);
2807 return m(pStubMsg
, pFormat
);
2811 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2812 unsigned char *pMemory
,
2813 PFORMAT_STRING pFormat
,
2814 PFORMAT_STRING pPointer
)
2816 PFORMAT_STRING desc
;
2820 while (*pFormat
!= RPC_FC_END
) {
2826 TRACE("byte=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2827 safe_copy_to_buffer(pStubMsg
, pMemory
, 1);
2833 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2834 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
2839 USHORT val
= *(DWORD
*)pMemory
;
2840 TRACE("enum16=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2841 if (32767 < *(DWORD
*)pMemory
)
2842 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
2843 safe_copy_to_buffer(pStubMsg
, &val
, 2);
2850 TRACE("long=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2851 safe_copy_to_buffer(pStubMsg
, pMemory
, 4);
2854 case RPC_FC_INT3264
:
2855 case RPC_FC_UINT3264
:
2857 UINT val
= *(UINT_PTR
*)pMemory
;
2858 TRACE("int3264=%ld <= %p\n", *(UINT_PTR
*)pMemory
, pMemory
);
2859 safe_copy_to_buffer(pStubMsg
, &val
, sizeof(UINT
));
2860 pMemory
+= sizeof(UINT_PTR
);
2864 TRACE("float=%f <= %p\n", *(float*)pMemory
, pMemory
);
2865 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
2866 pMemory
+= sizeof(float);
2869 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2870 safe_copy_to_buffer(pStubMsg
, pMemory
, 8);
2874 TRACE("double=%f <= %p\n", *(double*)pMemory
, pMemory
);
2875 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
2876 pMemory
+= sizeof(double);
2882 case RPC_FC_POINTER
:
2884 unsigned char *saved_buffer
;
2885 int pointer_buffer_mark_set
= 0;
2886 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
2887 TRACE("pStubMsg->Buffer before %p\n", pStubMsg
->Buffer
);
2888 if (*pFormat
!= RPC_FC_POINTER
)
2890 if (*pPointer
!= RPC_FC_RP
)
2891 align_pointer_clear(&pStubMsg
->Buffer
, 4);
2892 saved_buffer
= pStubMsg
->Buffer
;
2893 if (pStubMsg
->PointerBufferMark
)
2895 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2896 pStubMsg
->PointerBufferMark
= NULL
;
2897 pointer_buffer_mark_set
= 1;
2899 else if (*pPointer
!= RPC_FC_RP
)
2900 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2901 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char**)pMemory
, pPointer
);
2902 if (pointer_buffer_mark_set
)
2904 STD_OVERFLOW_CHECK(pStubMsg
);
2905 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2906 pStubMsg
->Buffer
= saved_buffer
;
2907 if (*pPointer
!= RPC_FC_RP
)
2908 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2910 TRACE("pStubMsg->Buffer after %p\n", pStubMsg
->Buffer
);
2911 if (*pFormat
== RPC_FC_POINTER
)
2915 pMemory
+= sizeof(void *);
2918 case RPC_FC_ALIGNM2
:
2919 align_pointer(&pMemory
, 2);
2921 case RPC_FC_ALIGNM4
:
2922 align_pointer(&pMemory
, 4);
2924 case RPC_FC_ALIGNM8
:
2925 align_pointer(&pMemory
, 8);
2927 case RPC_FC_STRUCTPAD1
:
2928 case RPC_FC_STRUCTPAD2
:
2929 case RPC_FC_STRUCTPAD3
:
2930 case RPC_FC_STRUCTPAD4
:
2931 case RPC_FC_STRUCTPAD5
:
2932 case RPC_FC_STRUCTPAD6
:
2933 case RPC_FC_STRUCTPAD7
:
2934 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2936 case RPC_FC_EMBEDDED_COMPLEX
:
2937 pMemory
+= pFormat
[1];
2939 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2940 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2941 TRACE("embedded complex (size=%d) <= %p\n", size
, pMemory
);
2942 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
2945 /* for some reason interface pointers aren't generated as
2946 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2947 * they still need the derefencing treatment that pointers are
2949 if (*desc
== RPC_FC_IP
)
2950 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2952 m(pStubMsg
, pMemory
, desc
);
2954 else FIXME("no marshaller for embedded type %02x\n", *desc
);
2961 FIXME("unhandled format 0x%02x\n", *pFormat
);
2969 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2970 unsigned char *pMemory
,
2971 PFORMAT_STRING pFormat
,
2972 PFORMAT_STRING pPointer
,
2973 unsigned char fMustAlloc
)
2975 PFORMAT_STRING desc
;
2979 while (*pFormat
!= RPC_FC_END
) {
2985 safe_copy_from_buffer(pStubMsg
, pMemory
, 1);
2986 TRACE("byte=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2992 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
2993 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2999 safe_copy_from_buffer(pStubMsg
, &val
, 2);
3000 *(DWORD
*)pMemory
= val
;
3001 TRACE("enum16=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
3002 if (32767 < *(DWORD
*)pMemory
)
3003 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
3010 safe_copy_from_buffer(pStubMsg
, pMemory
, 4);
3011 TRACE("long=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
3014 case RPC_FC_INT3264
:
3017 safe_copy_from_buffer(pStubMsg
, &val
, 4);
3018 *(INT_PTR
*)pMemory
= val
;
3019 TRACE("int3264=%ld => %p\n", *(INT_PTR
*)pMemory
, pMemory
);
3020 pMemory
+= sizeof(INT_PTR
);
3023 case RPC_FC_UINT3264
:
3026 safe_copy_from_buffer(pStubMsg
, &val
, 4);
3027 *(UINT_PTR
*)pMemory
= val
;
3028 TRACE("uint3264=%ld => %p\n", *(UINT_PTR
*)pMemory
, pMemory
);
3029 pMemory
+= sizeof(UINT_PTR
);
3033 safe_copy_from_buffer(pStubMsg
, pMemory
, sizeof(float));
3034 TRACE("float=%f => %p\n", *(float*)pMemory
, pMemory
);
3035 pMemory
+= sizeof(float);
3038 safe_copy_from_buffer(pStubMsg
, pMemory
, 8);
3039 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
3043 safe_copy_from_buffer(pStubMsg
, pMemory
, sizeof(double));
3044 TRACE("double=%f => %p\n", *(double*)pMemory
, pMemory
);
3045 pMemory
+= sizeof(double);
3051 case RPC_FC_POINTER
:
3053 unsigned char *saved_buffer
;
3054 int pointer_buffer_mark_set
= 0;
3055 TRACE("pointer => %p\n", pMemory
);
3056 if (*pFormat
!= RPC_FC_POINTER
)
3058 if (*pPointer
!= RPC_FC_RP
)
3059 align_pointer(&pStubMsg
->Buffer
, 4);
3060 saved_buffer
= pStubMsg
->Buffer
;
3061 if (pStubMsg
->PointerBufferMark
)
3063 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3064 pStubMsg
->PointerBufferMark
= NULL
;
3065 pointer_buffer_mark_set
= 1;
3067 else if (*pPointer
!= RPC_FC_RP
)
3068 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3070 PointerUnmarshall(pStubMsg
, saved_buffer
, (unsigned char**)pMemory
, *(unsigned char**)pMemory
, pPointer
, fMustAlloc
);
3071 if (pointer_buffer_mark_set
)
3073 STD_OVERFLOW_CHECK(pStubMsg
);
3074 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3075 pStubMsg
->Buffer
= saved_buffer
;
3076 if (*pPointer
!= RPC_FC_RP
)
3077 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3079 if (*pFormat
== RPC_FC_POINTER
)
3083 pMemory
+= sizeof(void *);
3086 case RPC_FC_ALIGNM2
:
3087 align_pointer_clear(&pMemory
, 2);
3089 case RPC_FC_ALIGNM4
:
3090 align_pointer_clear(&pMemory
, 4);
3092 case RPC_FC_ALIGNM8
:
3093 align_pointer_clear(&pMemory
, 8);
3095 case RPC_FC_STRUCTPAD1
:
3096 case RPC_FC_STRUCTPAD2
:
3097 case RPC_FC_STRUCTPAD3
:
3098 case RPC_FC_STRUCTPAD4
:
3099 case RPC_FC_STRUCTPAD5
:
3100 case RPC_FC_STRUCTPAD6
:
3101 case RPC_FC_STRUCTPAD7
:
3102 memset(pMemory
, 0, *pFormat
- RPC_FC_STRUCTPAD1
+ 1);
3103 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3105 case RPC_FC_EMBEDDED_COMPLEX
:
3106 pMemory
+= pFormat
[1];
3108 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3109 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3110 TRACE("embedded complex (size=%d) => %p\n", size
, pMemory
);
3112 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
3113 * since the type is part of the memory block that is encompassed by
3114 * the whole complex type. Memory is forced to allocate when pointers
3115 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
3116 * clearing the memory we pass in to the unmarshaller */
3117 memset(pMemory
, 0, size
);
3118 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
3121 /* for some reason interface pointers aren't generated as
3122 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3123 * they still need the derefencing treatment that pointers are
3125 if (*desc
== RPC_FC_IP
)
3126 m(pStubMsg
, (unsigned char **)pMemory
, desc
, FALSE
);
3128 m(pStubMsg
, &pMemory
, desc
, FALSE
);
3130 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
3137 FIXME("unhandled format %d\n", *pFormat
);
3145 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3146 unsigned char *pMemory
,
3147 PFORMAT_STRING pFormat
,
3148 PFORMAT_STRING pPointer
)
3150 PFORMAT_STRING desc
;
3154 while (*pFormat
!= RPC_FC_END
) {
3160 safe_buffer_length_increment(pStubMsg
, 1);
3166 safe_buffer_length_increment(pStubMsg
, 2);
3170 safe_buffer_length_increment(pStubMsg
, 2);
3177 safe_buffer_length_increment(pStubMsg
, 4);
3180 case RPC_FC_INT3264
:
3181 case RPC_FC_UINT3264
:
3182 safe_buffer_length_increment(pStubMsg
, 4);
3183 pMemory
+= sizeof(INT_PTR
);
3187 safe_buffer_length_increment(pStubMsg
, 8);
3194 case RPC_FC_POINTER
:
3195 if (*pFormat
!= RPC_FC_POINTER
)
3197 if (!pStubMsg
->IgnoreEmbeddedPointers
)
3199 int saved_buffer_length
= pStubMsg
->BufferLength
;
3200 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3201 pStubMsg
->PointerLength
= 0;
3202 if(!pStubMsg
->BufferLength
)
3203 ERR("BufferLength == 0??\n");
3204 PointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
3205 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3206 pStubMsg
->BufferLength
= saved_buffer_length
;
3208 if (*pPointer
!= RPC_FC_RP
)
3210 align_length(&pStubMsg
->BufferLength
, 4);
3211 safe_buffer_length_increment(pStubMsg
, 4);
3213 if (*pFormat
== RPC_FC_POINTER
)
3217 pMemory
+= sizeof(void*);
3219 case RPC_FC_ALIGNM2
:
3220 align_pointer(&pMemory
, 2);
3222 case RPC_FC_ALIGNM4
:
3223 align_pointer(&pMemory
, 4);
3225 case RPC_FC_ALIGNM8
:
3226 align_pointer(&pMemory
, 8);
3228 case RPC_FC_STRUCTPAD1
:
3229 case RPC_FC_STRUCTPAD2
:
3230 case RPC_FC_STRUCTPAD3
:
3231 case RPC_FC_STRUCTPAD4
:
3232 case RPC_FC_STRUCTPAD5
:
3233 case RPC_FC_STRUCTPAD6
:
3234 case RPC_FC_STRUCTPAD7
:
3235 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3237 case RPC_FC_EMBEDDED_COMPLEX
:
3238 pMemory
+= pFormat
[1];
3240 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3241 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3242 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
3245 /* for some reason interface pointers aren't generated as
3246 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3247 * they still need the derefencing treatment that pointers are
3249 if (*desc
== RPC_FC_IP
)
3250 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
3252 m(pStubMsg
, pMemory
, desc
);
3254 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
3261 FIXME("unhandled format 0x%02x\n", *pFormat
);
3269 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
3270 unsigned char *pMemory
,
3271 PFORMAT_STRING pFormat
,
3272 PFORMAT_STRING pPointer
)
3274 PFORMAT_STRING desc
;
3278 while (*pFormat
!= RPC_FC_END
) {
3298 case RPC_FC_INT3264
:
3299 case RPC_FC_UINT3264
:
3300 pMemory
+= sizeof(INT_PTR
);
3310 case RPC_FC_POINTER
:
3311 if (*pFormat
!= RPC_FC_POINTER
)
3313 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
3314 if (*pFormat
== RPC_FC_POINTER
)
3318 pMemory
+= sizeof(void *);
3320 case RPC_FC_ALIGNM2
:
3321 align_pointer(&pMemory
, 2);
3323 case RPC_FC_ALIGNM4
:
3324 align_pointer(&pMemory
, 4);
3326 case RPC_FC_ALIGNM8
:
3327 align_pointer(&pMemory
, 8);
3329 case RPC_FC_STRUCTPAD1
:
3330 case RPC_FC_STRUCTPAD2
:
3331 case RPC_FC_STRUCTPAD3
:
3332 case RPC_FC_STRUCTPAD4
:
3333 case RPC_FC_STRUCTPAD5
:
3334 case RPC_FC_STRUCTPAD6
:
3335 case RPC_FC_STRUCTPAD7
:
3336 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3338 case RPC_FC_EMBEDDED_COMPLEX
:
3339 pMemory
+= pFormat
[1];
3341 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3342 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3343 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
3346 /* for some reason interface pointers aren't generated as
3347 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3348 * they still need the derefencing treatment that pointers are
3350 if (*desc
== RPC_FC_IP
)
3351 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
3353 m(pStubMsg
, pMemory
, desc
);
3361 FIXME("unhandled format 0x%02x\n", *pFormat
);
3369 static ULONG
ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3370 PFORMAT_STRING pFormat
,
3371 PFORMAT_STRING pPointer
)
3373 PFORMAT_STRING desc
;
3376 while (*pFormat
!= RPC_FC_END
) {
3383 safe_buffer_increment(pStubMsg
, 1);
3389 safe_buffer_increment(pStubMsg
, 2);
3393 safe_buffer_increment(pStubMsg
, 2);
3400 safe_buffer_increment(pStubMsg
, 4);
3402 case RPC_FC_INT3264
:
3403 case RPC_FC_UINT3264
:
3404 size
+= sizeof(INT_PTR
);
3405 safe_buffer_increment(pStubMsg
, 4);
3410 safe_buffer_increment(pStubMsg
, 8);
3416 case RPC_FC_POINTER
:
3418 unsigned char *saved_buffer
;
3419 int pointer_buffer_mark_set
= 0;
3420 if (*pFormat
!= RPC_FC_POINTER
)
3422 if (*pPointer
!= RPC_FC_RP
)
3423 align_pointer(&pStubMsg
->Buffer
, 4);
3424 saved_buffer
= pStubMsg
->Buffer
;
3425 if (pStubMsg
->PointerBufferMark
)
3427 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3428 pStubMsg
->PointerBufferMark
= NULL
;
3429 pointer_buffer_mark_set
= 1;
3431 else if (*pPointer
!= RPC_FC_RP
)
3432 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3434 if (!pStubMsg
->IgnoreEmbeddedPointers
)
3435 PointerMemorySize(pStubMsg
, saved_buffer
, pPointer
);
3436 if (pointer_buffer_mark_set
)
3438 STD_OVERFLOW_CHECK(pStubMsg
);
3439 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3440 pStubMsg
->Buffer
= saved_buffer
;
3441 if (*pPointer
!= RPC_FC_RP
)
3442 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3444 if (*pFormat
== RPC_FC_POINTER
)
3448 size
+= sizeof(void *);
3451 case RPC_FC_ALIGNM2
:
3452 align_length(&size
, 2);
3454 case RPC_FC_ALIGNM4
:
3455 align_length(&size
, 4);
3457 case RPC_FC_ALIGNM8
:
3458 align_length(&size
, 8);
3460 case RPC_FC_STRUCTPAD1
:
3461 case RPC_FC_STRUCTPAD2
:
3462 case RPC_FC_STRUCTPAD3
:
3463 case RPC_FC_STRUCTPAD4
:
3464 case RPC_FC_STRUCTPAD5
:
3465 case RPC_FC_STRUCTPAD6
:
3466 case RPC_FC_STRUCTPAD7
:
3467 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3469 case RPC_FC_EMBEDDED_COMPLEX
:
3472 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3473 size
+= EmbeddedComplexMemorySize(pStubMsg
, desc
);
3479 FIXME("unhandled format 0x%02x\n", *pFormat
);
3487 ULONG
ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
3489 PFORMAT_STRING desc
;
3492 while (*pFormat
!= RPC_FC_END
) {
3512 case RPC_FC_INT3264
:
3513 case RPC_FC_UINT3264
:
3514 size
+= sizeof(INT_PTR
);
3524 case RPC_FC_POINTER
:
3525 size
+= sizeof(void *);
3526 if (*pFormat
!= RPC_FC_POINTER
)
3529 case RPC_FC_ALIGNM2
:
3530 align_length(&size
, 2);
3532 case RPC_FC_ALIGNM4
:
3533 align_length(&size
, 4);
3535 case RPC_FC_ALIGNM8
:
3536 align_length(&size
, 8);
3538 case RPC_FC_STRUCTPAD1
:
3539 case RPC_FC_STRUCTPAD2
:
3540 case RPC_FC_STRUCTPAD3
:
3541 case RPC_FC_STRUCTPAD4
:
3542 case RPC_FC_STRUCTPAD5
:
3543 case RPC_FC_STRUCTPAD6
:
3544 case RPC_FC_STRUCTPAD7
:
3545 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3547 case RPC_FC_EMBEDDED_COMPLEX
:
3550 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3551 size
+= EmbeddedComplexSize(pStubMsg
, desc
);
3557 FIXME("unhandled format 0x%02x\n", *pFormat
);
3565 /***********************************************************************
3566 * NdrComplexStructMarshall [RPCRT4.@]
3568 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3569 unsigned char *pMemory
,
3570 PFORMAT_STRING pFormat
)
3572 PFORMAT_STRING conf_array
= NULL
;
3573 PFORMAT_STRING pointer_desc
= NULL
;
3574 unsigned char *OldMemory
= pStubMsg
->Memory
;
3575 int pointer_buffer_mark_set
= 0;
3577 ULONG max_count
= 0;
3580 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3582 if (!pStubMsg
->PointerBufferMark
)
3584 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3585 /* save buffer length */
3586 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
3588 /* get the buffer pointer after complex array data, but before
3590 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
;
3591 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3592 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
3593 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3595 /* save it for use by embedded pointer code later */
3596 pStubMsg
->PointerBufferMark
= (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
;
3597 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->PointerBufferMark
- pStubMsg
->Buffer
));
3598 pointer_buffer_mark_set
= 1;
3600 /* restore the original buffer length */
3601 pStubMsg
->BufferLength
= saved_buffer_length
;
3604 align_pointer_clear(&pStubMsg
->Buffer
, pFormat
[1] + 1);
3607 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3609 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3612 pStubMsg
->Memory
= pMemory
;
3616 ULONG struct_size
= ComplexStructSize(pStubMsg
, pFormat
);
3617 array_compute_and_write_conformance(conf_array
[0], pStubMsg
,
3618 pMemory
+ struct_size
, conf_array
);
3619 /* these could be changed in ComplexMarshall so save them for later */
3620 max_count
= pStubMsg
->MaxCount
;
3621 count
= pStubMsg
->ActualCount
;
3622 offset
= pStubMsg
->Offset
;
3625 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3629 pStubMsg
->MaxCount
= max_count
;
3630 pStubMsg
->ActualCount
= count
;
3631 pStubMsg
->Offset
= offset
;
3632 array_write_variance_and_marshall(conf_array
[0], pStubMsg
, pMemory
,
3633 conf_array
, TRUE
/* fHasPointers */);
3636 pStubMsg
->Memory
= OldMemory
;
3638 if (pointer_buffer_mark_set
)
3640 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3641 pStubMsg
->PointerBufferMark
= NULL
;
3644 STD_OVERFLOW_CHECK(pStubMsg
);
3649 /***********************************************************************
3650 * NdrComplexStructUnmarshall [RPCRT4.@]
3652 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3653 unsigned char **ppMemory
,
3654 PFORMAT_STRING pFormat
,
3655 unsigned char fMustAlloc
)
3657 unsigned size
= *(const WORD
*)(pFormat
+2);
3658 PFORMAT_STRING conf_array
= NULL
;
3659 PFORMAT_STRING pointer_desc
= NULL
;
3660 unsigned char *pMemory
;
3661 int pointer_buffer_mark_set
= 0;
3663 ULONG max_count
= 0;
3665 ULONG array_size
= 0;
3667 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3669 if (!pStubMsg
->PointerBufferMark
)
3671 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3672 /* save buffer pointer */
3673 unsigned char *saved_buffer
= pStubMsg
->Buffer
;
3675 /* get the buffer pointer after complex array data, but before
3677 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3678 NdrComplexStructMemorySize(pStubMsg
, pFormat
);
3679 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3681 /* save it for use by embedded pointer code later */
3682 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3683 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->PointerBufferMark
- saved_buffer
));
3684 pointer_buffer_mark_set
= 1;
3686 /* restore the original buffer */
3687 pStubMsg
->Buffer
= saved_buffer
;
3690 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
3693 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3695 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3700 array_size
= array_read_conformance(conf_array
[0], pStubMsg
, conf_array
);
3703 /* these could be changed in ComplexMarshall so save them for later */
3704 max_count
= pStubMsg
->MaxCount
;
3705 count
= pStubMsg
->ActualCount
;
3706 offset
= pStubMsg
->Offset
;
3709 if (!fMustAlloc
&& !*ppMemory
)
3712 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3714 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
, fMustAlloc
);
3718 pStubMsg
->MaxCount
= max_count
;
3719 pStubMsg
->ActualCount
= count
;
3720 pStubMsg
->Offset
= offset
;
3722 memset(pMemory
, 0, array_size
);
3723 array_read_variance_and_unmarshall(conf_array
[0], pStubMsg
, &pMemory
,
3725 FALSE
/* fUseBufferMemoryServer */,
3726 TRUE
/* fUnmarshall */);
3729 if (pointer_buffer_mark_set
)
3731 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3732 pStubMsg
->PointerBufferMark
= NULL
;
3738 /***********************************************************************
3739 * NdrComplexStructBufferSize [RPCRT4.@]
3741 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3742 unsigned char *pMemory
,
3743 PFORMAT_STRING pFormat
)
3745 PFORMAT_STRING conf_array
= NULL
;
3746 PFORMAT_STRING pointer_desc
= NULL
;
3747 unsigned char *OldMemory
= pStubMsg
->Memory
;
3748 int pointer_length_set
= 0;
3750 ULONG max_count
= 0;
3753 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3755 align_length(&pStubMsg
->BufferLength
, pFormat
[1] + 1);
3757 if(!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
3759 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3760 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
3762 /* get the buffer length after complex struct data, but before
3764 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3765 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
3766 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3768 /* save it for use by embedded pointer code later */
3769 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3770 pointer_length_set
= 1;
3771 TRACE("difference = 0x%x\n", pStubMsg
->PointerLength
- saved_buffer_length
);
3773 /* restore the original buffer length */
3774 pStubMsg
->BufferLength
= saved_buffer_length
;
3778 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3780 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3783 pStubMsg
->Memory
= pMemory
;
3787 ULONG struct_size
= ComplexStructSize(pStubMsg
, pFormat
);
3788 array_compute_and_size_conformance(conf_array
[0], pStubMsg
, pMemory
+ struct_size
,
3791 /* these could be changed in ComplexMarshall so save them for later */
3792 max_count
= pStubMsg
->MaxCount
;
3793 count
= pStubMsg
->ActualCount
;
3794 offset
= pStubMsg
->Offset
;
3797 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3801 pStubMsg
->MaxCount
= max_count
;
3802 pStubMsg
->ActualCount
= count
;
3803 pStubMsg
->Offset
= offset
;
3804 array_buffer_size(conf_array
[0], pStubMsg
, pMemory
, conf_array
,
3805 TRUE
/* fHasPointers */);
3808 pStubMsg
->Memory
= OldMemory
;
3810 if(pointer_length_set
)
3812 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3813 pStubMsg
->PointerLength
= 0;
3818 /***********************************************************************
3819 * NdrComplexStructMemorySize [RPCRT4.@]
3821 ULONG WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3822 PFORMAT_STRING pFormat
)
3824 unsigned size
= *(const WORD
*)(pFormat
+2);
3825 PFORMAT_STRING conf_array
= NULL
;
3826 PFORMAT_STRING pointer_desc
= NULL
;
3828 ULONG max_count
= 0;
3831 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3833 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
3836 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3838 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3843 array_read_conformance(conf_array
[0], pStubMsg
, conf_array
);
3845 /* these could be changed in ComplexStructMemorySize so save them for
3847 max_count
= pStubMsg
->MaxCount
;
3848 count
= pStubMsg
->ActualCount
;
3849 offset
= pStubMsg
->Offset
;
3852 ComplexStructMemorySize(pStubMsg
, pFormat
, pointer_desc
);
3856 pStubMsg
->MaxCount
= max_count
;
3857 pStubMsg
->ActualCount
= count
;
3858 pStubMsg
->Offset
= offset
;
3859 array_memory_size(conf_array
[0], pStubMsg
, conf_array
,
3860 TRUE
/* fHasPointers */);
3866 /***********************************************************************
3867 * NdrComplexStructFree [RPCRT4.@]
3869 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3870 unsigned char *pMemory
,
3871 PFORMAT_STRING pFormat
)
3873 PFORMAT_STRING conf_array
= NULL
;
3874 PFORMAT_STRING pointer_desc
= NULL
;
3875 unsigned char *OldMemory
= pStubMsg
->Memory
;
3877 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3880 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3882 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3885 pStubMsg
->Memory
= pMemory
;
3887 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3890 array_free(conf_array
[0], pStubMsg
, pMemory
, conf_array
,
3891 TRUE
/* fHasPointers */);
3893 pStubMsg
->Memory
= OldMemory
;
3896 /***********************************************************************
3897 * NdrConformantArrayMarshall [RPCRT4.@]
3899 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3900 unsigned char *pMemory
,
3901 PFORMAT_STRING pFormat
)
3903 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3904 if (pFormat
[0] != RPC_FC_CARRAY
)
3906 ERR("invalid format = 0x%x\n", pFormat
[0]);
3907 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3910 array_compute_and_write_conformance(RPC_FC_CARRAY
, pStubMsg
, pMemory
,
3912 array_write_variance_and_marshall(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3913 TRUE
/* fHasPointers */);
3918 /***********************************************************************
3919 * NdrConformantArrayUnmarshall [RPCRT4.@]
3921 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3922 unsigned char **ppMemory
,
3923 PFORMAT_STRING pFormat
,
3924 unsigned char fMustAlloc
)
3926 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3927 if (pFormat
[0] != RPC_FC_CARRAY
)
3929 ERR("invalid format = 0x%x\n", pFormat
[0]);
3930 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3933 array_read_conformance(RPC_FC_CARRAY
, pStubMsg
, pFormat
);
3934 array_read_variance_and_unmarshall(RPC_FC_CARRAY
, pStubMsg
, ppMemory
, pFormat
,
3936 TRUE
/* fUseBufferMemoryServer */,
3937 TRUE
/* fUnmarshall */);
3942 /***********************************************************************
3943 * NdrConformantArrayBufferSize [RPCRT4.@]
3945 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3946 unsigned char *pMemory
,
3947 PFORMAT_STRING pFormat
)
3949 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3950 if (pFormat
[0] != RPC_FC_CARRAY
)
3952 ERR("invalid format = 0x%x\n", pFormat
[0]);
3953 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3956 array_compute_and_size_conformance(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
);
3957 array_buffer_size(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3958 TRUE
/* fHasPointers */);
3961 /***********************************************************************
3962 * NdrConformantArrayMemorySize [RPCRT4.@]
3964 ULONG WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3965 PFORMAT_STRING pFormat
)
3967 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3968 if (pFormat
[0] != RPC_FC_CARRAY
)
3970 ERR("invalid format = 0x%x\n", pFormat
[0]);
3971 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3974 array_read_conformance(RPC_FC_CARRAY
, pStubMsg
, pFormat
);
3975 array_memory_size(RPC_FC_CARRAY
, pStubMsg
, pFormat
, TRUE
/* fHasPointers */);
3977 return pStubMsg
->MemorySize
;
3980 /***********************************************************************
3981 * NdrConformantArrayFree [RPCRT4.@]
3983 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3984 unsigned char *pMemory
,
3985 PFORMAT_STRING pFormat
)
3987 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3988 if (pFormat
[0] != RPC_FC_CARRAY
)
3990 ERR("invalid format = 0x%x\n", pFormat
[0]);
3991 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3994 array_free(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3995 TRUE
/* fHasPointers */);
3999 /***********************************************************************
4000 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
4002 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
4003 unsigned char* pMemory
,
4004 PFORMAT_STRING pFormat
)
4006 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4008 if (pFormat
[0] != RPC_FC_CVARRAY
)
4010 ERR("invalid format type %x\n", pFormat
[0]);
4011 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4015 array_compute_and_write_conformance(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
4017 array_write_variance_and_marshall(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
4018 pFormat
, TRUE
/* fHasPointers */);
4024 /***********************************************************************
4025 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
4027 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
4028 unsigned char** ppMemory
,
4029 PFORMAT_STRING pFormat
,
4030 unsigned char fMustAlloc
)
4032 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4034 if (pFormat
[0] != RPC_FC_CVARRAY
)
4036 ERR("invalid format type %x\n", pFormat
[0]);
4037 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4041 array_read_conformance(RPC_FC_CVARRAY
, pStubMsg
, pFormat
);
4042 array_read_variance_and_unmarshall(RPC_FC_CVARRAY
, pStubMsg
, ppMemory
,
4043 pFormat
, fMustAlloc
,
4044 TRUE
/* fUseBufferMemoryServer */,
4045 TRUE
/* fUnmarshall */);
4051 /***********************************************************************
4052 * NdrConformantVaryingArrayFree [RPCRT4.@]
4054 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
4055 unsigned char* pMemory
,
4056 PFORMAT_STRING pFormat
)
4058 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4060 if (pFormat
[0] != RPC_FC_CVARRAY
)
4062 ERR("invalid format type %x\n", pFormat
[0]);
4063 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4067 array_free(RPC_FC_CVARRAY
, pStubMsg
, pMemory
, pFormat
,
4068 TRUE
/* fHasPointers */);
4072 /***********************************************************************
4073 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
4075 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
4076 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
4078 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4080 if (pFormat
[0] != RPC_FC_CVARRAY
)
4082 ERR("invalid format type %x\n", pFormat
[0]);
4083 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4087 array_compute_and_size_conformance(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
4089 array_buffer_size(RPC_FC_CVARRAY
, pStubMsg
, pMemory
, pFormat
,
4090 TRUE
/* fHasPointers */);
4094 /***********************************************************************
4095 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
4097 ULONG WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
4098 PFORMAT_STRING pFormat
)
4100 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4102 if (pFormat
[0] != RPC_FC_CVARRAY
)
4104 ERR("invalid format type %x\n", pFormat
[0]);
4105 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4106 return pStubMsg
->MemorySize
;
4109 array_read_conformance(RPC_FC_CVARRAY
, pStubMsg
, pFormat
);
4110 array_memory_size(RPC_FC_CVARRAY
, pStubMsg
, pFormat
,
4111 TRUE
/* fHasPointers */);
4113 return pStubMsg
->MemorySize
;
4117 /***********************************************************************
4118 * NdrComplexArrayMarshall [RPCRT4.@]
4120 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4121 unsigned char *pMemory
,
4122 PFORMAT_STRING pFormat
)
4124 int pointer_buffer_mark_set
= 0;
4126 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4128 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4130 ERR("invalid format type %x\n", pFormat
[0]);
4131 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4135 if (!pStubMsg
->PointerBufferMark
)
4137 /* save buffer fields that may be changed by buffer sizer functions
4138 * and that may be needed later on */
4139 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
4140 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
4141 ULONG_PTR saved_max_count
= pStubMsg
->MaxCount
;
4142 ULONG saved_offset
= pStubMsg
->Offset
;
4143 ULONG saved_actual_count
= pStubMsg
->ActualCount
;
4145 /* get the buffer pointer after complex array data, but before
4147 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
;
4148 pStubMsg
->IgnoreEmbeddedPointers
= 1;
4149 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
4150 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
4152 /* save it for use by embedded pointer code later */
4153 pStubMsg
->PointerBufferMark
= (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
;
4154 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
));
4155 pointer_buffer_mark_set
= 1;
4157 /* restore fields */
4158 pStubMsg
->ActualCount
= saved_actual_count
;
4159 pStubMsg
->Offset
= saved_offset
;
4160 pStubMsg
->MaxCount
= saved_max_count
;
4161 pStubMsg
->BufferLength
= saved_buffer_length
;
4164 array_compute_and_write_conformance(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pMemory
, pFormat
);
4165 array_write_variance_and_marshall(RPC_FC_BOGUS_ARRAY
, pStubMsg
,
4166 pMemory
, pFormat
, TRUE
/* fHasPointers */);
4168 STD_OVERFLOW_CHECK(pStubMsg
);
4170 if (pointer_buffer_mark_set
)
4172 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4173 pStubMsg
->PointerBufferMark
= NULL
;
4179 /***********************************************************************
4180 * NdrComplexArrayUnmarshall [RPCRT4.@]
4182 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4183 unsigned char **ppMemory
,
4184 PFORMAT_STRING pFormat
,
4185 unsigned char fMustAlloc
)
4187 unsigned char *saved_buffer
;
4188 int pointer_buffer_mark_set
= 0;
4189 int saved_ignore_embedded
;
4191 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4193 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4195 ERR("invalid format type %x\n", pFormat
[0]);
4196 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4200 saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
4201 /* save buffer pointer */
4202 saved_buffer
= pStubMsg
->Buffer
;
4203 /* get the buffer pointer after complex array data, but before
4205 pStubMsg
->IgnoreEmbeddedPointers
= 1;
4206 pStubMsg
->MemorySize
= 0;
4207 NdrComplexArrayMemorySize(pStubMsg
, pFormat
);
4208 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
4210 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->Buffer
- saved_buffer
));
4211 if (!pStubMsg
->PointerBufferMark
)
4213 /* save it for use by embedded pointer code later */
4214 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4215 pointer_buffer_mark_set
= 1;
4217 /* restore the original buffer */
4218 pStubMsg
->Buffer
= saved_buffer
;
4220 array_read_conformance(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pFormat
);
4221 array_read_variance_and_unmarshall(RPC_FC_BOGUS_ARRAY
, pStubMsg
, ppMemory
, pFormat
, fMustAlloc
,
4222 TRUE
/* fUseBufferMemoryServer */, TRUE
/* fUnmarshall */);
4224 if (pointer_buffer_mark_set
)
4226 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4227 pStubMsg
->PointerBufferMark
= NULL
;
4233 /***********************************************************************
4234 * NdrComplexArrayBufferSize [RPCRT4.@]
4236 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4237 unsigned char *pMemory
,
4238 PFORMAT_STRING pFormat
)
4240 int pointer_length_set
= 0;
4242 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4244 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4246 ERR("invalid format type %x\n", pFormat
[0]);
4247 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4251 if (!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
4253 /* save buffer fields that may be changed by buffer sizer functions
4254 * and that may be needed later on */
4255 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
4256 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
4257 ULONG_PTR saved_max_count
= pStubMsg
->MaxCount
;
4258 ULONG saved_offset
= pStubMsg
->Offset
;
4259 ULONG saved_actual_count
= pStubMsg
->ActualCount
;
4261 /* get the buffer pointer after complex array data, but before
4263 pStubMsg
->IgnoreEmbeddedPointers
= 1;
4264 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
4265 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
4267 /* save it for use by embedded pointer code later */
4268 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4269 pointer_length_set
= 1;
4271 /* restore fields */
4272 pStubMsg
->ActualCount
= saved_actual_count
;
4273 pStubMsg
->Offset
= saved_offset
;
4274 pStubMsg
->MaxCount
= saved_max_count
;
4275 pStubMsg
->BufferLength
= saved_buffer_length
;
4278 array_compute_and_size_conformance(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pMemory
, pFormat
);
4279 array_buffer_size(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pMemory
, pFormat
, TRUE
/* fHasPointers */);
4281 if(pointer_length_set
)
4283 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4284 pStubMsg
->PointerLength
= 0;
4288 /***********************************************************************
4289 * NdrComplexArrayMemorySize [RPCRT4.@]
4291 ULONG WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4292 PFORMAT_STRING pFormat
)
4294 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
4296 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4298 ERR("invalid format type %x\n", pFormat
[0]);
4299 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4303 array_read_conformance(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pFormat
);
4304 array_memory_size(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pFormat
, TRUE
/* fHasPointers */);
4305 return pStubMsg
->MemorySize
;
4308 /***********************************************************************
4309 * NdrComplexArrayFree [RPCRT4.@]
4311 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4312 unsigned char *pMemory
,
4313 PFORMAT_STRING pFormat
)
4315 ULONG i
, count
, def
;
4317 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4319 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4321 ERR("invalid format type %x\n", pFormat
[0]);
4322 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4326 def
= *(const WORD
*)&pFormat
[2];
4329 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
4330 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
4332 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
4333 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
4335 count
= pStubMsg
->ActualCount
;
4336 for (i
= 0; i
< count
; i
++)
4337 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
4340 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg
,
4341 USER_MARSHAL_CB_TYPE cbtype
, PFORMAT_STRING pFormat
,
4342 USER_MARSHAL_CB
*umcb
)
4344 umcb
->Flags
= MAKELONG(pStubMsg
->dwDestContext
,
4345 pStubMsg
->RpcMsg
->DataRepresentation
);
4346 umcb
->pStubMsg
= pStubMsg
;
4347 umcb
->pReserve
= NULL
;
4348 umcb
->Signature
= USER_MARSHAL_CB_SIGNATURE
;
4349 umcb
->CBType
= cbtype
;
4350 umcb
->pFormat
= pFormat
;
4351 umcb
->pTypeFormat
= NULL
/* FIXME */;
4354 #define USER_MARSHAL_PTR_PREFIX \
4355 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4356 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4358 /***********************************************************************
4359 * NdrUserMarshalMarshall [RPCRT4.@]
4361 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4362 unsigned char *pMemory
,
4363 PFORMAT_STRING pFormat
)
4365 unsigned flags
= pFormat
[1];
4366 unsigned index
= *(const WORD
*)&pFormat
[2];
4367 unsigned char *saved_buffer
= NULL
;
4368 USER_MARSHAL_CB umcb
;
4370 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4371 TRACE("index=%d\n", index
);
4373 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_MARSHALL
, pFormat
, &umcb
);
4375 if (flags
& USER_MARSHAL_POINTER
)
4377 align_pointer_clear(&pStubMsg
->Buffer
, 4);
4378 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, USER_MARSHAL_PTR_PREFIX
);
4379 pStubMsg
->Buffer
+= 4;
4380 if (pStubMsg
->PointerBufferMark
)
4382 saved_buffer
= pStubMsg
->Buffer
;
4383 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4384 pStubMsg
->PointerBufferMark
= NULL
;
4386 align_pointer_clear(&pStubMsg
->Buffer
, 8);
4389 align_pointer_clear(&pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4392 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
4393 &umcb
.Flags
, pStubMsg
->Buffer
, pMemory
);
4397 STD_OVERFLOW_CHECK(pStubMsg
);
4398 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4399 pStubMsg
->Buffer
= saved_buffer
;
4402 STD_OVERFLOW_CHECK(pStubMsg
);
4407 /***********************************************************************
4408 * NdrUserMarshalUnmarshall [RPCRT4.@]
4410 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4411 unsigned char **ppMemory
,
4412 PFORMAT_STRING pFormat
,
4413 unsigned char fMustAlloc
)
4415 unsigned flags
= pFormat
[1];
4416 unsigned index
= *(const WORD
*)&pFormat
[2];
4417 DWORD memsize
= *(const WORD
*)&pFormat
[4];
4418 unsigned char *saved_buffer
= NULL
;
4419 USER_MARSHAL_CB umcb
;
4421 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4422 TRACE("index=%d\n", index
);
4424 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_UNMARSHALL
, pFormat
, &umcb
);
4426 if (flags
& USER_MARSHAL_POINTER
)
4428 align_pointer(&pStubMsg
->Buffer
, 4);
4429 /* skip pointer prefix */
4430 pStubMsg
->Buffer
+= 4;
4431 if (pStubMsg
->PointerBufferMark
)
4433 saved_buffer
= pStubMsg
->Buffer
;
4434 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4435 pStubMsg
->PointerBufferMark
= NULL
;
4437 align_pointer(&pStubMsg
->Buffer
, 8);
4440 align_pointer(&pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4442 if (!fMustAlloc
&& !*ppMemory
)
4446 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
4447 memset(*ppMemory
, 0, memsize
);
4451 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
4452 &umcb
.Flags
, pStubMsg
->Buffer
, *ppMemory
);
4456 STD_OVERFLOW_CHECK(pStubMsg
);
4457 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4458 pStubMsg
->Buffer
= saved_buffer
;
4464 /***********************************************************************
4465 * NdrUserMarshalBufferSize [RPCRT4.@]
4467 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4468 unsigned char *pMemory
,
4469 PFORMAT_STRING pFormat
)
4471 unsigned flags
= pFormat
[1];
4472 unsigned index
= *(const WORD
*)&pFormat
[2];
4473 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
4474 USER_MARSHAL_CB umcb
;
4475 ULONG saved_buffer_length
= 0;
4477 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4478 TRACE("index=%d\n", index
);
4480 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_BUFFER_SIZE
, pFormat
, &umcb
);
4482 if (flags
& USER_MARSHAL_POINTER
)
4484 align_length(&pStubMsg
->BufferLength
, 4);
4485 /* skip pointer prefix */
4486 safe_buffer_length_increment(pStubMsg
, 4);
4487 if (pStubMsg
->IgnoreEmbeddedPointers
)
4489 if (pStubMsg
->PointerLength
)
4491 saved_buffer_length
= pStubMsg
->BufferLength
;
4492 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4493 pStubMsg
->PointerLength
= 0;
4495 align_length(&pStubMsg
->BufferLength
, 8);
4498 align_length(&pStubMsg
->BufferLength
, (flags
& 0xf) + 1);
4501 TRACE("size=%d\n", bufsize
);
4502 safe_buffer_length_increment(pStubMsg
, bufsize
);
4505 pStubMsg
->BufferLength
=
4506 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
4507 &umcb
.Flags
, pStubMsg
->BufferLength
, pMemory
);
4509 if (saved_buffer_length
)
4511 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4512 pStubMsg
->BufferLength
= saved_buffer_length
;
4517 /***********************************************************************
4518 * NdrUserMarshalMemorySize [RPCRT4.@]
4520 ULONG WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4521 PFORMAT_STRING pFormat
)
4523 unsigned flags
= pFormat
[1];
4524 unsigned index
= *(const WORD
*)&pFormat
[2];
4525 DWORD memsize
= *(const WORD
*)&pFormat
[4];
4526 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
4528 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
4529 TRACE("index=%d\n", index
);
4531 pStubMsg
->MemorySize
+= memsize
;
4533 if (flags
& USER_MARSHAL_POINTER
)
4535 align_pointer(&pStubMsg
->Buffer
, 4);
4536 /* skip pointer prefix */
4537 pStubMsg
->Buffer
+= 4;
4538 if (pStubMsg
->IgnoreEmbeddedPointers
)
4539 return pStubMsg
->MemorySize
;
4540 align_pointer(&pStubMsg
->Buffer
, 8);
4543 align_pointer(&pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4546 FIXME("not implemented for varying buffer size\n");
4548 pStubMsg
->Buffer
+= bufsize
;
4550 return pStubMsg
->MemorySize
;
4553 /***********************************************************************
4554 * NdrUserMarshalFree [RPCRT4.@]
4556 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
4557 unsigned char *pMemory
,
4558 PFORMAT_STRING pFormat
)
4560 /* unsigned flags = pFormat[1]; */
4561 unsigned index
= *(const WORD
*)&pFormat
[2];
4562 USER_MARSHAL_CB umcb
;
4564 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4565 TRACE("index=%d\n", index
);
4567 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_FREE
, pFormat
, &umcb
);
4569 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
4570 &umcb
.Flags
, pMemory
);
4573 /***********************************************************************
4574 * NdrGetUserMarshalInfo [RPCRT4.@]
4576 RPC_STATUS RPC_ENTRY
NdrGetUserMarshalInfo(ULONG
*flags
, ULONG level
, NDR_USER_MARSHAL_INFO
*umi
)
4578 USER_MARSHAL_CB
*umcb
= CONTAINING_RECORD(flags
, USER_MARSHAL_CB
, Flags
);
4580 TRACE("(%p,%u,%p)\n", flags
, level
, umi
);
4583 return RPC_S_INVALID_ARG
;
4585 memset(&umi
->u1
.Level1
, 0, sizeof(umi
->u1
.Level1
));
4586 umi
->InformationLevel
= level
;
4588 if (umcb
->Signature
!= USER_MARSHAL_CB_SIGNATURE
)
4589 return RPC_S_INVALID_ARG
;
4591 umi
->u1
.Level1
.pfnAllocate
= umcb
->pStubMsg
->pfnAllocate
;
4592 umi
->u1
.Level1
.pfnFree
= umcb
->pStubMsg
->pfnFree
;
4593 umi
->u1
.Level1
.pRpcChannelBuffer
= umcb
->pStubMsg
->pRpcChannelBuffer
;
4595 switch (umcb
->CBType
)
4597 case USER_MARSHAL_CB_MARSHALL
:
4598 case USER_MARSHAL_CB_UNMARSHALL
:
4600 RPC_MESSAGE
*msg
= umcb
->pStubMsg
->RpcMsg
;
4601 unsigned char *buffer_start
= msg
->Buffer
;
4602 unsigned char *buffer_end
=
4603 (unsigned char *)msg
->Buffer
+ msg
->BufferLength
;
4605 if (umcb
->pStubMsg
->Buffer
< buffer_start
||
4606 umcb
->pStubMsg
->Buffer
> buffer_end
)
4607 return ERROR_INVALID_USER_BUFFER
;
4609 umi
->u1
.Level1
.Buffer
= umcb
->pStubMsg
->Buffer
;
4610 umi
->u1
.Level1
.BufferSize
= buffer_end
- umcb
->pStubMsg
->Buffer
;
4613 case USER_MARSHAL_CB_BUFFER_SIZE
:
4614 case USER_MARSHAL_CB_FREE
:
4617 WARN("unrecognised CBType %d\n", umcb
->CBType
);
4623 /***********************************************************************
4624 * NdrClearOutParameters [RPCRT4.@]
4626 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
4627 PFORMAT_STRING pFormat
,
4630 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
4633 /***********************************************************************
4634 * NdrConvert [RPCRT4.@]
4636 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
4638 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
4639 /* FIXME: since this stub doesn't do any converting, the proper behavior
4640 is to raise an exception */
4643 /***********************************************************************
4644 * NdrConvert2 [RPCRT4.@]
4646 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, LONG NumberParams
)
4648 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4649 pStubMsg
, pFormat
, NumberParams
);
4650 /* FIXME: since this stub doesn't do any converting, the proper behavior
4651 is to raise an exception */
4654 #include "pshpack1.h"
4655 typedef struct _NDR_CSTRUCT_FORMAT
4658 unsigned char alignment
;
4659 unsigned short memory_size
;
4660 short offset_to_array_description
;
4661 } NDR_CSTRUCT_FORMAT
, NDR_CVSTRUCT_FORMAT
;
4662 #include "poppack.h"
4664 /***********************************************************************
4665 * NdrConformantStructMarshall [RPCRT4.@]
4667 unsigned char * WINAPI
NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4668 unsigned char *pMemory
,
4669 PFORMAT_STRING pFormat
)
4671 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4672 PFORMAT_STRING pCArrayFormat
;
4673 ULONG esize
, bufsize
;
4675 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4677 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4678 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4680 ERR("invalid format type %x\n", pCStructFormat
->type
);
4681 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4685 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4686 pCStructFormat
->offset_to_array_description
;
4687 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4689 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4690 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4693 esize
= *(const WORD
*)(pCArrayFormat
+2);
4695 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4696 pCArrayFormat
+ 4, 0);
4698 WriteConformance(pStubMsg
);
4700 align_pointer_clear(&pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4702 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4704 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4705 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4707 ERR("integer overflow of memory_size %u with bufsize %u\n",
4708 pCStructFormat
->memory_size
, bufsize
);
4709 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4711 /* copy constant sized part of struct */
4712 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4713 safe_copy_to_buffer(pStubMsg
, pMemory
, pCStructFormat
->memory_size
+ bufsize
);
4715 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4716 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4721 /***********************************************************************
4722 * NdrConformantStructUnmarshall [RPCRT4.@]
4724 unsigned char * WINAPI
NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4725 unsigned char **ppMemory
,
4726 PFORMAT_STRING pFormat
,
4727 unsigned char fMustAlloc
)
4729 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4730 PFORMAT_STRING pCArrayFormat
;
4731 ULONG esize
, bufsize
;
4732 unsigned char *saved_buffer
;
4734 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4736 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4737 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4739 ERR("invalid format type %x\n", pCStructFormat
->type
);
4740 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4743 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4744 pCStructFormat
->offset_to_array_description
;
4745 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4747 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4748 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4751 esize
= *(const WORD
*)(pCArrayFormat
+2);
4753 pCArrayFormat
= ReadConformance(pStubMsg
, pCArrayFormat
+ 4);
4755 align_pointer(&pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4757 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4759 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4760 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4762 ERR("integer overflow of memory_size %u with bufsize %u\n",
4763 pCStructFormat
->memory_size
, bufsize
);
4764 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4769 SIZE_T size
= pCStructFormat
->memory_size
+ bufsize
;
4770 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4774 if (!pStubMsg
->IsClient
&& !*ppMemory
)
4775 /* for servers, we just point straight into the RPC buffer */
4776 *ppMemory
= pStubMsg
->Buffer
;
4779 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4780 safe_buffer_increment(pStubMsg
, pCStructFormat
->memory_size
+ bufsize
);
4781 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4782 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4784 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
4785 if (*ppMemory
!= saved_buffer
)
4786 memcpy(*ppMemory
, saved_buffer
, pCStructFormat
->memory_size
+ bufsize
);
4791 /***********************************************************************
4792 * NdrConformantStructBufferSize [RPCRT4.@]
4794 void WINAPI
NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4795 unsigned char *pMemory
,
4796 PFORMAT_STRING pFormat
)
4798 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4799 PFORMAT_STRING pCArrayFormat
;
4802 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4804 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4805 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4807 ERR("invalid format type %x\n", pCStructFormat
->type
);
4808 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4811 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4812 pCStructFormat
->offset_to_array_description
;
4813 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4815 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4816 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4819 esize
= *(const WORD
*)(pCArrayFormat
+2);
4821 pCArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
, pCArrayFormat
+4, 0);
4822 SizeConformance(pStubMsg
);
4824 align_length(&pStubMsg
->BufferLength
, pCStructFormat
->alignment
+ 1);
4826 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4828 safe_buffer_length_increment(pStubMsg
, pCStructFormat
->memory_size
);
4829 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
4831 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4832 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4835 /***********************************************************************
4836 * NdrConformantStructMemorySize [RPCRT4.@]
4838 ULONG WINAPI
NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4839 PFORMAT_STRING pFormat
)
4845 /***********************************************************************
4846 * NdrConformantStructFree [RPCRT4.@]
4848 void WINAPI
NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
4849 unsigned char *pMemory
,
4850 PFORMAT_STRING pFormat
)
4852 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4853 PFORMAT_STRING pCArrayFormat
;
4855 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4857 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4858 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4860 ERR("invalid format type %x\n", pCStructFormat
->type
);
4861 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4865 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4866 pCStructFormat
->offset_to_array_description
;
4867 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4869 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4870 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4874 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4875 pCArrayFormat
+ 4, 0);
4877 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4879 /* copy constant sized part of struct */
4880 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4882 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4883 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4886 /***********************************************************************
4887 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4889 unsigned char * WINAPI
NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4890 unsigned char *pMemory
,
4891 PFORMAT_STRING pFormat
)
4893 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4894 PFORMAT_STRING pCVArrayFormat
;
4896 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4898 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4899 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4901 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4902 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4906 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4907 pCVStructFormat
->offset_to_array_description
;
4909 array_compute_and_write_conformance(*pCVArrayFormat
, pStubMsg
,
4910 pMemory
+ pCVStructFormat
->memory_size
,
4913 align_pointer_clear(&pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4915 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4917 /* write constant sized part */
4918 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4919 safe_copy_to_buffer(pStubMsg
, pMemory
, pCVStructFormat
->memory_size
);
4921 array_write_variance_and_marshall(*pCVArrayFormat
, pStubMsg
,
4922 pMemory
+ pCVStructFormat
->memory_size
,
4923 pCVArrayFormat
, FALSE
/* fHasPointers */);
4925 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4930 /***********************************************************************
4931 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4933 unsigned char * WINAPI
NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4934 unsigned char **ppMemory
,
4935 PFORMAT_STRING pFormat
,
4936 unsigned char fMustAlloc
)
4938 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4939 PFORMAT_STRING pCVArrayFormat
;
4940 ULONG memsize
, bufsize
;
4941 unsigned char *saved_buffer
, *saved_array_buffer
;
4943 unsigned char *array_memory
;
4945 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4947 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4948 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4950 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4951 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4955 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4956 pCVStructFormat
->offset_to_array_description
;
4958 memsize
= array_read_conformance(*pCVArrayFormat
, pStubMsg
,
4961 align_pointer(&pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4963 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4965 /* work out how much memory to allocate if we need to do so */
4966 if (!fMustAlloc
&& !*ppMemory
)
4970 SIZE_T size
= pCVStructFormat
->memory_size
+ memsize
;
4971 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4974 /* mark the start of the constant data */
4975 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4976 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4978 array_memory
= *ppMemory
+ pCVStructFormat
->memory_size
;
4979 bufsize
= array_read_variance_and_unmarshall(*pCVArrayFormat
, pStubMsg
,
4980 &array_memory
, pCVArrayFormat
,
4981 FALSE
/* fMustAlloc */,
4982 FALSE
/* fUseServerBufferMemory */,
4983 FALSE
/* fUnmarshall */);
4985 /* save offset in case unmarshalling pointers changes it */
4986 offset
= pStubMsg
->Offset
;
4988 /* mark the start of the array data */
4989 saved_array_buffer
= pStubMsg
->Buffer
;
4990 safe_buffer_increment(pStubMsg
, bufsize
);
4992 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4994 /* copy the constant data */
4995 memcpy(*ppMemory
, saved_buffer
, pCVStructFormat
->memory_size
);
4996 /* copy the array data */
4997 TRACE("copying %p to %p\n", saved_array_buffer
, *ppMemory
+ pCVStructFormat
->memory_size
);
4998 memcpy(*ppMemory
+ pCVStructFormat
->memory_size
+ offset
,
4999 saved_array_buffer
, bufsize
);
5001 if (*pCVArrayFormat
== RPC_FC_C_CSTRING
)
5002 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory
+ pCVStructFormat
->memory_size
)));
5003 else if (*pCVArrayFormat
== RPC_FC_C_WSTRING
)
5004 TRACE("string=%s\n", debugstr_w((WCHAR
*)(*ppMemory
+ pCVStructFormat
->memory_size
)));
5009 /***********************************************************************
5010 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
5012 void WINAPI
NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5013 unsigned char *pMemory
,
5014 PFORMAT_STRING pFormat
)
5016 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
5017 PFORMAT_STRING pCVArrayFormat
;
5019 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5021 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
5022 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
5024 ERR("invalid format type %x\n", pCVStructFormat
->type
);
5025 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5029 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
5030 pCVStructFormat
->offset_to_array_description
;
5031 array_compute_and_size_conformance(*pCVArrayFormat
, pStubMsg
,
5032 pMemory
+ pCVStructFormat
->memory_size
,
5035 align_length(&pStubMsg
->BufferLength
, pCVStructFormat
->alignment
+ 1);
5037 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
5039 safe_buffer_length_increment(pStubMsg
, pCVStructFormat
->memory_size
);
5041 array_buffer_size(*pCVArrayFormat
, pStubMsg
,
5042 pMemory
+ pCVStructFormat
->memory_size
, pCVArrayFormat
,
5043 FALSE
/* fHasPointers */);
5045 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5048 /***********************************************************************
5049 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
5051 ULONG WINAPI
NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5052 PFORMAT_STRING pFormat
)
5054 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
5055 PFORMAT_STRING pCVArrayFormat
;
5057 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5059 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
5060 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
5062 ERR("invalid format type %x\n", pCVStructFormat
->type
);
5063 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5067 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
5068 pCVStructFormat
->offset_to_array_description
;
5069 array_read_conformance(*pCVArrayFormat
, pStubMsg
, pCVArrayFormat
);
5071 align_pointer(&pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
5073 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
5075 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
5076 array_memory_size(*pCVArrayFormat
, pStubMsg
, pCVArrayFormat
,
5077 FALSE
/* fHasPointers */);
5079 pStubMsg
->MemorySize
+= pCVStructFormat
->memory_size
;
5081 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5083 return pStubMsg
->MemorySize
;
5086 /***********************************************************************
5087 * NdrConformantVaryingStructFree [RPCRT4.@]
5089 void WINAPI
NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
5090 unsigned char *pMemory
,
5091 PFORMAT_STRING pFormat
)
5093 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
5094 PFORMAT_STRING pCVArrayFormat
;
5096 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5098 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
5099 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
5101 ERR("invalid format type %x\n", pCVStructFormat
->type
);
5102 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5106 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
5107 pCVStructFormat
->offset_to_array_description
;
5108 array_free(*pCVArrayFormat
, pStubMsg
,
5109 pMemory
+ pCVStructFormat
->memory_size
, pCVArrayFormat
,
5110 FALSE
/* fHasPointers */);
5112 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
5114 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5117 #include "pshpack1.h"
5121 unsigned char alignment
;
5122 unsigned short total_size
;
5123 } NDR_SMFARRAY_FORMAT
;
5128 unsigned char alignment
;
5130 } NDR_LGFARRAY_FORMAT
;
5131 #include "poppack.h"
5133 /***********************************************************************
5134 * NdrFixedArrayMarshall [RPCRT4.@]
5136 unsigned char * WINAPI
NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5137 unsigned char *pMemory
,
5138 PFORMAT_STRING pFormat
)
5140 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5143 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5145 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5146 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5148 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5149 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5153 align_pointer_clear(&pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
5155 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5157 total_size
= pSmFArrayFormat
->total_size
;
5158 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5162 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5163 total_size
= pLgFArrayFormat
->total_size
;
5164 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5167 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5168 safe_copy_to_buffer(pStubMsg
, pMemory
, total_size
);
5170 pFormat
= EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
5175 /***********************************************************************
5176 * NdrFixedArrayUnmarshall [RPCRT4.@]
5178 unsigned char * WINAPI
NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5179 unsigned char **ppMemory
,
5180 PFORMAT_STRING pFormat
,
5181 unsigned char fMustAlloc
)
5183 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5185 unsigned char *saved_buffer
;
5187 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5189 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5190 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5192 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5193 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5197 align_pointer(&pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
5199 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5201 total_size
= pSmFArrayFormat
->total_size
;
5202 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5206 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5207 total_size
= pLgFArrayFormat
->total_size
;
5208 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5212 *ppMemory
= NdrAllocate(pStubMsg
, total_size
);
5215 if (!pStubMsg
->IsClient
&& !*ppMemory
)
5216 /* for servers, we just point straight into the RPC buffer */
5217 *ppMemory
= pStubMsg
->Buffer
;
5220 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5221 safe_buffer_increment(pStubMsg
, total_size
);
5222 pFormat
= EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
5224 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
5225 if (*ppMemory
!= saved_buffer
)
5226 memcpy(*ppMemory
, saved_buffer
, total_size
);
5231 /***********************************************************************
5232 * NdrFixedArrayBufferSize [RPCRT4.@]
5234 void WINAPI
NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5235 unsigned char *pMemory
,
5236 PFORMAT_STRING pFormat
)
5238 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5241 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5243 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5244 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5246 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5247 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5251 align_length(&pStubMsg
->BufferLength
, pSmFArrayFormat
->alignment
+ 1);
5253 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5255 total_size
= pSmFArrayFormat
->total_size
;
5256 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5260 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5261 total_size
= pLgFArrayFormat
->total_size
;
5262 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5264 safe_buffer_length_increment(pStubMsg
, total_size
);
5266 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5269 /***********************************************************************
5270 * NdrFixedArrayMemorySize [RPCRT4.@]
5272 ULONG WINAPI
NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5273 PFORMAT_STRING pFormat
)
5275 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5278 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5280 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5281 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5283 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5284 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5288 align_pointer(&pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
5290 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5292 total_size
= pSmFArrayFormat
->total_size
;
5293 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5297 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5298 total_size
= pLgFArrayFormat
->total_size
;
5299 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5301 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5302 safe_buffer_increment(pStubMsg
, total_size
);
5303 pStubMsg
->MemorySize
+= total_size
;
5305 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5310 /***********************************************************************
5311 * NdrFixedArrayFree [RPCRT4.@]
5313 void WINAPI
NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
5314 unsigned char *pMemory
,
5315 PFORMAT_STRING pFormat
)
5317 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5319 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5321 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5322 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5324 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5325 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5329 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5330 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5333 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5334 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5337 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5340 /***********************************************************************
5341 * NdrVaryingArrayMarshall [RPCRT4.@]
5343 unsigned char * WINAPI
NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5344 unsigned char *pMemory
,
5345 PFORMAT_STRING pFormat
)
5347 unsigned char alignment
;
5348 DWORD elements
, esize
;
5351 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5353 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5354 (pFormat
[0] != RPC_FC_LGVARRAY
))
5356 ERR("invalid format type %x\n", pFormat
[0]);
5357 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5361 alignment
= pFormat
[1] + 1;
5363 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5366 pFormat
+= sizeof(WORD
);
5367 elements
= *(const WORD
*)pFormat
;
5368 pFormat
+= sizeof(WORD
);
5373 pFormat
+= sizeof(DWORD
);
5374 elements
= *(const DWORD
*)pFormat
;
5375 pFormat
+= sizeof(DWORD
);
5378 esize
= *(const WORD
*)pFormat
;
5379 pFormat
+= sizeof(WORD
);
5381 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5382 if ((pStubMsg
->ActualCount
> elements
) ||
5383 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5385 RpcRaiseException(RPC_S_INVALID_BOUND
);
5389 WriteVariance(pStubMsg
);
5391 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
5393 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
5394 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5395 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
5397 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
5402 /***********************************************************************
5403 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5405 unsigned char * WINAPI
NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5406 unsigned char **ppMemory
,
5407 PFORMAT_STRING pFormat
,
5408 unsigned char fMustAlloc
)
5410 unsigned char alignment
;
5411 DWORD size
, elements
, esize
;
5413 unsigned char *saved_buffer
;
5416 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5418 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5419 (pFormat
[0] != RPC_FC_LGVARRAY
))
5421 ERR("invalid format type %x\n", pFormat
[0]);
5422 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5426 alignment
= pFormat
[1] + 1;
5428 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5431 size
= *(const WORD
*)pFormat
;
5432 pFormat
+= sizeof(WORD
);
5433 elements
= *(const WORD
*)pFormat
;
5434 pFormat
+= sizeof(WORD
);
5439 size
= *(const DWORD
*)pFormat
;
5440 pFormat
+= sizeof(DWORD
);
5441 elements
= *(const DWORD
*)pFormat
;
5442 pFormat
+= sizeof(DWORD
);
5445 esize
= *(const WORD
*)pFormat
;
5446 pFormat
+= sizeof(WORD
);
5448 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
5450 align_pointer(&pStubMsg
->Buffer
, alignment
);
5452 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
5453 offset
= pStubMsg
->Offset
;
5455 if (!fMustAlloc
&& !*ppMemory
)
5458 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5459 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5460 safe_buffer_increment(pStubMsg
, bufsize
);
5462 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
5464 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
5469 /***********************************************************************
5470 * NdrVaryingArrayBufferSize [RPCRT4.@]
5472 void WINAPI
NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5473 unsigned char *pMemory
,
5474 PFORMAT_STRING pFormat
)
5476 unsigned char alignment
;
5477 DWORD elements
, esize
;
5479 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5481 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5482 (pFormat
[0] != RPC_FC_LGVARRAY
))
5484 ERR("invalid format type %x\n", pFormat
[0]);
5485 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5489 alignment
= pFormat
[1] + 1;
5491 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5494 pFormat
+= sizeof(WORD
);
5495 elements
= *(const WORD
*)pFormat
;
5496 pFormat
+= sizeof(WORD
);
5501 pFormat
+= sizeof(DWORD
);
5502 elements
= *(const DWORD
*)pFormat
;
5503 pFormat
+= sizeof(DWORD
);
5506 esize
= *(const WORD
*)pFormat
;
5507 pFormat
+= sizeof(WORD
);
5509 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5510 if ((pStubMsg
->ActualCount
> elements
) ||
5511 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5513 RpcRaiseException(RPC_S_INVALID_BOUND
);
5517 SizeVariance(pStubMsg
);
5519 align_length(&pStubMsg
->BufferLength
, alignment
);
5521 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
5523 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5526 /***********************************************************************
5527 * NdrVaryingArrayMemorySize [RPCRT4.@]
5529 ULONG WINAPI
NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5530 PFORMAT_STRING pFormat
)
5532 unsigned char alignment
;
5533 DWORD size
, elements
, esize
;
5535 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5537 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5538 (pFormat
[0] != RPC_FC_LGVARRAY
))
5540 ERR("invalid format type %x\n", pFormat
[0]);
5541 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5545 alignment
= pFormat
[1] + 1;
5547 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5550 size
= *(const WORD
*)pFormat
;
5551 pFormat
+= sizeof(WORD
);
5552 elements
= *(const WORD
*)pFormat
;
5553 pFormat
+= sizeof(WORD
);
5558 size
= *(const DWORD
*)pFormat
;
5559 pFormat
+= sizeof(DWORD
);
5560 elements
= *(const DWORD
*)pFormat
;
5561 pFormat
+= sizeof(DWORD
);
5564 esize
= *(const WORD
*)pFormat
;
5565 pFormat
+= sizeof(WORD
);
5567 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
5569 align_pointer(&pStubMsg
->Buffer
, alignment
);
5571 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
5572 pStubMsg
->MemorySize
+= size
;
5574 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5576 return pStubMsg
->MemorySize
;
5579 /***********************************************************************
5580 * NdrVaryingArrayFree [RPCRT4.@]
5582 void WINAPI
NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
5583 unsigned char *pMemory
,
5584 PFORMAT_STRING pFormat
)
5588 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5590 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5591 (pFormat
[0] != RPC_FC_LGVARRAY
))
5593 ERR("invalid format type %x\n", pFormat
[0]);
5594 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5598 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5601 pFormat
+= sizeof(WORD
);
5602 elements
= *(const WORD
*)pFormat
;
5603 pFormat
+= sizeof(WORD
);
5608 pFormat
+= sizeof(DWORD
);
5609 elements
= *(const DWORD
*)pFormat
;
5610 pFormat
+= sizeof(DWORD
);
5613 pFormat
+= sizeof(WORD
);
5615 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5616 if ((pStubMsg
->ActualCount
> elements
) ||
5617 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5619 RpcRaiseException(RPC_S_INVALID_BOUND
);
5623 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5626 static ULONG
get_discriminant(unsigned char fc
, const unsigned char *pMemory
)
5639 return *(const USHORT
*)pMemory
;
5643 return *(const ULONG
*)pMemory
;
5644 case RPC_FC_INT3264
:
5645 case RPC_FC_UINT3264
:
5646 return *(const ULONG_PTR
*)pMemory
;
5648 FIXME("Unhandled base type: 0x%02x\n", fc
);
5653 static PFORMAT_STRING
get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg
,
5655 PFORMAT_STRING pFormat
)
5657 unsigned short num_arms
, arm
, type
;
5659 num_arms
= *(const SHORT
*)pFormat
& 0x0fff;
5661 for(arm
= 0; arm
< num_arms
; arm
++)
5663 if(discriminant
== *(const ULONG
*)pFormat
)
5671 type
= *(const unsigned short*)pFormat
;
5672 TRACE("type %04x\n", type
);
5673 if(arm
== num_arms
) /* default arm extras */
5677 ERR("no arm for 0x%x and no default case\n", discriminant
);
5678 RpcRaiseException(RPC_S_INVALID_TAG
);
5683 TRACE("falling back to empty default case for 0x%x\n", discriminant
);
5690 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
, ULONG discriminant
, PFORMAT_STRING pFormat
)
5692 unsigned short type
;
5696 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5700 type
= *(const unsigned short*)pFormat
;
5701 if((type
& 0xff00) == 0x8000)
5703 unsigned char basetype
= LOBYTE(type
);
5704 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &basetype
);
5708 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5709 NDR_MARSHALL m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
5712 unsigned char *saved_buffer
= NULL
;
5713 int pointer_buffer_mark_set
= 0;
5720 align_pointer_clear(&pStubMsg
->Buffer
, 4);
5721 saved_buffer
= pStubMsg
->Buffer
;
5722 if (pStubMsg
->PointerBufferMark
)
5724 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5725 pStubMsg
->PointerBufferMark
= NULL
;
5726 pointer_buffer_mark_set
= 1;
5729 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
5731 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char **)pMemory
, desc
);
5732 if (pointer_buffer_mark_set
)
5734 STD_OVERFLOW_CHECK(pStubMsg
);
5735 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5736 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5738 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5739 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
5740 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5742 pStubMsg
->Buffer
= saved_buffer
+ 4;
5746 m(pStubMsg
, pMemory
, desc
);
5749 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5754 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5755 unsigned char **ppMemory
,
5757 PFORMAT_STRING pFormat
,
5758 unsigned char fMustAlloc
)
5760 unsigned short type
;
5764 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5768 type
= *(const unsigned short*)pFormat
;
5769 if((type
& 0xff00) == 0x8000)
5771 unsigned char basetype
= LOBYTE(type
);
5772 return NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &basetype
, FALSE
);
5776 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5777 NDR_UNMARSHALL m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
5780 unsigned char *saved_buffer
= NULL
;
5781 int pointer_buffer_mark_set
= 0;
5788 align_pointer(&pStubMsg
->Buffer
, 4);
5789 saved_buffer
= pStubMsg
->Buffer
;
5790 if (pStubMsg
->PointerBufferMark
)
5792 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5793 pStubMsg
->PointerBufferMark
= NULL
;
5794 pointer_buffer_mark_set
= 1;
5797 pStubMsg
->Buffer
+= 4; /* for pointer ID */
5799 if (saved_buffer
+ 4 > pStubMsg
->BufferEnd
)
5801 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5802 saved_buffer
, pStubMsg
->BufferEnd
);
5803 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5806 PointerUnmarshall(pStubMsg
, saved_buffer
, *(unsigned char ***)ppMemory
, **(unsigned char ***)ppMemory
, desc
, fMustAlloc
);
5807 if (pointer_buffer_mark_set
)
5809 STD_OVERFLOW_CHECK(pStubMsg
);
5810 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5811 pStubMsg
->Buffer
= saved_buffer
+ 4;
5815 m(pStubMsg
, ppMemory
, desc
, fMustAlloc
);
5818 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5823 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg
,
5824 unsigned char *pMemory
,
5826 PFORMAT_STRING pFormat
)
5828 unsigned short type
;
5832 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5836 type
= *(const unsigned short*)pFormat
;
5837 if((type
& 0xff00) == 0x8000)
5839 unsigned char basetype
= LOBYTE(type
);
5840 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &basetype
);
5844 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5845 NDR_BUFFERSIZE m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
5854 align_length(&pStubMsg
->BufferLength
, 4);
5855 safe_buffer_length_increment(pStubMsg
, 4); /* for pointer ID */
5856 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5858 int saved_buffer_length
= pStubMsg
->BufferLength
;
5859 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
5860 pStubMsg
->PointerLength
= 0;
5861 if(!pStubMsg
->BufferLength
)
5862 ERR("BufferLength == 0??\n");
5863 PointerBufferSize(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5864 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
5865 pStubMsg
->BufferLength
= saved_buffer_length
;
5869 m(pStubMsg
, pMemory
, desc
);
5872 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
5876 static ULONG
union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg
,
5878 PFORMAT_STRING pFormat
)
5880 unsigned short type
, size
;
5882 size
= *(const unsigned short*)pFormat
;
5883 pStubMsg
->Memory
+= size
;
5886 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5890 type
= *(const unsigned short*)pFormat
;
5891 if((type
& 0xff00) == 0x8000)
5893 return NdrBaseTypeMemorySize(pStubMsg
, pFormat
);
5897 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5898 NDR_MEMORYSIZE m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
5899 unsigned char *saved_buffer
;
5908 align_pointer(&pStubMsg
->Buffer
, 4);
5909 saved_buffer
= pStubMsg
->Buffer
;
5910 safe_buffer_increment(pStubMsg
, 4);
5911 align_length(&pStubMsg
->MemorySize
, sizeof(void *));
5912 pStubMsg
->MemorySize
+= sizeof(void *);
5913 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5914 PointerMemorySize(pStubMsg
, saved_buffer
, pFormat
);
5917 return m(pStubMsg
, desc
);
5920 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5923 TRACE("size %d\n", size
);
5927 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg
,
5928 unsigned char *pMemory
,
5930 PFORMAT_STRING pFormat
)
5932 unsigned short type
;
5936 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5940 type
= *(const unsigned short*)pFormat
;
5941 if((type
& 0xff00) != 0x8000)
5943 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5944 NDR_FREE m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
5953 PointerFree(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5956 m(pStubMsg
, pMemory
, desc
);
5962 /***********************************************************************
5963 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5965 unsigned char * WINAPI
NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5966 unsigned char *pMemory
,
5967 PFORMAT_STRING pFormat
)
5969 unsigned char switch_type
;
5970 unsigned char increment
;
5973 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5976 switch_type
= *pFormat
& 0xf;
5977 increment
= (*pFormat
& 0xf0) >> 4;
5980 align_pointer_clear(&pStubMsg
->Buffer
, increment
);
5982 switch_value
= get_discriminant(switch_type
, pMemory
);
5983 TRACE("got switch value 0x%x\n", switch_value
);
5985 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &switch_type
);
5986 pMemory
+= increment
;
5988 return union_arm_marshall(pStubMsg
, pMemory
, switch_value
, pFormat
);
5991 /***********************************************************************
5992 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5994 unsigned char * WINAPI
NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5995 unsigned char **ppMemory
,
5996 PFORMAT_STRING pFormat
,
5997 unsigned char fMustAlloc
)
5999 unsigned char switch_type
;
6000 unsigned char increment
;
6002 unsigned short size
;
6003 unsigned char *pMemoryArm
;
6005 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
6008 switch_type
= *pFormat
& 0xf;
6009 increment
= (*pFormat
& 0xf0) >> 4;
6012 align_pointer(&pStubMsg
->Buffer
, increment
);
6013 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
6014 TRACE("got switch value 0x%x\n", switch_value
);
6016 size
= *(const unsigned short*)pFormat
+ increment
;
6017 if (!fMustAlloc
&& !*ppMemory
)
6020 *ppMemory
= NdrAllocate(pStubMsg
, size
);
6022 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6023 * since the arm is part of the memory block that is encompassed by
6024 * the whole union. Memory is forced to allocate when pointers
6025 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6026 * clearing the memory we pass in to the unmarshaller */
6028 memset(*ppMemory
, 0, size
);
6030 NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &switch_type
, FALSE
);
6031 pMemoryArm
= *ppMemory
+ increment
;
6033 return union_arm_unmarshall(pStubMsg
, &pMemoryArm
, switch_value
, pFormat
, FALSE
);
6036 /***********************************************************************
6037 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
6039 void WINAPI
NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6040 unsigned char *pMemory
,
6041 PFORMAT_STRING pFormat
)
6043 unsigned char switch_type
;
6044 unsigned char increment
;
6047 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6050 switch_type
= *pFormat
& 0xf;
6051 increment
= (*pFormat
& 0xf0) >> 4;
6054 align_length(&pStubMsg
->BufferLength
, increment
);
6055 switch_value
= get_discriminant(switch_type
, pMemory
);
6056 TRACE("got switch value 0x%x\n", switch_value
);
6058 /* Add discriminant size */
6059 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&switch_value
, &switch_type
);
6060 pMemory
+= increment
;
6062 union_arm_buffer_size(pStubMsg
, pMemory
, switch_value
, pFormat
);
6065 /***********************************************************************
6066 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
6068 ULONG WINAPI
NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6069 PFORMAT_STRING pFormat
)
6071 unsigned char switch_type
;
6072 unsigned char increment
;
6075 switch_type
= *pFormat
& 0xf;
6076 increment
= (*pFormat
& 0xf0) >> 4;
6079 align_pointer(&pStubMsg
->Buffer
, increment
);
6080 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
6081 TRACE("got switch value 0x%x\n", switch_value
);
6083 pStubMsg
->Memory
+= increment
;
6085 return increment
+ union_arm_memory_size(pStubMsg
, switch_value
, pFormat
+ *(const SHORT
*)pFormat
);
6088 /***********************************************************************
6089 * NdrEncapsulatedUnionFree [RPCRT4.@]
6091 void WINAPI
NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
6092 unsigned char *pMemory
,
6093 PFORMAT_STRING pFormat
)
6095 unsigned char switch_type
;
6096 unsigned char increment
;
6099 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6102 switch_type
= *pFormat
& 0xf;
6103 increment
= (*pFormat
& 0xf0) >> 4;
6106 switch_value
= get_discriminant(switch_type
, pMemory
);
6107 TRACE("got switch value 0x%x\n", switch_value
);
6109 pMemory
+= increment
;
6111 union_arm_free(pStubMsg
, pMemory
, switch_value
, pFormat
);
6114 /***********************************************************************
6115 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
6117 unsigned char * WINAPI
NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6118 unsigned char *pMemory
,
6119 PFORMAT_STRING pFormat
)
6121 unsigned char switch_type
;
6123 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6126 switch_type
= *pFormat
;
6129 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6130 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6131 /* Marshall discriminant */
6132 NdrBaseTypeMarshall(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
6134 return union_arm_marshall(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6137 static LONG
unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg
,
6138 PFORMAT_STRING
*ppFormat
)
6140 LONG discriminant
= 0;
6150 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
6159 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6160 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
6168 align_pointer(&pStubMsg
->Buffer
, sizeof(ULONG
));
6169 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
6174 FIXME("Unhandled base type: 0x%02x\n", **ppFormat
);
6178 if (pStubMsg
->fHasNewCorrDesc
)
6182 return discriminant
;
6185 /**********************************************************************
6186 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
6188 unsigned char * WINAPI
NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6189 unsigned char **ppMemory
,
6190 PFORMAT_STRING pFormat
,
6191 unsigned char fMustAlloc
)
6194 unsigned short size
;
6196 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
6199 /* Unmarshall discriminant */
6200 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
6201 TRACE("unmarshalled discriminant %x\n", discriminant
);
6203 pFormat
+= *(const SHORT
*)pFormat
;
6205 size
= *(const unsigned short*)pFormat
;
6207 if (!fMustAlloc
&& !*ppMemory
)
6210 *ppMemory
= NdrAllocate(pStubMsg
, size
);
6212 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6213 * since the arm is part of the memory block that is encompassed by
6214 * the whole union. Memory is forced to allocate when pointers
6215 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6216 * clearing the memory we pass in to the unmarshaller */
6218 memset(*ppMemory
, 0, size
);
6220 return union_arm_unmarshall(pStubMsg
, ppMemory
, discriminant
, pFormat
, FALSE
);
6223 /***********************************************************************
6224 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
6226 void WINAPI
NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6227 unsigned char *pMemory
,
6228 PFORMAT_STRING pFormat
)
6230 unsigned char switch_type
;
6232 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6235 switch_type
= *pFormat
;
6238 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6239 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6240 /* Add discriminant size */
6241 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
6243 union_arm_buffer_size(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6246 /***********************************************************************
6247 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
6249 ULONG WINAPI
NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6250 PFORMAT_STRING pFormat
)
6255 /* Unmarshall discriminant */
6256 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
6257 TRACE("unmarshalled discriminant 0x%x\n", discriminant
);
6259 return union_arm_memory_size(pStubMsg
, discriminant
, pFormat
+ *(const SHORT
*)pFormat
);
6262 /***********************************************************************
6263 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6265 void WINAPI
NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
6266 unsigned char *pMemory
,
6267 PFORMAT_STRING pFormat
)
6269 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6273 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6274 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6276 union_arm_free(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6279 /***********************************************************************
6280 * NdrByteCountPointerMarshall [RPCRT4.@]
6282 unsigned char * WINAPI
NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6283 unsigned char *pMemory
,
6284 PFORMAT_STRING pFormat
)
6290 /***********************************************************************
6291 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6293 unsigned char * WINAPI
NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6294 unsigned char **ppMemory
,
6295 PFORMAT_STRING pFormat
,
6296 unsigned char fMustAlloc
)
6302 /***********************************************************************
6303 * NdrByteCountPointerBufferSize [RPCRT4.@]
6305 void WINAPI
NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6306 unsigned char *pMemory
,
6307 PFORMAT_STRING pFormat
)
6312 /***********************************************************************
6313 * NdrByteCountPointerMemorySize [internal]
6315 static ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6316 PFORMAT_STRING pFormat
)
6322 /***********************************************************************
6323 * NdrByteCountPointerFree [RPCRT4.@]
6325 void WINAPI
NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
6326 unsigned char *pMemory
,
6327 PFORMAT_STRING pFormat
)
6332 /***********************************************************************
6333 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6335 unsigned char * WINAPI
NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6336 unsigned char *pMemory
,
6337 PFORMAT_STRING pFormat
)
6343 /***********************************************************************
6344 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6346 unsigned char * WINAPI
NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6347 unsigned char **ppMemory
,
6348 PFORMAT_STRING pFormat
,
6349 unsigned char fMustAlloc
)
6355 /***********************************************************************
6356 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6358 void WINAPI
NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6359 unsigned char *pMemory
,
6360 PFORMAT_STRING pFormat
)
6365 /***********************************************************************
6366 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6368 ULONG WINAPI
NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6369 PFORMAT_STRING pFormat
)
6375 /***********************************************************************
6376 * NdrXmitOrRepAsFree [RPCRT4.@]
6378 void WINAPI
NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg
,
6379 unsigned char *pMemory
,
6380 PFORMAT_STRING pFormat
)
6385 /***********************************************************************
6386 * NdrRangeMarshall [internal]
6388 static unsigned char *WINAPI
NdrRangeMarshall(
6389 PMIDL_STUB_MESSAGE pStubMsg
,
6390 unsigned char *pMemory
,
6391 PFORMAT_STRING pFormat
)
6393 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6394 unsigned char base_type
;
6396 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6398 if (pRange
->type
!= RPC_FC_RANGE
)
6400 ERR("invalid format type %x\n", pRange
->type
);
6401 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6405 base_type
= pRange
->flags_type
& 0xf;
6407 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &base_type
);
6410 /***********************************************************************
6411 * NdrRangeUnmarshall [RPCRT4.@]
6413 unsigned char *WINAPI
NdrRangeUnmarshall(
6414 PMIDL_STUB_MESSAGE pStubMsg
,
6415 unsigned char **ppMemory
,
6416 PFORMAT_STRING pFormat
,
6417 unsigned char fMustAlloc
)
6419 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6420 unsigned char base_type
;
6422 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6424 if (pRange
->type
!= RPC_FC_RANGE
)
6426 ERR("invalid format type %x\n", pRange
->type
);
6427 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6430 base_type
= pRange
->flags_type
& 0xf;
6432 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6433 base_type
, pRange
->low_value
, pRange
->high_value
);
6435 #define RANGE_UNMARSHALL(mem_type, wire_type, format_spec) \
6438 align_pointer(&pStubMsg->Buffer, sizeof(wire_type)); \
6439 if (!fMustAlloc && !*ppMemory) \
6440 fMustAlloc = TRUE; \
6442 *ppMemory = NdrAllocate(pStubMsg, sizeof(mem_type)); \
6443 if (pStubMsg->Buffer + sizeof(wire_type) > pStubMsg->BufferEnd) \
6445 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6446 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6447 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6449 if ((*(wire_type *)pStubMsg->Buffer < (mem_type)pRange->low_value) || \
6450 (*(wire_type *)pStubMsg->Buffer > (mem_type)pRange->high_value)) \
6452 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6453 *(wire_type *)pStubMsg->Buffer, (mem_type)pRange->low_value, \
6454 (mem_type)pRange->high_value); \
6455 RpcRaiseException(RPC_S_INVALID_BOUND); \
6458 TRACE("*ppMemory: %p\n", *ppMemory); \
6459 **(mem_type **)ppMemory = *(wire_type *)pStubMsg->Buffer; \
6460 pStubMsg->Buffer += sizeof(wire_type); \
6467 RANGE_UNMARSHALL(UCHAR
, UCHAR
, "%d");
6468 TRACE("value: 0x%02x\n", **ppMemory
);
6472 RANGE_UNMARSHALL(CHAR
, CHAR
, "%u");
6473 TRACE("value: 0x%02x\n", **ppMemory
);
6475 case RPC_FC_WCHAR
: /* FIXME: valid? */
6477 RANGE_UNMARSHALL(USHORT
, USHORT
, "%u");
6478 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6481 RANGE_UNMARSHALL(SHORT
, SHORT
, "%d");
6482 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6486 RANGE_UNMARSHALL(LONG
, LONG
, "%d");
6487 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6490 RANGE_UNMARSHALL(ULONG
, ULONG
, "%u");
6491 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6494 RANGE_UNMARSHALL(UINT
, USHORT
, "%u");
6495 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
6501 ERR("invalid range base type: 0x%02x\n", base_type
);
6502 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6508 /***********************************************************************
6509 * NdrRangeBufferSize [internal]
6511 static void WINAPI
NdrRangeBufferSize(
6512 PMIDL_STUB_MESSAGE pStubMsg
,
6513 unsigned char *pMemory
,
6514 PFORMAT_STRING pFormat
)
6516 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6517 unsigned char base_type
;
6519 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6521 if (pRange
->type
!= RPC_FC_RANGE
)
6523 ERR("invalid format type %x\n", pRange
->type
);
6524 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6526 base_type
= pRange
->flags_type
& 0xf;
6528 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &base_type
);
6531 /***********************************************************************
6532 * NdrRangeMemorySize [internal]
6534 static ULONG WINAPI
NdrRangeMemorySize(
6535 PMIDL_STUB_MESSAGE pStubMsg
,
6536 PFORMAT_STRING pFormat
)
6538 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6539 unsigned char base_type
;
6541 if (pRange
->type
!= RPC_FC_RANGE
)
6543 ERR("invalid format type %x\n", pRange
->type
);
6544 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6547 base_type
= pRange
->flags_type
& 0xf;
6549 return NdrBaseTypeMemorySize(pStubMsg
, &base_type
);
6552 /***********************************************************************
6553 * NdrRangeFree [internal]
6555 static void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6556 unsigned char *pMemory
,
6557 PFORMAT_STRING pFormat
)
6559 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6564 /***********************************************************************
6565 * NdrBaseTypeMarshall [internal]
6567 static unsigned char *WINAPI
NdrBaseTypeMarshall(
6568 PMIDL_STUB_MESSAGE pStubMsg
,
6569 unsigned char *pMemory
,
6570 PFORMAT_STRING pFormat
)
6572 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6580 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(UCHAR
));
6581 TRACE("value: 0x%02x\n", *pMemory
);
6586 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(USHORT
));
6587 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(USHORT
));
6588 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
6592 case RPC_FC_ERROR_STATUS_T
:
6594 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(ULONG
));
6595 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONG
));
6596 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
6599 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(float));
6600 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
6603 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(double));
6604 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
6607 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(ULONGLONG
));
6608 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONGLONG
));
6609 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
6613 USHORT val
= *(UINT
*)pMemory
;
6614 /* only 16-bits on the wire, so do a sanity check */
6615 if (*(UINT
*)pMemory
> SHRT_MAX
)
6616 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
6617 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(USHORT
));
6618 safe_copy_to_buffer(pStubMsg
, &val
, sizeof(val
));
6619 TRACE("value: 0x%04x\n", *(UINT
*)pMemory
);
6622 case RPC_FC_INT3264
:
6623 case RPC_FC_UINT3264
:
6625 UINT val
= *(UINT_PTR
*)pMemory
;
6626 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(UINT
));
6627 safe_copy_to_buffer(pStubMsg
, &val
, sizeof(val
));
6633 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6636 /* FIXME: what is the correct return value? */
6640 /***********************************************************************
6641 * NdrBaseTypeUnmarshall [internal]
6643 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(
6644 PMIDL_STUB_MESSAGE pStubMsg
,
6645 unsigned char **ppMemory
,
6646 PFORMAT_STRING pFormat
,
6647 unsigned char fMustAlloc
)
6649 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6651 #define BASE_TYPE_UNMARSHALL(type) do { \
6652 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
6653 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6655 *ppMemory = pStubMsg->Buffer; \
6656 TRACE("*ppMemory: %p\n", *ppMemory); \
6657 safe_buffer_increment(pStubMsg, sizeof(type)); \
6662 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6663 TRACE("*ppMemory: %p\n", *ppMemory); \
6664 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6674 BASE_TYPE_UNMARSHALL(UCHAR
);
6675 TRACE("value: 0x%02x\n", **ppMemory
);
6680 BASE_TYPE_UNMARSHALL(USHORT
);
6681 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6685 case RPC_FC_ERROR_STATUS_T
:
6687 BASE_TYPE_UNMARSHALL(ULONG
);
6688 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6691 BASE_TYPE_UNMARSHALL(float);
6692 TRACE("value: %f\n", **(float **)ppMemory
);
6695 BASE_TYPE_UNMARSHALL(double);
6696 TRACE("value: %f\n", **(double **)ppMemory
);
6699 BASE_TYPE_UNMARSHALL(ULONGLONG
);
6700 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG
**)ppMemory
));
6705 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6706 if (!fMustAlloc
&& !*ppMemory
)
6709 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT
));
6710 safe_copy_from_buffer(pStubMsg
, &val
, sizeof(USHORT
));
6711 /* 16-bits on the wire, but int in memory */
6712 **(UINT
**)ppMemory
= val
;
6713 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
6716 case RPC_FC_INT3264
:
6717 if (sizeof(INT_PTR
) == sizeof(INT
)) BASE_TYPE_UNMARSHALL(INT
);
6721 align_pointer(&pStubMsg
->Buffer
, sizeof(INT
));
6722 if (!fMustAlloc
&& !*ppMemory
)
6725 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(INT_PTR
));
6726 safe_copy_from_buffer(pStubMsg
, &val
, sizeof(INT
));
6727 **(INT_PTR
**)ppMemory
= val
;
6728 TRACE("value: 0x%08lx\n", **(INT_PTR
**)ppMemory
);
6731 case RPC_FC_UINT3264
:
6732 if (sizeof(UINT_PTR
) == sizeof(UINT
)) BASE_TYPE_UNMARSHALL(UINT
);
6736 align_pointer(&pStubMsg
->Buffer
, sizeof(UINT
));
6737 if (!fMustAlloc
&& !*ppMemory
)
6740 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT_PTR
));
6741 safe_copy_from_buffer(pStubMsg
, &val
, sizeof(UINT
));
6742 **(UINT_PTR
**)ppMemory
= val
;
6743 TRACE("value: 0x%08lx\n", **(UINT_PTR
**)ppMemory
);
6749 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6751 #undef BASE_TYPE_UNMARSHALL
6753 /* FIXME: what is the correct return value? */
6758 /***********************************************************************
6759 * NdrBaseTypeBufferSize [internal]
6761 static void WINAPI
NdrBaseTypeBufferSize(
6762 PMIDL_STUB_MESSAGE pStubMsg
,
6763 unsigned char *pMemory
,
6764 PFORMAT_STRING pFormat
)
6766 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6774 safe_buffer_length_increment(pStubMsg
, sizeof(UCHAR
));
6780 align_length(&pStubMsg
->BufferLength
, sizeof(USHORT
));
6781 safe_buffer_length_increment(pStubMsg
, sizeof(USHORT
));
6786 case RPC_FC_INT3264
:
6787 case RPC_FC_UINT3264
:
6788 align_length(&pStubMsg
->BufferLength
, sizeof(ULONG
));
6789 safe_buffer_length_increment(pStubMsg
, sizeof(ULONG
));
6792 align_length(&pStubMsg
->BufferLength
, sizeof(float));
6793 safe_buffer_length_increment(pStubMsg
, sizeof(float));
6796 align_length(&pStubMsg
->BufferLength
, sizeof(double));
6797 safe_buffer_length_increment(pStubMsg
, sizeof(double));
6800 align_length(&pStubMsg
->BufferLength
, sizeof(ULONGLONG
));
6801 safe_buffer_length_increment(pStubMsg
, sizeof(ULONGLONG
));
6803 case RPC_FC_ERROR_STATUS_T
:
6804 align_length(&pStubMsg
->BufferLength
, sizeof(error_status_t
));
6805 safe_buffer_length_increment(pStubMsg
, sizeof(error_status_t
));
6810 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6814 /***********************************************************************
6815 * NdrBaseTypeMemorySize [internal]
6817 static ULONG WINAPI
NdrBaseTypeMemorySize(
6818 PMIDL_STUB_MESSAGE pStubMsg
,
6819 PFORMAT_STRING pFormat
)
6821 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg
, *pFormat
);
6829 safe_buffer_increment(pStubMsg
, sizeof(UCHAR
));
6830 pStubMsg
->MemorySize
+= sizeof(UCHAR
);
6831 return sizeof(UCHAR
);
6835 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6836 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6837 align_length(&pStubMsg
->MemorySize
, sizeof(USHORT
));
6838 pStubMsg
->MemorySize
+= sizeof(USHORT
);
6839 return sizeof(USHORT
);
6843 align_pointer(&pStubMsg
->Buffer
, sizeof(ULONG
));
6844 safe_buffer_increment(pStubMsg
, sizeof(ULONG
));
6845 align_length(&pStubMsg
->MemorySize
, sizeof(ULONG
));
6846 pStubMsg
->MemorySize
+= sizeof(ULONG
);
6847 return sizeof(ULONG
);
6849 align_pointer(&pStubMsg
->Buffer
, sizeof(float));
6850 safe_buffer_increment(pStubMsg
, sizeof(float));
6851 align_length(&pStubMsg
->MemorySize
, sizeof(float));
6852 pStubMsg
->MemorySize
+= sizeof(float);
6853 return sizeof(float);
6855 align_pointer(&pStubMsg
->Buffer
, sizeof(double));
6856 safe_buffer_increment(pStubMsg
, sizeof(double));
6857 align_length(&pStubMsg
->MemorySize
, sizeof(double));
6858 pStubMsg
->MemorySize
+= sizeof(double);
6859 return sizeof(double);
6861 align_pointer(&pStubMsg
->Buffer
, sizeof(ULONGLONG
));
6862 safe_buffer_increment(pStubMsg
, sizeof(ULONGLONG
));
6863 align_length(&pStubMsg
->MemorySize
, sizeof(ULONGLONG
));
6864 pStubMsg
->MemorySize
+= sizeof(ULONGLONG
);
6865 return sizeof(ULONGLONG
);
6866 case RPC_FC_ERROR_STATUS_T
:
6867 align_pointer(&pStubMsg
->Buffer
, sizeof(error_status_t
));
6868 safe_buffer_increment(pStubMsg
, sizeof(error_status_t
));
6869 align_length(&pStubMsg
->MemorySize
, sizeof(error_status_t
));
6870 pStubMsg
->MemorySize
+= sizeof(error_status_t
);
6871 return sizeof(error_status_t
);
6873 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6874 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6875 align_length(&pStubMsg
->MemorySize
, sizeof(UINT
));
6876 pStubMsg
->MemorySize
+= sizeof(UINT
);
6877 return sizeof(UINT
);
6878 case RPC_FC_INT3264
:
6879 case RPC_FC_UINT3264
:
6880 align_pointer(&pStubMsg
->Buffer
, sizeof(UINT
));
6881 safe_buffer_increment(pStubMsg
, sizeof(UINT
));
6882 align_length(&pStubMsg
->MemorySize
, sizeof(UINT_PTR
));
6883 pStubMsg
->MemorySize
+= sizeof(UINT_PTR
);
6884 return sizeof(UINT_PTR
);
6886 align_length(&pStubMsg
->MemorySize
, sizeof(void *));
6887 pStubMsg
->MemorySize
+= sizeof(void *);
6888 return sizeof(void *);
6890 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6895 /***********************************************************************
6896 * NdrBaseTypeFree [internal]
6898 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6899 unsigned char *pMemory
,
6900 PFORMAT_STRING pFormat
)
6902 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6907 /***********************************************************************
6908 * NdrContextHandleBufferSize [internal]
6910 static void WINAPI
NdrContextHandleBufferSize(
6911 PMIDL_STUB_MESSAGE pStubMsg
,
6912 unsigned char *pMemory
,
6913 PFORMAT_STRING pFormat
)
6915 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6917 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6919 ERR("invalid format type %x\n", *pFormat
);
6920 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6922 align_length(&pStubMsg
->BufferLength
, 4);
6923 safe_buffer_length_increment(pStubMsg
, cbNDRContext
);
6926 /***********************************************************************
6927 * NdrContextHandleMarshall [internal]
6929 static unsigned char *WINAPI
NdrContextHandleMarshall(
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
!= RPC_FC_BIND_CONTEXT
)
6938 ERR("invalid format type %x\n", *pFormat
);
6939 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6941 TRACE("flags: 0x%02x\n", pFormat
[1]);
6943 if (pStubMsg
->IsClient
)
6945 if (pFormat
[1] & HANDLE_PARAM_IS_VIA_PTR
)
6946 NdrClientContextMarshall(pStubMsg
, *(NDR_CCONTEXT
**)pMemory
, FALSE
);
6948 NdrClientContextMarshall(pStubMsg
, pMemory
, FALSE
);
6952 NDR_SCONTEXT ctxt
= NDRSContextFromValue(pMemory
);
6953 NDR_RUNDOWN rundown
= pStubMsg
->StubDesc
->apfnNdrRundownRoutines
[pFormat
[2]];
6954 NdrServerContextNewMarshall(pStubMsg
, ctxt
, rundown
, pFormat
);
6960 /***********************************************************************
6961 * NdrContextHandleUnmarshall [internal]
6963 static unsigned char *WINAPI
NdrContextHandleUnmarshall(
6964 PMIDL_STUB_MESSAGE pStubMsg
,
6965 unsigned char **ppMemory
,
6966 PFORMAT_STRING pFormat
,
6967 unsigned char fMustAlloc
)
6969 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg
,
6970 ppMemory
, pFormat
, fMustAlloc
? "TRUE": "FALSE");
6972 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6974 ERR("invalid format type %x\n", *pFormat
);
6975 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6977 TRACE("flags: 0x%02x\n", pFormat
[1]);
6979 if (pStubMsg
->IsClient
)
6981 /* [out]-only or [ret] param */
6982 if ((pFormat
[1] & (HANDLE_PARAM_IS_IN
|HANDLE_PARAM_IS_OUT
)) == HANDLE_PARAM_IS_OUT
)
6983 **(NDR_CCONTEXT
**)ppMemory
= NULL
;
6984 NdrClientContextUnmarshall(pStubMsg
, *(NDR_CCONTEXT
**)ppMemory
, pStubMsg
->RpcMsg
->Handle
);
6989 ctxt
= NdrServerContextNewUnmarshall(pStubMsg
, pFormat
);
6990 if (pFormat
[1] & HANDLE_PARAM_IS_VIA_PTR
)
6991 *(void **)ppMemory
= NDRSContextValue(ctxt
);
6993 *(void **)ppMemory
= *NDRSContextValue(ctxt
);
6999 /***********************************************************************
7000 * NdrClientContextMarshall [RPCRT4.@]
7002 void WINAPI
NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7003 NDR_CCONTEXT ContextHandle
,
7006 TRACE("(%p, %p, %d)\n", pStubMsg
, ContextHandle
, fCheck
);
7008 align_pointer_clear(&pStubMsg
->Buffer
, 4);
7010 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7012 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7013 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7014 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7017 /* FIXME: what does fCheck do? */
7018 NDRCContextMarshall(ContextHandle
,
7021 pStubMsg
->Buffer
+= cbNDRContext
;
7024 /***********************************************************************
7025 * NdrClientContextUnmarshall [RPCRT4.@]
7027 void WINAPI
NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7028 NDR_CCONTEXT
* pContextHandle
,
7029 RPC_BINDING_HANDLE BindHandle
)
7031 TRACE("(%p, %p, %p)\n", pStubMsg
, pContextHandle
, BindHandle
);
7033 align_pointer(&pStubMsg
->Buffer
, 4);
7035 if (pStubMsg
->Buffer
+ cbNDRContext
> pStubMsg
->BufferEnd
)
7036 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7038 NDRCContextUnmarshall(pContextHandle
,
7041 pStubMsg
->RpcMsg
->DataRepresentation
);
7043 pStubMsg
->Buffer
+= cbNDRContext
;
7046 void WINAPI
NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7047 NDR_SCONTEXT ContextHandle
,
7048 NDR_RUNDOWN RundownRoutine
)
7050 TRACE("(%p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
);
7052 align_pointer(&pStubMsg
->Buffer
, 4);
7054 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7056 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7057 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7058 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7061 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
7062 pStubMsg
->Buffer
, RundownRoutine
, NULL
,
7063 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
7064 pStubMsg
->Buffer
+= cbNDRContext
;
7067 NDR_SCONTEXT WINAPI
NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
)
7069 NDR_SCONTEXT ContextHandle
;
7071 TRACE("(%p)\n", pStubMsg
);
7073 align_pointer(&pStubMsg
->Buffer
, 4);
7075 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7077 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7078 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7079 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7082 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
7084 pStubMsg
->RpcMsg
->DataRepresentation
,
7085 NULL
, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
7086 pStubMsg
->Buffer
+= cbNDRContext
;
7088 return ContextHandle
;
7091 void WINAPI
NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg
,
7092 unsigned char* pMemory
,
7093 PFORMAT_STRING pFormat
)
7095 FIXME("(%p, %p, %p): stub\n", pStubMsg
, pMemory
, pFormat
);
7098 NDR_SCONTEXT WINAPI
NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg
,
7099 PFORMAT_STRING pFormat
)
7101 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
7102 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
7104 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
7106 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
7107 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
7108 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
7109 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
7110 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
7112 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
7113 if_id
= &sif
->InterfaceId
;
7116 return NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
, NULL
,
7117 pStubMsg
->RpcMsg
->DataRepresentation
, if_id
,
7121 void WINAPI
NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7122 NDR_SCONTEXT ContextHandle
,
7123 NDR_RUNDOWN RundownRoutine
,
7124 PFORMAT_STRING pFormat
)
7126 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
7127 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
7129 TRACE("(%p, %p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
, pFormat
);
7131 align_pointer(&pStubMsg
->Buffer
, 4);
7133 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7135 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7136 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7137 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7140 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
7141 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
7142 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
7143 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
7144 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
7146 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
7147 if_id
= &sif
->InterfaceId
;
7150 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
7151 pStubMsg
->Buffer
, RundownRoutine
, if_id
, flags
);
7152 pStubMsg
->Buffer
+= cbNDRContext
;
7155 NDR_SCONTEXT WINAPI
NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7156 PFORMAT_STRING pFormat
)
7158 NDR_SCONTEXT ContextHandle
;
7159 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
7160 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
7162 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
7164 align_pointer(&pStubMsg
->Buffer
, 4);
7166 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7168 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7169 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7170 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7173 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
7174 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
7175 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
7176 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
7177 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
7179 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
7180 if_id
= &sif
->InterfaceId
;
7183 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
7185 pStubMsg
->RpcMsg
->DataRepresentation
,
7187 pStubMsg
->Buffer
+= cbNDRContext
;
7189 return ContextHandle
;
7192 /***********************************************************************
7193 * NdrCorrelationInitialize [RPCRT4.@]
7195 * Initializes correlation validity checking.
7198 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7199 * pMemory [I] Pointer to memory to use as a cache.
7200 * CacheSize [I] Size of the memory pointed to by pMemory.
7201 * Flags [I] Reserved. Set to zero.
7206 void WINAPI
NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg
, void *pMemory
, ULONG CacheSize
, ULONG Flags
)
7208 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg
, pMemory
, CacheSize
, Flags
);
7209 pStubMsg
->fHasNewCorrDesc
= TRUE
;
7212 /***********************************************************************
7213 * NdrCorrelationPass [RPCRT4.@]
7215 * Performs correlation validity checking.
7218 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7223 void WINAPI
NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg
)
7225 FIXME("(%p): stub\n", pStubMsg
);
7228 /***********************************************************************
7229 * NdrCorrelationFree [RPCRT4.@]
7231 * Frees any resources used while unmarshalling parameters that need
7232 * correlation validity checking.
7235 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7240 void WINAPI
NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg
)
7242 FIXME("(%p): stub\n", pStubMsg
);