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 **current_ptr
= pPointer
;
923 if (pStubMsg
->IsClient
) {
925 /* if we aren't forcing allocation of memory then try to use the existing
926 * (source) pointer to unmarshall the data into so that [in,out]
927 * parameters behave correctly. it doesn't matter if the parameter is
928 * [out] only since in that case the pointer will be NULL. we force
929 * allocation when the source pointer is NULL here instead of in the type
930 * unmarshalling routine for the benefit of the deref code below */
933 TRACE("setting *pPointer to %p\n", pSrcPointer
);
934 *pPointer
= pSrcPointer
;
940 /* the memory in a stub is never initialised, so we have to work out here
941 * whether we have to initialise it so we can use the optimisation of
942 * setting the pointer to the buffer, if possible, or set fMustAlloc to
944 if (attr
& RPC_FC_P_DEREF
) {
951 if (attr
& RPC_FC_P_ALLOCALLNODES
)
952 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
954 if (attr
& RPC_FC_P_DEREF
) {
956 unsigned char *base_ptr_val
= NdrAllocate(pStubMsg
, sizeof(void *));
957 *pPointer
= base_ptr_val
;
958 current_ptr
= (unsigned char **)base_ptr_val
;
960 current_ptr
= *(unsigned char***)current_ptr
;
961 TRACE("deref => %p\n", current_ptr
);
962 if (!fMustAlloc
&& !*current_ptr
) fMustAlloc
= TRUE
;
964 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
965 if (m
) m(pStubMsg
, current_ptr
, desc
, fMustAlloc
);
966 else FIXME("no unmarshaller for data type=%02x\n", *desc
);
968 if (type
== RPC_FC_FP
)
969 NdrFullPointerInsertRefId(pStubMsg
->FullPtrXlatTables
, pointer_id
,
973 TRACE("pointer=%p\n", *pPointer
);
976 /***********************************************************************
977 * PointerBufferSize [internal]
979 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
980 unsigned char *Pointer
,
981 PFORMAT_STRING pFormat
)
983 unsigned type
= pFormat
[0], attr
= pFormat
[1];
986 int pointer_needs_sizing
;
989 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
990 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
992 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
993 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
996 case RPC_FC_RP
: /* ref pointer (always non-null) */
999 ERR("NULL ref pointer is not allowed\n");
1000 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
1005 /* NULL pointer has no further representation */
1010 pointer_needs_sizing
= !NdrFullPointerQueryPointer(
1011 pStubMsg
->FullPtrXlatTables
, Pointer
, 0, &pointer_id
);
1012 if (!pointer_needs_sizing
)
1016 FIXME("unhandled ptr type=%02x\n", type
);
1017 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1021 if (attr
& RPC_FC_P_DEREF
) {
1022 Pointer
= *(unsigned char**)Pointer
;
1023 TRACE("deref => %p\n", Pointer
);
1026 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
1027 if (m
) m(pStubMsg
, Pointer
, desc
);
1028 else FIXME("no buffersizer for data type=%02x\n", *desc
);
1031 /***********************************************************************
1032 * PointerMemorySize [internal]
1034 static ULONG
PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1035 unsigned char *Buffer
, PFORMAT_STRING pFormat
)
1037 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1038 PFORMAT_STRING desc
;
1040 DWORD pointer_id
= 0;
1041 int pointer_needs_sizing
;
1043 TRACE("(%p,%p,%p)\n", pStubMsg
, Buffer
, pFormat
);
1044 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1046 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1047 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1050 case RPC_FC_RP
: /* ref pointer (always non-null) */
1051 pointer_needs_sizing
= 1;
1053 case RPC_FC_UP
: /* unique pointer */
1054 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
1055 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1056 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1058 pointer_needs_sizing
= 1;
1060 pointer_needs_sizing
= 0;
1065 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1066 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1067 pointer_needs_sizing
= !NdrFullPointerQueryRefId(
1068 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, &pointer
);
1072 FIXME("unhandled ptr type=%02x\n", type
);
1073 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1077 if (attr
& RPC_FC_P_DEREF
) {
1078 align_length(&pStubMsg
->MemorySize
, sizeof(void*));
1079 pStubMsg
->MemorySize
+= sizeof(void*);
1083 if (pointer_needs_sizing
) {
1084 m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
1085 if (m
) m(pStubMsg
, desc
);
1086 else FIXME("no memorysizer for data type=%02x\n", *desc
);
1089 return pStubMsg
->MemorySize
;
1092 /***********************************************************************
1093 * PointerFree [internal]
1095 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1096 unsigned char *Pointer
,
1097 PFORMAT_STRING pFormat
)
1099 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1100 PFORMAT_STRING desc
;
1102 unsigned char *current_pointer
= Pointer
;
1104 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1105 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1106 if (attr
& RPC_FC_P_DONTFREE
) return;
1108 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1109 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1111 if (!Pointer
) return;
1113 if (type
== RPC_FC_FP
) {
1114 int pointer_needs_freeing
= NdrFullPointerFree(
1115 pStubMsg
->FullPtrXlatTables
, Pointer
);
1116 if (!pointer_needs_freeing
)
1120 if (attr
& RPC_FC_P_DEREF
) {
1121 current_pointer
= *(unsigned char**)Pointer
;
1122 TRACE("deref => %p\n", current_pointer
);
1125 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
1126 if (m
) m(pStubMsg
, current_pointer
, desc
);
1128 /* this check stops us from trying to free buffer memory. we don't have to
1129 * worry about clients, since they won't call this function.
1130 * we don't have to check for the buffer being reallocated because
1131 * BufferStart and BufferEnd won't be reset when allocating memory for
1132 * sending the response. we don't have to check for the new buffer here as
1133 * it won't be used a type memory, only for buffer memory */
1134 if (Pointer
>= pStubMsg
->BufferStart
&& Pointer
< pStubMsg
->BufferEnd
)
1137 if (attr
& RPC_FC_P_ONSTACK
) {
1138 TRACE("not freeing stack ptr %p\n", Pointer
);
1141 TRACE("freeing %p\n", Pointer
);
1142 NdrFree(pStubMsg
, Pointer
);
1145 TRACE("not freeing %p\n", Pointer
);
1148 /***********************************************************************
1149 * EmbeddedPointerMarshall
1151 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1152 unsigned char *pMemory
,
1153 PFORMAT_STRING pFormat
)
1155 unsigned char *Mark
= pStubMsg
->BufferMark
;
1156 unsigned rep
, count
, stride
;
1158 unsigned char *saved_buffer
= NULL
;
1160 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1162 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1165 if (pStubMsg
->PointerBufferMark
)
1167 saved_buffer
= pStubMsg
->Buffer
;
1168 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1169 pStubMsg
->PointerBufferMark
= NULL
;
1172 while (pFormat
[0] != RPC_FC_END
) {
1173 switch (pFormat
[0]) {
1175 FIXME("unknown repeat type %d\n", pFormat
[0]);
1176 case RPC_FC_NO_REPEAT
:
1182 case RPC_FC_FIXED_REPEAT
:
1183 rep
= *(const WORD
*)&pFormat
[2];
1184 stride
= *(const WORD
*)&pFormat
[4];
1185 count
= *(const WORD
*)&pFormat
[8];
1188 case RPC_FC_VARIABLE_REPEAT
:
1189 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1190 stride
= *(const WORD
*)&pFormat
[2];
1191 count
= *(const WORD
*)&pFormat
[6];
1195 for (i
= 0; i
< rep
; i
++) {
1196 PFORMAT_STRING info
= pFormat
;
1197 unsigned char *membase
= pMemory
+ (i
* stride
);
1198 unsigned char *bufbase
= Mark
+ (i
* stride
);
1201 for (u
=0; u
<count
; u
++,info
+=8) {
1202 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1203 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1204 unsigned char *saved_memory
= pStubMsg
->Memory
;
1206 pStubMsg
->Memory
= pMemory
;
1207 PointerMarshall(pStubMsg
, bufptr
, *(unsigned char**)memptr
, info
+4);
1208 pStubMsg
->Memory
= saved_memory
;
1211 pFormat
+= 8 * count
;
1216 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1217 pStubMsg
->Buffer
= saved_buffer
;
1220 STD_OVERFLOW_CHECK(pStubMsg
);
1225 /***********************************************************************
1226 * EmbeddedPointerUnmarshall
1228 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1229 unsigned char *pDstBuffer
,
1230 unsigned char *pSrcMemoryPtrs
,
1231 PFORMAT_STRING pFormat
,
1232 unsigned char fMustAlloc
)
1234 unsigned char *Mark
= pStubMsg
->BufferMark
;
1235 unsigned rep
, count
, stride
;
1237 unsigned char *saved_buffer
= NULL
;
1239 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg
, pDstBuffer
, pSrcMemoryPtrs
, pFormat
, fMustAlloc
);
1241 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1244 if (pStubMsg
->PointerBufferMark
)
1246 saved_buffer
= pStubMsg
->Buffer
;
1247 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1248 pStubMsg
->PointerBufferMark
= NULL
;
1251 while (pFormat
[0] != RPC_FC_END
) {
1252 TRACE("pFormat[0] = 0x%x\n", pFormat
[0]);
1253 switch (pFormat
[0]) {
1255 FIXME("unknown repeat type %d\n", pFormat
[0]);
1256 case RPC_FC_NO_REPEAT
:
1262 case RPC_FC_FIXED_REPEAT
:
1263 rep
= *(const WORD
*)&pFormat
[2];
1264 stride
= *(const WORD
*)&pFormat
[4];
1265 count
= *(const WORD
*)&pFormat
[8];
1268 case RPC_FC_VARIABLE_REPEAT
:
1269 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1270 stride
= *(const WORD
*)&pFormat
[2];
1271 count
= *(const WORD
*)&pFormat
[6];
1275 for (i
= 0; i
< rep
; i
++) {
1276 PFORMAT_STRING info
= pFormat
;
1277 unsigned char *bufdstbase
= pDstBuffer
+ (i
* stride
);
1278 unsigned char *memsrcbase
= pSrcMemoryPtrs
+ (i
* stride
);
1279 unsigned char *bufbase
= Mark
+ (i
* stride
);
1282 for (u
=0; u
<count
; u
++,info
+=8) {
1283 unsigned char **bufdstptr
= (unsigned char **)(bufdstbase
+ *(const SHORT
*)&info
[2]);
1284 unsigned char **memsrcptr
= (unsigned char **)(memsrcbase
+ *(const SHORT
*)&info
[0]);
1285 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1286 PointerUnmarshall(pStubMsg
, bufptr
, bufdstptr
, *memsrcptr
, info
+4, fMustAlloc
);
1289 pFormat
+= 8 * count
;
1294 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1295 pStubMsg
->Buffer
= saved_buffer
;
1301 /***********************************************************************
1302 * EmbeddedPointerBufferSize
1304 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1305 unsigned char *pMemory
,
1306 PFORMAT_STRING pFormat
)
1308 unsigned rep
, count
, stride
;
1310 ULONG saved_buffer_length
= 0;
1312 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1314 if (pStubMsg
->IgnoreEmbeddedPointers
) return;
1316 if (*pFormat
!= RPC_FC_PP
) return;
1319 if (pStubMsg
->PointerLength
)
1321 saved_buffer_length
= pStubMsg
->BufferLength
;
1322 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
1323 pStubMsg
->PointerLength
= 0;
1326 while (pFormat
[0] != RPC_FC_END
) {
1327 switch (pFormat
[0]) {
1329 FIXME("unknown repeat type %d\n", pFormat
[0]);
1330 case RPC_FC_NO_REPEAT
:
1336 case RPC_FC_FIXED_REPEAT
:
1337 rep
= *(const WORD
*)&pFormat
[2];
1338 stride
= *(const WORD
*)&pFormat
[4];
1339 count
= *(const WORD
*)&pFormat
[8];
1342 case RPC_FC_VARIABLE_REPEAT
:
1343 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1344 stride
= *(const WORD
*)&pFormat
[2];
1345 count
= *(const WORD
*)&pFormat
[6];
1349 for (i
= 0; i
< rep
; i
++) {
1350 PFORMAT_STRING info
= pFormat
;
1351 unsigned char *membase
= pMemory
+ (i
* stride
);
1354 for (u
=0; u
<count
; u
++,info
+=8) {
1355 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1356 unsigned char *saved_memory
= pStubMsg
->Memory
;
1358 pStubMsg
->Memory
= pMemory
;
1359 PointerBufferSize(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1360 pStubMsg
->Memory
= saved_memory
;
1363 pFormat
+= 8 * count
;
1366 if (saved_buffer_length
)
1368 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
1369 pStubMsg
->BufferLength
= saved_buffer_length
;
1373 /***********************************************************************
1374 * EmbeddedPointerMemorySize [internal]
1376 static ULONG
EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1377 PFORMAT_STRING pFormat
)
1379 unsigned char *Mark
= pStubMsg
->BufferMark
;
1380 unsigned rep
, count
, stride
;
1382 unsigned char *saved_buffer
= NULL
;
1384 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1386 if (pStubMsg
->IgnoreEmbeddedPointers
) return 0;
1388 if (pStubMsg
->PointerBufferMark
)
1390 saved_buffer
= pStubMsg
->Buffer
;
1391 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1392 pStubMsg
->PointerBufferMark
= NULL
;
1395 if (*pFormat
!= RPC_FC_PP
) return 0;
1398 while (pFormat
[0] != RPC_FC_END
) {
1399 switch (pFormat
[0]) {
1401 FIXME("unknown repeat type %d\n", pFormat
[0]);
1402 case RPC_FC_NO_REPEAT
:
1408 case RPC_FC_FIXED_REPEAT
:
1409 rep
= *(const WORD
*)&pFormat
[2];
1410 stride
= *(const WORD
*)&pFormat
[4];
1411 count
= *(const WORD
*)&pFormat
[8];
1414 case RPC_FC_VARIABLE_REPEAT
:
1415 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1416 stride
= *(const WORD
*)&pFormat
[2];
1417 count
= *(const WORD
*)&pFormat
[6];
1421 for (i
= 0; i
< rep
; i
++) {
1422 PFORMAT_STRING info
= pFormat
;
1423 unsigned char *bufbase
= Mark
+ (i
* stride
);
1425 for (u
=0; u
<count
; u
++,info
+=8) {
1426 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1427 PointerMemorySize(pStubMsg
, bufptr
, info
+4);
1430 pFormat
+= 8 * count
;
1435 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1436 pStubMsg
->Buffer
= saved_buffer
;
1442 /***********************************************************************
1443 * EmbeddedPointerFree [internal]
1445 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1446 unsigned char *pMemory
,
1447 PFORMAT_STRING pFormat
)
1449 unsigned rep
, count
, stride
;
1452 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1453 if (*pFormat
!= RPC_FC_PP
) return;
1456 while (pFormat
[0] != RPC_FC_END
) {
1457 switch (pFormat
[0]) {
1459 FIXME("unknown repeat type %d\n", pFormat
[0]);
1460 case RPC_FC_NO_REPEAT
:
1466 case RPC_FC_FIXED_REPEAT
:
1467 rep
= *(const WORD
*)&pFormat
[2];
1468 stride
= *(const WORD
*)&pFormat
[4];
1469 count
= *(const WORD
*)&pFormat
[8];
1472 case RPC_FC_VARIABLE_REPEAT
:
1473 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1474 stride
= *(const WORD
*)&pFormat
[2];
1475 count
= *(const WORD
*)&pFormat
[6];
1479 for (i
= 0; i
< rep
; i
++) {
1480 PFORMAT_STRING info
= pFormat
;
1481 unsigned char *membase
= pMemory
+ (i
* stride
);
1484 for (u
=0; u
<count
; u
++,info
+=8) {
1485 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1486 unsigned char *saved_memory
= pStubMsg
->Memory
;
1488 pStubMsg
->Memory
= pMemory
;
1489 PointerFree(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1490 pStubMsg
->Memory
= saved_memory
;
1493 pFormat
+= 8 * count
;
1497 /***********************************************************************
1498 * NdrPointerMarshall [RPCRT4.@]
1500 unsigned char * WINAPI
NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1501 unsigned char *pMemory
,
1502 PFORMAT_STRING pFormat
)
1504 unsigned char *Buffer
;
1506 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1508 /* Increment the buffer here instead of in PointerMarshall,
1509 * as that is used by embedded pointers which already handle the incrementing
1510 * the buffer, and shouldn't write any additional pointer data to the wire */
1511 if (*pFormat
!= RPC_FC_RP
)
1513 align_pointer_clear(&pStubMsg
->Buffer
, 4);
1514 Buffer
= pStubMsg
->Buffer
;
1515 safe_buffer_increment(pStubMsg
, 4);
1518 Buffer
= pStubMsg
->Buffer
;
1520 PointerMarshall(pStubMsg
, Buffer
, pMemory
, pFormat
);
1525 /***********************************************************************
1526 * NdrPointerUnmarshall [RPCRT4.@]
1528 unsigned char * WINAPI
NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1529 unsigned char **ppMemory
,
1530 PFORMAT_STRING pFormat
,
1531 unsigned char fMustAlloc
)
1533 unsigned char *Buffer
;
1535 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1537 if (*pFormat
== RPC_FC_RP
)
1539 Buffer
= pStubMsg
->Buffer
;
1540 /* Do the NULL ref pointer check here because embedded pointers can be
1541 * NULL if the type the pointer is embedded in was allocated rather than
1542 * being passed in by the client */
1543 if (pStubMsg
->IsClient
&& !*ppMemory
)
1545 ERR("NULL ref pointer is not allowed\n");
1546 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
1551 /* Increment the buffer here instead of in PointerUnmarshall,
1552 * as that is used by embedded pointers which already handle the incrementing
1553 * the buffer, and shouldn't read any additional pointer data from the
1555 align_pointer(&pStubMsg
->Buffer
, 4);
1556 Buffer
= pStubMsg
->Buffer
;
1557 safe_buffer_increment(pStubMsg
, 4);
1560 PointerUnmarshall(pStubMsg
, Buffer
, ppMemory
, *ppMemory
, pFormat
, fMustAlloc
);
1565 /***********************************************************************
1566 * NdrPointerBufferSize [RPCRT4.@]
1568 void WINAPI
NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1569 unsigned char *pMemory
,
1570 PFORMAT_STRING pFormat
)
1572 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1574 /* Increment the buffer length here instead of in PointerBufferSize,
1575 * as that is used by embedded pointers which already handle the buffer
1576 * length, and shouldn't write anything more to the wire */
1577 if (*pFormat
!= RPC_FC_RP
)
1579 align_length(&pStubMsg
->BufferLength
, 4);
1580 safe_buffer_length_increment(pStubMsg
, 4);
1583 PointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1586 /***********************************************************************
1587 * NdrPointerMemorySize [RPCRT4.@]
1589 ULONG WINAPI
NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1590 PFORMAT_STRING pFormat
)
1592 unsigned char *Buffer
= pStubMsg
->Buffer
;
1593 if (*pFormat
!= RPC_FC_RP
)
1595 align_pointer(&pStubMsg
->Buffer
, 4);
1596 safe_buffer_increment(pStubMsg
, 4);
1598 align_length(&pStubMsg
->MemorySize
, sizeof(void *));
1599 return PointerMemorySize(pStubMsg
, Buffer
, pFormat
);
1602 /***********************************************************************
1603 * NdrPointerFree [RPCRT4.@]
1605 void WINAPI
NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1606 unsigned char *pMemory
,
1607 PFORMAT_STRING pFormat
)
1609 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1610 PointerFree(pStubMsg
, pMemory
, pFormat
);
1613 /***********************************************************************
1614 * NdrSimpleTypeMarshall [RPCRT4.@]
1616 void WINAPI
NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1617 unsigned char FormatChar
)
1619 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &FormatChar
);
1622 /***********************************************************************
1623 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1625 * Unmarshall a base type.
1628 * Doesn't check that the buffer is long enough before copying, so the caller
1631 void WINAPI
NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1632 unsigned char FormatChar
)
1634 #define BASE_TYPE_UNMARSHALL(type) \
1635 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
1636 TRACE("pMemory: %p\n", pMemory); \
1637 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1638 pStubMsg->Buffer += sizeof(type);
1646 BASE_TYPE_UNMARSHALL(UCHAR
);
1647 TRACE("value: 0x%02x\n", *pMemory
);
1652 BASE_TYPE_UNMARSHALL(USHORT
);
1653 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
1657 case RPC_FC_ERROR_STATUS_T
:
1659 BASE_TYPE_UNMARSHALL(ULONG
);
1660 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
1663 BASE_TYPE_UNMARSHALL(float);
1664 TRACE("value: %f\n", *(float *)pMemory
);
1667 BASE_TYPE_UNMARSHALL(double);
1668 TRACE("value: %f\n", *(double *)pMemory
);
1671 BASE_TYPE_UNMARSHALL(ULONGLONG
);
1672 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
1675 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
1676 TRACE("pMemory: %p\n", pMemory
);
1677 /* 16-bits on the wire, but int in memory */
1678 *(UINT
*)pMemory
= *(USHORT
*)pStubMsg
->Buffer
;
1679 pStubMsg
->Buffer
+= sizeof(USHORT
);
1680 TRACE("value: 0x%08x\n", *(UINT
*)pMemory
);
1682 case RPC_FC_INT3264
:
1683 align_pointer(&pStubMsg
->Buffer
, sizeof(INT
));
1684 /* 32-bits on the wire, but int_ptr in memory */
1685 *(INT_PTR
*)pMemory
= *(INT
*)pStubMsg
->Buffer
;
1686 pStubMsg
->Buffer
+= sizeof(INT
);
1687 TRACE("value: 0x%08lx\n", *(INT_PTR
*)pMemory
);
1689 case RPC_FC_UINT3264
:
1690 align_pointer(&pStubMsg
->Buffer
, sizeof(UINT
));
1691 /* 32-bits on the wire, but int_ptr in memory */
1692 *(UINT_PTR
*)pMemory
= *(UINT
*)pStubMsg
->Buffer
;
1693 pStubMsg
->Buffer
+= sizeof(UINT
);
1694 TRACE("value: 0x%08lx\n", *(UINT_PTR
*)pMemory
);
1699 FIXME("Unhandled base type: 0x%02x\n", FormatChar
);
1701 #undef BASE_TYPE_UNMARSHALL
1704 /***********************************************************************
1705 * NdrSimpleStructMarshall [RPCRT4.@]
1707 unsigned char * WINAPI
NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1708 unsigned char *pMemory
,
1709 PFORMAT_STRING pFormat
)
1711 unsigned size
= *(const WORD
*)(pFormat
+2);
1712 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1714 align_pointer_clear(&pStubMsg
->Buffer
, pFormat
[1] + 1);
1716 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1717 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
1719 if (pFormat
[0] != RPC_FC_STRUCT
)
1720 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
+4);
1725 /***********************************************************************
1726 * NdrSimpleStructUnmarshall [RPCRT4.@]
1728 unsigned char * WINAPI
NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1729 unsigned char **ppMemory
,
1730 PFORMAT_STRING pFormat
,
1731 unsigned char fMustAlloc
)
1733 unsigned size
= *(const WORD
*)(pFormat
+2);
1734 unsigned char *saved_buffer
;
1735 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1737 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
1740 *ppMemory
= NdrAllocate(pStubMsg
, size
);
1743 if (!pStubMsg
->IsClient
&& !*ppMemory
)
1744 /* for servers, we just point straight into the RPC buffer */
1745 *ppMemory
= pStubMsg
->Buffer
;
1748 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1749 safe_buffer_increment(pStubMsg
, size
);
1750 if (pFormat
[0] == RPC_FC_PSTRUCT
)
1751 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
+4, fMustAlloc
);
1753 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
1754 if (*ppMemory
!= saved_buffer
)
1755 memcpy(*ppMemory
, saved_buffer
, size
);
1760 /***********************************************************************
1761 * NdrSimpleStructBufferSize [RPCRT4.@]
1763 void WINAPI
NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1764 unsigned char *pMemory
,
1765 PFORMAT_STRING pFormat
)
1767 unsigned size
= *(const WORD
*)(pFormat
+2);
1768 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1770 align_length(&pStubMsg
->BufferLength
, pFormat
[1] + 1);
1772 safe_buffer_length_increment(pStubMsg
, size
);
1773 if (pFormat
[0] != RPC_FC_STRUCT
)
1774 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
+4);
1777 /***********************************************************************
1778 * NdrSimpleStructMemorySize [RPCRT4.@]
1780 ULONG WINAPI
NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1781 PFORMAT_STRING pFormat
)
1783 unsigned short size
= *(const WORD
*)(pFormat
+2);
1785 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1787 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
1788 pStubMsg
->MemorySize
+= size
;
1789 safe_buffer_increment(pStubMsg
, size
);
1791 if (pFormat
[0] != RPC_FC_STRUCT
)
1792 EmbeddedPointerMemorySize(pStubMsg
, pFormat
+4);
1793 return pStubMsg
->MemorySize
;
1796 /***********************************************************************
1797 * NdrSimpleStructFree [RPCRT4.@]
1799 void WINAPI
NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
1800 unsigned char *pMemory
,
1801 PFORMAT_STRING pFormat
)
1803 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1804 if (pFormat
[0] != RPC_FC_STRUCT
)
1805 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
+4);
1810 static inline void array_compute_and_size_conformance(
1811 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1812 PFORMAT_STRING pFormat
)
1819 ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1820 SizeConformance(pStubMsg
);
1822 case RPC_FC_CVARRAY
:
1823 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, 0);
1824 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
1825 SizeConformance(pStubMsg
);
1827 case RPC_FC_C_CSTRING
:
1828 case RPC_FC_C_WSTRING
:
1829 if (fc
== RPC_FC_C_CSTRING
)
1831 TRACE("string=%s\n", debugstr_a((const char *)pMemory
));
1832 pStubMsg
->ActualCount
= strlen((const char *)pMemory
)+1;
1836 TRACE("string=%s\n", debugstr_w((LPCWSTR
)pMemory
));
1837 pStubMsg
->ActualCount
= strlenW((LPCWSTR
)pMemory
)+1;
1840 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
1841 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
1843 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
1845 SizeConformance(pStubMsg
);
1847 case RPC_FC_BOGUS_ARRAY
:
1848 count
= *(const WORD
*)(pFormat
+ 2);
1850 if (IsConformanceOrVariancePresent(pFormat
)) SizeConformance(pStubMsg
);
1851 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, count
);
1852 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
1855 ERR("unknown array format 0x%x\n", fc
);
1856 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1860 static inline void array_buffer_size(
1861 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1862 PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
1866 unsigned char alignment
;
1871 esize
= *(const WORD
*)(pFormat
+2);
1872 alignment
= pFormat
[1] + 1;
1874 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1876 align_length(&pStubMsg
->BufferLength
, alignment
);
1878 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
1879 /* conformance value plus array */
1880 safe_buffer_length_increment(pStubMsg
, size
);
1883 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1885 case RPC_FC_CVARRAY
:
1886 esize
= *(const WORD
*)(pFormat
+2);
1887 alignment
= pFormat
[1] + 1;
1889 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1890 pFormat
= SkipVariance(pStubMsg
, pFormat
);
1892 SizeVariance(pStubMsg
);
1894 align_length(&pStubMsg
->BufferLength
, alignment
);
1896 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1897 safe_buffer_length_increment(pStubMsg
, size
);
1900 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1902 case RPC_FC_C_CSTRING
:
1903 case RPC_FC_C_WSTRING
:
1904 if (fc
== RPC_FC_C_CSTRING
)
1909 SizeVariance(pStubMsg
);
1911 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1912 safe_buffer_length_increment(pStubMsg
, size
);
1914 case RPC_FC_BOGUS_ARRAY
:
1915 alignment
= pFormat
[1] + 1;
1916 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1917 if (IsConformanceOrVariancePresent(pFormat
)) SizeVariance(pStubMsg
);
1918 pFormat
= SkipVariance(pStubMsg
, pFormat
);
1920 align_length(&pStubMsg
->BufferLength
, alignment
);
1922 size
= pStubMsg
->ActualCount
;
1923 for (i
= 0; i
< size
; i
++)
1924 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
1927 ERR("unknown array format 0x%x\n", fc
);
1928 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1932 static inline void array_compute_and_write_conformance(
1933 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1934 PFORMAT_STRING pFormat
)
1937 BOOL conformance_present
;
1942 ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1943 WriteConformance(pStubMsg
);
1945 case RPC_FC_CVARRAY
:
1946 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, 0);
1947 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
1948 WriteConformance(pStubMsg
);
1950 case RPC_FC_C_CSTRING
:
1951 case RPC_FC_C_WSTRING
:
1952 if (fc
== RPC_FC_C_CSTRING
)
1954 TRACE("string=%s\n", debugstr_a((const char *)pMemory
));
1955 pStubMsg
->ActualCount
= strlen((const char *)pMemory
)+1;
1959 TRACE("string=%s\n", debugstr_w((LPCWSTR
)pMemory
));
1960 pStubMsg
->ActualCount
= strlenW((LPCWSTR
)pMemory
)+1;
1962 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
1963 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
1965 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
1966 pStubMsg
->Offset
= 0;
1967 WriteConformance(pStubMsg
);
1969 case RPC_FC_BOGUS_ARRAY
:
1970 def
= *(const WORD
*)(pFormat
+ 2);
1972 conformance_present
= IsConformanceOrVariancePresent(pFormat
);
1973 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
1974 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
1975 if (conformance_present
) WriteConformance(pStubMsg
);
1978 ERR("unknown array format 0x%x\n", fc
);
1979 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1983 static inline void array_write_variance_and_marshall(
1984 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1985 PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
1989 unsigned char alignment
;
1994 esize
= *(const WORD
*)(pFormat
+2);
1995 alignment
= pFormat
[1] + 1;
1997 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1999 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
2001 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2003 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2004 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
2007 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2009 case RPC_FC_CVARRAY
:
2010 esize
= *(const WORD
*)(pFormat
+2);
2011 alignment
= pFormat
[1] + 1;
2013 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2014 pFormat
= SkipVariance(pStubMsg
, pFormat
);
2016 WriteVariance(pStubMsg
);
2018 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
2020 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2023 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2024 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, size
);
2027 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2029 case RPC_FC_C_CSTRING
:
2030 case RPC_FC_C_WSTRING
:
2031 if (fc
== RPC_FC_C_CSTRING
)
2036 WriteVariance(pStubMsg
);
2038 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2039 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
2041 case RPC_FC_BOGUS_ARRAY
:
2042 alignment
= pFormat
[1] + 1;
2043 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2044 if (IsConformanceOrVariancePresent(pFormat
)) WriteVariance(pStubMsg
);
2045 pFormat
= SkipVariance(pStubMsg
, pFormat
);
2047 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
2049 size
= pStubMsg
->ActualCount
;
2050 for (i
= 0; i
< size
; i
++)
2051 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
2054 ERR("unknown array format 0x%x\n", fc
);
2055 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2059 static inline ULONG
array_read_conformance(
2060 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
2067 esize
= *(const WORD
*)(pFormat
+2);
2068 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2069 return safe_multiply(esize
, pStubMsg
->MaxCount
);
2070 case RPC_FC_CVARRAY
:
2071 esize
= *(const WORD
*)(pFormat
+2);
2072 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2073 return safe_multiply(esize
, pStubMsg
->MaxCount
);
2074 case RPC_FC_C_CSTRING
:
2075 case RPC_FC_C_WSTRING
:
2076 if (fc
== RPC_FC_C_CSTRING
)
2081 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
2082 ReadConformance(pStubMsg
, pFormat
+ 2);
2084 ReadConformance(pStubMsg
, NULL
);
2085 return safe_multiply(esize
, pStubMsg
->MaxCount
);
2086 case RPC_FC_BOGUS_ARRAY
:
2087 def
= *(const WORD
*)(pFormat
+ 2);
2089 if (IsConformanceOrVariancePresent(pFormat
)) pFormat
= ReadConformance(pStubMsg
, pFormat
);
2092 pStubMsg
->MaxCount
= def
;
2093 pFormat
= SkipConformance( pStubMsg
, pFormat
);
2095 pFormat
= SkipVariance( pStubMsg
, pFormat
);
2097 esize
= ComplexStructSize(pStubMsg
, pFormat
);
2098 return safe_multiply(pStubMsg
->MaxCount
, esize
);
2100 ERR("unknown array format 0x%x\n", fc
);
2101 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2105 static inline ULONG
array_read_variance_and_unmarshall(
2106 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char **ppMemory
,
2107 PFORMAT_STRING pFormat
, unsigned char fMustAlloc
,
2108 unsigned char fUseBufferMemoryServer
, unsigned char fUnmarshall
)
2110 ULONG bufsize
, memsize
;
2112 unsigned char alignment
;
2113 unsigned char *saved_buffer
, *pMemory
;
2114 ULONG i
, offset
, count
;
2119 esize
= *(const WORD
*)(pFormat
+2);
2120 alignment
= pFormat
[1] + 1;
2122 bufsize
= memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2124 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2126 align_pointer(&pStubMsg
->Buffer
, alignment
);
2131 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2134 if (fUseBufferMemoryServer
&& !pStubMsg
->IsClient
&& !*ppMemory
)
2135 /* for servers, we just point straight into the RPC buffer */
2136 *ppMemory
= pStubMsg
->Buffer
;
2139 saved_buffer
= pStubMsg
->Buffer
;
2140 safe_buffer_increment(pStubMsg
, bufsize
);
2142 pStubMsg
->BufferMark
= saved_buffer
;
2143 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
2145 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
2146 if (*ppMemory
!= saved_buffer
)
2147 memcpy(*ppMemory
, saved_buffer
, bufsize
);
2150 case RPC_FC_CVARRAY
:
2151 esize
= *(const WORD
*)(pFormat
+2);
2152 alignment
= pFormat
[1] + 1;
2154 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2156 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2158 align_pointer(&pStubMsg
->Buffer
, alignment
);
2160 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2161 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2165 offset
= pStubMsg
->Offset
;
2167 if (!fMustAlloc
&& !*ppMemory
)
2170 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2171 saved_buffer
= pStubMsg
->Buffer
;
2172 safe_buffer_increment(pStubMsg
, bufsize
);
2174 pStubMsg
->BufferMark
= saved_buffer
;
2175 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
,
2178 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
2181 case RPC_FC_C_CSTRING
:
2182 case RPC_FC_C_WSTRING
:
2183 if (fc
== RPC_FC_C_CSTRING
)
2188 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
2190 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
2192 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2193 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
2194 RpcRaiseException(RPC_S_INVALID_BOUND
);
2196 if (pStubMsg
->Offset
)
2198 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2199 RpcRaiseException(RPC_S_INVALID_BOUND
);
2202 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2203 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2205 validate_string_data(pStubMsg
, bufsize
, esize
);
2210 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2213 if (fUseBufferMemoryServer
&& !pStubMsg
->IsClient
&&
2214 !*ppMemory
&& (pStubMsg
->MaxCount
== pStubMsg
->ActualCount
))
2215 /* if the data in the RPC buffer is big enough, we just point
2216 * straight into it */
2217 *ppMemory
= pStubMsg
->Buffer
;
2218 else if (!*ppMemory
)
2219 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2222 if (*ppMemory
== pStubMsg
->Buffer
)
2223 safe_buffer_increment(pStubMsg
, bufsize
);
2225 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
2227 if (*pFormat
== RPC_FC_C_CSTRING
)
2228 TRACE("string=%s\n", debugstr_a((char*)*ppMemory
));
2230 TRACE("string=%s\n", debugstr_w((LPWSTR
)*ppMemory
));
2234 case RPC_FC_BOGUS_ARRAY
:
2235 alignment
= pFormat
[1] + 1;
2236 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2237 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2239 esize
= ComplexStructSize(pStubMsg
, pFormat
);
2240 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2242 assert( fUnmarshall
);
2244 if (!fMustAlloc
&& !*ppMemory
)
2247 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2249 align_pointer(&pStubMsg
->Buffer
, alignment
);
2250 saved_buffer
= pStubMsg
->Buffer
;
2252 pMemory
= *ppMemory
;
2253 count
= pStubMsg
->ActualCount
;
2254 for (i
= 0; i
< count
; i
++)
2255 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
, fMustAlloc
);
2256 return pStubMsg
->Buffer
- saved_buffer
;
2259 ERR("unknown array format 0x%x\n", fc
);
2260 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2264 static inline void array_memory_size(
2265 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
,
2266 unsigned char fHasPointers
)
2268 ULONG i
, count
, SavedMemorySize
;
2269 ULONG bufsize
, memsize
;
2271 unsigned char alignment
;
2276 esize
= *(const WORD
*)(pFormat
+2);
2277 alignment
= pFormat
[1] + 1;
2279 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2281 bufsize
= memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2282 pStubMsg
->MemorySize
+= memsize
;
2284 align_pointer(&pStubMsg
->Buffer
, alignment
);
2286 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2287 safe_buffer_increment(pStubMsg
, bufsize
);
2290 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2292 case RPC_FC_CVARRAY
:
2293 esize
= *(const WORD
*)(pFormat
+2);
2294 alignment
= pFormat
[1] + 1;
2296 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2298 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2300 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2301 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2302 pStubMsg
->MemorySize
+= memsize
;
2304 align_pointer(&pStubMsg
->Buffer
, alignment
);
2306 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2307 safe_buffer_increment(pStubMsg
, bufsize
);
2310 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2312 case RPC_FC_C_CSTRING
:
2313 case RPC_FC_C_WSTRING
:
2314 if (fc
== RPC_FC_C_CSTRING
)
2319 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
2321 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
2323 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2324 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
2325 RpcRaiseException(RPC_S_INVALID_BOUND
);
2327 if (pStubMsg
->Offset
)
2329 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2330 RpcRaiseException(RPC_S_INVALID_BOUND
);
2333 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2334 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2336 validate_string_data(pStubMsg
, bufsize
, esize
);
2338 safe_buffer_increment(pStubMsg
, bufsize
);
2339 pStubMsg
->MemorySize
+= memsize
;
2341 case RPC_FC_BOGUS_ARRAY
:
2342 alignment
= pFormat
[1] + 1;
2343 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2344 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2346 align_pointer(&pStubMsg
->Buffer
, alignment
);
2348 SavedMemorySize
= pStubMsg
->MemorySize
;
2350 esize
= ComplexStructSize(pStubMsg
, pFormat
);
2351 memsize
= safe_multiply(pStubMsg
->MaxCount
, esize
);
2353 count
= pStubMsg
->ActualCount
;
2354 for (i
= 0; i
< count
; i
++)
2355 ComplexStructMemorySize(pStubMsg
, pFormat
, NULL
);
2357 pStubMsg
->MemorySize
= SavedMemorySize
+ memsize
;
2360 ERR("unknown array format 0x%x\n", fc
);
2361 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2365 static inline void array_free(
2366 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
,
2367 unsigned char *pMemory
, PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
2374 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2376 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2378 case RPC_FC_CVARRAY
:
2379 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2380 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2382 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2384 case RPC_FC_C_CSTRING
:
2385 case RPC_FC_C_WSTRING
:
2386 /* No embedded pointers so nothing to do */
2388 case RPC_FC_BOGUS_ARRAY
:
2389 count
= *(const WORD
*)(pFormat
+ 2);
2390 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, count
);
2391 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
2393 count
= pStubMsg
->ActualCount
;
2394 for (i
= 0; i
< count
; i
++)
2395 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
2398 ERR("unknown array format 0x%x\n", fc
);
2399 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2404 * NdrConformantString:
2406 * What MS calls a ConformantString is, in DCE terminology,
2407 * a Varying-Conformant String.
2409 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2410 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2411 * into unmarshalled string)
2412 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2414 * data: CHARTYPE[maxlen]
2416 * ], where CHARTYPE is the appropriate character type (specified externally)
2420 /***********************************************************************
2421 * NdrConformantStringMarshall [RPCRT4.@]
2423 unsigned char *WINAPI
NdrConformantStringMarshall(MIDL_STUB_MESSAGE
*pStubMsg
,
2424 unsigned char *pszMessage
, PFORMAT_STRING pFormat
)
2426 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg
, pszMessage
, pFormat
);
2428 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2429 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2430 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2433 /* allow compiler to optimise inline function by passing constant into
2434 * these functions */
2435 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2436 array_compute_and_write_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pszMessage
,
2438 array_write_variance_and_marshall(RPC_FC_C_CSTRING
, pStubMsg
, pszMessage
,
2439 pFormat
, TRUE
/* fHasPointers */);
2441 array_compute_and_write_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pszMessage
,
2443 array_write_variance_and_marshall(RPC_FC_C_WSTRING
, pStubMsg
, pszMessage
,
2444 pFormat
, TRUE
/* fHasPointers */);
2450 /***********************************************************************
2451 * NdrConformantStringBufferSize [RPCRT4.@]
2453 void WINAPI
NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2454 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
2456 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2458 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2459 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2460 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2463 /* allow compiler to optimise inline function by passing constant into
2464 * these functions */
2465 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2466 array_compute_and_size_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pMemory
,
2468 array_buffer_size(RPC_FC_C_CSTRING
, pStubMsg
, pMemory
, pFormat
,
2469 TRUE
/* fHasPointers */);
2471 array_compute_and_size_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pMemory
,
2473 array_buffer_size(RPC_FC_C_WSTRING
, pStubMsg
, pMemory
, pFormat
,
2474 TRUE
/* fHasPointers */);
2478 /************************************************************************
2479 * NdrConformantStringMemorySize [RPCRT4.@]
2481 ULONG WINAPI
NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
2482 PFORMAT_STRING pFormat
)
2484 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
2486 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2487 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2488 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2491 /* allow compiler to optimise inline function by passing constant into
2492 * these functions */
2493 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2494 array_read_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
);
2495 array_memory_size(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
,
2496 TRUE
/* fHasPointers */);
2498 array_read_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
);
2499 array_memory_size(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
,
2500 TRUE
/* fHasPointers */);
2503 return pStubMsg
->MemorySize
;
2506 /************************************************************************
2507 * NdrConformantStringUnmarshall [RPCRT4.@]
2509 unsigned char *WINAPI
NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2510 unsigned char** ppMemory
, PFORMAT_STRING pFormat
, unsigned char fMustAlloc
)
2512 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2513 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
2515 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2516 ERR("Unhandled string type: %#x\n", *pFormat
);
2517 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2520 /* allow compiler to optimise inline function by passing constant into
2521 * these functions */
2522 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2523 array_read_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
);
2524 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING
, pStubMsg
, ppMemory
,
2525 pFormat
, fMustAlloc
,
2526 TRUE
/* fUseBufferMemoryServer */,
2527 TRUE
/* fUnmarshall */);
2529 array_read_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
);
2530 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING
, pStubMsg
, ppMemory
,
2531 pFormat
, fMustAlloc
,
2532 TRUE
/* fUseBufferMemoryServer */,
2533 TRUE
/* fUnmarshall */);
2539 /***********************************************************************
2540 * NdrNonConformantStringMarshall [RPCRT4.@]
2542 unsigned char * WINAPI
NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2543 unsigned char *pMemory
,
2544 PFORMAT_STRING pFormat
)
2546 ULONG esize
, size
, maxsize
;
2548 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2550 maxsize
= *(const USHORT
*)&pFormat
[2];
2552 if (*pFormat
== RPC_FC_CSTRING
)
2555 const char *str
= (const char *)pMemory
;
2556 while (i
< maxsize
&& str
[i
]) i
++;
2557 TRACE("string=%s\n", debugstr_an(str
, i
));
2558 pStubMsg
->ActualCount
= i
+ 1;
2561 else if (*pFormat
== RPC_FC_WSTRING
)
2564 const WCHAR
*str
= (const WCHAR
*)pMemory
;
2565 while (i
< maxsize
&& str
[i
]) i
++;
2566 TRACE("string=%s\n", debugstr_wn(str
, i
));
2567 pStubMsg
->ActualCount
= i
+ 1;
2572 ERR("Unhandled string type: %#x\n", *pFormat
);
2573 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2576 pStubMsg
->Offset
= 0;
2577 WriteVariance(pStubMsg
);
2579 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2580 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
2585 /***********************************************************************
2586 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2588 unsigned char * WINAPI
NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2589 unsigned char **ppMemory
,
2590 PFORMAT_STRING pFormat
,
2591 unsigned char fMustAlloc
)
2593 ULONG bufsize
, memsize
, esize
, maxsize
;
2595 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2596 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
2598 maxsize
= *(const USHORT
*)&pFormat
[2];
2600 ReadVariance(pStubMsg
, NULL
, maxsize
);
2601 if (pStubMsg
->Offset
)
2603 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2604 RpcRaiseException(RPC_S_INVALID_BOUND
);
2607 if (*pFormat
== RPC_FC_CSTRING
) esize
= 1;
2608 else if (*pFormat
== RPC_FC_WSTRING
) esize
= 2;
2611 ERR("Unhandled string type: %#x\n", *pFormat
);
2612 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2615 memsize
= esize
* maxsize
;
2616 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2618 validate_string_data(pStubMsg
, bufsize
, esize
);
2620 if (!fMustAlloc
&& !*ppMemory
)
2623 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2625 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
2627 if (*pFormat
== RPC_FC_CSTRING
) {
2628 TRACE("string=%s\n", debugstr_an((char*)*ppMemory
, pStubMsg
->ActualCount
));
2630 else if (*pFormat
== RPC_FC_WSTRING
) {
2631 TRACE("string=%s\n", debugstr_wn((LPWSTR
)*ppMemory
, pStubMsg
->ActualCount
));
2637 /***********************************************************************
2638 * NdrNonConformantStringBufferSize [RPCRT4.@]
2640 void WINAPI
NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2641 unsigned char *pMemory
,
2642 PFORMAT_STRING pFormat
)
2644 ULONG esize
, maxsize
;
2646 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2648 maxsize
= *(const USHORT
*)&pFormat
[2];
2650 SizeVariance(pStubMsg
);
2652 if (*pFormat
== RPC_FC_CSTRING
)
2655 const char *str
= (const char *)pMemory
;
2656 while (i
< maxsize
&& str
[i
]) i
++;
2657 TRACE("string=%s\n", debugstr_an(str
, i
));
2658 pStubMsg
->ActualCount
= i
+ 1;
2661 else if (*pFormat
== RPC_FC_WSTRING
)
2664 const WCHAR
*str
= (const WCHAR
*)pMemory
;
2665 while (i
< maxsize
&& str
[i
]) i
++;
2666 TRACE("string=%s\n", debugstr_wn(str
, i
));
2667 pStubMsg
->ActualCount
= i
+ 1;
2672 ERR("Unhandled string type: %#x\n", *pFormat
);
2673 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2676 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
2679 /***********************************************************************
2680 * NdrNonConformantStringMemorySize [RPCRT4.@]
2682 ULONG WINAPI
NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2683 PFORMAT_STRING pFormat
)
2685 ULONG bufsize
, memsize
, esize
, maxsize
;
2687 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
2689 maxsize
= *(const USHORT
*)&pFormat
[2];
2691 ReadVariance(pStubMsg
, NULL
, maxsize
);
2693 if (pStubMsg
->Offset
)
2695 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2696 RpcRaiseException(RPC_S_INVALID_BOUND
);
2699 if (*pFormat
== RPC_FC_CSTRING
) esize
= 1;
2700 else if (*pFormat
== RPC_FC_WSTRING
) esize
= 2;
2703 ERR("Unhandled string type: %#x\n", *pFormat
);
2704 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2707 memsize
= esize
* maxsize
;
2708 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2710 validate_string_data(pStubMsg
, bufsize
, esize
);
2712 safe_buffer_increment(pStubMsg
, bufsize
);
2713 pStubMsg
->MemorySize
+= memsize
;
2715 return pStubMsg
->MemorySize
;
2720 #include "pshpack1.h"
2724 unsigned char flags_type
; /* flags in upper nibble, type in lower nibble */
2728 #include "poppack.h"
2730 static ULONG
EmbeddedComplexSize(MIDL_STUB_MESSAGE
*pStubMsg
,
2731 PFORMAT_STRING pFormat
)
2735 case RPC_FC_PSTRUCT
:
2736 case RPC_FC_CSTRUCT
:
2737 case RPC_FC_BOGUS_STRUCT
:
2738 case RPC_FC_SMFARRAY
:
2739 case RPC_FC_SMVARRAY
:
2740 case RPC_FC_CSTRING
:
2741 return *(const WORD
*)&pFormat
[2];
2742 case RPC_FC_USER_MARSHAL
:
2743 return *(const WORD
*)&pFormat
[4];
2744 case RPC_FC_RANGE
: {
2745 switch (((const NDR_RANGE
*)pFormat
)->flags_type
& 0xf) {
2750 return sizeof(UCHAR
);
2754 return sizeof(USHORT
);
2758 case RPC_FC_INT3264
:
2759 case RPC_FC_UINT3264
:
2760 return sizeof(ULONG
);
2762 return sizeof(float);
2764 return sizeof(double);
2766 return sizeof(ULONGLONG
);
2768 return sizeof(UINT
);
2770 ERR("unknown type 0x%x\n", ((const NDR_RANGE
*)pFormat
)->flags_type
& 0xf);
2771 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2774 case RPC_FC_NON_ENCAPSULATED_UNION
:
2776 if (pStubMsg
->fHasNewCorrDesc
)
2781 pFormat
+= *(const SHORT
*)pFormat
;
2782 return *(const SHORT
*)pFormat
;
2784 return sizeof(void *);
2785 case RPC_FC_WSTRING
:
2786 return *(const WORD
*)&pFormat
[2] * 2;
2788 FIXME("unhandled embedded type %02x\n", *pFormat
);
2794 static ULONG
EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2795 PFORMAT_STRING pFormat
)
2797 NDR_MEMORYSIZE m
= NdrMemorySizer
[*pFormat
& NDR_TABLE_MASK
];
2801 FIXME("no memorysizer for data type=%02x\n", *pFormat
);
2805 return m(pStubMsg
, pFormat
);
2809 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2810 unsigned char *pMemory
,
2811 PFORMAT_STRING pFormat
,
2812 PFORMAT_STRING pPointer
)
2814 PFORMAT_STRING desc
;
2818 while (*pFormat
!= RPC_FC_END
) {
2824 TRACE("byte=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2825 safe_copy_to_buffer(pStubMsg
, pMemory
, 1);
2831 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2832 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
2837 USHORT val
= *(DWORD
*)pMemory
;
2838 TRACE("enum16=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2839 if (32767 < *(DWORD
*)pMemory
)
2840 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
2841 safe_copy_to_buffer(pStubMsg
, &val
, 2);
2848 TRACE("long=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2849 safe_copy_to_buffer(pStubMsg
, pMemory
, 4);
2852 case RPC_FC_INT3264
:
2853 case RPC_FC_UINT3264
:
2855 UINT val
= *(UINT_PTR
*)pMemory
;
2856 TRACE("int3264=%ld <= %p\n", *(UINT_PTR
*)pMemory
, pMemory
);
2857 safe_copy_to_buffer(pStubMsg
, &val
, sizeof(UINT
));
2858 pMemory
+= sizeof(UINT_PTR
);
2862 TRACE("float=%f <= %p\n", *(float*)pMemory
, pMemory
);
2863 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
2864 pMemory
+= sizeof(float);
2867 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2868 safe_copy_to_buffer(pStubMsg
, pMemory
, 8);
2872 TRACE("double=%f <= %p\n", *(double*)pMemory
, pMemory
);
2873 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
2874 pMemory
+= sizeof(double);
2880 case RPC_FC_POINTER
:
2882 unsigned char *saved_buffer
;
2883 int pointer_buffer_mark_set
= 0;
2884 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
2885 TRACE("pStubMsg->Buffer before %p\n", pStubMsg
->Buffer
);
2886 if (*pFormat
!= RPC_FC_POINTER
)
2888 if (*pPointer
!= RPC_FC_RP
)
2889 align_pointer_clear(&pStubMsg
->Buffer
, 4);
2890 saved_buffer
= pStubMsg
->Buffer
;
2891 if (pStubMsg
->PointerBufferMark
)
2893 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2894 pStubMsg
->PointerBufferMark
= NULL
;
2895 pointer_buffer_mark_set
= 1;
2897 else if (*pPointer
!= RPC_FC_RP
)
2898 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2899 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char**)pMemory
, pPointer
);
2900 if (pointer_buffer_mark_set
)
2902 STD_OVERFLOW_CHECK(pStubMsg
);
2903 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2904 pStubMsg
->Buffer
= saved_buffer
;
2905 if (*pPointer
!= RPC_FC_RP
)
2906 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2908 TRACE("pStubMsg->Buffer after %p\n", pStubMsg
->Buffer
);
2909 if (*pFormat
== RPC_FC_POINTER
)
2913 pMemory
+= sizeof(void *);
2916 case RPC_FC_ALIGNM2
:
2917 align_pointer(&pMemory
, 2);
2919 case RPC_FC_ALIGNM4
:
2920 align_pointer(&pMemory
, 4);
2922 case RPC_FC_ALIGNM8
:
2923 align_pointer(&pMemory
, 8);
2925 case RPC_FC_STRUCTPAD1
:
2926 case RPC_FC_STRUCTPAD2
:
2927 case RPC_FC_STRUCTPAD3
:
2928 case RPC_FC_STRUCTPAD4
:
2929 case RPC_FC_STRUCTPAD5
:
2930 case RPC_FC_STRUCTPAD6
:
2931 case RPC_FC_STRUCTPAD7
:
2932 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2934 case RPC_FC_EMBEDDED_COMPLEX
:
2935 pMemory
+= pFormat
[1];
2937 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2938 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2939 TRACE("embedded complex (size=%d) <= %p\n", size
, pMemory
);
2940 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
2943 /* for some reason interface pointers aren't generated as
2944 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2945 * they still need the derefencing treatment that pointers are
2947 if (*desc
== RPC_FC_IP
)
2948 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2950 m(pStubMsg
, pMemory
, desc
);
2952 else FIXME("no marshaller for embedded type %02x\n", *desc
);
2959 FIXME("unhandled format 0x%02x\n", *pFormat
);
2967 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2968 unsigned char *pMemory
,
2969 PFORMAT_STRING pFormat
,
2970 PFORMAT_STRING pPointer
,
2971 unsigned char fMustAlloc
)
2973 PFORMAT_STRING desc
;
2977 while (*pFormat
!= RPC_FC_END
) {
2983 safe_copy_from_buffer(pStubMsg
, pMemory
, 1);
2984 TRACE("byte=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2990 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
2991 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2997 safe_copy_from_buffer(pStubMsg
, &val
, 2);
2998 *(DWORD
*)pMemory
= val
;
2999 TRACE("enum16=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
3000 if (32767 < *(DWORD
*)pMemory
)
3001 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
3008 safe_copy_from_buffer(pStubMsg
, pMemory
, 4);
3009 TRACE("long=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
3012 case RPC_FC_INT3264
:
3015 safe_copy_from_buffer(pStubMsg
, &val
, 4);
3016 *(INT_PTR
*)pMemory
= val
;
3017 TRACE("int3264=%ld => %p\n", *(INT_PTR
*)pMemory
, pMemory
);
3018 pMemory
+= sizeof(INT_PTR
);
3021 case RPC_FC_UINT3264
:
3024 safe_copy_from_buffer(pStubMsg
, &val
, 4);
3025 *(UINT_PTR
*)pMemory
= val
;
3026 TRACE("uint3264=%ld => %p\n", *(UINT_PTR
*)pMemory
, pMemory
);
3027 pMemory
+= sizeof(UINT_PTR
);
3031 safe_copy_from_buffer(pStubMsg
, pMemory
, sizeof(float));
3032 TRACE("float=%f => %p\n", *(float*)pMemory
, pMemory
);
3033 pMemory
+= sizeof(float);
3036 safe_copy_from_buffer(pStubMsg
, pMemory
, 8);
3037 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
3041 safe_copy_from_buffer(pStubMsg
, pMemory
, sizeof(double));
3042 TRACE("double=%f => %p\n", *(double*)pMemory
, pMemory
);
3043 pMemory
+= sizeof(double);
3049 case RPC_FC_POINTER
:
3051 unsigned char *saved_buffer
;
3052 int pointer_buffer_mark_set
= 0;
3053 TRACE("pointer => %p\n", pMemory
);
3054 if (*pFormat
!= RPC_FC_POINTER
)
3056 if (*pPointer
!= RPC_FC_RP
)
3057 align_pointer(&pStubMsg
->Buffer
, 4);
3058 saved_buffer
= pStubMsg
->Buffer
;
3059 if (pStubMsg
->PointerBufferMark
)
3061 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3062 pStubMsg
->PointerBufferMark
= NULL
;
3063 pointer_buffer_mark_set
= 1;
3065 else if (*pPointer
!= RPC_FC_RP
)
3066 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3068 PointerUnmarshall(pStubMsg
, saved_buffer
, (unsigned char**)pMemory
, *(unsigned char**)pMemory
, pPointer
, fMustAlloc
);
3069 if (pointer_buffer_mark_set
)
3071 STD_OVERFLOW_CHECK(pStubMsg
);
3072 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3073 pStubMsg
->Buffer
= saved_buffer
;
3074 if (*pPointer
!= RPC_FC_RP
)
3075 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3077 if (*pFormat
== RPC_FC_POINTER
)
3081 pMemory
+= sizeof(void *);
3084 case RPC_FC_ALIGNM2
:
3085 align_pointer_clear(&pMemory
, 2);
3087 case RPC_FC_ALIGNM4
:
3088 align_pointer_clear(&pMemory
, 4);
3090 case RPC_FC_ALIGNM8
:
3091 align_pointer_clear(&pMemory
, 8);
3093 case RPC_FC_STRUCTPAD1
:
3094 case RPC_FC_STRUCTPAD2
:
3095 case RPC_FC_STRUCTPAD3
:
3096 case RPC_FC_STRUCTPAD4
:
3097 case RPC_FC_STRUCTPAD5
:
3098 case RPC_FC_STRUCTPAD6
:
3099 case RPC_FC_STRUCTPAD7
:
3100 memset(pMemory
, 0, *pFormat
- RPC_FC_STRUCTPAD1
+ 1);
3101 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3103 case RPC_FC_EMBEDDED_COMPLEX
:
3104 pMemory
+= pFormat
[1];
3106 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3107 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3108 TRACE("embedded complex (size=%d) => %p\n", size
, pMemory
);
3110 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
3111 * since the type is part of the memory block that is encompassed by
3112 * the whole complex type. Memory is forced to allocate when pointers
3113 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
3114 * clearing the memory we pass in to the unmarshaller */
3115 memset(pMemory
, 0, size
);
3116 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
3119 /* for some reason interface pointers aren't generated as
3120 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3121 * they still need the derefencing treatment that pointers are
3123 if (*desc
== RPC_FC_IP
)
3124 m(pStubMsg
, (unsigned char **)pMemory
, desc
, FALSE
);
3126 m(pStubMsg
, &pMemory
, desc
, FALSE
);
3128 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
3135 FIXME("unhandled format %d\n", *pFormat
);
3143 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3144 unsigned char *pMemory
,
3145 PFORMAT_STRING pFormat
,
3146 PFORMAT_STRING pPointer
)
3148 PFORMAT_STRING desc
;
3152 while (*pFormat
!= RPC_FC_END
) {
3158 safe_buffer_length_increment(pStubMsg
, 1);
3164 safe_buffer_length_increment(pStubMsg
, 2);
3168 safe_buffer_length_increment(pStubMsg
, 2);
3175 safe_buffer_length_increment(pStubMsg
, 4);
3178 case RPC_FC_INT3264
:
3179 case RPC_FC_UINT3264
:
3180 safe_buffer_length_increment(pStubMsg
, 4);
3181 pMemory
+= sizeof(INT_PTR
);
3185 safe_buffer_length_increment(pStubMsg
, 8);
3192 case RPC_FC_POINTER
:
3193 if (*pFormat
!= RPC_FC_POINTER
)
3195 if (!pStubMsg
->IgnoreEmbeddedPointers
)
3197 int saved_buffer_length
= pStubMsg
->BufferLength
;
3198 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3199 pStubMsg
->PointerLength
= 0;
3200 if(!pStubMsg
->BufferLength
)
3201 ERR("BufferLength == 0??\n");
3202 PointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
3203 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3204 pStubMsg
->BufferLength
= saved_buffer_length
;
3206 if (*pPointer
!= RPC_FC_RP
)
3208 align_length(&pStubMsg
->BufferLength
, 4);
3209 safe_buffer_length_increment(pStubMsg
, 4);
3211 if (*pFormat
== RPC_FC_POINTER
)
3215 pMemory
+= sizeof(void*);
3217 case RPC_FC_ALIGNM2
:
3218 align_pointer(&pMemory
, 2);
3220 case RPC_FC_ALIGNM4
:
3221 align_pointer(&pMemory
, 4);
3223 case RPC_FC_ALIGNM8
:
3224 align_pointer(&pMemory
, 8);
3226 case RPC_FC_STRUCTPAD1
:
3227 case RPC_FC_STRUCTPAD2
:
3228 case RPC_FC_STRUCTPAD3
:
3229 case RPC_FC_STRUCTPAD4
:
3230 case RPC_FC_STRUCTPAD5
:
3231 case RPC_FC_STRUCTPAD6
:
3232 case RPC_FC_STRUCTPAD7
:
3233 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3235 case RPC_FC_EMBEDDED_COMPLEX
:
3236 pMemory
+= pFormat
[1];
3238 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3239 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3240 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
3243 /* for some reason interface pointers aren't generated as
3244 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3245 * they still need the derefencing treatment that pointers are
3247 if (*desc
== RPC_FC_IP
)
3248 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
3250 m(pStubMsg
, pMemory
, desc
);
3252 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
3259 FIXME("unhandled format 0x%02x\n", *pFormat
);
3267 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
3268 unsigned char *pMemory
,
3269 PFORMAT_STRING pFormat
,
3270 PFORMAT_STRING pPointer
)
3272 PFORMAT_STRING desc
;
3276 while (*pFormat
!= RPC_FC_END
) {
3296 case RPC_FC_INT3264
:
3297 case RPC_FC_UINT3264
:
3298 pMemory
+= sizeof(INT_PTR
);
3308 case RPC_FC_POINTER
:
3309 if (*pFormat
!= RPC_FC_POINTER
)
3311 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
3312 if (*pFormat
== RPC_FC_POINTER
)
3316 pMemory
+= sizeof(void *);
3318 case RPC_FC_ALIGNM2
:
3319 align_pointer(&pMemory
, 2);
3321 case RPC_FC_ALIGNM4
:
3322 align_pointer(&pMemory
, 4);
3324 case RPC_FC_ALIGNM8
:
3325 align_pointer(&pMemory
, 8);
3327 case RPC_FC_STRUCTPAD1
:
3328 case RPC_FC_STRUCTPAD2
:
3329 case RPC_FC_STRUCTPAD3
:
3330 case RPC_FC_STRUCTPAD4
:
3331 case RPC_FC_STRUCTPAD5
:
3332 case RPC_FC_STRUCTPAD6
:
3333 case RPC_FC_STRUCTPAD7
:
3334 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3336 case RPC_FC_EMBEDDED_COMPLEX
:
3337 pMemory
+= pFormat
[1];
3339 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3340 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3341 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
3344 /* for some reason interface pointers aren't generated as
3345 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3346 * they still need the derefencing treatment that pointers are
3348 if (*desc
== RPC_FC_IP
)
3349 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
3351 m(pStubMsg
, pMemory
, desc
);
3359 FIXME("unhandled format 0x%02x\n", *pFormat
);
3367 static ULONG
ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3368 PFORMAT_STRING pFormat
,
3369 PFORMAT_STRING pPointer
)
3371 PFORMAT_STRING desc
;
3374 while (*pFormat
!= RPC_FC_END
) {
3381 safe_buffer_increment(pStubMsg
, 1);
3387 safe_buffer_increment(pStubMsg
, 2);
3391 safe_buffer_increment(pStubMsg
, 2);
3398 safe_buffer_increment(pStubMsg
, 4);
3400 case RPC_FC_INT3264
:
3401 case RPC_FC_UINT3264
:
3402 size
+= sizeof(INT_PTR
);
3403 safe_buffer_increment(pStubMsg
, 4);
3408 safe_buffer_increment(pStubMsg
, 8);
3414 case RPC_FC_POINTER
:
3416 unsigned char *saved_buffer
;
3417 int pointer_buffer_mark_set
= 0;
3418 if (*pFormat
!= RPC_FC_POINTER
)
3420 if (*pPointer
!= RPC_FC_RP
)
3421 align_pointer(&pStubMsg
->Buffer
, 4);
3422 saved_buffer
= pStubMsg
->Buffer
;
3423 if (pStubMsg
->PointerBufferMark
)
3425 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3426 pStubMsg
->PointerBufferMark
= NULL
;
3427 pointer_buffer_mark_set
= 1;
3429 else if (*pPointer
!= RPC_FC_RP
)
3430 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3432 if (!pStubMsg
->IgnoreEmbeddedPointers
)
3433 PointerMemorySize(pStubMsg
, saved_buffer
, pPointer
);
3434 if (pointer_buffer_mark_set
)
3436 STD_OVERFLOW_CHECK(pStubMsg
);
3437 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3438 pStubMsg
->Buffer
= saved_buffer
;
3439 if (*pPointer
!= RPC_FC_RP
)
3440 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3442 if (*pFormat
== RPC_FC_POINTER
)
3446 size
+= sizeof(void *);
3449 case RPC_FC_ALIGNM2
:
3450 align_length(&size
, 2);
3452 case RPC_FC_ALIGNM4
:
3453 align_length(&size
, 4);
3455 case RPC_FC_ALIGNM8
:
3456 align_length(&size
, 8);
3458 case RPC_FC_STRUCTPAD1
:
3459 case RPC_FC_STRUCTPAD2
:
3460 case RPC_FC_STRUCTPAD3
:
3461 case RPC_FC_STRUCTPAD4
:
3462 case RPC_FC_STRUCTPAD5
:
3463 case RPC_FC_STRUCTPAD6
:
3464 case RPC_FC_STRUCTPAD7
:
3465 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3467 case RPC_FC_EMBEDDED_COMPLEX
:
3470 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3471 size
+= EmbeddedComplexMemorySize(pStubMsg
, desc
);
3477 FIXME("unhandled format 0x%02x\n", *pFormat
);
3485 ULONG
ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
3487 PFORMAT_STRING desc
;
3490 while (*pFormat
!= RPC_FC_END
) {
3510 case RPC_FC_INT3264
:
3511 case RPC_FC_UINT3264
:
3512 size
+= sizeof(INT_PTR
);
3522 case RPC_FC_POINTER
:
3523 size
+= sizeof(void *);
3524 if (*pFormat
!= RPC_FC_POINTER
)
3527 case RPC_FC_ALIGNM2
:
3528 align_length(&size
, 2);
3530 case RPC_FC_ALIGNM4
:
3531 align_length(&size
, 4);
3533 case RPC_FC_ALIGNM8
:
3534 align_length(&size
, 8);
3536 case RPC_FC_STRUCTPAD1
:
3537 case RPC_FC_STRUCTPAD2
:
3538 case RPC_FC_STRUCTPAD3
:
3539 case RPC_FC_STRUCTPAD4
:
3540 case RPC_FC_STRUCTPAD5
:
3541 case RPC_FC_STRUCTPAD6
:
3542 case RPC_FC_STRUCTPAD7
:
3543 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3545 case RPC_FC_EMBEDDED_COMPLEX
:
3548 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3549 size
+= EmbeddedComplexSize(pStubMsg
, desc
);
3555 FIXME("unhandled format 0x%02x\n", *pFormat
);
3563 /***********************************************************************
3564 * NdrComplexStructMarshall [RPCRT4.@]
3566 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3567 unsigned char *pMemory
,
3568 PFORMAT_STRING pFormat
)
3570 PFORMAT_STRING conf_array
= NULL
;
3571 PFORMAT_STRING pointer_desc
= NULL
;
3572 unsigned char *OldMemory
= pStubMsg
->Memory
;
3573 int pointer_buffer_mark_set
= 0;
3575 ULONG max_count
= 0;
3578 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3580 if (!pStubMsg
->PointerBufferMark
)
3582 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3583 /* save buffer length */
3584 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
3586 /* get the buffer pointer after complex array data, but before
3588 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
;
3589 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3590 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
3591 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3593 /* save it for use by embedded pointer code later */
3594 pStubMsg
->PointerBufferMark
= (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
;
3595 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->PointerBufferMark
- pStubMsg
->Buffer
));
3596 pointer_buffer_mark_set
= 1;
3598 /* restore the original buffer length */
3599 pStubMsg
->BufferLength
= saved_buffer_length
;
3602 align_pointer_clear(&pStubMsg
->Buffer
, pFormat
[1] + 1);
3605 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3607 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3610 pStubMsg
->Memory
= pMemory
;
3614 ULONG struct_size
= ComplexStructSize(pStubMsg
, pFormat
);
3615 array_compute_and_write_conformance(conf_array
[0], pStubMsg
,
3616 pMemory
+ struct_size
, conf_array
);
3617 /* these could be changed in ComplexMarshall so save them for later */
3618 max_count
= pStubMsg
->MaxCount
;
3619 count
= pStubMsg
->ActualCount
;
3620 offset
= pStubMsg
->Offset
;
3623 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3627 pStubMsg
->MaxCount
= max_count
;
3628 pStubMsg
->ActualCount
= count
;
3629 pStubMsg
->Offset
= offset
;
3630 array_write_variance_and_marshall(conf_array
[0], pStubMsg
, pMemory
,
3631 conf_array
, TRUE
/* fHasPointers */);
3634 pStubMsg
->Memory
= OldMemory
;
3636 if (pointer_buffer_mark_set
)
3638 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3639 pStubMsg
->PointerBufferMark
= NULL
;
3642 STD_OVERFLOW_CHECK(pStubMsg
);
3647 /***********************************************************************
3648 * NdrComplexStructUnmarshall [RPCRT4.@]
3650 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3651 unsigned char **ppMemory
,
3652 PFORMAT_STRING pFormat
,
3653 unsigned char fMustAlloc
)
3655 unsigned size
= *(const WORD
*)(pFormat
+2);
3656 PFORMAT_STRING conf_array
= NULL
;
3657 PFORMAT_STRING pointer_desc
= NULL
;
3658 unsigned char *pMemory
;
3659 int pointer_buffer_mark_set
= 0;
3661 ULONG max_count
= 0;
3663 ULONG array_size
= 0;
3665 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3667 if (!pStubMsg
->PointerBufferMark
)
3669 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3670 /* save buffer pointer */
3671 unsigned char *saved_buffer
= pStubMsg
->Buffer
;
3673 /* get the buffer pointer after complex array data, but before
3675 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3676 NdrComplexStructMemorySize(pStubMsg
, pFormat
);
3677 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3679 /* save it for use by embedded pointer code later */
3680 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3681 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->PointerBufferMark
- saved_buffer
));
3682 pointer_buffer_mark_set
= 1;
3684 /* restore the original buffer */
3685 pStubMsg
->Buffer
= saved_buffer
;
3688 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
3691 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3693 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3698 array_size
= array_read_conformance(conf_array
[0], pStubMsg
, conf_array
);
3701 /* these could be changed in ComplexMarshall so save them for later */
3702 max_count
= pStubMsg
->MaxCount
;
3703 count
= pStubMsg
->ActualCount
;
3704 offset
= pStubMsg
->Offset
;
3707 if (!fMustAlloc
&& !*ppMemory
)
3710 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3712 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
, fMustAlloc
);
3716 pStubMsg
->MaxCount
= max_count
;
3717 pStubMsg
->ActualCount
= count
;
3718 pStubMsg
->Offset
= offset
;
3720 memset(pMemory
, 0, array_size
);
3721 array_read_variance_and_unmarshall(conf_array
[0], pStubMsg
, &pMemory
,
3723 FALSE
/* fUseBufferMemoryServer */,
3724 TRUE
/* fUnmarshall */);
3727 if (pointer_buffer_mark_set
)
3729 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3730 pStubMsg
->PointerBufferMark
= NULL
;
3736 /***********************************************************************
3737 * NdrComplexStructBufferSize [RPCRT4.@]
3739 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3740 unsigned char *pMemory
,
3741 PFORMAT_STRING pFormat
)
3743 PFORMAT_STRING conf_array
= NULL
;
3744 PFORMAT_STRING pointer_desc
= NULL
;
3745 unsigned char *OldMemory
= pStubMsg
->Memory
;
3746 int pointer_length_set
= 0;
3748 ULONG max_count
= 0;
3751 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3753 align_length(&pStubMsg
->BufferLength
, pFormat
[1] + 1);
3755 if(!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
3757 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3758 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
3760 /* get the buffer length after complex struct data, but before
3762 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3763 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
3764 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3766 /* save it for use by embedded pointer code later */
3767 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3768 pointer_length_set
= 1;
3769 TRACE("difference = 0x%x\n", pStubMsg
->PointerLength
- saved_buffer_length
);
3771 /* restore the original buffer length */
3772 pStubMsg
->BufferLength
= saved_buffer_length
;
3776 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3778 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3781 pStubMsg
->Memory
= pMemory
;
3785 ULONG struct_size
= ComplexStructSize(pStubMsg
, pFormat
);
3786 array_compute_and_size_conformance(conf_array
[0], pStubMsg
, pMemory
+ struct_size
,
3789 /* these could be changed in ComplexMarshall so save them for later */
3790 max_count
= pStubMsg
->MaxCount
;
3791 count
= pStubMsg
->ActualCount
;
3792 offset
= pStubMsg
->Offset
;
3795 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3799 pStubMsg
->MaxCount
= max_count
;
3800 pStubMsg
->ActualCount
= count
;
3801 pStubMsg
->Offset
= offset
;
3802 array_buffer_size(conf_array
[0], pStubMsg
, pMemory
, conf_array
,
3803 TRUE
/* fHasPointers */);
3806 pStubMsg
->Memory
= OldMemory
;
3808 if(pointer_length_set
)
3810 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3811 pStubMsg
->PointerLength
= 0;
3816 /***********************************************************************
3817 * NdrComplexStructMemorySize [RPCRT4.@]
3819 ULONG WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3820 PFORMAT_STRING pFormat
)
3822 unsigned size
= *(const WORD
*)(pFormat
+2);
3823 PFORMAT_STRING conf_array
= NULL
;
3824 PFORMAT_STRING pointer_desc
= NULL
;
3826 ULONG max_count
= 0;
3829 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3831 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
3834 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3836 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3841 array_read_conformance(conf_array
[0], pStubMsg
, conf_array
);
3843 /* these could be changed in ComplexStructMemorySize so save them for
3845 max_count
= pStubMsg
->MaxCount
;
3846 count
= pStubMsg
->ActualCount
;
3847 offset
= pStubMsg
->Offset
;
3850 ComplexStructMemorySize(pStubMsg
, pFormat
, pointer_desc
);
3854 pStubMsg
->MaxCount
= max_count
;
3855 pStubMsg
->ActualCount
= count
;
3856 pStubMsg
->Offset
= offset
;
3857 array_memory_size(conf_array
[0], pStubMsg
, conf_array
,
3858 TRUE
/* fHasPointers */);
3864 /***********************************************************************
3865 * NdrComplexStructFree [RPCRT4.@]
3867 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3868 unsigned char *pMemory
,
3869 PFORMAT_STRING pFormat
)
3871 PFORMAT_STRING conf_array
= NULL
;
3872 PFORMAT_STRING pointer_desc
= NULL
;
3873 unsigned char *OldMemory
= pStubMsg
->Memory
;
3875 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3878 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3880 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3883 pStubMsg
->Memory
= pMemory
;
3885 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3888 array_free(conf_array
[0], pStubMsg
, pMemory
, conf_array
,
3889 TRUE
/* fHasPointers */);
3891 pStubMsg
->Memory
= OldMemory
;
3894 /***********************************************************************
3895 * NdrConformantArrayMarshall [RPCRT4.@]
3897 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3898 unsigned char *pMemory
,
3899 PFORMAT_STRING pFormat
)
3901 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3902 if (pFormat
[0] != RPC_FC_CARRAY
)
3904 ERR("invalid format = 0x%x\n", pFormat
[0]);
3905 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3908 array_compute_and_write_conformance(RPC_FC_CARRAY
, pStubMsg
, pMemory
,
3910 array_write_variance_and_marshall(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3911 TRUE
/* fHasPointers */);
3916 /***********************************************************************
3917 * NdrConformantArrayUnmarshall [RPCRT4.@]
3919 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3920 unsigned char **ppMemory
,
3921 PFORMAT_STRING pFormat
,
3922 unsigned char fMustAlloc
)
3924 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3925 if (pFormat
[0] != RPC_FC_CARRAY
)
3927 ERR("invalid format = 0x%x\n", pFormat
[0]);
3928 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3931 array_read_conformance(RPC_FC_CARRAY
, pStubMsg
, pFormat
);
3932 array_read_variance_and_unmarshall(RPC_FC_CARRAY
, pStubMsg
, ppMemory
, pFormat
,
3934 TRUE
/* fUseBufferMemoryServer */,
3935 TRUE
/* fUnmarshall */);
3940 /***********************************************************************
3941 * NdrConformantArrayBufferSize [RPCRT4.@]
3943 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3944 unsigned char *pMemory
,
3945 PFORMAT_STRING pFormat
)
3947 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3948 if (pFormat
[0] != RPC_FC_CARRAY
)
3950 ERR("invalid format = 0x%x\n", pFormat
[0]);
3951 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3954 array_compute_and_size_conformance(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
);
3955 array_buffer_size(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3956 TRUE
/* fHasPointers */);
3959 /***********************************************************************
3960 * NdrConformantArrayMemorySize [RPCRT4.@]
3962 ULONG WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3963 PFORMAT_STRING pFormat
)
3965 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3966 if (pFormat
[0] != RPC_FC_CARRAY
)
3968 ERR("invalid format = 0x%x\n", pFormat
[0]);
3969 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3972 array_read_conformance(RPC_FC_CARRAY
, pStubMsg
, pFormat
);
3973 array_memory_size(RPC_FC_CARRAY
, pStubMsg
, pFormat
, TRUE
/* fHasPointers */);
3975 return pStubMsg
->MemorySize
;
3978 /***********************************************************************
3979 * NdrConformantArrayFree [RPCRT4.@]
3981 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3982 unsigned char *pMemory
,
3983 PFORMAT_STRING pFormat
)
3985 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3986 if (pFormat
[0] != RPC_FC_CARRAY
)
3988 ERR("invalid format = 0x%x\n", pFormat
[0]);
3989 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3992 array_free(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3993 TRUE
/* fHasPointers */);
3997 /***********************************************************************
3998 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
4000 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
4001 unsigned char* pMemory
,
4002 PFORMAT_STRING pFormat
)
4004 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4006 if (pFormat
[0] != RPC_FC_CVARRAY
)
4008 ERR("invalid format type %x\n", pFormat
[0]);
4009 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4013 array_compute_and_write_conformance(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
4015 array_write_variance_and_marshall(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
4016 pFormat
, TRUE
/* fHasPointers */);
4022 /***********************************************************************
4023 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
4025 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
4026 unsigned char** ppMemory
,
4027 PFORMAT_STRING pFormat
,
4028 unsigned char fMustAlloc
)
4030 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4032 if (pFormat
[0] != RPC_FC_CVARRAY
)
4034 ERR("invalid format type %x\n", pFormat
[0]);
4035 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4039 array_read_conformance(RPC_FC_CVARRAY
, pStubMsg
, pFormat
);
4040 array_read_variance_and_unmarshall(RPC_FC_CVARRAY
, pStubMsg
, ppMemory
,
4041 pFormat
, fMustAlloc
,
4042 TRUE
/* fUseBufferMemoryServer */,
4043 TRUE
/* fUnmarshall */);
4049 /***********************************************************************
4050 * NdrConformantVaryingArrayFree [RPCRT4.@]
4052 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
4053 unsigned char* pMemory
,
4054 PFORMAT_STRING pFormat
)
4056 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4058 if (pFormat
[0] != RPC_FC_CVARRAY
)
4060 ERR("invalid format type %x\n", pFormat
[0]);
4061 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4065 array_free(RPC_FC_CVARRAY
, pStubMsg
, pMemory
, pFormat
,
4066 TRUE
/* fHasPointers */);
4070 /***********************************************************************
4071 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
4073 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
4074 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
4076 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4078 if (pFormat
[0] != RPC_FC_CVARRAY
)
4080 ERR("invalid format type %x\n", pFormat
[0]);
4081 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4085 array_compute_and_size_conformance(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
4087 array_buffer_size(RPC_FC_CVARRAY
, pStubMsg
, pMemory
, pFormat
,
4088 TRUE
/* fHasPointers */);
4092 /***********************************************************************
4093 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
4095 ULONG WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
4096 PFORMAT_STRING pFormat
)
4098 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4100 if (pFormat
[0] != RPC_FC_CVARRAY
)
4102 ERR("invalid format type %x\n", pFormat
[0]);
4103 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4104 return pStubMsg
->MemorySize
;
4107 array_read_conformance(RPC_FC_CVARRAY
, pStubMsg
, pFormat
);
4108 array_memory_size(RPC_FC_CVARRAY
, pStubMsg
, pFormat
,
4109 TRUE
/* fHasPointers */);
4111 return pStubMsg
->MemorySize
;
4115 /***********************************************************************
4116 * NdrComplexArrayMarshall [RPCRT4.@]
4118 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4119 unsigned char *pMemory
,
4120 PFORMAT_STRING pFormat
)
4122 int pointer_buffer_mark_set
= 0;
4124 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4126 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4128 ERR("invalid format type %x\n", pFormat
[0]);
4129 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4133 if (!pStubMsg
->PointerBufferMark
)
4135 /* save buffer fields that may be changed by buffer sizer functions
4136 * and that may be needed later on */
4137 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
4138 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
4139 ULONG_PTR saved_max_count
= pStubMsg
->MaxCount
;
4140 ULONG saved_offset
= pStubMsg
->Offset
;
4141 ULONG saved_actual_count
= pStubMsg
->ActualCount
;
4143 /* get the buffer pointer after complex array data, but before
4145 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
;
4146 pStubMsg
->IgnoreEmbeddedPointers
= 1;
4147 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
4148 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
4150 /* save it for use by embedded pointer code later */
4151 pStubMsg
->PointerBufferMark
= (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
;
4152 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
));
4153 pointer_buffer_mark_set
= 1;
4155 /* restore fields */
4156 pStubMsg
->ActualCount
= saved_actual_count
;
4157 pStubMsg
->Offset
= saved_offset
;
4158 pStubMsg
->MaxCount
= saved_max_count
;
4159 pStubMsg
->BufferLength
= saved_buffer_length
;
4162 array_compute_and_write_conformance(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pMemory
, pFormat
);
4163 array_write_variance_and_marshall(RPC_FC_BOGUS_ARRAY
, pStubMsg
,
4164 pMemory
, pFormat
, TRUE
/* fHasPointers */);
4166 STD_OVERFLOW_CHECK(pStubMsg
);
4168 if (pointer_buffer_mark_set
)
4170 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4171 pStubMsg
->PointerBufferMark
= NULL
;
4177 /***********************************************************************
4178 * NdrComplexArrayUnmarshall [RPCRT4.@]
4180 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4181 unsigned char **ppMemory
,
4182 PFORMAT_STRING pFormat
,
4183 unsigned char fMustAlloc
)
4185 unsigned char *saved_buffer
;
4186 int pointer_buffer_mark_set
= 0;
4187 int saved_ignore_embedded
;
4189 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4191 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4193 ERR("invalid format type %x\n", pFormat
[0]);
4194 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4198 saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
4199 /* save buffer pointer */
4200 saved_buffer
= pStubMsg
->Buffer
;
4201 /* get the buffer pointer after complex array data, but before
4203 pStubMsg
->IgnoreEmbeddedPointers
= 1;
4204 pStubMsg
->MemorySize
= 0;
4205 NdrComplexArrayMemorySize(pStubMsg
, pFormat
);
4206 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
4208 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->Buffer
- saved_buffer
));
4209 if (!pStubMsg
->PointerBufferMark
)
4211 /* save it for use by embedded pointer code later */
4212 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4213 pointer_buffer_mark_set
= 1;
4215 /* restore the original buffer */
4216 pStubMsg
->Buffer
= saved_buffer
;
4218 array_read_conformance(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pFormat
);
4219 array_read_variance_and_unmarshall(RPC_FC_BOGUS_ARRAY
, pStubMsg
, ppMemory
, pFormat
, fMustAlloc
,
4220 TRUE
/* fUseBufferMemoryServer */, TRUE
/* fUnmarshall */);
4222 if (pointer_buffer_mark_set
)
4224 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4225 pStubMsg
->PointerBufferMark
= NULL
;
4231 /***********************************************************************
4232 * NdrComplexArrayBufferSize [RPCRT4.@]
4234 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4235 unsigned char *pMemory
,
4236 PFORMAT_STRING pFormat
)
4238 int pointer_length_set
= 0;
4240 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4242 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4244 ERR("invalid format type %x\n", pFormat
[0]);
4245 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4249 if (!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
4251 /* save buffer fields that may be changed by buffer sizer functions
4252 * and that may be needed later on */
4253 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
4254 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
4255 ULONG_PTR saved_max_count
= pStubMsg
->MaxCount
;
4256 ULONG saved_offset
= pStubMsg
->Offset
;
4257 ULONG saved_actual_count
= pStubMsg
->ActualCount
;
4259 /* get the buffer pointer after complex array data, but before
4261 pStubMsg
->IgnoreEmbeddedPointers
= 1;
4262 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
4263 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
4265 /* save it for use by embedded pointer code later */
4266 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4267 pointer_length_set
= 1;
4269 /* restore fields */
4270 pStubMsg
->ActualCount
= saved_actual_count
;
4271 pStubMsg
->Offset
= saved_offset
;
4272 pStubMsg
->MaxCount
= saved_max_count
;
4273 pStubMsg
->BufferLength
= saved_buffer_length
;
4276 array_compute_and_size_conformance(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pMemory
, pFormat
);
4277 array_buffer_size(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pMemory
, pFormat
, TRUE
/* fHasPointers */);
4279 if(pointer_length_set
)
4281 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4282 pStubMsg
->PointerLength
= 0;
4286 /***********************************************************************
4287 * NdrComplexArrayMemorySize [RPCRT4.@]
4289 ULONG WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4290 PFORMAT_STRING pFormat
)
4292 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
4294 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4296 ERR("invalid format type %x\n", pFormat
[0]);
4297 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4301 array_read_conformance(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pFormat
);
4302 array_memory_size(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pFormat
, TRUE
/* fHasPointers */);
4303 return pStubMsg
->MemorySize
;
4306 /***********************************************************************
4307 * NdrComplexArrayFree [RPCRT4.@]
4309 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4310 unsigned char *pMemory
,
4311 PFORMAT_STRING pFormat
)
4313 ULONG i
, count
, def
;
4315 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4317 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4319 ERR("invalid format type %x\n", pFormat
[0]);
4320 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4324 def
= *(const WORD
*)&pFormat
[2];
4327 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
4328 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
4330 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
4331 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
4333 count
= pStubMsg
->ActualCount
;
4334 for (i
= 0; i
< count
; i
++)
4335 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
4338 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg
,
4339 USER_MARSHAL_CB_TYPE cbtype
, PFORMAT_STRING pFormat
,
4340 USER_MARSHAL_CB
*umcb
)
4342 umcb
->Flags
= MAKELONG(pStubMsg
->dwDestContext
,
4343 pStubMsg
->RpcMsg
->DataRepresentation
);
4344 umcb
->pStubMsg
= pStubMsg
;
4345 umcb
->pReserve
= NULL
;
4346 umcb
->Signature
= USER_MARSHAL_CB_SIGNATURE
;
4347 umcb
->CBType
= cbtype
;
4348 umcb
->pFormat
= pFormat
;
4349 umcb
->pTypeFormat
= NULL
/* FIXME */;
4352 #define USER_MARSHAL_PTR_PREFIX \
4353 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4354 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4356 /***********************************************************************
4357 * NdrUserMarshalMarshall [RPCRT4.@]
4359 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4360 unsigned char *pMemory
,
4361 PFORMAT_STRING pFormat
)
4363 unsigned flags
= pFormat
[1];
4364 unsigned index
= *(const WORD
*)&pFormat
[2];
4365 unsigned char *saved_buffer
= NULL
;
4366 USER_MARSHAL_CB umcb
;
4368 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4369 TRACE("index=%d\n", index
);
4371 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_MARSHALL
, pFormat
, &umcb
);
4373 if (flags
& USER_MARSHAL_POINTER
)
4375 align_pointer_clear(&pStubMsg
->Buffer
, 4);
4376 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, USER_MARSHAL_PTR_PREFIX
);
4377 pStubMsg
->Buffer
+= 4;
4378 if (pStubMsg
->PointerBufferMark
)
4380 saved_buffer
= pStubMsg
->Buffer
;
4381 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4382 pStubMsg
->PointerBufferMark
= NULL
;
4384 align_pointer_clear(&pStubMsg
->Buffer
, 8);
4387 align_pointer_clear(&pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4390 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
4391 &umcb
.Flags
, pStubMsg
->Buffer
, pMemory
);
4395 STD_OVERFLOW_CHECK(pStubMsg
);
4396 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4397 pStubMsg
->Buffer
= saved_buffer
;
4400 STD_OVERFLOW_CHECK(pStubMsg
);
4405 /***********************************************************************
4406 * NdrUserMarshalUnmarshall [RPCRT4.@]
4408 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4409 unsigned char **ppMemory
,
4410 PFORMAT_STRING pFormat
,
4411 unsigned char fMustAlloc
)
4413 unsigned flags
= pFormat
[1];
4414 unsigned index
= *(const WORD
*)&pFormat
[2];
4415 DWORD memsize
= *(const WORD
*)&pFormat
[4];
4416 unsigned char *saved_buffer
= NULL
;
4417 USER_MARSHAL_CB umcb
;
4419 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4420 TRACE("index=%d\n", index
);
4422 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_UNMARSHALL
, pFormat
, &umcb
);
4424 if (flags
& USER_MARSHAL_POINTER
)
4426 align_pointer(&pStubMsg
->Buffer
, 4);
4427 /* skip pointer prefix */
4428 pStubMsg
->Buffer
+= 4;
4429 if (pStubMsg
->PointerBufferMark
)
4431 saved_buffer
= pStubMsg
->Buffer
;
4432 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4433 pStubMsg
->PointerBufferMark
= NULL
;
4435 align_pointer(&pStubMsg
->Buffer
, 8);
4438 align_pointer(&pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4440 if (!fMustAlloc
&& !*ppMemory
)
4444 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
4445 memset(*ppMemory
, 0, memsize
);
4449 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
4450 &umcb
.Flags
, pStubMsg
->Buffer
, *ppMemory
);
4454 STD_OVERFLOW_CHECK(pStubMsg
);
4455 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4456 pStubMsg
->Buffer
= saved_buffer
;
4462 /***********************************************************************
4463 * NdrUserMarshalBufferSize [RPCRT4.@]
4465 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4466 unsigned char *pMemory
,
4467 PFORMAT_STRING pFormat
)
4469 unsigned flags
= pFormat
[1];
4470 unsigned index
= *(const WORD
*)&pFormat
[2];
4471 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
4472 USER_MARSHAL_CB umcb
;
4473 ULONG saved_buffer_length
= 0;
4475 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4476 TRACE("index=%d\n", index
);
4478 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_BUFFER_SIZE
, pFormat
, &umcb
);
4480 if (flags
& USER_MARSHAL_POINTER
)
4482 align_length(&pStubMsg
->BufferLength
, 4);
4483 /* skip pointer prefix */
4484 safe_buffer_length_increment(pStubMsg
, 4);
4485 if (pStubMsg
->IgnoreEmbeddedPointers
)
4487 if (pStubMsg
->PointerLength
)
4489 saved_buffer_length
= pStubMsg
->BufferLength
;
4490 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4491 pStubMsg
->PointerLength
= 0;
4493 align_length(&pStubMsg
->BufferLength
, 8);
4496 align_length(&pStubMsg
->BufferLength
, (flags
& 0xf) + 1);
4499 TRACE("size=%d\n", bufsize
);
4500 safe_buffer_length_increment(pStubMsg
, bufsize
);
4503 pStubMsg
->BufferLength
=
4504 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
4505 &umcb
.Flags
, pStubMsg
->BufferLength
, pMemory
);
4507 if (saved_buffer_length
)
4509 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4510 pStubMsg
->BufferLength
= saved_buffer_length
;
4515 /***********************************************************************
4516 * NdrUserMarshalMemorySize [RPCRT4.@]
4518 ULONG WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4519 PFORMAT_STRING pFormat
)
4521 unsigned flags
= pFormat
[1];
4522 unsigned index
= *(const WORD
*)&pFormat
[2];
4523 DWORD memsize
= *(const WORD
*)&pFormat
[4];
4524 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
4526 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
4527 TRACE("index=%d\n", index
);
4529 pStubMsg
->MemorySize
+= memsize
;
4531 if (flags
& USER_MARSHAL_POINTER
)
4533 align_pointer(&pStubMsg
->Buffer
, 4);
4534 /* skip pointer prefix */
4535 pStubMsg
->Buffer
+= 4;
4536 if (pStubMsg
->IgnoreEmbeddedPointers
)
4537 return pStubMsg
->MemorySize
;
4538 align_pointer(&pStubMsg
->Buffer
, 8);
4541 align_pointer(&pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4544 FIXME("not implemented for varying buffer size\n");
4546 pStubMsg
->Buffer
+= bufsize
;
4548 return pStubMsg
->MemorySize
;
4551 /***********************************************************************
4552 * NdrUserMarshalFree [RPCRT4.@]
4554 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
4555 unsigned char *pMemory
,
4556 PFORMAT_STRING pFormat
)
4558 /* unsigned flags = pFormat[1]; */
4559 unsigned index
= *(const WORD
*)&pFormat
[2];
4560 USER_MARSHAL_CB umcb
;
4562 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4563 TRACE("index=%d\n", index
);
4565 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_FREE
, pFormat
, &umcb
);
4567 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
4568 &umcb
.Flags
, pMemory
);
4571 /***********************************************************************
4572 * NdrGetUserMarshalInfo [RPCRT4.@]
4574 RPC_STATUS RPC_ENTRY
NdrGetUserMarshalInfo(ULONG
*flags
, ULONG level
, NDR_USER_MARSHAL_INFO
*umi
)
4576 USER_MARSHAL_CB
*umcb
= CONTAINING_RECORD(flags
, USER_MARSHAL_CB
, Flags
);
4578 TRACE("(%p,%u,%p)\n", flags
, level
, umi
);
4581 return RPC_S_INVALID_ARG
;
4583 memset(&umi
->u1
.Level1
, 0, sizeof(umi
->u1
.Level1
));
4584 umi
->InformationLevel
= level
;
4586 if (umcb
->Signature
!= USER_MARSHAL_CB_SIGNATURE
)
4587 return RPC_S_INVALID_ARG
;
4589 umi
->u1
.Level1
.pfnAllocate
= umcb
->pStubMsg
->pfnAllocate
;
4590 umi
->u1
.Level1
.pfnFree
= umcb
->pStubMsg
->pfnFree
;
4591 umi
->u1
.Level1
.pRpcChannelBuffer
= umcb
->pStubMsg
->pRpcChannelBuffer
;
4593 switch (umcb
->CBType
)
4595 case USER_MARSHAL_CB_MARSHALL
:
4596 case USER_MARSHAL_CB_UNMARSHALL
:
4598 RPC_MESSAGE
*msg
= umcb
->pStubMsg
->RpcMsg
;
4599 unsigned char *buffer_start
= msg
->Buffer
;
4600 unsigned char *buffer_end
=
4601 (unsigned char *)msg
->Buffer
+ msg
->BufferLength
;
4603 if (umcb
->pStubMsg
->Buffer
< buffer_start
||
4604 umcb
->pStubMsg
->Buffer
> buffer_end
)
4605 return ERROR_INVALID_USER_BUFFER
;
4607 umi
->u1
.Level1
.Buffer
= umcb
->pStubMsg
->Buffer
;
4608 umi
->u1
.Level1
.BufferSize
= buffer_end
- umcb
->pStubMsg
->Buffer
;
4611 case USER_MARSHAL_CB_BUFFER_SIZE
:
4612 case USER_MARSHAL_CB_FREE
:
4615 WARN("unrecognised CBType %d\n", umcb
->CBType
);
4621 /***********************************************************************
4622 * NdrClearOutParameters [RPCRT4.@]
4624 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
4625 PFORMAT_STRING pFormat
,
4628 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
4631 /***********************************************************************
4632 * NdrConvert [RPCRT4.@]
4634 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
4636 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
4637 /* FIXME: since this stub doesn't do any converting, the proper behavior
4638 is to raise an exception */
4641 /***********************************************************************
4642 * NdrConvert2 [RPCRT4.@]
4644 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, LONG NumberParams
)
4646 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4647 pStubMsg
, pFormat
, NumberParams
);
4648 /* FIXME: since this stub doesn't do any converting, the proper behavior
4649 is to raise an exception */
4652 #include "pshpack1.h"
4653 typedef struct _NDR_CSTRUCT_FORMAT
4656 unsigned char alignment
;
4657 unsigned short memory_size
;
4658 short offset_to_array_description
;
4659 } NDR_CSTRUCT_FORMAT
, NDR_CVSTRUCT_FORMAT
;
4660 #include "poppack.h"
4662 /***********************************************************************
4663 * NdrConformantStructMarshall [RPCRT4.@]
4665 unsigned char * WINAPI
NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4666 unsigned char *pMemory
,
4667 PFORMAT_STRING pFormat
)
4669 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4670 PFORMAT_STRING pCArrayFormat
;
4671 ULONG esize
, bufsize
;
4673 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4675 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4676 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4678 ERR("invalid format type %x\n", pCStructFormat
->type
);
4679 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4683 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4684 pCStructFormat
->offset_to_array_description
;
4685 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4687 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4688 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4691 esize
= *(const WORD
*)(pCArrayFormat
+2);
4693 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4694 pCArrayFormat
+ 4, 0);
4696 WriteConformance(pStubMsg
);
4698 align_pointer_clear(&pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4700 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4702 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4703 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4705 ERR("integer overflow of memory_size %u with bufsize %u\n",
4706 pCStructFormat
->memory_size
, bufsize
);
4707 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4709 /* copy constant sized part of struct */
4710 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4711 safe_copy_to_buffer(pStubMsg
, pMemory
, pCStructFormat
->memory_size
+ bufsize
);
4713 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4714 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4719 /***********************************************************************
4720 * NdrConformantStructUnmarshall [RPCRT4.@]
4722 unsigned char * WINAPI
NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4723 unsigned char **ppMemory
,
4724 PFORMAT_STRING pFormat
,
4725 unsigned char fMustAlloc
)
4727 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4728 PFORMAT_STRING pCArrayFormat
;
4729 ULONG esize
, bufsize
;
4730 unsigned char *saved_buffer
;
4732 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4734 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4735 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4737 ERR("invalid format type %x\n", pCStructFormat
->type
);
4738 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4741 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4742 pCStructFormat
->offset_to_array_description
;
4743 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4745 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4746 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4749 esize
= *(const WORD
*)(pCArrayFormat
+2);
4751 pCArrayFormat
= ReadConformance(pStubMsg
, pCArrayFormat
+ 4);
4753 align_pointer(&pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4755 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4757 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4758 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4760 ERR("integer overflow of memory_size %u with bufsize %u\n",
4761 pCStructFormat
->memory_size
, bufsize
);
4762 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4767 SIZE_T size
= pCStructFormat
->memory_size
+ bufsize
;
4768 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4772 if (!pStubMsg
->IsClient
&& !*ppMemory
)
4773 /* for servers, we just point straight into the RPC buffer */
4774 *ppMemory
= pStubMsg
->Buffer
;
4777 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4778 safe_buffer_increment(pStubMsg
, pCStructFormat
->memory_size
+ bufsize
);
4779 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4780 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4782 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
4783 if (*ppMemory
!= saved_buffer
)
4784 memcpy(*ppMemory
, saved_buffer
, pCStructFormat
->memory_size
+ bufsize
);
4789 /***********************************************************************
4790 * NdrConformantStructBufferSize [RPCRT4.@]
4792 void WINAPI
NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4793 unsigned char *pMemory
,
4794 PFORMAT_STRING pFormat
)
4796 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4797 PFORMAT_STRING pCArrayFormat
;
4800 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4802 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4803 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4805 ERR("invalid format type %x\n", pCStructFormat
->type
);
4806 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4809 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4810 pCStructFormat
->offset_to_array_description
;
4811 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4813 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4814 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4817 esize
= *(const WORD
*)(pCArrayFormat
+2);
4819 pCArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
, pCArrayFormat
+4, 0);
4820 SizeConformance(pStubMsg
);
4822 align_length(&pStubMsg
->BufferLength
, pCStructFormat
->alignment
+ 1);
4824 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4826 safe_buffer_length_increment(pStubMsg
, pCStructFormat
->memory_size
);
4827 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
4829 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4830 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4833 /***********************************************************************
4834 * NdrConformantStructMemorySize [RPCRT4.@]
4836 ULONG WINAPI
NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4837 PFORMAT_STRING pFormat
)
4843 /***********************************************************************
4844 * NdrConformantStructFree [RPCRT4.@]
4846 void WINAPI
NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
4847 unsigned char *pMemory
,
4848 PFORMAT_STRING pFormat
)
4850 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4851 PFORMAT_STRING pCArrayFormat
;
4853 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4855 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4856 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4858 ERR("invalid format type %x\n", pCStructFormat
->type
);
4859 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4863 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4864 pCStructFormat
->offset_to_array_description
;
4865 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4867 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4868 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4872 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4873 pCArrayFormat
+ 4, 0);
4875 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4877 /* copy constant sized part of struct */
4878 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4880 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4881 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4884 /***********************************************************************
4885 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4887 unsigned char * WINAPI
NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4888 unsigned char *pMemory
,
4889 PFORMAT_STRING pFormat
)
4891 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4892 PFORMAT_STRING pCVArrayFormat
;
4894 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4896 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4897 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4899 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4900 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4904 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4905 pCVStructFormat
->offset_to_array_description
;
4907 array_compute_and_write_conformance(*pCVArrayFormat
, pStubMsg
,
4908 pMemory
+ pCVStructFormat
->memory_size
,
4911 align_pointer_clear(&pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4913 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4915 /* write constant sized part */
4916 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4917 safe_copy_to_buffer(pStubMsg
, pMemory
, pCVStructFormat
->memory_size
);
4919 array_write_variance_and_marshall(*pCVArrayFormat
, pStubMsg
,
4920 pMemory
+ pCVStructFormat
->memory_size
,
4921 pCVArrayFormat
, FALSE
/* fHasPointers */);
4923 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4928 /***********************************************************************
4929 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4931 unsigned char * WINAPI
NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4932 unsigned char **ppMemory
,
4933 PFORMAT_STRING pFormat
,
4934 unsigned char fMustAlloc
)
4936 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4937 PFORMAT_STRING pCVArrayFormat
;
4938 ULONG memsize
, bufsize
;
4939 unsigned char *saved_buffer
, *saved_array_buffer
;
4941 unsigned char *array_memory
;
4943 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4945 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4946 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4948 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4949 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4953 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4954 pCVStructFormat
->offset_to_array_description
;
4956 memsize
= array_read_conformance(*pCVArrayFormat
, pStubMsg
,
4959 align_pointer(&pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4961 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4963 /* work out how much memory to allocate if we need to do so */
4964 if (!fMustAlloc
&& !*ppMemory
)
4968 SIZE_T size
= pCVStructFormat
->memory_size
+ memsize
;
4969 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4972 /* mark the start of the constant data */
4973 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4974 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4976 array_memory
= *ppMemory
+ pCVStructFormat
->memory_size
;
4977 bufsize
= array_read_variance_and_unmarshall(*pCVArrayFormat
, pStubMsg
,
4978 &array_memory
, pCVArrayFormat
,
4979 FALSE
/* fMustAlloc */,
4980 FALSE
/* fUseServerBufferMemory */,
4981 FALSE
/* fUnmarshall */);
4983 /* save offset in case unmarshalling pointers changes it */
4984 offset
= pStubMsg
->Offset
;
4986 /* mark the start of the array data */
4987 saved_array_buffer
= pStubMsg
->Buffer
;
4988 safe_buffer_increment(pStubMsg
, bufsize
);
4990 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4992 /* copy the constant data */
4993 memcpy(*ppMemory
, saved_buffer
, pCVStructFormat
->memory_size
);
4994 /* copy the array data */
4995 TRACE("copying %p to %p\n", saved_array_buffer
, *ppMemory
+ pCVStructFormat
->memory_size
);
4996 memcpy(*ppMemory
+ pCVStructFormat
->memory_size
+ offset
,
4997 saved_array_buffer
, bufsize
);
4999 if (*pCVArrayFormat
== RPC_FC_C_CSTRING
)
5000 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory
+ pCVStructFormat
->memory_size
)));
5001 else if (*pCVArrayFormat
== RPC_FC_C_WSTRING
)
5002 TRACE("string=%s\n", debugstr_w((WCHAR
*)(*ppMemory
+ pCVStructFormat
->memory_size
)));
5007 /***********************************************************************
5008 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
5010 void WINAPI
NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5011 unsigned char *pMemory
,
5012 PFORMAT_STRING pFormat
)
5014 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
5015 PFORMAT_STRING pCVArrayFormat
;
5017 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5019 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
5020 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
5022 ERR("invalid format type %x\n", pCVStructFormat
->type
);
5023 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5027 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
5028 pCVStructFormat
->offset_to_array_description
;
5029 array_compute_and_size_conformance(*pCVArrayFormat
, pStubMsg
,
5030 pMemory
+ pCVStructFormat
->memory_size
,
5033 align_length(&pStubMsg
->BufferLength
, pCVStructFormat
->alignment
+ 1);
5035 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
5037 safe_buffer_length_increment(pStubMsg
, pCVStructFormat
->memory_size
);
5039 array_buffer_size(*pCVArrayFormat
, pStubMsg
,
5040 pMemory
+ pCVStructFormat
->memory_size
, pCVArrayFormat
,
5041 FALSE
/* fHasPointers */);
5043 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5046 /***********************************************************************
5047 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
5049 ULONG WINAPI
NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5050 PFORMAT_STRING pFormat
)
5052 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
5053 PFORMAT_STRING pCVArrayFormat
;
5055 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5057 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
5058 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
5060 ERR("invalid format type %x\n", pCVStructFormat
->type
);
5061 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5065 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
5066 pCVStructFormat
->offset_to_array_description
;
5067 array_read_conformance(*pCVArrayFormat
, pStubMsg
, pCVArrayFormat
);
5069 align_pointer(&pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
5071 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
5073 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
5074 array_memory_size(*pCVArrayFormat
, pStubMsg
, pCVArrayFormat
,
5075 FALSE
/* fHasPointers */);
5077 pStubMsg
->MemorySize
+= pCVStructFormat
->memory_size
;
5079 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5081 return pStubMsg
->MemorySize
;
5084 /***********************************************************************
5085 * NdrConformantVaryingStructFree [RPCRT4.@]
5087 void WINAPI
NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
5088 unsigned char *pMemory
,
5089 PFORMAT_STRING pFormat
)
5091 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
5092 PFORMAT_STRING pCVArrayFormat
;
5094 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5096 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
5097 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
5099 ERR("invalid format type %x\n", pCVStructFormat
->type
);
5100 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5104 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
5105 pCVStructFormat
->offset_to_array_description
;
5106 array_free(*pCVArrayFormat
, pStubMsg
,
5107 pMemory
+ pCVStructFormat
->memory_size
, pCVArrayFormat
,
5108 FALSE
/* fHasPointers */);
5110 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
5112 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5115 #include "pshpack1.h"
5119 unsigned char alignment
;
5120 unsigned short total_size
;
5121 } NDR_SMFARRAY_FORMAT
;
5126 unsigned char alignment
;
5128 } NDR_LGFARRAY_FORMAT
;
5129 #include "poppack.h"
5131 /***********************************************************************
5132 * NdrFixedArrayMarshall [RPCRT4.@]
5134 unsigned char * WINAPI
NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5135 unsigned char *pMemory
,
5136 PFORMAT_STRING pFormat
)
5138 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5141 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5143 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5144 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5146 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5147 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5151 align_pointer_clear(&pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
5153 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5155 total_size
= pSmFArrayFormat
->total_size
;
5156 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5160 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5161 total_size
= pLgFArrayFormat
->total_size
;
5162 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5165 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5166 safe_copy_to_buffer(pStubMsg
, pMemory
, total_size
);
5168 pFormat
= EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
5173 /***********************************************************************
5174 * NdrFixedArrayUnmarshall [RPCRT4.@]
5176 unsigned char * WINAPI
NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5177 unsigned char **ppMemory
,
5178 PFORMAT_STRING pFormat
,
5179 unsigned char fMustAlloc
)
5181 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5183 unsigned char *saved_buffer
;
5185 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5187 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5188 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5190 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5191 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5195 align_pointer(&pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
5197 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5199 total_size
= pSmFArrayFormat
->total_size
;
5200 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5204 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5205 total_size
= pLgFArrayFormat
->total_size
;
5206 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5210 *ppMemory
= NdrAllocate(pStubMsg
, total_size
);
5213 if (!pStubMsg
->IsClient
&& !*ppMemory
)
5214 /* for servers, we just point straight into the RPC buffer */
5215 *ppMemory
= pStubMsg
->Buffer
;
5218 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5219 safe_buffer_increment(pStubMsg
, total_size
);
5220 pFormat
= EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
5222 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
5223 if (*ppMemory
!= saved_buffer
)
5224 memcpy(*ppMemory
, saved_buffer
, total_size
);
5229 /***********************************************************************
5230 * NdrFixedArrayBufferSize [RPCRT4.@]
5232 void WINAPI
NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5233 unsigned char *pMemory
,
5234 PFORMAT_STRING pFormat
)
5236 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5239 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5241 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5242 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5244 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5245 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5249 align_length(&pStubMsg
->BufferLength
, pSmFArrayFormat
->alignment
+ 1);
5251 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5253 total_size
= pSmFArrayFormat
->total_size
;
5254 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5258 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5259 total_size
= pLgFArrayFormat
->total_size
;
5260 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5262 safe_buffer_length_increment(pStubMsg
, total_size
);
5264 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5267 /***********************************************************************
5268 * NdrFixedArrayMemorySize [RPCRT4.@]
5270 ULONG WINAPI
NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5271 PFORMAT_STRING pFormat
)
5273 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5276 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5278 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5279 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5281 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5282 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5286 align_pointer(&pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
5288 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5290 total_size
= pSmFArrayFormat
->total_size
;
5291 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5295 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5296 total_size
= pLgFArrayFormat
->total_size
;
5297 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5299 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5300 safe_buffer_increment(pStubMsg
, total_size
);
5301 pStubMsg
->MemorySize
+= total_size
;
5303 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5308 /***********************************************************************
5309 * NdrFixedArrayFree [RPCRT4.@]
5311 void WINAPI
NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
5312 unsigned char *pMemory
,
5313 PFORMAT_STRING pFormat
)
5315 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5317 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5319 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5320 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5322 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5323 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5327 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5328 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5331 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5332 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5335 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5338 /***********************************************************************
5339 * NdrVaryingArrayMarshall [RPCRT4.@]
5341 unsigned char * WINAPI
NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5342 unsigned char *pMemory
,
5343 PFORMAT_STRING pFormat
)
5345 unsigned char alignment
;
5346 DWORD elements
, esize
;
5349 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5351 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5352 (pFormat
[0] != RPC_FC_LGVARRAY
))
5354 ERR("invalid format type %x\n", pFormat
[0]);
5355 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5359 alignment
= pFormat
[1] + 1;
5361 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5364 pFormat
+= sizeof(WORD
);
5365 elements
= *(const WORD
*)pFormat
;
5366 pFormat
+= sizeof(WORD
);
5371 pFormat
+= sizeof(DWORD
);
5372 elements
= *(const DWORD
*)pFormat
;
5373 pFormat
+= sizeof(DWORD
);
5376 esize
= *(const WORD
*)pFormat
;
5377 pFormat
+= sizeof(WORD
);
5379 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5380 if ((pStubMsg
->ActualCount
> elements
) ||
5381 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5383 RpcRaiseException(RPC_S_INVALID_BOUND
);
5387 WriteVariance(pStubMsg
);
5389 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
5391 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
5392 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5393 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
5395 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
5400 /***********************************************************************
5401 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5403 unsigned char * WINAPI
NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5404 unsigned char **ppMemory
,
5405 PFORMAT_STRING pFormat
,
5406 unsigned char fMustAlloc
)
5408 unsigned char alignment
;
5409 DWORD size
, elements
, esize
;
5411 unsigned char *saved_buffer
;
5414 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5416 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5417 (pFormat
[0] != RPC_FC_LGVARRAY
))
5419 ERR("invalid format type %x\n", pFormat
[0]);
5420 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5424 alignment
= pFormat
[1] + 1;
5426 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5429 size
= *(const WORD
*)pFormat
;
5430 pFormat
+= sizeof(WORD
);
5431 elements
= *(const WORD
*)pFormat
;
5432 pFormat
+= sizeof(WORD
);
5437 size
= *(const DWORD
*)pFormat
;
5438 pFormat
+= sizeof(DWORD
);
5439 elements
= *(const DWORD
*)pFormat
;
5440 pFormat
+= sizeof(DWORD
);
5443 esize
= *(const WORD
*)pFormat
;
5444 pFormat
+= sizeof(WORD
);
5446 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
5448 align_pointer(&pStubMsg
->Buffer
, alignment
);
5450 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
5451 offset
= pStubMsg
->Offset
;
5453 if (!fMustAlloc
&& !*ppMemory
)
5456 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5457 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5458 safe_buffer_increment(pStubMsg
, bufsize
);
5460 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
5462 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
5467 /***********************************************************************
5468 * NdrVaryingArrayBufferSize [RPCRT4.@]
5470 void WINAPI
NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5471 unsigned char *pMemory
,
5472 PFORMAT_STRING pFormat
)
5474 unsigned char alignment
;
5475 DWORD elements
, esize
;
5477 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5479 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5480 (pFormat
[0] != RPC_FC_LGVARRAY
))
5482 ERR("invalid format type %x\n", pFormat
[0]);
5483 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5487 alignment
= pFormat
[1] + 1;
5489 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5492 pFormat
+= sizeof(WORD
);
5493 elements
= *(const WORD
*)pFormat
;
5494 pFormat
+= sizeof(WORD
);
5499 pFormat
+= sizeof(DWORD
);
5500 elements
= *(const DWORD
*)pFormat
;
5501 pFormat
+= sizeof(DWORD
);
5504 esize
= *(const WORD
*)pFormat
;
5505 pFormat
+= sizeof(WORD
);
5507 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5508 if ((pStubMsg
->ActualCount
> elements
) ||
5509 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5511 RpcRaiseException(RPC_S_INVALID_BOUND
);
5515 SizeVariance(pStubMsg
);
5517 align_length(&pStubMsg
->BufferLength
, alignment
);
5519 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
5521 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5524 /***********************************************************************
5525 * NdrVaryingArrayMemorySize [RPCRT4.@]
5527 ULONG WINAPI
NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5528 PFORMAT_STRING pFormat
)
5530 unsigned char alignment
;
5531 DWORD size
, elements
, esize
;
5533 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5535 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5536 (pFormat
[0] != RPC_FC_LGVARRAY
))
5538 ERR("invalid format type %x\n", pFormat
[0]);
5539 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5543 alignment
= pFormat
[1] + 1;
5545 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5548 size
= *(const WORD
*)pFormat
;
5549 pFormat
+= sizeof(WORD
);
5550 elements
= *(const WORD
*)pFormat
;
5551 pFormat
+= sizeof(WORD
);
5556 size
= *(const DWORD
*)pFormat
;
5557 pFormat
+= sizeof(DWORD
);
5558 elements
= *(const DWORD
*)pFormat
;
5559 pFormat
+= sizeof(DWORD
);
5562 esize
= *(const WORD
*)pFormat
;
5563 pFormat
+= sizeof(WORD
);
5565 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
5567 align_pointer(&pStubMsg
->Buffer
, alignment
);
5569 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
5570 pStubMsg
->MemorySize
+= size
;
5572 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5574 return pStubMsg
->MemorySize
;
5577 /***********************************************************************
5578 * NdrVaryingArrayFree [RPCRT4.@]
5580 void WINAPI
NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
5581 unsigned char *pMemory
,
5582 PFORMAT_STRING pFormat
)
5586 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5588 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5589 (pFormat
[0] != RPC_FC_LGVARRAY
))
5591 ERR("invalid format type %x\n", pFormat
[0]);
5592 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5596 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5599 pFormat
+= sizeof(WORD
);
5600 elements
= *(const WORD
*)pFormat
;
5601 pFormat
+= sizeof(WORD
);
5606 pFormat
+= sizeof(DWORD
);
5607 elements
= *(const DWORD
*)pFormat
;
5608 pFormat
+= sizeof(DWORD
);
5611 pFormat
+= sizeof(WORD
);
5613 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5614 if ((pStubMsg
->ActualCount
> elements
) ||
5615 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5617 RpcRaiseException(RPC_S_INVALID_BOUND
);
5621 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5624 static ULONG
get_discriminant(unsigned char fc
, const unsigned char *pMemory
)
5637 return *(const USHORT
*)pMemory
;
5641 return *(const ULONG
*)pMemory
;
5642 case RPC_FC_INT3264
:
5643 case RPC_FC_UINT3264
:
5644 return *(const ULONG_PTR
*)pMemory
;
5646 FIXME("Unhandled base type: 0x%02x\n", fc
);
5651 static PFORMAT_STRING
get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg
,
5653 PFORMAT_STRING pFormat
)
5655 unsigned short num_arms
, arm
, type
;
5657 num_arms
= *(const SHORT
*)pFormat
& 0x0fff;
5659 for(arm
= 0; arm
< num_arms
; arm
++)
5661 if(discriminant
== *(const ULONG
*)pFormat
)
5669 type
= *(const unsigned short*)pFormat
;
5670 TRACE("type %04x\n", type
);
5671 if(arm
== num_arms
) /* default arm extras */
5675 ERR("no arm for 0x%x and no default case\n", discriminant
);
5676 RpcRaiseException(RPC_S_INVALID_TAG
);
5681 TRACE("falling back to empty default case for 0x%x\n", discriminant
);
5688 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
, ULONG discriminant
, PFORMAT_STRING pFormat
)
5690 unsigned short type
;
5694 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5698 type
= *(const unsigned short*)pFormat
;
5699 if((type
& 0xff00) == 0x8000)
5701 unsigned char basetype
= LOBYTE(type
);
5702 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &basetype
);
5706 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5707 NDR_MARSHALL m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
5710 unsigned char *saved_buffer
= NULL
;
5711 int pointer_buffer_mark_set
= 0;
5718 align_pointer_clear(&pStubMsg
->Buffer
, 4);
5719 saved_buffer
= pStubMsg
->Buffer
;
5720 if (pStubMsg
->PointerBufferMark
)
5722 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5723 pStubMsg
->PointerBufferMark
= NULL
;
5724 pointer_buffer_mark_set
= 1;
5727 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
5729 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char **)pMemory
, desc
);
5730 if (pointer_buffer_mark_set
)
5732 STD_OVERFLOW_CHECK(pStubMsg
);
5733 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5734 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5736 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5737 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
5738 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5740 pStubMsg
->Buffer
= saved_buffer
+ 4;
5744 m(pStubMsg
, pMemory
, desc
);
5747 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5752 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5753 unsigned char **ppMemory
,
5755 PFORMAT_STRING pFormat
,
5756 unsigned char fMustAlloc
)
5758 unsigned short type
;
5762 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5766 type
= *(const unsigned short*)pFormat
;
5767 if((type
& 0xff00) == 0x8000)
5769 unsigned char basetype
= LOBYTE(type
);
5770 return NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &basetype
, FALSE
);
5774 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5775 NDR_UNMARSHALL m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
5778 unsigned char *saved_buffer
= NULL
;
5779 int pointer_buffer_mark_set
= 0;
5786 align_pointer(&pStubMsg
->Buffer
, 4);
5787 saved_buffer
= pStubMsg
->Buffer
;
5788 if (pStubMsg
->PointerBufferMark
)
5790 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5791 pStubMsg
->PointerBufferMark
= NULL
;
5792 pointer_buffer_mark_set
= 1;
5795 pStubMsg
->Buffer
+= 4; /* for pointer ID */
5797 if (saved_buffer
+ 4 > pStubMsg
->BufferEnd
)
5799 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5800 saved_buffer
, pStubMsg
->BufferEnd
);
5801 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5804 PointerUnmarshall(pStubMsg
, saved_buffer
, *(unsigned char ***)ppMemory
, **(unsigned char ***)ppMemory
, desc
, fMustAlloc
);
5805 if (pointer_buffer_mark_set
)
5807 STD_OVERFLOW_CHECK(pStubMsg
);
5808 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5809 pStubMsg
->Buffer
= saved_buffer
+ 4;
5813 m(pStubMsg
, ppMemory
, desc
, fMustAlloc
);
5816 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5821 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg
,
5822 unsigned char *pMemory
,
5824 PFORMAT_STRING pFormat
)
5826 unsigned short type
;
5830 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5834 type
= *(const unsigned short*)pFormat
;
5835 if((type
& 0xff00) == 0x8000)
5837 unsigned char basetype
= LOBYTE(type
);
5838 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &basetype
);
5842 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5843 NDR_BUFFERSIZE m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
5852 align_length(&pStubMsg
->BufferLength
, 4);
5853 safe_buffer_length_increment(pStubMsg
, 4); /* for pointer ID */
5854 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5856 int saved_buffer_length
= pStubMsg
->BufferLength
;
5857 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
5858 pStubMsg
->PointerLength
= 0;
5859 if(!pStubMsg
->BufferLength
)
5860 ERR("BufferLength == 0??\n");
5861 PointerBufferSize(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5862 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
5863 pStubMsg
->BufferLength
= saved_buffer_length
;
5867 m(pStubMsg
, pMemory
, desc
);
5870 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
5874 static ULONG
union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg
,
5876 PFORMAT_STRING pFormat
)
5878 unsigned short type
, size
;
5880 size
= *(const unsigned short*)pFormat
;
5881 pStubMsg
->Memory
+= size
;
5884 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5888 type
= *(const unsigned short*)pFormat
;
5889 if((type
& 0xff00) == 0x8000)
5891 return NdrBaseTypeMemorySize(pStubMsg
, pFormat
);
5895 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5896 NDR_MEMORYSIZE m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
5897 unsigned char *saved_buffer
;
5906 align_pointer(&pStubMsg
->Buffer
, 4);
5907 saved_buffer
= pStubMsg
->Buffer
;
5908 safe_buffer_increment(pStubMsg
, 4);
5909 align_length(&pStubMsg
->MemorySize
, sizeof(void *));
5910 pStubMsg
->MemorySize
+= sizeof(void *);
5911 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5912 PointerMemorySize(pStubMsg
, saved_buffer
, pFormat
);
5915 return m(pStubMsg
, desc
);
5918 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5921 TRACE("size %d\n", size
);
5925 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg
,
5926 unsigned char *pMemory
,
5928 PFORMAT_STRING pFormat
)
5930 unsigned short type
;
5934 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5938 type
= *(const unsigned short*)pFormat
;
5939 if((type
& 0xff00) != 0x8000)
5941 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5942 NDR_FREE m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
5951 PointerFree(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5954 m(pStubMsg
, pMemory
, desc
);
5960 /***********************************************************************
5961 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5963 unsigned char * WINAPI
NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5964 unsigned char *pMemory
,
5965 PFORMAT_STRING pFormat
)
5967 unsigned char switch_type
;
5968 unsigned char increment
;
5971 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5974 switch_type
= *pFormat
& 0xf;
5975 increment
= (*pFormat
& 0xf0) >> 4;
5978 align_pointer_clear(&pStubMsg
->Buffer
, increment
);
5980 switch_value
= get_discriminant(switch_type
, pMemory
);
5981 TRACE("got switch value 0x%x\n", switch_value
);
5983 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &switch_type
);
5984 pMemory
+= increment
;
5986 return union_arm_marshall(pStubMsg
, pMemory
, switch_value
, pFormat
);
5989 /***********************************************************************
5990 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5992 unsigned char * WINAPI
NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5993 unsigned char **ppMemory
,
5994 PFORMAT_STRING pFormat
,
5995 unsigned char fMustAlloc
)
5997 unsigned char switch_type
;
5998 unsigned char increment
;
6000 unsigned short size
;
6001 unsigned char *pMemoryArm
;
6003 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
6006 switch_type
= *pFormat
& 0xf;
6007 increment
= (*pFormat
& 0xf0) >> 4;
6010 align_pointer(&pStubMsg
->Buffer
, increment
);
6011 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
6012 TRACE("got switch value 0x%x\n", switch_value
);
6014 size
= *(const unsigned short*)pFormat
+ increment
;
6015 if (!fMustAlloc
&& !*ppMemory
)
6018 *ppMemory
= NdrAllocate(pStubMsg
, size
);
6020 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6021 * since the arm is part of the memory block that is encompassed by
6022 * the whole union. Memory is forced to allocate when pointers
6023 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6024 * clearing the memory we pass in to the unmarshaller */
6026 memset(*ppMemory
, 0, size
);
6028 NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &switch_type
, FALSE
);
6029 pMemoryArm
= *ppMemory
+ increment
;
6031 return union_arm_unmarshall(pStubMsg
, &pMemoryArm
, switch_value
, pFormat
, FALSE
);
6034 /***********************************************************************
6035 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
6037 void WINAPI
NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6038 unsigned char *pMemory
,
6039 PFORMAT_STRING pFormat
)
6041 unsigned char switch_type
;
6042 unsigned char increment
;
6045 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6048 switch_type
= *pFormat
& 0xf;
6049 increment
= (*pFormat
& 0xf0) >> 4;
6052 align_length(&pStubMsg
->BufferLength
, increment
);
6053 switch_value
= get_discriminant(switch_type
, pMemory
);
6054 TRACE("got switch value 0x%x\n", switch_value
);
6056 /* Add discriminant size */
6057 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&switch_value
, &switch_type
);
6058 pMemory
+= increment
;
6060 union_arm_buffer_size(pStubMsg
, pMemory
, switch_value
, pFormat
);
6063 /***********************************************************************
6064 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
6066 ULONG WINAPI
NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6067 PFORMAT_STRING pFormat
)
6069 unsigned char switch_type
;
6070 unsigned char increment
;
6073 switch_type
= *pFormat
& 0xf;
6074 increment
= (*pFormat
& 0xf0) >> 4;
6077 align_pointer(&pStubMsg
->Buffer
, increment
);
6078 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
6079 TRACE("got switch value 0x%x\n", switch_value
);
6081 pStubMsg
->Memory
+= increment
;
6083 return increment
+ union_arm_memory_size(pStubMsg
, switch_value
, pFormat
+ *(const SHORT
*)pFormat
);
6086 /***********************************************************************
6087 * NdrEncapsulatedUnionFree [RPCRT4.@]
6089 void WINAPI
NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
6090 unsigned char *pMemory
,
6091 PFORMAT_STRING pFormat
)
6093 unsigned char switch_type
;
6094 unsigned char increment
;
6097 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6100 switch_type
= *pFormat
& 0xf;
6101 increment
= (*pFormat
& 0xf0) >> 4;
6104 switch_value
= get_discriminant(switch_type
, pMemory
);
6105 TRACE("got switch value 0x%x\n", switch_value
);
6107 pMemory
+= increment
;
6109 union_arm_free(pStubMsg
, pMemory
, switch_value
, pFormat
);
6112 /***********************************************************************
6113 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
6115 unsigned char * WINAPI
NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6116 unsigned char *pMemory
,
6117 PFORMAT_STRING pFormat
)
6119 unsigned char switch_type
;
6121 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6124 switch_type
= *pFormat
;
6127 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6128 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6129 /* Marshall discriminant */
6130 NdrBaseTypeMarshall(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
6132 return union_arm_marshall(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6135 static LONG
unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg
,
6136 PFORMAT_STRING
*ppFormat
)
6138 LONG discriminant
= 0;
6148 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
6157 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6158 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
6166 align_pointer(&pStubMsg
->Buffer
, sizeof(ULONG
));
6167 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
6172 FIXME("Unhandled base type: 0x%02x\n", **ppFormat
);
6176 if (pStubMsg
->fHasNewCorrDesc
)
6180 return discriminant
;
6183 /**********************************************************************
6184 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
6186 unsigned char * WINAPI
NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6187 unsigned char **ppMemory
,
6188 PFORMAT_STRING pFormat
,
6189 unsigned char fMustAlloc
)
6192 unsigned short size
;
6194 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
6197 /* Unmarshall discriminant */
6198 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
6199 TRACE("unmarshalled discriminant %x\n", discriminant
);
6201 pFormat
+= *(const SHORT
*)pFormat
;
6203 size
= *(const unsigned short*)pFormat
;
6205 if (!fMustAlloc
&& !*ppMemory
)
6208 *ppMemory
= NdrAllocate(pStubMsg
, size
);
6210 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6211 * since the arm is part of the memory block that is encompassed by
6212 * the whole union. Memory is forced to allocate when pointers
6213 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6214 * clearing the memory we pass in to the unmarshaller */
6216 memset(*ppMemory
, 0, size
);
6218 return union_arm_unmarshall(pStubMsg
, ppMemory
, discriminant
, pFormat
, FALSE
);
6221 /***********************************************************************
6222 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
6224 void WINAPI
NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6225 unsigned char *pMemory
,
6226 PFORMAT_STRING pFormat
)
6228 unsigned char switch_type
;
6230 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6233 switch_type
= *pFormat
;
6236 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6237 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6238 /* Add discriminant size */
6239 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
6241 union_arm_buffer_size(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6244 /***********************************************************************
6245 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
6247 ULONG WINAPI
NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6248 PFORMAT_STRING pFormat
)
6253 /* Unmarshall discriminant */
6254 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
6255 TRACE("unmarshalled discriminant 0x%x\n", discriminant
);
6257 return union_arm_memory_size(pStubMsg
, discriminant
, pFormat
+ *(const SHORT
*)pFormat
);
6260 /***********************************************************************
6261 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6263 void WINAPI
NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
6264 unsigned char *pMemory
,
6265 PFORMAT_STRING pFormat
)
6267 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6271 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6272 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6274 union_arm_free(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6277 /***********************************************************************
6278 * NdrByteCountPointerMarshall [RPCRT4.@]
6280 unsigned char * WINAPI
NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6281 unsigned char *pMemory
,
6282 PFORMAT_STRING pFormat
)
6288 /***********************************************************************
6289 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6291 unsigned char * WINAPI
NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6292 unsigned char **ppMemory
,
6293 PFORMAT_STRING pFormat
,
6294 unsigned char fMustAlloc
)
6300 /***********************************************************************
6301 * NdrByteCountPointerBufferSize [RPCRT4.@]
6303 void WINAPI
NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6304 unsigned char *pMemory
,
6305 PFORMAT_STRING pFormat
)
6310 /***********************************************************************
6311 * NdrByteCountPointerMemorySize [internal]
6313 static ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6314 PFORMAT_STRING pFormat
)
6320 /***********************************************************************
6321 * NdrByteCountPointerFree [RPCRT4.@]
6323 void WINAPI
NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
6324 unsigned char *pMemory
,
6325 PFORMAT_STRING pFormat
)
6330 /***********************************************************************
6331 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6333 unsigned char * WINAPI
NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6334 unsigned char *pMemory
,
6335 PFORMAT_STRING pFormat
)
6341 /***********************************************************************
6342 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6344 unsigned char * WINAPI
NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6345 unsigned char **ppMemory
,
6346 PFORMAT_STRING pFormat
,
6347 unsigned char fMustAlloc
)
6353 /***********************************************************************
6354 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6356 void WINAPI
NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6357 unsigned char *pMemory
,
6358 PFORMAT_STRING pFormat
)
6363 /***********************************************************************
6364 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6366 ULONG WINAPI
NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6367 PFORMAT_STRING pFormat
)
6373 /***********************************************************************
6374 * NdrXmitOrRepAsFree [RPCRT4.@]
6376 void WINAPI
NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg
,
6377 unsigned char *pMemory
,
6378 PFORMAT_STRING pFormat
)
6383 /***********************************************************************
6384 * NdrRangeMarshall [internal]
6386 static unsigned char *WINAPI
NdrRangeMarshall(
6387 PMIDL_STUB_MESSAGE pStubMsg
,
6388 unsigned char *pMemory
,
6389 PFORMAT_STRING pFormat
)
6391 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6392 unsigned char base_type
;
6394 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6396 if (pRange
->type
!= RPC_FC_RANGE
)
6398 ERR("invalid format type %x\n", pRange
->type
);
6399 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6403 base_type
= pRange
->flags_type
& 0xf;
6405 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &base_type
);
6408 /***********************************************************************
6409 * NdrRangeUnmarshall [RPCRT4.@]
6411 unsigned char *WINAPI
NdrRangeUnmarshall(
6412 PMIDL_STUB_MESSAGE pStubMsg
,
6413 unsigned char **ppMemory
,
6414 PFORMAT_STRING pFormat
,
6415 unsigned char fMustAlloc
)
6417 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6418 unsigned char base_type
;
6420 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6422 if (pRange
->type
!= RPC_FC_RANGE
)
6424 ERR("invalid format type %x\n", pRange
->type
);
6425 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6428 base_type
= pRange
->flags_type
& 0xf;
6430 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6431 base_type
, pRange
->low_value
, pRange
->high_value
);
6433 #define RANGE_UNMARSHALL(mem_type, wire_type, format_spec) \
6436 align_pointer(&pStubMsg->Buffer, sizeof(wire_type)); \
6437 if (!fMustAlloc && !*ppMemory) \
6438 fMustAlloc = TRUE; \
6440 *ppMemory = NdrAllocate(pStubMsg, sizeof(mem_type)); \
6441 if (pStubMsg->Buffer + sizeof(wire_type) > pStubMsg->BufferEnd) \
6443 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6444 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6445 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6447 if ((*(wire_type *)pStubMsg->Buffer < (mem_type)pRange->low_value) || \
6448 (*(wire_type *)pStubMsg->Buffer > (mem_type)pRange->high_value)) \
6450 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6451 *(wire_type *)pStubMsg->Buffer, (mem_type)pRange->low_value, \
6452 (mem_type)pRange->high_value); \
6453 RpcRaiseException(RPC_S_INVALID_BOUND); \
6456 TRACE("*ppMemory: %p\n", *ppMemory); \
6457 **(mem_type **)ppMemory = *(wire_type *)pStubMsg->Buffer; \
6458 pStubMsg->Buffer += sizeof(wire_type); \
6465 RANGE_UNMARSHALL(UCHAR
, UCHAR
, "%d");
6466 TRACE("value: 0x%02x\n", **ppMemory
);
6470 RANGE_UNMARSHALL(CHAR
, CHAR
, "%u");
6471 TRACE("value: 0x%02x\n", **ppMemory
);
6473 case RPC_FC_WCHAR
: /* FIXME: valid? */
6475 RANGE_UNMARSHALL(USHORT
, USHORT
, "%u");
6476 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6479 RANGE_UNMARSHALL(SHORT
, SHORT
, "%d");
6480 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6484 RANGE_UNMARSHALL(LONG
, LONG
, "%d");
6485 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6488 RANGE_UNMARSHALL(ULONG
, ULONG
, "%u");
6489 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6492 RANGE_UNMARSHALL(UINT
, USHORT
, "%u");
6493 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
6499 ERR("invalid range base type: 0x%02x\n", base_type
);
6500 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6506 /***********************************************************************
6507 * NdrRangeBufferSize [internal]
6509 static void WINAPI
NdrRangeBufferSize(
6510 PMIDL_STUB_MESSAGE pStubMsg
,
6511 unsigned char *pMemory
,
6512 PFORMAT_STRING pFormat
)
6514 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6515 unsigned char base_type
;
6517 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6519 if (pRange
->type
!= RPC_FC_RANGE
)
6521 ERR("invalid format type %x\n", pRange
->type
);
6522 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6524 base_type
= pRange
->flags_type
& 0xf;
6526 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &base_type
);
6529 /***********************************************************************
6530 * NdrRangeMemorySize [internal]
6532 static ULONG WINAPI
NdrRangeMemorySize(
6533 PMIDL_STUB_MESSAGE pStubMsg
,
6534 PFORMAT_STRING pFormat
)
6536 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6537 unsigned char base_type
;
6539 if (pRange
->type
!= RPC_FC_RANGE
)
6541 ERR("invalid format type %x\n", pRange
->type
);
6542 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6545 base_type
= pRange
->flags_type
& 0xf;
6547 return NdrBaseTypeMemorySize(pStubMsg
, &base_type
);
6550 /***********************************************************************
6551 * NdrRangeFree [internal]
6553 static void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6554 unsigned char *pMemory
,
6555 PFORMAT_STRING pFormat
)
6557 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6562 /***********************************************************************
6563 * NdrBaseTypeMarshall [internal]
6565 static unsigned char *WINAPI
NdrBaseTypeMarshall(
6566 PMIDL_STUB_MESSAGE pStubMsg
,
6567 unsigned char *pMemory
,
6568 PFORMAT_STRING pFormat
)
6570 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6578 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(UCHAR
));
6579 TRACE("value: 0x%02x\n", *pMemory
);
6584 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(USHORT
));
6585 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(USHORT
));
6586 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
6590 case RPC_FC_ERROR_STATUS_T
:
6592 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(ULONG
));
6593 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONG
));
6594 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
6597 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(float));
6598 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
6601 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(double));
6602 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
6605 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(ULONGLONG
));
6606 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONGLONG
));
6607 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
6611 USHORT val
= *(UINT
*)pMemory
;
6612 /* only 16-bits on the wire, so do a sanity check */
6613 if (*(UINT
*)pMemory
> SHRT_MAX
)
6614 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
6615 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(USHORT
));
6616 safe_copy_to_buffer(pStubMsg
, &val
, sizeof(val
));
6617 TRACE("value: 0x%04x\n", *(UINT
*)pMemory
);
6620 case RPC_FC_INT3264
:
6621 case RPC_FC_UINT3264
:
6623 UINT val
= *(UINT_PTR
*)pMemory
;
6624 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(UINT
));
6625 safe_copy_to_buffer(pStubMsg
, &val
, sizeof(val
));
6631 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6634 /* FIXME: what is the correct return value? */
6638 /***********************************************************************
6639 * NdrBaseTypeUnmarshall [internal]
6641 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(
6642 PMIDL_STUB_MESSAGE pStubMsg
,
6643 unsigned char **ppMemory
,
6644 PFORMAT_STRING pFormat
,
6645 unsigned char fMustAlloc
)
6647 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6649 #define BASE_TYPE_UNMARSHALL(type) do { \
6650 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
6651 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6653 *ppMemory = pStubMsg->Buffer; \
6654 TRACE("*ppMemory: %p\n", *ppMemory); \
6655 safe_buffer_increment(pStubMsg, sizeof(type)); \
6660 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6661 TRACE("*ppMemory: %p\n", *ppMemory); \
6662 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6672 BASE_TYPE_UNMARSHALL(UCHAR
);
6673 TRACE("value: 0x%02x\n", **ppMemory
);
6678 BASE_TYPE_UNMARSHALL(USHORT
);
6679 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6683 case RPC_FC_ERROR_STATUS_T
:
6685 BASE_TYPE_UNMARSHALL(ULONG
);
6686 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6689 BASE_TYPE_UNMARSHALL(float);
6690 TRACE("value: %f\n", **(float **)ppMemory
);
6693 BASE_TYPE_UNMARSHALL(double);
6694 TRACE("value: %f\n", **(double **)ppMemory
);
6697 BASE_TYPE_UNMARSHALL(ULONGLONG
);
6698 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG
**)ppMemory
));
6703 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6704 if (!fMustAlloc
&& !*ppMemory
)
6707 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT
));
6708 safe_copy_from_buffer(pStubMsg
, &val
, sizeof(USHORT
));
6709 /* 16-bits on the wire, but int in memory */
6710 **(UINT
**)ppMemory
= val
;
6711 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
6714 case RPC_FC_INT3264
:
6715 if (sizeof(INT_PTR
) == sizeof(INT
)) BASE_TYPE_UNMARSHALL(INT
);
6719 align_pointer(&pStubMsg
->Buffer
, sizeof(INT
));
6720 if (!fMustAlloc
&& !*ppMemory
)
6723 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(INT_PTR
));
6724 safe_copy_from_buffer(pStubMsg
, &val
, sizeof(INT
));
6725 **(INT_PTR
**)ppMemory
= val
;
6726 TRACE("value: 0x%08lx\n", **(INT_PTR
**)ppMemory
);
6729 case RPC_FC_UINT3264
:
6730 if (sizeof(UINT_PTR
) == sizeof(UINT
)) BASE_TYPE_UNMARSHALL(UINT
);
6734 align_pointer(&pStubMsg
->Buffer
, sizeof(UINT
));
6735 if (!fMustAlloc
&& !*ppMemory
)
6738 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT_PTR
));
6739 safe_copy_from_buffer(pStubMsg
, &val
, sizeof(UINT
));
6740 **(UINT_PTR
**)ppMemory
= val
;
6741 TRACE("value: 0x%08lx\n", **(UINT_PTR
**)ppMemory
);
6747 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6749 #undef BASE_TYPE_UNMARSHALL
6751 /* FIXME: what is the correct return value? */
6756 /***********************************************************************
6757 * NdrBaseTypeBufferSize [internal]
6759 static void WINAPI
NdrBaseTypeBufferSize(
6760 PMIDL_STUB_MESSAGE pStubMsg
,
6761 unsigned char *pMemory
,
6762 PFORMAT_STRING pFormat
)
6764 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6772 safe_buffer_length_increment(pStubMsg
, sizeof(UCHAR
));
6778 align_length(&pStubMsg
->BufferLength
, sizeof(USHORT
));
6779 safe_buffer_length_increment(pStubMsg
, sizeof(USHORT
));
6784 case RPC_FC_INT3264
:
6785 case RPC_FC_UINT3264
:
6786 align_length(&pStubMsg
->BufferLength
, sizeof(ULONG
));
6787 safe_buffer_length_increment(pStubMsg
, sizeof(ULONG
));
6790 align_length(&pStubMsg
->BufferLength
, sizeof(float));
6791 safe_buffer_length_increment(pStubMsg
, sizeof(float));
6794 align_length(&pStubMsg
->BufferLength
, sizeof(double));
6795 safe_buffer_length_increment(pStubMsg
, sizeof(double));
6798 align_length(&pStubMsg
->BufferLength
, sizeof(ULONGLONG
));
6799 safe_buffer_length_increment(pStubMsg
, sizeof(ULONGLONG
));
6801 case RPC_FC_ERROR_STATUS_T
:
6802 align_length(&pStubMsg
->BufferLength
, sizeof(error_status_t
));
6803 safe_buffer_length_increment(pStubMsg
, sizeof(error_status_t
));
6808 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6812 /***********************************************************************
6813 * NdrBaseTypeMemorySize [internal]
6815 static ULONG WINAPI
NdrBaseTypeMemorySize(
6816 PMIDL_STUB_MESSAGE pStubMsg
,
6817 PFORMAT_STRING pFormat
)
6819 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg
, *pFormat
);
6827 safe_buffer_increment(pStubMsg
, sizeof(UCHAR
));
6828 pStubMsg
->MemorySize
+= sizeof(UCHAR
);
6829 return sizeof(UCHAR
);
6833 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6834 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6835 align_length(&pStubMsg
->MemorySize
, sizeof(USHORT
));
6836 pStubMsg
->MemorySize
+= sizeof(USHORT
);
6837 return sizeof(USHORT
);
6841 align_pointer(&pStubMsg
->Buffer
, sizeof(ULONG
));
6842 safe_buffer_increment(pStubMsg
, sizeof(ULONG
));
6843 align_length(&pStubMsg
->MemorySize
, sizeof(ULONG
));
6844 pStubMsg
->MemorySize
+= sizeof(ULONG
);
6845 return sizeof(ULONG
);
6847 align_pointer(&pStubMsg
->Buffer
, sizeof(float));
6848 safe_buffer_increment(pStubMsg
, sizeof(float));
6849 align_length(&pStubMsg
->MemorySize
, sizeof(float));
6850 pStubMsg
->MemorySize
+= sizeof(float);
6851 return sizeof(float);
6853 align_pointer(&pStubMsg
->Buffer
, sizeof(double));
6854 safe_buffer_increment(pStubMsg
, sizeof(double));
6855 align_length(&pStubMsg
->MemorySize
, sizeof(double));
6856 pStubMsg
->MemorySize
+= sizeof(double);
6857 return sizeof(double);
6859 align_pointer(&pStubMsg
->Buffer
, sizeof(ULONGLONG
));
6860 safe_buffer_increment(pStubMsg
, sizeof(ULONGLONG
));
6861 align_length(&pStubMsg
->MemorySize
, sizeof(ULONGLONG
));
6862 pStubMsg
->MemorySize
+= sizeof(ULONGLONG
);
6863 return sizeof(ULONGLONG
);
6864 case RPC_FC_ERROR_STATUS_T
:
6865 align_pointer(&pStubMsg
->Buffer
, sizeof(error_status_t
));
6866 safe_buffer_increment(pStubMsg
, sizeof(error_status_t
));
6867 align_length(&pStubMsg
->MemorySize
, sizeof(error_status_t
));
6868 pStubMsg
->MemorySize
+= sizeof(error_status_t
);
6869 return sizeof(error_status_t
);
6871 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6872 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6873 align_length(&pStubMsg
->MemorySize
, sizeof(UINT
));
6874 pStubMsg
->MemorySize
+= sizeof(UINT
);
6875 return sizeof(UINT
);
6876 case RPC_FC_INT3264
:
6877 case RPC_FC_UINT3264
:
6878 align_pointer(&pStubMsg
->Buffer
, sizeof(UINT
));
6879 safe_buffer_increment(pStubMsg
, sizeof(UINT
));
6880 align_length(&pStubMsg
->MemorySize
, sizeof(UINT_PTR
));
6881 pStubMsg
->MemorySize
+= sizeof(UINT_PTR
);
6882 return sizeof(UINT_PTR
);
6884 align_length(&pStubMsg
->MemorySize
, sizeof(void *));
6885 pStubMsg
->MemorySize
+= sizeof(void *);
6886 return sizeof(void *);
6888 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6893 /***********************************************************************
6894 * NdrBaseTypeFree [internal]
6896 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6897 unsigned char *pMemory
,
6898 PFORMAT_STRING pFormat
)
6900 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6905 /***********************************************************************
6906 * NdrContextHandleBufferSize [internal]
6908 static void WINAPI
NdrContextHandleBufferSize(
6909 PMIDL_STUB_MESSAGE pStubMsg
,
6910 unsigned char *pMemory
,
6911 PFORMAT_STRING pFormat
)
6913 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6915 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6917 ERR("invalid format type %x\n", *pFormat
);
6918 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6920 align_length(&pStubMsg
->BufferLength
, 4);
6921 safe_buffer_length_increment(pStubMsg
, cbNDRContext
);
6924 /***********************************************************************
6925 * NdrContextHandleMarshall [internal]
6927 static unsigned char *WINAPI
NdrContextHandleMarshall(
6928 PMIDL_STUB_MESSAGE pStubMsg
,
6929 unsigned char *pMemory
,
6930 PFORMAT_STRING pFormat
)
6932 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6934 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6936 ERR("invalid format type %x\n", *pFormat
);
6937 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6939 TRACE("flags: 0x%02x\n", pFormat
[1]);
6941 if (pStubMsg
->IsClient
)
6943 if (pFormat
[1] & HANDLE_PARAM_IS_VIA_PTR
)
6944 NdrClientContextMarshall(pStubMsg
, *(NDR_CCONTEXT
**)pMemory
, FALSE
);
6946 NdrClientContextMarshall(pStubMsg
, pMemory
, FALSE
);
6950 NDR_SCONTEXT ctxt
= NDRSContextFromValue(pMemory
);
6951 NDR_RUNDOWN rundown
= pStubMsg
->StubDesc
->apfnNdrRundownRoutines
[pFormat
[2]];
6952 NdrServerContextNewMarshall(pStubMsg
, ctxt
, rundown
, pFormat
);
6958 /***********************************************************************
6959 * NdrContextHandleUnmarshall [internal]
6961 static unsigned char *WINAPI
NdrContextHandleUnmarshall(
6962 PMIDL_STUB_MESSAGE pStubMsg
,
6963 unsigned char **ppMemory
,
6964 PFORMAT_STRING pFormat
,
6965 unsigned char fMustAlloc
)
6967 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg
,
6968 ppMemory
, pFormat
, fMustAlloc
? "TRUE": "FALSE");
6970 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6972 ERR("invalid format type %x\n", *pFormat
);
6973 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6975 TRACE("flags: 0x%02x\n", pFormat
[1]);
6977 if (pStubMsg
->IsClient
)
6979 /* [out]-only or [ret] param */
6980 if ((pFormat
[1] & (HANDLE_PARAM_IS_IN
|HANDLE_PARAM_IS_OUT
)) == HANDLE_PARAM_IS_OUT
)
6981 **(NDR_CCONTEXT
**)ppMemory
= NULL
;
6982 NdrClientContextUnmarshall(pStubMsg
, *(NDR_CCONTEXT
**)ppMemory
, pStubMsg
->RpcMsg
->Handle
);
6987 ctxt
= NdrServerContextNewUnmarshall(pStubMsg
, pFormat
);
6988 if (pFormat
[1] & HANDLE_PARAM_IS_VIA_PTR
)
6989 *(void **)ppMemory
= NDRSContextValue(ctxt
);
6991 *(void **)ppMemory
= *NDRSContextValue(ctxt
);
6997 /***********************************************************************
6998 * NdrClientContextMarshall [RPCRT4.@]
7000 void WINAPI
NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7001 NDR_CCONTEXT ContextHandle
,
7004 TRACE("(%p, %p, %d)\n", pStubMsg
, ContextHandle
, fCheck
);
7006 align_pointer_clear(&pStubMsg
->Buffer
, 4);
7008 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7010 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7011 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7012 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7015 /* FIXME: what does fCheck do? */
7016 NDRCContextMarshall(ContextHandle
,
7019 pStubMsg
->Buffer
+= cbNDRContext
;
7022 /***********************************************************************
7023 * NdrClientContextUnmarshall [RPCRT4.@]
7025 void WINAPI
NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7026 NDR_CCONTEXT
* pContextHandle
,
7027 RPC_BINDING_HANDLE BindHandle
)
7029 TRACE("(%p, %p, %p)\n", pStubMsg
, pContextHandle
, BindHandle
);
7031 align_pointer(&pStubMsg
->Buffer
, 4);
7033 if (pStubMsg
->Buffer
+ cbNDRContext
> pStubMsg
->BufferEnd
)
7034 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7036 NDRCContextUnmarshall(pContextHandle
,
7039 pStubMsg
->RpcMsg
->DataRepresentation
);
7041 pStubMsg
->Buffer
+= cbNDRContext
;
7044 void WINAPI
NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7045 NDR_SCONTEXT ContextHandle
,
7046 NDR_RUNDOWN RundownRoutine
)
7048 TRACE("(%p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
);
7050 align_pointer(&pStubMsg
->Buffer
, 4);
7052 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7054 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7055 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7056 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7059 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
7060 pStubMsg
->Buffer
, RundownRoutine
, NULL
,
7061 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
7062 pStubMsg
->Buffer
+= cbNDRContext
;
7065 NDR_SCONTEXT WINAPI
NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
)
7067 NDR_SCONTEXT ContextHandle
;
7069 TRACE("(%p)\n", pStubMsg
);
7071 align_pointer(&pStubMsg
->Buffer
, 4);
7073 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7075 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7076 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7077 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7080 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
7082 pStubMsg
->RpcMsg
->DataRepresentation
,
7083 NULL
, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
7084 pStubMsg
->Buffer
+= cbNDRContext
;
7086 return ContextHandle
;
7089 void WINAPI
NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg
,
7090 unsigned char* pMemory
,
7091 PFORMAT_STRING pFormat
)
7093 FIXME("(%p, %p, %p): stub\n", pStubMsg
, pMemory
, pFormat
);
7096 NDR_SCONTEXT WINAPI
NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg
,
7097 PFORMAT_STRING pFormat
)
7099 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
7100 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
7102 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
7104 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
7105 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
7106 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
7107 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
7108 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
7110 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
7111 if_id
= &sif
->InterfaceId
;
7114 return NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
, NULL
,
7115 pStubMsg
->RpcMsg
->DataRepresentation
, if_id
,
7119 void WINAPI
NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7120 NDR_SCONTEXT ContextHandle
,
7121 NDR_RUNDOWN RundownRoutine
,
7122 PFORMAT_STRING pFormat
)
7124 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
7125 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
7127 TRACE("(%p, %p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
, pFormat
);
7129 align_pointer(&pStubMsg
->Buffer
, 4);
7131 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7133 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7134 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7135 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7138 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
7139 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
7140 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
7141 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
7142 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
7144 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
7145 if_id
= &sif
->InterfaceId
;
7148 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
7149 pStubMsg
->Buffer
, RundownRoutine
, if_id
, flags
);
7150 pStubMsg
->Buffer
+= cbNDRContext
;
7153 NDR_SCONTEXT WINAPI
NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7154 PFORMAT_STRING pFormat
)
7156 NDR_SCONTEXT ContextHandle
;
7157 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
7158 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
7160 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
7162 align_pointer(&pStubMsg
->Buffer
, 4);
7164 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7166 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7167 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7168 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7171 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
7172 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
7173 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
7174 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
7175 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
7177 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
7178 if_id
= &sif
->InterfaceId
;
7181 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
7183 pStubMsg
->RpcMsg
->DataRepresentation
,
7185 pStubMsg
->Buffer
+= cbNDRContext
;
7187 return ContextHandle
;
7190 /***********************************************************************
7191 * NdrCorrelationInitialize [RPCRT4.@]
7193 * Initializes correlation validity checking.
7196 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7197 * pMemory [I] Pointer to memory to use as a cache.
7198 * CacheSize [I] Size of the memory pointed to by pMemory.
7199 * Flags [I] Reserved. Set to zero.
7204 void WINAPI
NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg
, void *pMemory
, ULONG CacheSize
, ULONG Flags
)
7206 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg
, pMemory
, CacheSize
, Flags
);
7207 pStubMsg
->fHasNewCorrDesc
= TRUE
;
7210 /***********************************************************************
7211 * NdrCorrelationPass [RPCRT4.@]
7213 * Performs correlation validity checking.
7216 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7221 void WINAPI
NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg
)
7223 FIXME("(%p): stub\n", pStubMsg
);
7226 /***********************************************************************
7227 * NdrCorrelationFree [RPCRT4.@]
7229 * Frees any resources used while unmarshalling parameters that need
7230 * correlation validity checking.
7233 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7238 void WINAPI
NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg
)
7240 FIXME("(%p): stub\n", pStubMsg
);