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=%ld\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 ULONG_PTR max_count
, old_max_count
= pStubMsg
->MaxCount
;
595 pStubMsg
->StackTop
= ptr
;
597 /* ofs is index into StubDesc->apfnExprEval */
598 TRACE("callback conformance into apfnExprEval[%d]\n", ofs
);
599 pStubMsg
->StubDesc
->apfnExprEval
[ofs
](pStubMsg
);
601 pStubMsg
->StackTop
= old_stack_top
;
603 /* the callback function always stores the computed value in MaxCount */
604 max_count
= pStubMsg
->MaxCount
;
605 pStubMsg
->MaxCount
= old_max_count
;
610 ptr
= (char *)ptr
+ ofs
;
623 data
= *(USHORT
*)ptr
;
634 data
= *(ULONGLONG
*)ptr
;
637 FIXME("unknown conformance data type %x\n", dtype
);
640 TRACE("dereferenced data type %x at %p, got %ld\n", dtype
, ptr
, data
);
643 switch (pFormat
[1]) {
644 case RPC_FC_DEREFERENCE
: /* already handled */
661 FIXME("unknown conformance op %d\n", pFormat
[1]);
666 TRACE("resulting conformance is %ld\n", *pCount
);
667 if (pStubMsg
->fHasNewCorrDesc
)
673 static inline PFORMAT_STRING
SkipConformance(PMIDL_STUB_MESSAGE pStubMsg
,
674 PFORMAT_STRING pFormat
)
676 if (pStubMsg
->fHasNewCorrDesc
)
683 static inline PFORMAT_STRING
SkipVariance(PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
685 return SkipConformance( pStubMsg
, pFormat
);
688 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
689 * the result overflows 32-bits */
690 static inline ULONG
safe_multiply(ULONG a
, ULONG b
)
692 ULONGLONG ret
= (ULONGLONG
)a
* b
;
693 if (ret
> 0xffffffff)
695 RpcRaiseException(RPC_S_INVALID_BOUND
);
701 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
703 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
704 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
705 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
706 pStubMsg
->Buffer
+= size
;
709 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
711 if (pStubMsg
->BufferLength
+ size
< pStubMsg
->BufferLength
) /* integer overflow of pStubMsg->BufferSize */
713 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
714 pStubMsg
->BufferLength
, size
);
715 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
717 pStubMsg
->BufferLength
+= size
;
720 /* copies data from the buffer, checking that there is enough data in the buffer
722 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, void *p
, ULONG size
)
724 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
725 (pStubMsg
->Buffer
+ size
> pStubMsg
->BufferEnd
))
727 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
728 pStubMsg
->Buffer
, pStubMsg
->BufferEnd
, size
);
729 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
731 if (p
== pStubMsg
->Buffer
)
732 ERR("pointer is the same as the buffer\n");
733 memcpy(p
, pStubMsg
->Buffer
, size
);
734 pStubMsg
->Buffer
+= size
;
737 /* copies data to the buffer, checking that there is enough space to do so */
738 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, const void *p
, ULONG size
)
740 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
741 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
743 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
744 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
,
746 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
748 memcpy(pStubMsg
->Buffer
, p
, size
);
749 pStubMsg
->Buffer
+= size
;
752 /* verify that string data sitting in the buffer is valid and safe to
754 static void validate_string_data(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG bufsize
, ULONG esize
)
758 /* verify the buffer is safe to access */
759 if ((pStubMsg
->Buffer
+ bufsize
< pStubMsg
->Buffer
) ||
760 (pStubMsg
->Buffer
+ bufsize
> pStubMsg
->BufferEnd
))
762 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize
,
763 pStubMsg
->BufferEnd
, pStubMsg
->Buffer
);
764 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
767 /* strings must always have null terminating bytes */
770 ERR("invalid string length of %d\n", bufsize
/ esize
);
771 RpcRaiseException(RPC_S_INVALID_BOUND
);
774 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
775 if (pStubMsg
->Buffer
[i
] != 0)
777 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
778 i
, pStubMsg
->Buffer
[i
]);
779 RpcRaiseException(RPC_S_INVALID_BOUND
);
783 static inline void dump_pointer_attr(unsigned char attr
)
785 if (attr
& RPC_FC_P_ALLOCALLNODES
)
786 TRACE(" RPC_FC_P_ALLOCALLNODES");
787 if (attr
& RPC_FC_P_DONTFREE
)
788 TRACE(" RPC_FC_P_DONTFREE");
789 if (attr
& RPC_FC_P_ONSTACK
)
790 TRACE(" RPC_FC_P_ONSTACK");
791 if (attr
& RPC_FC_P_SIMPLEPOINTER
)
792 TRACE(" RPC_FC_P_SIMPLEPOINTER");
793 if (attr
& RPC_FC_P_DEREF
)
794 TRACE(" RPC_FC_P_DEREF");
798 /***********************************************************************
799 * PointerMarshall [internal]
801 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
802 unsigned char *Buffer
,
803 unsigned char *Pointer
,
804 PFORMAT_STRING pFormat
)
806 unsigned type
= pFormat
[0], attr
= pFormat
[1];
810 BOOL pointer_needs_marshaling
;
812 TRACE("(%p,%p,%p,%p)\n", pStubMsg
, Buffer
, Pointer
, pFormat
);
813 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
815 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
816 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
819 case RPC_FC_RP
: /* ref pointer (always non-null) */
822 ERR("NULL ref pointer is not allowed\n");
823 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
825 pointer_needs_marshaling
= TRUE
;
827 case RPC_FC_UP
: /* unique pointer */
828 case RPC_FC_OP
: /* object pointer - same as unique here */
830 pointer_needs_marshaling
= TRUE
;
832 pointer_needs_marshaling
= FALSE
;
833 pointer_id
= Pointer
? NDR_POINTER_ID(pStubMsg
) : 0;
834 TRACE("writing 0x%08x to buffer\n", pointer_id
);
835 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
838 pointer_needs_marshaling
= !NdrFullPointerQueryPointer(
839 pStubMsg
->FullPtrXlatTables
, Pointer
, 1, &pointer_id
);
840 TRACE("writing 0x%08x to buffer\n", pointer_id
);
841 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
844 FIXME("unhandled ptr type=%02x\n", type
);
845 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
849 TRACE("calling marshaller for type 0x%x\n", (int)*desc
);
851 if (pointer_needs_marshaling
) {
852 if (attr
& RPC_FC_P_DEREF
) {
853 Pointer
= *(unsigned char**)Pointer
;
854 TRACE("deref => %p\n", Pointer
);
856 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
857 if (m
) m(pStubMsg
, Pointer
, desc
);
858 else FIXME("no marshaller for data type=%02x\n", *desc
);
861 STD_OVERFLOW_CHECK(pStubMsg
);
864 /***********************************************************************
865 * PointerUnmarshall [internal]
867 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
868 unsigned char *Buffer
,
869 unsigned char **pPointer
,
870 unsigned char *pSrcPointer
,
871 PFORMAT_STRING pFormat
,
872 unsigned char fMustAlloc
)
874 unsigned type
= pFormat
[0], attr
= pFormat
[1];
877 DWORD pointer_id
= 0;
878 BOOL pointer_needs_unmarshaling
;
880 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg
, Buffer
, pPointer
, pSrcPointer
, pFormat
, fMustAlloc
);
881 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
883 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
884 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
887 case RPC_FC_RP
: /* ref pointer (always non-null) */
888 pointer_needs_unmarshaling
= TRUE
;
890 case RPC_FC_UP
: /* unique pointer */
891 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
892 TRACE("pointer_id is 0x%08x\n", pointer_id
);
894 pointer_needs_unmarshaling
= TRUE
;
897 pointer_needs_unmarshaling
= FALSE
;
900 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
901 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
902 TRACE("pointer_id is 0x%08x\n", pointer_id
);
903 if (!fMustAlloc
&& pSrcPointer
)
905 FIXME("free object pointer %p\n", pSrcPointer
);
909 pointer_needs_unmarshaling
= TRUE
;
913 pointer_needs_unmarshaling
= FALSE
;
917 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
918 TRACE("pointer_id is 0x%08x\n", pointer_id
);
919 pointer_needs_unmarshaling
= !NdrFullPointerQueryRefId(
920 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, (void **)pPointer
);
923 FIXME("unhandled ptr type=%02x\n", type
);
924 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
928 if (pointer_needs_unmarshaling
) {
929 unsigned char **current_ptr
= pPointer
;
930 if (pStubMsg
->IsClient
) {
932 /* if we aren't forcing allocation of memory then try to use the existing
933 * (source) pointer to unmarshall the data into so that [in,out]
934 * parameters behave correctly. it doesn't matter if the parameter is
935 * [out] only since in that case the pointer will be NULL. we force
936 * allocation when the source pointer is NULL here instead of in the type
937 * unmarshalling routine for the benefit of the deref code below */
940 TRACE("setting *pPointer to %p\n", pSrcPointer
);
941 *pPointer
= pSrcPointer
;
947 /* the memory in a stub is never initialised, so we have to work out here
948 * whether we have to initialise it so we can use the optimisation of
949 * setting the pointer to the buffer, if possible, or set fMustAlloc to
951 if (attr
& RPC_FC_P_DEREF
) {
958 if (attr
& RPC_FC_P_ALLOCALLNODES
)
959 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
961 if (attr
& RPC_FC_P_DEREF
) {
963 unsigned char *base_ptr_val
= NdrAllocate(pStubMsg
, sizeof(void *));
964 *pPointer
= base_ptr_val
;
965 current_ptr
= (unsigned char **)base_ptr_val
;
967 current_ptr
= *(unsigned char***)current_ptr
;
968 TRACE("deref => %p\n", current_ptr
);
969 if (!fMustAlloc
&& !*current_ptr
) fMustAlloc
= TRUE
;
971 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
972 if (m
) m(pStubMsg
, current_ptr
, desc
, fMustAlloc
);
973 else FIXME("no unmarshaller for data type=%02x\n", *desc
);
975 if (type
== RPC_FC_FP
)
976 NdrFullPointerInsertRefId(pStubMsg
->FullPtrXlatTables
, pointer_id
,
980 TRACE("pointer=%p\n", *pPointer
);
983 /***********************************************************************
984 * PointerBufferSize [internal]
986 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
987 unsigned char *Pointer
,
988 PFORMAT_STRING pFormat
)
990 unsigned type
= pFormat
[0], attr
= pFormat
[1];
993 BOOL pointer_needs_sizing
;
996 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
997 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
999 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1000 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1003 case RPC_FC_RP
: /* ref pointer (always non-null) */
1006 ERR("NULL ref pointer is not allowed\n");
1007 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
1012 /* NULL pointer has no further representation */
1017 pointer_needs_sizing
= !NdrFullPointerQueryPointer(
1018 pStubMsg
->FullPtrXlatTables
, Pointer
, 0, &pointer_id
);
1019 if (!pointer_needs_sizing
)
1023 FIXME("unhandled ptr type=%02x\n", type
);
1024 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1028 if (attr
& RPC_FC_P_DEREF
) {
1029 Pointer
= *(unsigned char**)Pointer
;
1030 TRACE("deref => %p\n", Pointer
);
1033 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
1034 if (m
) m(pStubMsg
, Pointer
, desc
);
1035 else FIXME("no buffersizer for data type=%02x\n", *desc
);
1038 /***********************************************************************
1039 * PointerMemorySize [internal]
1041 static ULONG
PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1042 unsigned char *Buffer
, PFORMAT_STRING pFormat
)
1044 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1045 PFORMAT_STRING desc
;
1047 DWORD pointer_id
= 0;
1048 BOOL pointer_needs_sizing
;
1050 TRACE("(%p,%p,%p)\n", pStubMsg
, Buffer
, pFormat
);
1051 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1053 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1054 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1057 case RPC_FC_RP
: /* ref pointer (always non-null) */
1058 pointer_needs_sizing
= TRUE
;
1060 case RPC_FC_UP
: /* unique pointer */
1061 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
1062 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1063 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1065 pointer_needs_sizing
= TRUE
;
1067 pointer_needs_sizing
= FALSE
;
1072 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1073 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1074 pointer_needs_sizing
= !NdrFullPointerQueryRefId(
1075 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, &pointer
);
1079 FIXME("unhandled ptr type=%02x\n", type
);
1080 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1084 if (attr
& RPC_FC_P_DEREF
) {
1085 align_length(&pStubMsg
->MemorySize
, sizeof(void*));
1086 pStubMsg
->MemorySize
+= sizeof(void*);
1090 if (pointer_needs_sizing
) {
1091 m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
1092 if (m
) m(pStubMsg
, desc
);
1093 else FIXME("no memorysizer for data type=%02x\n", *desc
);
1096 return pStubMsg
->MemorySize
;
1099 /***********************************************************************
1100 * PointerFree [internal]
1102 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1103 unsigned char *Pointer
,
1104 PFORMAT_STRING pFormat
)
1106 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1107 PFORMAT_STRING desc
;
1109 unsigned char *current_pointer
= Pointer
;
1111 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1112 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1113 if (attr
& RPC_FC_P_DONTFREE
) return;
1115 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1116 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1118 if (!Pointer
) return;
1120 if (type
== RPC_FC_FP
) {
1121 int pointer_needs_freeing
= NdrFullPointerFree(
1122 pStubMsg
->FullPtrXlatTables
, Pointer
);
1123 if (!pointer_needs_freeing
)
1127 if (attr
& RPC_FC_P_DEREF
) {
1128 current_pointer
= *(unsigned char**)Pointer
;
1129 TRACE("deref => %p\n", current_pointer
);
1132 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
1133 if (m
) m(pStubMsg
, current_pointer
, desc
);
1135 /* this check stops us from trying to free buffer memory. we don't have to
1136 * worry about clients, since they won't call this function.
1137 * we don't have to check for the buffer being reallocated because
1138 * BufferStart and BufferEnd won't be reset when allocating memory for
1139 * sending the response. we don't have to check for the new buffer here as
1140 * it won't be used a type memory, only for buffer memory */
1141 if (Pointer
>= pStubMsg
->BufferStart
&& Pointer
< pStubMsg
->BufferEnd
)
1144 if (attr
& RPC_FC_P_ONSTACK
) {
1145 TRACE("not freeing stack ptr %p\n", Pointer
);
1148 TRACE("freeing %p\n", Pointer
);
1149 NdrFree(pStubMsg
, Pointer
);
1152 TRACE("not freeing %p\n", Pointer
);
1155 /***********************************************************************
1156 * EmbeddedPointerMarshall
1158 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1159 unsigned char *pMemory
,
1160 PFORMAT_STRING pFormat
)
1162 unsigned char *Mark
= pStubMsg
->BufferMark
;
1163 unsigned rep
, count
, stride
;
1165 unsigned char *saved_buffer
= NULL
;
1167 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1169 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1172 if (pStubMsg
->PointerBufferMark
)
1174 saved_buffer
= pStubMsg
->Buffer
;
1175 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1176 pStubMsg
->PointerBufferMark
= NULL
;
1179 while (pFormat
[0] != RPC_FC_END
) {
1180 switch (pFormat
[0]) {
1182 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat
[0]);
1184 case RPC_FC_NO_REPEAT
:
1190 case RPC_FC_FIXED_REPEAT
:
1191 rep
= *(const WORD
*)&pFormat
[2];
1192 stride
= *(const WORD
*)&pFormat
[4];
1193 count
= *(const WORD
*)&pFormat
[8];
1196 case RPC_FC_VARIABLE_REPEAT
:
1197 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1198 stride
= *(const WORD
*)&pFormat
[2];
1199 count
= *(const WORD
*)&pFormat
[6];
1203 for (i
= 0; i
< rep
; i
++) {
1204 PFORMAT_STRING info
= pFormat
;
1205 unsigned char *membase
= pMemory
+ (i
* stride
);
1206 unsigned char *bufbase
= Mark
+ (i
* stride
);
1209 for (u
=0; u
<count
; u
++,info
+=8) {
1210 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1211 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1212 unsigned char *saved_memory
= pStubMsg
->Memory
;
1214 pStubMsg
->Memory
= pMemory
;
1215 PointerMarshall(pStubMsg
, bufptr
, *(unsigned char**)memptr
, info
+4);
1216 pStubMsg
->Memory
= saved_memory
;
1219 pFormat
+= 8 * count
;
1224 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1225 pStubMsg
->Buffer
= saved_buffer
;
1228 STD_OVERFLOW_CHECK(pStubMsg
);
1233 /***********************************************************************
1234 * EmbeddedPointerUnmarshall
1236 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1237 unsigned char *pDstBuffer
,
1238 unsigned char *pSrcMemoryPtrs
,
1239 PFORMAT_STRING pFormat
,
1240 unsigned char fMustAlloc
)
1242 unsigned char *Mark
= pStubMsg
->BufferMark
;
1243 unsigned rep
, count
, stride
;
1245 unsigned char *saved_buffer
= NULL
;
1247 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg
, pDstBuffer
, pSrcMemoryPtrs
, pFormat
, fMustAlloc
);
1249 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1252 if (pStubMsg
->PointerBufferMark
)
1254 saved_buffer
= pStubMsg
->Buffer
;
1255 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1256 pStubMsg
->PointerBufferMark
= NULL
;
1259 while (pFormat
[0] != RPC_FC_END
) {
1260 TRACE("pFormat[0] = 0x%x\n", pFormat
[0]);
1261 switch (pFormat
[0]) {
1263 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat
[0]);
1265 case RPC_FC_NO_REPEAT
:
1271 case RPC_FC_FIXED_REPEAT
:
1272 rep
= *(const WORD
*)&pFormat
[2];
1273 stride
= *(const WORD
*)&pFormat
[4];
1274 count
= *(const WORD
*)&pFormat
[8];
1277 case RPC_FC_VARIABLE_REPEAT
:
1278 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1279 stride
= *(const WORD
*)&pFormat
[2];
1280 count
= *(const WORD
*)&pFormat
[6];
1284 for (i
= 0; i
< rep
; i
++) {
1285 PFORMAT_STRING info
= pFormat
;
1286 unsigned char *bufdstbase
= pDstBuffer
+ (i
* stride
);
1287 unsigned char *memsrcbase
= pSrcMemoryPtrs
+ (i
* stride
);
1288 unsigned char *bufbase
= Mark
+ (i
* stride
);
1291 for (u
=0; u
<count
; u
++,info
+=8) {
1292 unsigned char **bufdstptr
= (unsigned char **)(bufdstbase
+ *(const SHORT
*)&info
[2]);
1293 unsigned char **memsrcptr
= (unsigned char **)(memsrcbase
+ *(const SHORT
*)&info
[0]);
1294 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1295 PointerUnmarshall(pStubMsg
, bufptr
, bufdstptr
, *memsrcptr
, info
+4, fMustAlloc
);
1298 pFormat
+= 8 * count
;
1303 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1304 pStubMsg
->Buffer
= saved_buffer
;
1310 /***********************************************************************
1311 * EmbeddedPointerBufferSize
1313 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1314 unsigned char *pMemory
,
1315 PFORMAT_STRING pFormat
)
1317 unsigned rep
, count
, stride
;
1319 ULONG saved_buffer_length
= 0;
1321 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1323 if (pStubMsg
->IgnoreEmbeddedPointers
) return;
1325 if (*pFormat
!= RPC_FC_PP
) return;
1328 if (pStubMsg
->PointerLength
)
1330 saved_buffer_length
= pStubMsg
->BufferLength
;
1331 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
1332 pStubMsg
->PointerLength
= 0;
1335 while (pFormat
[0] != RPC_FC_END
) {
1336 switch (pFormat
[0]) {
1338 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat
[0]);
1340 case RPC_FC_NO_REPEAT
:
1346 case RPC_FC_FIXED_REPEAT
:
1347 rep
= *(const WORD
*)&pFormat
[2];
1348 stride
= *(const WORD
*)&pFormat
[4];
1349 count
= *(const WORD
*)&pFormat
[8];
1352 case RPC_FC_VARIABLE_REPEAT
:
1353 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1354 stride
= *(const WORD
*)&pFormat
[2];
1355 count
= *(const WORD
*)&pFormat
[6];
1359 for (i
= 0; i
< rep
; i
++) {
1360 PFORMAT_STRING info
= pFormat
;
1361 unsigned char *membase
= pMemory
+ (i
* stride
);
1364 for (u
=0; u
<count
; u
++,info
+=8) {
1365 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1366 unsigned char *saved_memory
= pStubMsg
->Memory
;
1368 pStubMsg
->Memory
= pMemory
;
1369 PointerBufferSize(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1370 pStubMsg
->Memory
= saved_memory
;
1373 pFormat
+= 8 * count
;
1376 if (saved_buffer_length
)
1378 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
1379 pStubMsg
->BufferLength
= saved_buffer_length
;
1383 /***********************************************************************
1384 * EmbeddedPointerMemorySize [internal]
1386 static ULONG
EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1387 PFORMAT_STRING pFormat
)
1389 unsigned char *Mark
= pStubMsg
->BufferMark
;
1390 unsigned rep
, count
, stride
;
1392 unsigned char *saved_buffer
= NULL
;
1394 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1396 if (pStubMsg
->IgnoreEmbeddedPointers
) return 0;
1398 if (pStubMsg
->PointerBufferMark
)
1400 saved_buffer
= pStubMsg
->Buffer
;
1401 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1402 pStubMsg
->PointerBufferMark
= NULL
;
1405 if (*pFormat
!= RPC_FC_PP
) return 0;
1408 while (pFormat
[0] != RPC_FC_END
) {
1409 switch (pFormat
[0]) {
1411 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat
[0]);
1413 case RPC_FC_NO_REPEAT
:
1419 case RPC_FC_FIXED_REPEAT
:
1420 rep
= *(const WORD
*)&pFormat
[2];
1421 stride
= *(const WORD
*)&pFormat
[4];
1422 count
= *(const WORD
*)&pFormat
[8];
1425 case RPC_FC_VARIABLE_REPEAT
:
1426 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1427 stride
= *(const WORD
*)&pFormat
[2];
1428 count
= *(const WORD
*)&pFormat
[6];
1432 for (i
= 0; i
< rep
; i
++) {
1433 PFORMAT_STRING info
= pFormat
;
1434 unsigned char *bufbase
= Mark
+ (i
* stride
);
1436 for (u
=0; u
<count
; u
++,info
+=8) {
1437 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1438 PointerMemorySize(pStubMsg
, bufptr
, info
+4);
1441 pFormat
+= 8 * count
;
1446 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1447 pStubMsg
->Buffer
= saved_buffer
;
1453 /***********************************************************************
1454 * EmbeddedPointerFree [internal]
1456 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1457 unsigned char *pMemory
,
1458 PFORMAT_STRING pFormat
)
1460 unsigned rep
, count
, stride
;
1463 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1464 if (*pFormat
!= RPC_FC_PP
) return;
1467 while (pFormat
[0] != RPC_FC_END
) {
1468 switch (pFormat
[0]) {
1470 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat
[0]);
1472 case RPC_FC_NO_REPEAT
:
1478 case RPC_FC_FIXED_REPEAT
:
1479 rep
= *(const WORD
*)&pFormat
[2];
1480 stride
= *(const WORD
*)&pFormat
[4];
1481 count
= *(const WORD
*)&pFormat
[8];
1484 case RPC_FC_VARIABLE_REPEAT
:
1485 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1486 stride
= *(const WORD
*)&pFormat
[2];
1487 count
= *(const WORD
*)&pFormat
[6];
1491 for (i
= 0; i
< rep
; i
++) {
1492 PFORMAT_STRING info
= pFormat
;
1493 unsigned char *membase
= pMemory
+ (i
* stride
);
1496 for (u
=0; u
<count
; u
++,info
+=8) {
1497 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1498 unsigned char *saved_memory
= pStubMsg
->Memory
;
1500 pStubMsg
->Memory
= pMemory
;
1501 PointerFree(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1502 pStubMsg
->Memory
= saved_memory
;
1505 pFormat
+= 8 * count
;
1509 /***********************************************************************
1510 * NdrPointerMarshall [RPCRT4.@]
1512 unsigned char * WINAPI
NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1513 unsigned char *pMemory
,
1514 PFORMAT_STRING pFormat
)
1516 unsigned char *Buffer
;
1518 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1520 /* Increment the buffer here instead of in PointerMarshall,
1521 * as that is used by embedded pointers which already handle the incrementing
1522 * the buffer, and shouldn't write any additional pointer data to the wire */
1523 if (*pFormat
!= RPC_FC_RP
)
1525 align_pointer_clear(&pStubMsg
->Buffer
, 4);
1526 Buffer
= pStubMsg
->Buffer
;
1527 safe_buffer_increment(pStubMsg
, 4);
1530 Buffer
= pStubMsg
->Buffer
;
1532 PointerMarshall(pStubMsg
, Buffer
, pMemory
, pFormat
);
1537 /***********************************************************************
1538 * NdrPointerUnmarshall [RPCRT4.@]
1540 unsigned char * WINAPI
NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1541 unsigned char **ppMemory
,
1542 PFORMAT_STRING pFormat
,
1543 unsigned char fMustAlloc
)
1545 unsigned char *Buffer
;
1547 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1549 if (*pFormat
== RPC_FC_RP
)
1551 Buffer
= pStubMsg
->Buffer
;
1552 /* Do the NULL ref pointer check here because embedded pointers can be
1553 * NULL if the type the pointer is embedded in was allocated rather than
1554 * being passed in by the client */
1555 if (pStubMsg
->IsClient
&& !*ppMemory
)
1557 ERR("NULL ref pointer is not allowed\n");
1558 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
1563 /* Increment the buffer here instead of in PointerUnmarshall,
1564 * as that is used by embedded pointers which already handle the incrementing
1565 * the buffer, and shouldn't read any additional pointer data from the
1567 align_pointer(&pStubMsg
->Buffer
, 4);
1568 Buffer
= pStubMsg
->Buffer
;
1569 safe_buffer_increment(pStubMsg
, 4);
1572 PointerUnmarshall(pStubMsg
, Buffer
, ppMemory
, *ppMemory
, pFormat
, fMustAlloc
);
1577 /***********************************************************************
1578 * NdrPointerBufferSize [RPCRT4.@]
1580 void WINAPI
NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1581 unsigned char *pMemory
,
1582 PFORMAT_STRING pFormat
)
1584 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1586 /* Increment the buffer length here instead of in PointerBufferSize,
1587 * as that is used by embedded pointers which already handle the buffer
1588 * length, and shouldn't write anything more to the wire */
1589 if (*pFormat
!= RPC_FC_RP
)
1591 align_length(&pStubMsg
->BufferLength
, 4);
1592 safe_buffer_length_increment(pStubMsg
, 4);
1595 PointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1598 /***********************************************************************
1599 * NdrPointerMemorySize [RPCRT4.@]
1601 ULONG WINAPI
NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1602 PFORMAT_STRING pFormat
)
1604 unsigned char *Buffer
= pStubMsg
->Buffer
;
1605 if (*pFormat
!= RPC_FC_RP
)
1607 align_pointer(&pStubMsg
->Buffer
, 4);
1608 safe_buffer_increment(pStubMsg
, 4);
1610 align_length(&pStubMsg
->MemorySize
, sizeof(void *));
1611 return PointerMemorySize(pStubMsg
, Buffer
, pFormat
);
1614 /***********************************************************************
1615 * NdrPointerFree [RPCRT4.@]
1617 void WINAPI
NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1618 unsigned char *pMemory
,
1619 PFORMAT_STRING pFormat
)
1621 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1622 PointerFree(pStubMsg
, pMemory
, pFormat
);
1625 /***********************************************************************
1626 * NdrSimpleTypeMarshall [RPCRT4.@]
1628 void WINAPI
NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1629 unsigned char FormatChar
)
1631 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &FormatChar
);
1634 /***********************************************************************
1635 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1637 * Unmarshall a base type.
1640 * Doesn't check that the buffer is long enough before copying, so the caller
1643 void WINAPI
NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1644 unsigned char FormatChar
)
1646 #define BASE_TYPE_UNMARSHALL(type) \
1647 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
1648 TRACE("pMemory: %p\n", pMemory); \
1649 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1650 pStubMsg->Buffer += sizeof(type);
1658 BASE_TYPE_UNMARSHALL(UCHAR
);
1659 TRACE("value: 0x%02x\n", *pMemory
);
1664 BASE_TYPE_UNMARSHALL(USHORT
);
1665 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
1669 case RPC_FC_ERROR_STATUS_T
:
1671 BASE_TYPE_UNMARSHALL(ULONG
);
1672 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
1675 BASE_TYPE_UNMARSHALL(float);
1676 TRACE("value: %f\n", *(float *)pMemory
);
1679 BASE_TYPE_UNMARSHALL(double);
1680 TRACE("value: %f\n", *(double *)pMemory
);
1683 BASE_TYPE_UNMARSHALL(ULONGLONG
);
1684 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
1687 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
1688 TRACE("pMemory: %p\n", pMemory
);
1689 /* 16-bits on the wire, but int in memory */
1690 *(UINT
*)pMemory
= *(USHORT
*)pStubMsg
->Buffer
;
1691 pStubMsg
->Buffer
+= sizeof(USHORT
);
1692 TRACE("value: 0x%08x\n", *(UINT
*)pMemory
);
1694 case RPC_FC_INT3264
:
1695 align_pointer(&pStubMsg
->Buffer
, sizeof(INT
));
1696 /* 32-bits on the wire, but int_ptr in memory */
1697 *(INT_PTR
*)pMemory
= *(INT
*)pStubMsg
->Buffer
;
1698 pStubMsg
->Buffer
+= sizeof(INT
);
1699 TRACE("value: 0x%08lx\n", *(INT_PTR
*)pMemory
);
1701 case RPC_FC_UINT3264
:
1702 align_pointer(&pStubMsg
->Buffer
, sizeof(UINT
));
1703 /* 32-bits on the wire, but int_ptr in memory */
1704 *(UINT_PTR
*)pMemory
= *(UINT
*)pStubMsg
->Buffer
;
1705 pStubMsg
->Buffer
+= sizeof(UINT
);
1706 TRACE("value: 0x%08lx\n", *(UINT_PTR
*)pMemory
);
1711 FIXME("Unhandled base type: 0x%02x\n", FormatChar
);
1713 #undef BASE_TYPE_UNMARSHALL
1716 /***********************************************************************
1717 * NdrSimpleStructMarshall [RPCRT4.@]
1719 unsigned char * WINAPI
NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1720 unsigned char *pMemory
,
1721 PFORMAT_STRING pFormat
)
1723 unsigned size
= *(const WORD
*)(pFormat
+2);
1724 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1726 align_pointer_clear(&pStubMsg
->Buffer
, pFormat
[1] + 1);
1728 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1729 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
1731 if (pFormat
[0] != RPC_FC_STRUCT
)
1732 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
+4);
1737 /***********************************************************************
1738 * NdrSimpleStructUnmarshall [RPCRT4.@]
1740 unsigned char * WINAPI
NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1741 unsigned char **ppMemory
,
1742 PFORMAT_STRING pFormat
,
1743 unsigned char fMustAlloc
)
1745 unsigned size
= *(const WORD
*)(pFormat
+2);
1746 unsigned char *saved_buffer
;
1747 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1749 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
1752 *ppMemory
= NdrAllocate(pStubMsg
, size
);
1755 if (!pStubMsg
->IsClient
&& !*ppMemory
)
1756 /* for servers, we just point straight into the RPC buffer */
1757 *ppMemory
= pStubMsg
->Buffer
;
1760 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1761 safe_buffer_increment(pStubMsg
, size
);
1762 if (pFormat
[0] == RPC_FC_PSTRUCT
)
1763 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
+4, fMustAlloc
);
1765 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
1766 if (*ppMemory
!= saved_buffer
)
1767 memcpy(*ppMemory
, saved_buffer
, size
);
1772 /***********************************************************************
1773 * NdrSimpleStructBufferSize [RPCRT4.@]
1775 void WINAPI
NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1776 unsigned char *pMemory
,
1777 PFORMAT_STRING pFormat
)
1779 unsigned size
= *(const WORD
*)(pFormat
+2);
1780 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1782 align_length(&pStubMsg
->BufferLength
, pFormat
[1] + 1);
1784 safe_buffer_length_increment(pStubMsg
, size
);
1785 if (pFormat
[0] != RPC_FC_STRUCT
)
1786 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
+4);
1789 /***********************************************************************
1790 * NdrSimpleStructMemorySize [RPCRT4.@]
1792 ULONG WINAPI
NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1793 PFORMAT_STRING pFormat
)
1795 unsigned short size
= *(const WORD
*)(pFormat
+2);
1797 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1799 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
1800 pStubMsg
->MemorySize
+= size
;
1801 safe_buffer_increment(pStubMsg
, size
);
1803 if (pFormat
[0] != RPC_FC_STRUCT
)
1804 EmbeddedPointerMemorySize(pStubMsg
, pFormat
+4);
1805 return pStubMsg
->MemorySize
;
1808 /***********************************************************************
1809 * NdrSimpleStructFree [RPCRT4.@]
1811 void WINAPI
NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
1812 unsigned char *pMemory
,
1813 PFORMAT_STRING pFormat
)
1815 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1816 if (pFormat
[0] != RPC_FC_STRUCT
)
1817 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
+4);
1822 static inline void array_compute_and_size_conformance(
1823 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1824 PFORMAT_STRING pFormat
)
1831 ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1832 SizeConformance(pStubMsg
);
1834 case RPC_FC_CVARRAY
:
1835 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, 0);
1836 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
1837 SizeConformance(pStubMsg
);
1839 case RPC_FC_C_CSTRING
:
1840 case RPC_FC_C_WSTRING
:
1841 if (fc
== RPC_FC_C_CSTRING
)
1843 TRACE("string=%s\n", debugstr_a((const char *)pMemory
));
1844 pStubMsg
->ActualCount
= strlen((const char *)pMemory
)+1;
1848 TRACE("string=%s\n", debugstr_w((LPCWSTR
)pMemory
));
1849 pStubMsg
->ActualCount
= strlenW((LPCWSTR
)pMemory
)+1;
1852 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
1853 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
1855 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
1857 SizeConformance(pStubMsg
);
1859 case RPC_FC_BOGUS_ARRAY
:
1860 count
= *(const WORD
*)(pFormat
+ 2);
1862 if (IsConformanceOrVariancePresent(pFormat
)) SizeConformance(pStubMsg
);
1863 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, count
);
1864 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
1867 ERR("unknown array format 0x%x\n", fc
);
1868 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1872 static inline void array_buffer_size(
1873 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1874 PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
1878 unsigned char alignment
;
1883 esize
= *(const WORD
*)(pFormat
+2);
1884 alignment
= pFormat
[1] + 1;
1886 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1888 align_length(&pStubMsg
->BufferLength
, alignment
);
1890 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
1891 /* conformance value plus array */
1892 safe_buffer_length_increment(pStubMsg
, size
);
1895 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1897 case RPC_FC_CVARRAY
:
1898 esize
= *(const WORD
*)(pFormat
+2);
1899 alignment
= pFormat
[1] + 1;
1901 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1902 pFormat
= SkipVariance(pStubMsg
, pFormat
);
1904 SizeVariance(pStubMsg
);
1906 align_length(&pStubMsg
->BufferLength
, alignment
);
1908 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1909 safe_buffer_length_increment(pStubMsg
, size
);
1912 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1914 case RPC_FC_C_CSTRING
:
1915 case RPC_FC_C_WSTRING
:
1916 if (fc
== RPC_FC_C_CSTRING
)
1921 SizeVariance(pStubMsg
);
1923 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1924 safe_buffer_length_increment(pStubMsg
, size
);
1926 case RPC_FC_BOGUS_ARRAY
:
1927 alignment
= pFormat
[1] + 1;
1928 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1929 if (IsConformanceOrVariancePresent(pFormat
)) SizeVariance(pStubMsg
);
1930 pFormat
= SkipVariance(pStubMsg
, pFormat
);
1932 align_length(&pStubMsg
->BufferLength
, alignment
);
1934 size
= pStubMsg
->ActualCount
;
1935 for (i
= 0; i
< size
; i
++)
1936 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
1939 ERR("unknown array format 0x%x\n", fc
);
1940 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1944 static inline void array_compute_and_write_conformance(
1945 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1946 PFORMAT_STRING pFormat
)
1949 BOOL conformance_present
;
1954 ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1955 WriteConformance(pStubMsg
);
1957 case RPC_FC_CVARRAY
:
1958 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, 0);
1959 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
1960 WriteConformance(pStubMsg
);
1962 case RPC_FC_C_CSTRING
:
1963 case RPC_FC_C_WSTRING
:
1964 if (fc
== RPC_FC_C_CSTRING
)
1966 TRACE("string=%s\n", debugstr_a((const char *)pMemory
));
1967 pStubMsg
->ActualCount
= strlen((const char *)pMemory
)+1;
1971 TRACE("string=%s\n", debugstr_w((LPCWSTR
)pMemory
));
1972 pStubMsg
->ActualCount
= strlenW((LPCWSTR
)pMemory
)+1;
1974 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
1975 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
1977 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
1978 pStubMsg
->Offset
= 0;
1979 WriteConformance(pStubMsg
);
1981 case RPC_FC_BOGUS_ARRAY
:
1982 def
= *(const WORD
*)(pFormat
+ 2);
1984 conformance_present
= IsConformanceOrVariancePresent(pFormat
);
1985 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
1986 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
1987 if (conformance_present
) WriteConformance(pStubMsg
);
1990 ERR("unknown array format 0x%x\n", fc
);
1991 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1995 static inline void array_write_variance_and_marshall(
1996 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1997 PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
2001 unsigned char alignment
;
2006 esize
= *(const WORD
*)(pFormat
+2);
2007 alignment
= pFormat
[1] + 1;
2009 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2011 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
2013 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2015 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2016 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
2019 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2021 case RPC_FC_CVARRAY
:
2022 esize
= *(const WORD
*)(pFormat
+2);
2023 alignment
= pFormat
[1] + 1;
2025 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2026 pFormat
= SkipVariance(pStubMsg
, pFormat
);
2028 WriteVariance(pStubMsg
);
2030 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
2032 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2035 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2036 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, size
);
2039 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2041 case RPC_FC_C_CSTRING
:
2042 case RPC_FC_C_WSTRING
:
2043 if (fc
== RPC_FC_C_CSTRING
)
2048 WriteVariance(pStubMsg
);
2050 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2051 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
2053 case RPC_FC_BOGUS_ARRAY
:
2054 alignment
= pFormat
[1] + 1;
2055 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2056 if (IsConformanceOrVariancePresent(pFormat
)) WriteVariance(pStubMsg
);
2057 pFormat
= SkipVariance(pStubMsg
, pFormat
);
2059 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
2061 size
= pStubMsg
->ActualCount
;
2062 for (i
= 0; i
< size
; i
++)
2063 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
2066 ERR("unknown array format 0x%x\n", fc
);
2067 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2071 static inline ULONG
array_read_conformance(
2072 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
2079 esize
= *(const WORD
*)(pFormat
+2);
2080 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2081 return safe_multiply(esize
, pStubMsg
->MaxCount
);
2082 case RPC_FC_CVARRAY
:
2083 esize
= *(const WORD
*)(pFormat
+2);
2084 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2085 return safe_multiply(esize
, pStubMsg
->MaxCount
);
2086 case RPC_FC_C_CSTRING
:
2087 case RPC_FC_C_WSTRING
:
2088 if (fc
== RPC_FC_C_CSTRING
)
2093 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
2094 ReadConformance(pStubMsg
, pFormat
+ 2);
2096 ReadConformance(pStubMsg
, NULL
);
2097 return safe_multiply(esize
, pStubMsg
->MaxCount
);
2098 case RPC_FC_BOGUS_ARRAY
:
2099 def
= *(const WORD
*)(pFormat
+ 2);
2101 if (IsConformanceOrVariancePresent(pFormat
)) pFormat
= ReadConformance(pStubMsg
, pFormat
);
2104 pStubMsg
->MaxCount
= def
;
2105 pFormat
= SkipConformance( pStubMsg
, pFormat
);
2107 pFormat
= SkipVariance( pStubMsg
, pFormat
);
2109 esize
= ComplexStructSize(pStubMsg
, pFormat
);
2110 return safe_multiply(pStubMsg
->MaxCount
, esize
);
2112 ERR("unknown array format 0x%x\n", fc
);
2113 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2117 static inline ULONG
array_read_variance_and_unmarshall(
2118 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char **ppMemory
,
2119 PFORMAT_STRING pFormat
, unsigned char fMustAlloc
,
2120 unsigned char fUseBufferMemoryServer
, unsigned char fUnmarshall
)
2122 ULONG bufsize
, memsize
;
2124 unsigned char alignment
;
2125 unsigned char *saved_buffer
, *pMemory
;
2126 ULONG i
, offset
, count
;
2131 esize
= *(const WORD
*)(pFormat
+2);
2132 alignment
= pFormat
[1] + 1;
2134 bufsize
= memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2136 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2138 align_pointer(&pStubMsg
->Buffer
, alignment
);
2143 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2146 if (fUseBufferMemoryServer
&& !pStubMsg
->IsClient
&& !*ppMemory
)
2147 /* for servers, we just point straight into the RPC buffer */
2148 *ppMemory
= pStubMsg
->Buffer
;
2151 saved_buffer
= pStubMsg
->Buffer
;
2152 safe_buffer_increment(pStubMsg
, bufsize
);
2154 pStubMsg
->BufferMark
= saved_buffer
;
2155 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
2157 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
2158 if (*ppMemory
!= saved_buffer
)
2159 memcpy(*ppMemory
, saved_buffer
, bufsize
);
2162 case RPC_FC_CVARRAY
:
2163 esize
= *(const WORD
*)(pFormat
+2);
2164 alignment
= pFormat
[1] + 1;
2166 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2168 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2170 align_pointer(&pStubMsg
->Buffer
, alignment
);
2172 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2173 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2177 offset
= pStubMsg
->Offset
;
2179 if (!fMustAlloc
&& !*ppMemory
)
2182 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2183 saved_buffer
= pStubMsg
->Buffer
;
2184 safe_buffer_increment(pStubMsg
, bufsize
);
2186 pStubMsg
->BufferMark
= saved_buffer
;
2187 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
,
2190 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
2193 case RPC_FC_C_CSTRING
:
2194 case RPC_FC_C_WSTRING
:
2195 if (fc
== RPC_FC_C_CSTRING
)
2200 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
2202 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
2204 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2205 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
2206 RpcRaiseException(RPC_S_INVALID_BOUND
);
2208 if (pStubMsg
->Offset
)
2210 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2211 RpcRaiseException(RPC_S_INVALID_BOUND
);
2214 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2215 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2217 validate_string_data(pStubMsg
, bufsize
, esize
);
2222 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2225 if (fUseBufferMemoryServer
&& !pStubMsg
->IsClient
&&
2226 !*ppMemory
&& (pStubMsg
->MaxCount
== pStubMsg
->ActualCount
))
2227 /* if the data in the RPC buffer is big enough, we just point
2228 * straight into it */
2229 *ppMemory
= pStubMsg
->Buffer
;
2230 else if (!*ppMemory
)
2231 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2234 if (*ppMemory
== pStubMsg
->Buffer
)
2235 safe_buffer_increment(pStubMsg
, bufsize
);
2237 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
2239 if (*pFormat
== RPC_FC_C_CSTRING
)
2240 TRACE("string=%s\n", debugstr_a((char*)*ppMemory
));
2242 TRACE("string=%s\n", debugstr_w((LPWSTR
)*ppMemory
));
2246 case RPC_FC_BOGUS_ARRAY
:
2247 alignment
= pFormat
[1] + 1;
2248 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2249 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2251 esize
= ComplexStructSize(pStubMsg
, pFormat
);
2252 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2254 assert( fUnmarshall
);
2256 if (!fMustAlloc
&& !*ppMemory
)
2259 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2261 align_pointer(&pStubMsg
->Buffer
, alignment
);
2262 saved_buffer
= pStubMsg
->Buffer
;
2264 pMemory
= *ppMemory
;
2265 count
= pStubMsg
->ActualCount
;
2266 for (i
= 0; i
< count
; i
++)
2267 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
, fMustAlloc
);
2268 return pStubMsg
->Buffer
- saved_buffer
;
2271 ERR("unknown array format 0x%x\n", fc
);
2272 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2276 static inline void array_memory_size(
2277 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
,
2278 unsigned char fHasPointers
)
2280 ULONG i
, count
, SavedMemorySize
;
2281 ULONG bufsize
, memsize
;
2283 unsigned char alignment
;
2288 esize
= *(const WORD
*)(pFormat
+2);
2289 alignment
= pFormat
[1] + 1;
2291 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2293 bufsize
= memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2294 pStubMsg
->MemorySize
+= memsize
;
2296 align_pointer(&pStubMsg
->Buffer
, alignment
);
2298 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2299 safe_buffer_increment(pStubMsg
, bufsize
);
2302 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2304 case RPC_FC_CVARRAY
:
2305 esize
= *(const WORD
*)(pFormat
+2);
2306 alignment
= pFormat
[1] + 1;
2308 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2310 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2312 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2313 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2314 pStubMsg
->MemorySize
+= memsize
;
2316 align_pointer(&pStubMsg
->Buffer
, alignment
);
2318 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2319 safe_buffer_increment(pStubMsg
, bufsize
);
2322 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2324 case RPC_FC_C_CSTRING
:
2325 case RPC_FC_C_WSTRING
:
2326 if (fc
== RPC_FC_C_CSTRING
)
2331 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
2333 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
2335 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2336 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
2337 RpcRaiseException(RPC_S_INVALID_BOUND
);
2339 if (pStubMsg
->Offset
)
2341 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2342 RpcRaiseException(RPC_S_INVALID_BOUND
);
2345 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2346 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2348 validate_string_data(pStubMsg
, bufsize
, esize
);
2350 safe_buffer_increment(pStubMsg
, bufsize
);
2351 pStubMsg
->MemorySize
+= memsize
;
2353 case RPC_FC_BOGUS_ARRAY
:
2354 alignment
= pFormat
[1] + 1;
2355 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2356 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2358 align_pointer(&pStubMsg
->Buffer
, alignment
);
2360 SavedMemorySize
= pStubMsg
->MemorySize
;
2362 esize
= ComplexStructSize(pStubMsg
, pFormat
);
2363 memsize
= safe_multiply(pStubMsg
->MaxCount
, esize
);
2365 count
= pStubMsg
->ActualCount
;
2366 for (i
= 0; i
< count
; i
++)
2367 ComplexStructMemorySize(pStubMsg
, pFormat
, NULL
);
2369 pStubMsg
->MemorySize
= SavedMemorySize
+ memsize
;
2372 ERR("unknown array format 0x%x\n", fc
);
2373 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2377 static inline void array_free(
2378 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
,
2379 unsigned char *pMemory
, PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
2386 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2388 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2390 case RPC_FC_CVARRAY
:
2391 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2392 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2394 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2396 case RPC_FC_C_CSTRING
:
2397 case RPC_FC_C_WSTRING
:
2398 /* No embedded pointers so nothing to do */
2400 case RPC_FC_BOGUS_ARRAY
:
2401 count
= *(const WORD
*)(pFormat
+ 2);
2402 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, count
);
2403 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
2405 count
= pStubMsg
->ActualCount
;
2406 for (i
= 0; i
< count
; i
++)
2407 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
2410 ERR("unknown array format 0x%x\n", fc
);
2411 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2416 * NdrConformantString:
2418 * What MS calls a ConformantString is, in DCE terminology,
2419 * a Varying-Conformant String.
2421 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2422 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2423 * into unmarshalled string)
2424 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2426 * data: CHARTYPE[maxlen]
2428 * ], where CHARTYPE is the appropriate character type (specified externally)
2432 /***********************************************************************
2433 * NdrConformantStringMarshall [RPCRT4.@]
2435 unsigned char *WINAPI
NdrConformantStringMarshall(MIDL_STUB_MESSAGE
*pStubMsg
,
2436 unsigned char *pszMessage
, PFORMAT_STRING pFormat
)
2438 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg
, pszMessage
, pFormat
);
2440 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2441 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2442 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2445 /* allow compiler to optimise inline function by passing constant into
2446 * these functions */
2447 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2448 array_compute_and_write_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pszMessage
,
2450 array_write_variance_and_marshall(RPC_FC_C_CSTRING
, pStubMsg
, pszMessage
,
2451 pFormat
, TRUE
/* fHasPointers */);
2453 array_compute_and_write_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pszMessage
,
2455 array_write_variance_and_marshall(RPC_FC_C_WSTRING
, pStubMsg
, pszMessage
,
2456 pFormat
, TRUE
/* fHasPointers */);
2462 /***********************************************************************
2463 * NdrConformantStringBufferSize [RPCRT4.@]
2465 void WINAPI
NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2466 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
2468 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2470 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2471 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2472 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2475 /* allow compiler to optimise inline function by passing constant into
2476 * these functions */
2477 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2478 array_compute_and_size_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pMemory
,
2480 array_buffer_size(RPC_FC_C_CSTRING
, pStubMsg
, pMemory
, pFormat
,
2481 TRUE
/* fHasPointers */);
2483 array_compute_and_size_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pMemory
,
2485 array_buffer_size(RPC_FC_C_WSTRING
, pStubMsg
, pMemory
, pFormat
,
2486 TRUE
/* fHasPointers */);
2490 /************************************************************************
2491 * NdrConformantStringMemorySize [RPCRT4.@]
2493 ULONG WINAPI
NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
2494 PFORMAT_STRING pFormat
)
2496 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
2498 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2499 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2500 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2503 /* allow compiler to optimise inline function by passing constant into
2504 * these functions */
2505 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2506 array_read_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
);
2507 array_memory_size(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
,
2508 TRUE
/* fHasPointers */);
2510 array_read_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
);
2511 array_memory_size(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
,
2512 TRUE
/* fHasPointers */);
2515 return pStubMsg
->MemorySize
;
2518 /************************************************************************
2519 * NdrConformantStringUnmarshall [RPCRT4.@]
2521 unsigned char *WINAPI
NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2522 unsigned char** ppMemory
, PFORMAT_STRING pFormat
, unsigned char fMustAlloc
)
2524 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2525 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
2527 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2528 ERR("Unhandled string type: %#x\n", *pFormat
);
2529 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2532 /* allow compiler to optimise inline function by passing constant into
2533 * these functions */
2534 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2535 array_read_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
);
2536 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING
, pStubMsg
, ppMemory
,
2537 pFormat
, fMustAlloc
,
2538 TRUE
/* fUseBufferMemoryServer */,
2539 TRUE
/* fUnmarshall */);
2541 array_read_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
);
2542 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING
, pStubMsg
, ppMemory
,
2543 pFormat
, fMustAlloc
,
2544 TRUE
/* fUseBufferMemoryServer */,
2545 TRUE
/* fUnmarshall */);
2551 /***********************************************************************
2552 * NdrNonConformantStringMarshall [RPCRT4.@]
2554 unsigned char * WINAPI
NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2555 unsigned char *pMemory
,
2556 PFORMAT_STRING pFormat
)
2558 ULONG esize
, size
, maxsize
;
2560 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2562 maxsize
= *(const USHORT
*)&pFormat
[2];
2564 if (*pFormat
== RPC_FC_CSTRING
)
2567 const char *str
= (const char *)pMemory
;
2568 while (i
< maxsize
&& str
[i
]) i
++;
2569 TRACE("string=%s\n", debugstr_an(str
, i
));
2570 pStubMsg
->ActualCount
= i
+ 1;
2573 else if (*pFormat
== RPC_FC_WSTRING
)
2576 const WCHAR
*str
= (const WCHAR
*)pMemory
;
2577 while (i
< maxsize
&& str
[i
]) i
++;
2578 TRACE("string=%s\n", debugstr_wn(str
, i
));
2579 pStubMsg
->ActualCount
= i
+ 1;
2584 ERR("Unhandled string type: %#x\n", *pFormat
);
2585 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2588 pStubMsg
->Offset
= 0;
2589 WriteVariance(pStubMsg
);
2591 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2592 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
2597 /***********************************************************************
2598 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2600 unsigned char * WINAPI
NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2601 unsigned char **ppMemory
,
2602 PFORMAT_STRING pFormat
,
2603 unsigned char fMustAlloc
)
2605 ULONG bufsize
, memsize
, esize
, maxsize
;
2607 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2608 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
2610 maxsize
= *(const USHORT
*)&pFormat
[2];
2612 ReadVariance(pStubMsg
, NULL
, maxsize
);
2613 if (pStubMsg
->Offset
)
2615 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2616 RpcRaiseException(RPC_S_INVALID_BOUND
);
2619 if (*pFormat
== RPC_FC_CSTRING
) esize
= 1;
2620 else if (*pFormat
== RPC_FC_WSTRING
) esize
= 2;
2623 ERR("Unhandled string type: %#x\n", *pFormat
);
2624 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2627 memsize
= esize
* maxsize
;
2628 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2630 validate_string_data(pStubMsg
, bufsize
, esize
);
2632 if (!fMustAlloc
&& !*ppMemory
)
2635 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2637 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
2639 if (*pFormat
== RPC_FC_CSTRING
) {
2640 TRACE("string=%s\n", debugstr_an((char*)*ppMemory
, pStubMsg
->ActualCount
));
2642 else if (*pFormat
== RPC_FC_WSTRING
) {
2643 TRACE("string=%s\n", debugstr_wn((LPWSTR
)*ppMemory
, pStubMsg
->ActualCount
));
2649 /***********************************************************************
2650 * NdrNonConformantStringBufferSize [RPCRT4.@]
2652 void WINAPI
NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2653 unsigned char *pMemory
,
2654 PFORMAT_STRING pFormat
)
2656 ULONG esize
, maxsize
;
2658 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2660 maxsize
= *(const USHORT
*)&pFormat
[2];
2662 SizeVariance(pStubMsg
);
2664 if (*pFormat
== RPC_FC_CSTRING
)
2667 const char *str
= (const char *)pMemory
;
2668 while (i
< maxsize
&& str
[i
]) i
++;
2669 TRACE("string=%s\n", debugstr_an(str
, i
));
2670 pStubMsg
->ActualCount
= i
+ 1;
2673 else if (*pFormat
== RPC_FC_WSTRING
)
2676 const WCHAR
*str
= (const WCHAR
*)pMemory
;
2677 while (i
< maxsize
&& str
[i
]) i
++;
2678 TRACE("string=%s\n", debugstr_wn(str
, i
));
2679 pStubMsg
->ActualCount
= i
+ 1;
2684 ERR("Unhandled string type: %#x\n", *pFormat
);
2685 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2688 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
2691 /***********************************************************************
2692 * NdrNonConformantStringMemorySize [RPCRT4.@]
2694 ULONG WINAPI
NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2695 PFORMAT_STRING pFormat
)
2697 ULONG bufsize
, memsize
, esize
, maxsize
;
2699 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
2701 maxsize
= *(const USHORT
*)&pFormat
[2];
2703 ReadVariance(pStubMsg
, NULL
, maxsize
);
2705 if (pStubMsg
->Offset
)
2707 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2708 RpcRaiseException(RPC_S_INVALID_BOUND
);
2711 if (*pFormat
== RPC_FC_CSTRING
) esize
= 1;
2712 else if (*pFormat
== RPC_FC_WSTRING
) esize
= 2;
2715 ERR("Unhandled string type: %#x\n", *pFormat
);
2716 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2719 memsize
= esize
* maxsize
;
2720 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2722 validate_string_data(pStubMsg
, bufsize
, esize
);
2724 safe_buffer_increment(pStubMsg
, bufsize
);
2725 pStubMsg
->MemorySize
+= memsize
;
2727 return pStubMsg
->MemorySize
;
2732 #include "pshpack1.h"
2736 unsigned char flags_type
; /* flags in upper nibble, type in lower nibble */
2740 #include "poppack.h"
2742 static ULONG
EmbeddedComplexSize(MIDL_STUB_MESSAGE
*pStubMsg
,
2743 PFORMAT_STRING pFormat
)
2747 case RPC_FC_PSTRUCT
:
2748 case RPC_FC_CSTRUCT
:
2749 case RPC_FC_BOGUS_STRUCT
:
2750 case RPC_FC_SMFARRAY
:
2751 case RPC_FC_SMVARRAY
:
2752 case RPC_FC_CSTRING
:
2753 return *(const WORD
*)&pFormat
[2];
2754 case RPC_FC_USER_MARSHAL
:
2755 return *(const WORD
*)&pFormat
[4];
2756 case RPC_FC_RANGE
: {
2757 switch (((const NDR_RANGE
*)pFormat
)->flags_type
& 0xf) {
2762 return sizeof(UCHAR
);
2766 return sizeof(USHORT
);
2770 case RPC_FC_INT3264
:
2771 case RPC_FC_UINT3264
:
2772 return sizeof(ULONG
);
2774 return sizeof(float);
2776 return sizeof(double);
2778 return sizeof(ULONGLONG
);
2780 return sizeof(UINT
);
2782 ERR("unknown type 0x%x\n", ((const NDR_RANGE
*)pFormat
)->flags_type
& 0xf);
2783 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2786 case RPC_FC_NON_ENCAPSULATED_UNION
:
2788 if (pStubMsg
->fHasNewCorrDesc
)
2793 pFormat
+= *(const SHORT
*)pFormat
;
2794 return *(const SHORT
*)pFormat
;
2796 return sizeof(void *);
2797 case RPC_FC_WSTRING
:
2798 return *(const WORD
*)&pFormat
[2] * 2;
2800 FIXME("unhandled embedded type %02x\n", *pFormat
);
2806 static ULONG
EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2807 PFORMAT_STRING pFormat
)
2809 NDR_MEMORYSIZE m
= NdrMemorySizer
[*pFormat
& NDR_TABLE_MASK
];
2813 FIXME("no memorysizer for data type=%02x\n", *pFormat
);
2817 return m(pStubMsg
, pFormat
);
2821 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2822 unsigned char *pMemory
,
2823 PFORMAT_STRING pFormat
,
2824 PFORMAT_STRING pPointer
)
2826 PFORMAT_STRING desc
;
2830 while (*pFormat
!= RPC_FC_END
) {
2836 TRACE("byte=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2837 safe_copy_to_buffer(pStubMsg
, pMemory
, 1);
2843 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2844 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
2849 USHORT val
= *(DWORD
*)pMemory
;
2850 TRACE("enum16=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2851 if (32767 < *(DWORD
*)pMemory
)
2852 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
2853 safe_copy_to_buffer(pStubMsg
, &val
, 2);
2860 TRACE("long=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2861 safe_copy_to_buffer(pStubMsg
, pMemory
, 4);
2864 case RPC_FC_INT3264
:
2865 case RPC_FC_UINT3264
:
2867 UINT val
= *(UINT_PTR
*)pMemory
;
2868 TRACE("int3264=%ld <= %p\n", *(UINT_PTR
*)pMemory
, pMemory
);
2869 safe_copy_to_buffer(pStubMsg
, &val
, sizeof(UINT
));
2870 pMemory
+= sizeof(UINT_PTR
);
2874 TRACE("float=%f <= %p\n", *(float*)pMemory
, pMemory
);
2875 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
2876 pMemory
+= sizeof(float);
2879 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2880 safe_copy_to_buffer(pStubMsg
, pMemory
, 8);
2884 TRACE("double=%f <= %p\n", *(double*)pMemory
, pMemory
);
2885 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
2886 pMemory
+= sizeof(double);
2892 case RPC_FC_POINTER
:
2894 unsigned char *saved_buffer
;
2895 BOOL pointer_buffer_mark_set
= FALSE
;
2896 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
2897 TRACE("pStubMsg->Buffer before %p\n", pStubMsg
->Buffer
);
2898 if (*pFormat
!= RPC_FC_POINTER
)
2900 if (*pPointer
!= RPC_FC_RP
)
2901 align_pointer_clear(&pStubMsg
->Buffer
, 4);
2902 saved_buffer
= pStubMsg
->Buffer
;
2903 if (pStubMsg
->PointerBufferMark
)
2905 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2906 pStubMsg
->PointerBufferMark
= NULL
;
2907 pointer_buffer_mark_set
= TRUE
;
2909 else if (*pPointer
!= RPC_FC_RP
)
2910 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2911 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char**)pMemory
, pPointer
);
2912 if (pointer_buffer_mark_set
)
2914 STD_OVERFLOW_CHECK(pStubMsg
);
2915 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2916 pStubMsg
->Buffer
= saved_buffer
;
2917 if (*pPointer
!= RPC_FC_RP
)
2918 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2920 TRACE("pStubMsg->Buffer after %p\n", pStubMsg
->Buffer
);
2921 if (*pFormat
== RPC_FC_POINTER
)
2925 pMemory
+= sizeof(void *);
2928 case RPC_FC_ALIGNM2
:
2929 align_pointer(&pMemory
, 2);
2931 case RPC_FC_ALIGNM4
:
2932 align_pointer(&pMemory
, 4);
2934 case RPC_FC_ALIGNM8
:
2935 align_pointer(&pMemory
, 8);
2937 case RPC_FC_STRUCTPAD1
:
2938 case RPC_FC_STRUCTPAD2
:
2939 case RPC_FC_STRUCTPAD3
:
2940 case RPC_FC_STRUCTPAD4
:
2941 case RPC_FC_STRUCTPAD5
:
2942 case RPC_FC_STRUCTPAD6
:
2943 case RPC_FC_STRUCTPAD7
:
2944 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2946 case RPC_FC_EMBEDDED_COMPLEX
:
2947 pMemory
+= pFormat
[1];
2949 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2950 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2951 TRACE("embedded complex (size=%d) <= %p\n", size
, pMemory
);
2952 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
2955 /* for some reason interface pointers aren't generated as
2956 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2957 * they still need the derefencing treatment that pointers are
2959 if (*desc
== RPC_FC_IP
)
2960 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2962 m(pStubMsg
, pMemory
, desc
);
2964 else FIXME("no marshaller for embedded type %02x\n", *desc
);
2971 FIXME("unhandled format 0x%02x\n", *pFormat
);
2979 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2980 unsigned char *pMemory
,
2981 PFORMAT_STRING pFormat
,
2982 PFORMAT_STRING pPointer
,
2983 unsigned char fMustAlloc
)
2985 PFORMAT_STRING desc
;
2989 while (*pFormat
!= RPC_FC_END
) {
2995 safe_copy_from_buffer(pStubMsg
, pMemory
, 1);
2996 TRACE("byte=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
3002 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
3003 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
3009 safe_copy_from_buffer(pStubMsg
, &val
, 2);
3010 *(DWORD
*)pMemory
= val
;
3011 TRACE("enum16=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
3012 if (32767 < *(DWORD
*)pMemory
)
3013 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
3020 safe_copy_from_buffer(pStubMsg
, pMemory
, 4);
3021 TRACE("long=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
3024 case RPC_FC_INT3264
:
3027 safe_copy_from_buffer(pStubMsg
, &val
, 4);
3028 *(INT_PTR
*)pMemory
= val
;
3029 TRACE("int3264=%ld => %p\n", *(INT_PTR
*)pMemory
, pMemory
);
3030 pMemory
+= sizeof(INT_PTR
);
3033 case RPC_FC_UINT3264
:
3036 safe_copy_from_buffer(pStubMsg
, &val
, 4);
3037 *(UINT_PTR
*)pMemory
= val
;
3038 TRACE("uint3264=%ld => %p\n", *(UINT_PTR
*)pMemory
, pMemory
);
3039 pMemory
+= sizeof(UINT_PTR
);
3043 safe_copy_from_buffer(pStubMsg
, pMemory
, sizeof(float));
3044 TRACE("float=%f => %p\n", *(float*)pMemory
, pMemory
);
3045 pMemory
+= sizeof(float);
3048 safe_copy_from_buffer(pStubMsg
, pMemory
, 8);
3049 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
3053 safe_copy_from_buffer(pStubMsg
, pMemory
, sizeof(double));
3054 TRACE("double=%f => %p\n", *(double*)pMemory
, pMemory
);
3055 pMemory
+= sizeof(double);
3061 case RPC_FC_POINTER
:
3063 unsigned char *saved_buffer
;
3064 BOOL pointer_buffer_mark_set
= FALSE
;
3065 TRACE("pointer => %p\n", pMemory
);
3066 if (*pFormat
!= RPC_FC_POINTER
)
3068 if (*pPointer
!= RPC_FC_RP
)
3069 align_pointer(&pStubMsg
->Buffer
, 4);
3070 saved_buffer
= pStubMsg
->Buffer
;
3071 if (pStubMsg
->PointerBufferMark
)
3073 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3074 pStubMsg
->PointerBufferMark
= NULL
;
3075 pointer_buffer_mark_set
= TRUE
;
3077 else if (*pPointer
!= RPC_FC_RP
)
3078 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3080 PointerUnmarshall(pStubMsg
, saved_buffer
, (unsigned char**)pMemory
, *(unsigned char**)pMemory
, pPointer
, fMustAlloc
);
3081 if (pointer_buffer_mark_set
)
3083 STD_OVERFLOW_CHECK(pStubMsg
);
3084 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3085 pStubMsg
->Buffer
= saved_buffer
;
3086 if (*pPointer
!= RPC_FC_RP
)
3087 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3089 if (*pFormat
== RPC_FC_POINTER
)
3093 pMemory
+= sizeof(void *);
3096 case RPC_FC_ALIGNM2
:
3097 align_pointer_clear(&pMemory
, 2);
3099 case RPC_FC_ALIGNM4
:
3100 align_pointer_clear(&pMemory
, 4);
3102 case RPC_FC_ALIGNM8
:
3103 align_pointer_clear(&pMemory
, 8);
3105 case RPC_FC_STRUCTPAD1
:
3106 case RPC_FC_STRUCTPAD2
:
3107 case RPC_FC_STRUCTPAD3
:
3108 case RPC_FC_STRUCTPAD4
:
3109 case RPC_FC_STRUCTPAD5
:
3110 case RPC_FC_STRUCTPAD6
:
3111 case RPC_FC_STRUCTPAD7
:
3112 memset(pMemory
, 0, *pFormat
- RPC_FC_STRUCTPAD1
+ 1);
3113 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3115 case RPC_FC_EMBEDDED_COMPLEX
:
3116 pMemory
+= pFormat
[1];
3118 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3119 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3120 TRACE("embedded complex (size=%d) => %p\n", size
, pMemory
);
3122 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
3123 * since the type is part of the memory block that is encompassed by
3124 * the whole complex type. Memory is forced to allocate when pointers
3125 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
3126 * clearing the memory we pass in to the unmarshaller */
3127 memset(pMemory
, 0, size
);
3128 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
3131 /* for some reason interface pointers aren't generated as
3132 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3133 * they still need the derefencing treatment that pointers are
3135 if (*desc
== RPC_FC_IP
)
3136 m(pStubMsg
, (unsigned char **)pMemory
, desc
, FALSE
);
3138 m(pStubMsg
, &pMemory
, desc
, FALSE
);
3140 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
3147 FIXME("unhandled format %d\n", *pFormat
);
3155 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3156 unsigned char *pMemory
,
3157 PFORMAT_STRING pFormat
,
3158 PFORMAT_STRING pPointer
)
3160 PFORMAT_STRING desc
;
3164 while (*pFormat
!= RPC_FC_END
) {
3170 safe_buffer_length_increment(pStubMsg
, 1);
3176 safe_buffer_length_increment(pStubMsg
, 2);
3180 safe_buffer_length_increment(pStubMsg
, 2);
3187 safe_buffer_length_increment(pStubMsg
, 4);
3190 case RPC_FC_INT3264
:
3191 case RPC_FC_UINT3264
:
3192 safe_buffer_length_increment(pStubMsg
, 4);
3193 pMemory
+= sizeof(INT_PTR
);
3197 safe_buffer_length_increment(pStubMsg
, 8);
3204 case RPC_FC_POINTER
:
3205 if (*pFormat
!= RPC_FC_POINTER
)
3207 if (!pStubMsg
->IgnoreEmbeddedPointers
)
3209 int saved_buffer_length
= pStubMsg
->BufferLength
;
3210 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3211 pStubMsg
->PointerLength
= 0;
3212 if(!pStubMsg
->BufferLength
)
3213 ERR("BufferLength == 0??\n");
3214 PointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
3215 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3216 pStubMsg
->BufferLength
= saved_buffer_length
;
3218 if (*pPointer
!= RPC_FC_RP
)
3220 align_length(&pStubMsg
->BufferLength
, 4);
3221 safe_buffer_length_increment(pStubMsg
, 4);
3223 if (*pFormat
== RPC_FC_POINTER
)
3227 pMemory
+= sizeof(void*);
3229 case RPC_FC_ALIGNM2
:
3230 align_pointer(&pMemory
, 2);
3232 case RPC_FC_ALIGNM4
:
3233 align_pointer(&pMemory
, 4);
3235 case RPC_FC_ALIGNM8
:
3236 align_pointer(&pMemory
, 8);
3238 case RPC_FC_STRUCTPAD1
:
3239 case RPC_FC_STRUCTPAD2
:
3240 case RPC_FC_STRUCTPAD3
:
3241 case RPC_FC_STRUCTPAD4
:
3242 case RPC_FC_STRUCTPAD5
:
3243 case RPC_FC_STRUCTPAD6
:
3244 case RPC_FC_STRUCTPAD7
:
3245 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3247 case RPC_FC_EMBEDDED_COMPLEX
:
3248 pMemory
+= pFormat
[1];
3250 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3251 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3252 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
3255 /* for some reason interface pointers aren't generated as
3256 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3257 * they still need the derefencing treatment that pointers are
3259 if (*desc
== RPC_FC_IP
)
3260 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
3262 m(pStubMsg
, pMemory
, desc
);
3264 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
3271 FIXME("unhandled format 0x%02x\n", *pFormat
);
3279 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
3280 unsigned char *pMemory
,
3281 PFORMAT_STRING pFormat
,
3282 PFORMAT_STRING pPointer
)
3284 PFORMAT_STRING desc
;
3288 while (*pFormat
!= RPC_FC_END
) {
3308 case RPC_FC_INT3264
:
3309 case RPC_FC_UINT3264
:
3310 pMemory
+= sizeof(INT_PTR
);
3320 case RPC_FC_POINTER
:
3321 if (*pFormat
!= RPC_FC_POINTER
)
3323 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
3324 if (*pFormat
== RPC_FC_POINTER
)
3328 pMemory
+= sizeof(void *);
3330 case RPC_FC_ALIGNM2
:
3331 align_pointer(&pMemory
, 2);
3333 case RPC_FC_ALIGNM4
:
3334 align_pointer(&pMemory
, 4);
3336 case RPC_FC_ALIGNM8
:
3337 align_pointer(&pMemory
, 8);
3339 case RPC_FC_STRUCTPAD1
:
3340 case RPC_FC_STRUCTPAD2
:
3341 case RPC_FC_STRUCTPAD3
:
3342 case RPC_FC_STRUCTPAD4
:
3343 case RPC_FC_STRUCTPAD5
:
3344 case RPC_FC_STRUCTPAD6
:
3345 case RPC_FC_STRUCTPAD7
:
3346 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3348 case RPC_FC_EMBEDDED_COMPLEX
:
3349 pMemory
+= pFormat
[1];
3351 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3352 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3353 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
3356 /* for some reason interface pointers aren't generated as
3357 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3358 * they still need the derefencing treatment that pointers are
3360 if (*desc
== RPC_FC_IP
)
3361 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
3363 m(pStubMsg
, pMemory
, desc
);
3371 FIXME("unhandled format 0x%02x\n", *pFormat
);
3379 static ULONG
ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3380 PFORMAT_STRING pFormat
,
3381 PFORMAT_STRING pPointer
)
3383 PFORMAT_STRING desc
;
3386 while (*pFormat
!= RPC_FC_END
) {
3393 safe_buffer_increment(pStubMsg
, 1);
3399 safe_buffer_increment(pStubMsg
, 2);
3403 safe_buffer_increment(pStubMsg
, 2);
3410 safe_buffer_increment(pStubMsg
, 4);
3412 case RPC_FC_INT3264
:
3413 case RPC_FC_UINT3264
:
3414 size
+= sizeof(INT_PTR
);
3415 safe_buffer_increment(pStubMsg
, 4);
3420 safe_buffer_increment(pStubMsg
, 8);
3426 case RPC_FC_POINTER
:
3428 unsigned char *saved_buffer
;
3429 BOOL pointer_buffer_mark_set
= FALSE
;
3430 if (*pFormat
!= RPC_FC_POINTER
)
3432 if (*pPointer
!= RPC_FC_RP
)
3433 align_pointer(&pStubMsg
->Buffer
, 4);
3434 saved_buffer
= pStubMsg
->Buffer
;
3435 if (pStubMsg
->PointerBufferMark
)
3437 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3438 pStubMsg
->PointerBufferMark
= NULL
;
3439 pointer_buffer_mark_set
= TRUE
;
3441 else if (*pPointer
!= RPC_FC_RP
)
3442 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3444 if (!pStubMsg
->IgnoreEmbeddedPointers
)
3445 PointerMemorySize(pStubMsg
, saved_buffer
, pPointer
);
3446 if (pointer_buffer_mark_set
)
3448 STD_OVERFLOW_CHECK(pStubMsg
);
3449 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3450 pStubMsg
->Buffer
= saved_buffer
;
3451 if (*pPointer
!= RPC_FC_RP
)
3452 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3454 if (*pFormat
== RPC_FC_POINTER
)
3458 size
+= sizeof(void *);
3461 case RPC_FC_ALIGNM2
:
3462 align_length(&size
, 2);
3464 case RPC_FC_ALIGNM4
:
3465 align_length(&size
, 4);
3467 case RPC_FC_ALIGNM8
:
3468 align_length(&size
, 8);
3470 case RPC_FC_STRUCTPAD1
:
3471 case RPC_FC_STRUCTPAD2
:
3472 case RPC_FC_STRUCTPAD3
:
3473 case RPC_FC_STRUCTPAD4
:
3474 case RPC_FC_STRUCTPAD5
:
3475 case RPC_FC_STRUCTPAD6
:
3476 case RPC_FC_STRUCTPAD7
:
3477 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3479 case RPC_FC_EMBEDDED_COMPLEX
:
3482 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3483 size
+= EmbeddedComplexMemorySize(pStubMsg
, desc
);
3489 FIXME("unhandled format 0x%02x\n", *pFormat
);
3497 ULONG
ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
3499 PFORMAT_STRING desc
;
3502 while (*pFormat
!= RPC_FC_END
) {
3522 case RPC_FC_INT3264
:
3523 case RPC_FC_UINT3264
:
3524 size
+= sizeof(INT_PTR
);
3534 case RPC_FC_POINTER
:
3535 size
+= sizeof(void *);
3536 if (*pFormat
!= RPC_FC_POINTER
)
3539 case RPC_FC_ALIGNM2
:
3540 align_length(&size
, 2);
3542 case RPC_FC_ALIGNM4
:
3543 align_length(&size
, 4);
3545 case RPC_FC_ALIGNM8
:
3546 align_length(&size
, 8);
3548 case RPC_FC_STRUCTPAD1
:
3549 case RPC_FC_STRUCTPAD2
:
3550 case RPC_FC_STRUCTPAD3
:
3551 case RPC_FC_STRUCTPAD4
:
3552 case RPC_FC_STRUCTPAD5
:
3553 case RPC_FC_STRUCTPAD6
:
3554 case RPC_FC_STRUCTPAD7
:
3555 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3557 case RPC_FC_EMBEDDED_COMPLEX
:
3560 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3561 size
+= EmbeddedComplexSize(pStubMsg
, desc
);
3567 FIXME("unhandled format 0x%02x\n", *pFormat
);
3575 /***********************************************************************
3576 * NdrComplexStructMarshall [RPCRT4.@]
3578 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3579 unsigned char *pMemory
,
3580 PFORMAT_STRING pFormat
)
3582 PFORMAT_STRING conf_array
= NULL
;
3583 PFORMAT_STRING pointer_desc
= NULL
;
3584 unsigned char *OldMemory
= pStubMsg
->Memory
;
3585 BOOL pointer_buffer_mark_set
= FALSE
;
3587 ULONG max_count
= 0;
3590 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3592 if (!pStubMsg
->PointerBufferMark
)
3594 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3595 /* save buffer length */
3596 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
3598 /* get the buffer pointer after complex array data, but before
3600 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
;
3601 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3602 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
3603 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3605 /* save it for use by embedded pointer code later */
3606 pStubMsg
->PointerBufferMark
= (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
;
3607 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->PointerBufferMark
- pStubMsg
->Buffer
));
3608 pointer_buffer_mark_set
= TRUE
;
3610 /* restore the original buffer length */
3611 pStubMsg
->BufferLength
= saved_buffer_length
;
3614 align_pointer_clear(&pStubMsg
->Buffer
, pFormat
[1] + 1);
3617 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3619 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3622 pStubMsg
->Memory
= pMemory
;
3626 ULONG struct_size
= ComplexStructSize(pStubMsg
, pFormat
);
3627 array_compute_and_write_conformance(conf_array
[0], pStubMsg
,
3628 pMemory
+ struct_size
, conf_array
);
3629 /* these could be changed in ComplexMarshall so save them for later */
3630 max_count
= pStubMsg
->MaxCount
;
3631 count
= pStubMsg
->ActualCount
;
3632 offset
= pStubMsg
->Offset
;
3635 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3639 pStubMsg
->MaxCount
= max_count
;
3640 pStubMsg
->ActualCount
= count
;
3641 pStubMsg
->Offset
= offset
;
3642 array_write_variance_and_marshall(conf_array
[0], pStubMsg
, pMemory
,
3643 conf_array
, TRUE
/* fHasPointers */);
3646 pStubMsg
->Memory
= OldMemory
;
3648 if (pointer_buffer_mark_set
)
3650 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3651 pStubMsg
->PointerBufferMark
= NULL
;
3654 STD_OVERFLOW_CHECK(pStubMsg
);
3659 /***********************************************************************
3660 * NdrComplexStructUnmarshall [RPCRT4.@]
3662 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3663 unsigned char **ppMemory
,
3664 PFORMAT_STRING pFormat
,
3665 unsigned char fMustAlloc
)
3667 unsigned size
= *(const WORD
*)(pFormat
+2);
3668 PFORMAT_STRING conf_array
= NULL
;
3669 PFORMAT_STRING pointer_desc
= NULL
;
3670 unsigned char *pMemory
;
3671 BOOL pointer_buffer_mark_set
= FALSE
;
3673 ULONG max_count
= 0;
3675 ULONG array_size
= 0;
3677 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3679 if (!pStubMsg
->PointerBufferMark
)
3681 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3682 /* save buffer pointer */
3683 unsigned char *saved_buffer
= pStubMsg
->Buffer
;
3685 /* get the buffer pointer after complex array data, but before
3687 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3688 NdrComplexStructMemorySize(pStubMsg
, pFormat
);
3689 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3691 /* save it for use by embedded pointer code later */
3692 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3693 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->PointerBufferMark
- saved_buffer
));
3694 pointer_buffer_mark_set
= TRUE
;
3696 /* restore the original buffer */
3697 pStubMsg
->Buffer
= saved_buffer
;
3700 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
3703 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3705 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3710 array_size
= array_read_conformance(conf_array
[0], pStubMsg
, conf_array
);
3713 /* these could be changed in ComplexMarshall so save them for later */
3714 max_count
= pStubMsg
->MaxCount
;
3715 count
= pStubMsg
->ActualCount
;
3716 offset
= pStubMsg
->Offset
;
3719 if (!fMustAlloc
&& !*ppMemory
)
3722 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3724 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
, fMustAlloc
);
3728 pStubMsg
->MaxCount
= max_count
;
3729 pStubMsg
->ActualCount
= count
;
3730 pStubMsg
->Offset
= offset
;
3732 memset(pMemory
, 0, array_size
);
3733 array_read_variance_and_unmarshall(conf_array
[0], pStubMsg
, &pMemory
,
3735 FALSE
/* fUseBufferMemoryServer */,
3736 TRUE
/* fUnmarshall */);
3739 if (pointer_buffer_mark_set
)
3741 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3742 pStubMsg
->PointerBufferMark
= NULL
;
3748 /***********************************************************************
3749 * NdrComplexStructBufferSize [RPCRT4.@]
3751 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3752 unsigned char *pMemory
,
3753 PFORMAT_STRING pFormat
)
3755 PFORMAT_STRING conf_array
= NULL
;
3756 PFORMAT_STRING pointer_desc
= NULL
;
3757 unsigned char *OldMemory
= pStubMsg
->Memory
;
3758 int pointer_length_set
= 0;
3760 ULONG max_count
= 0;
3763 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3765 align_length(&pStubMsg
->BufferLength
, pFormat
[1] + 1);
3767 if(!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
3769 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3770 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
3772 /* get the buffer length after complex struct data, but before
3774 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3775 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
3776 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3778 /* save it for use by embedded pointer code later */
3779 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3780 pointer_length_set
= 1;
3781 TRACE("difference = 0x%x\n", pStubMsg
->PointerLength
- saved_buffer_length
);
3783 /* restore the original buffer length */
3784 pStubMsg
->BufferLength
= saved_buffer_length
;
3788 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3790 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3793 pStubMsg
->Memory
= pMemory
;
3797 ULONG struct_size
= ComplexStructSize(pStubMsg
, pFormat
);
3798 array_compute_and_size_conformance(conf_array
[0], pStubMsg
, pMemory
+ struct_size
,
3801 /* these could be changed in ComplexMarshall so save them for later */
3802 max_count
= pStubMsg
->MaxCount
;
3803 count
= pStubMsg
->ActualCount
;
3804 offset
= pStubMsg
->Offset
;
3807 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3811 pStubMsg
->MaxCount
= max_count
;
3812 pStubMsg
->ActualCount
= count
;
3813 pStubMsg
->Offset
= offset
;
3814 array_buffer_size(conf_array
[0], pStubMsg
, pMemory
, conf_array
,
3815 TRUE
/* fHasPointers */);
3818 pStubMsg
->Memory
= OldMemory
;
3820 if(pointer_length_set
)
3822 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3823 pStubMsg
->PointerLength
= 0;
3828 /***********************************************************************
3829 * NdrComplexStructMemorySize [RPCRT4.@]
3831 ULONG WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3832 PFORMAT_STRING pFormat
)
3834 unsigned size
= *(const WORD
*)(pFormat
+2);
3835 PFORMAT_STRING conf_array
= NULL
;
3836 PFORMAT_STRING pointer_desc
= NULL
;
3838 ULONG max_count
= 0;
3841 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3843 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
3846 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3848 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3853 array_read_conformance(conf_array
[0], pStubMsg
, conf_array
);
3855 /* these could be changed in ComplexStructMemorySize so save them for
3857 max_count
= pStubMsg
->MaxCount
;
3858 count
= pStubMsg
->ActualCount
;
3859 offset
= pStubMsg
->Offset
;
3862 ComplexStructMemorySize(pStubMsg
, pFormat
, pointer_desc
);
3866 pStubMsg
->MaxCount
= max_count
;
3867 pStubMsg
->ActualCount
= count
;
3868 pStubMsg
->Offset
= offset
;
3869 array_memory_size(conf_array
[0], pStubMsg
, conf_array
,
3870 TRUE
/* fHasPointers */);
3876 /***********************************************************************
3877 * NdrComplexStructFree [RPCRT4.@]
3879 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3880 unsigned char *pMemory
,
3881 PFORMAT_STRING pFormat
)
3883 PFORMAT_STRING conf_array
= NULL
;
3884 PFORMAT_STRING pointer_desc
= NULL
;
3885 unsigned char *OldMemory
= pStubMsg
->Memory
;
3887 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3890 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3892 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3895 pStubMsg
->Memory
= pMemory
;
3897 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3900 array_free(conf_array
[0], pStubMsg
, pMemory
, conf_array
,
3901 TRUE
/* fHasPointers */);
3903 pStubMsg
->Memory
= OldMemory
;
3906 /***********************************************************************
3907 * NdrConformantArrayMarshall [RPCRT4.@]
3909 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3910 unsigned char *pMemory
,
3911 PFORMAT_STRING pFormat
)
3913 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3914 if (pFormat
[0] != RPC_FC_CARRAY
)
3916 ERR("invalid format = 0x%x\n", pFormat
[0]);
3917 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3920 array_compute_and_write_conformance(RPC_FC_CARRAY
, pStubMsg
, pMemory
,
3922 array_write_variance_and_marshall(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3923 TRUE
/* fHasPointers */);
3928 /***********************************************************************
3929 * NdrConformantArrayUnmarshall [RPCRT4.@]
3931 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3932 unsigned char **ppMemory
,
3933 PFORMAT_STRING pFormat
,
3934 unsigned char fMustAlloc
)
3936 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3937 if (pFormat
[0] != RPC_FC_CARRAY
)
3939 ERR("invalid format = 0x%x\n", pFormat
[0]);
3940 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3943 array_read_conformance(RPC_FC_CARRAY
, pStubMsg
, pFormat
);
3944 array_read_variance_and_unmarshall(RPC_FC_CARRAY
, pStubMsg
, ppMemory
, pFormat
,
3946 TRUE
/* fUseBufferMemoryServer */,
3947 TRUE
/* fUnmarshall */);
3952 /***********************************************************************
3953 * NdrConformantArrayBufferSize [RPCRT4.@]
3955 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3956 unsigned char *pMemory
,
3957 PFORMAT_STRING pFormat
)
3959 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3960 if (pFormat
[0] != RPC_FC_CARRAY
)
3962 ERR("invalid format = 0x%x\n", pFormat
[0]);
3963 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3966 array_compute_and_size_conformance(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
);
3967 array_buffer_size(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3968 TRUE
/* fHasPointers */);
3971 /***********************************************************************
3972 * NdrConformantArrayMemorySize [RPCRT4.@]
3974 ULONG WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3975 PFORMAT_STRING pFormat
)
3977 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3978 if (pFormat
[0] != RPC_FC_CARRAY
)
3980 ERR("invalid format = 0x%x\n", pFormat
[0]);
3981 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3984 array_read_conformance(RPC_FC_CARRAY
, pStubMsg
, pFormat
);
3985 array_memory_size(RPC_FC_CARRAY
, pStubMsg
, pFormat
, TRUE
/* fHasPointers */);
3987 return pStubMsg
->MemorySize
;
3990 /***********************************************************************
3991 * NdrConformantArrayFree [RPCRT4.@]
3993 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3994 unsigned char *pMemory
,
3995 PFORMAT_STRING pFormat
)
3997 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3998 if (pFormat
[0] != RPC_FC_CARRAY
)
4000 ERR("invalid format = 0x%x\n", pFormat
[0]);
4001 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4004 array_free(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
4005 TRUE
/* fHasPointers */);
4009 /***********************************************************************
4010 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
4012 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
4013 unsigned char* pMemory
,
4014 PFORMAT_STRING pFormat
)
4016 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4018 if (pFormat
[0] != RPC_FC_CVARRAY
)
4020 ERR("invalid format type %x\n", pFormat
[0]);
4021 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4025 array_compute_and_write_conformance(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
4027 array_write_variance_and_marshall(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
4028 pFormat
, TRUE
/* fHasPointers */);
4034 /***********************************************************************
4035 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
4037 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
4038 unsigned char** ppMemory
,
4039 PFORMAT_STRING pFormat
,
4040 unsigned char fMustAlloc
)
4042 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4044 if (pFormat
[0] != RPC_FC_CVARRAY
)
4046 ERR("invalid format type %x\n", pFormat
[0]);
4047 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4051 array_read_conformance(RPC_FC_CVARRAY
, pStubMsg
, pFormat
);
4052 array_read_variance_and_unmarshall(RPC_FC_CVARRAY
, pStubMsg
, ppMemory
,
4053 pFormat
, fMustAlloc
,
4054 TRUE
/* fUseBufferMemoryServer */,
4055 TRUE
/* fUnmarshall */);
4061 /***********************************************************************
4062 * NdrConformantVaryingArrayFree [RPCRT4.@]
4064 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
4065 unsigned char* pMemory
,
4066 PFORMAT_STRING pFormat
)
4068 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4070 if (pFormat
[0] != RPC_FC_CVARRAY
)
4072 ERR("invalid format type %x\n", pFormat
[0]);
4073 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4077 array_free(RPC_FC_CVARRAY
, pStubMsg
, pMemory
, pFormat
,
4078 TRUE
/* fHasPointers */);
4082 /***********************************************************************
4083 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
4085 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
4086 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
4088 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4090 if (pFormat
[0] != RPC_FC_CVARRAY
)
4092 ERR("invalid format type %x\n", pFormat
[0]);
4093 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4097 array_compute_and_size_conformance(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
4099 array_buffer_size(RPC_FC_CVARRAY
, pStubMsg
, pMemory
, pFormat
,
4100 TRUE
/* fHasPointers */);
4104 /***********************************************************************
4105 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
4107 ULONG WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
4108 PFORMAT_STRING pFormat
)
4110 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4112 if (pFormat
[0] != RPC_FC_CVARRAY
)
4114 ERR("invalid format type %x\n", pFormat
[0]);
4115 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4116 return pStubMsg
->MemorySize
;
4119 array_read_conformance(RPC_FC_CVARRAY
, pStubMsg
, pFormat
);
4120 array_memory_size(RPC_FC_CVARRAY
, pStubMsg
, pFormat
,
4121 TRUE
/* fHasPointers */);
4123 return pStubMsg
->MemorySize
;
4127 /***********************************************************************
4128 * NdrComplexArrayMarshall [RPCRT4.@]
4130 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4131 unsigned char *pMemory
,
4132 PFORMAT_STRING pFormat
)
4134 BOOL pointer_buffer_mark_set
= FALSE
;
4136 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4138 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4140 ERR("invalid format type %x\n", pFormat
[0]);
4141 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4145 if (!pStubMsg
->PointerBufferMark
)
4147 /* save buffer fields that may be changed by buffer sizer functions
4148 * and that may be needed later on */
4149 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
4150 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
4151 ULONG_PTR saved_max_count
= pStubMsg
->MaxCount
;
4152 ULONG saved_offset
= pStubMsg
->Offset
;
4153 ULONG saved_actual_count
= pStubMsg
->ActualCount
;
4155 /* get the buffer pointer after complex array data, but before
4157 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
;
4158 pStubMsg
->IgnoreEmbeddedPointers
= 1;
4159 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
4160 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
4162 /* save it for use by embedded pointer code later */
4163 pStubMsg
->PointerBufferMark
= (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
;
4164 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
));
4165 pointer_buffer_mark_set
= TRUE
;
4167 /* restore fields */
4168 pStubMsg
->ActualCount
= saved_actual_count
;
4169 pStubMsg
->Offset
= saved_offset
;
4170 pStubMsg
->MaxCount
= saved_max_count
;
4171 pStubMsg
->BufferLength
= saved_buffer_length
;
4174 array_compute_and_write_conformance(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pMemory
, pFormat
);
4175 array_write_variance_and_marshall(RPC_FC_BOGUS_ARRAY
, pStubMsg
,
4176 pMemory
, pFormat
, TRUE
/* fHasPointers */);
4178 STD_OVERFLOW_CHECK(pStubMsg
);
4180 if (pointer_buffer_mark_set
)
4182 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4183 pStubMsg
->PointerBufferMark
= NULL
;
4189 /***********************************************************************
4190 * NdrComplexArrayUnmarshall [RPCRT4.@]
4192 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4193 unsigned char **ppMemory
,
4194 PFORMAT_STRING pFormat
,
4195 unsigned char fMustAlloc
)
4197 unsigned char *saved_buffer
;
4198 BOOL pointer_buffer_mark_set
= FALSE
;
4199 int saved_ignore_embedded
;
4201 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4203 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4205 ERR("invalid format type %x\n", pFormat
[0]);
4206 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4210 saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
4211 /* save buffer pointer */
4212 saved_buffer
= pStubMsg
->Buffer
;
4213 /* get the buffer pointer after complex array data, but before
4215 pStubMsg
->IgnoreEmbeddedPointers
= 1;
4216 pStubMsg
->MemorySize
= 0;
4217 NdrComplexArrayMemorySize(pStubMsg
, pFormat
);
4218 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
4220 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->Buffer
- saved_buffer
));
4221 if (!pStubMsg
->PointerBufferMark
)
4223 /* save it for use by embedded pointer code later */
4224 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4225 pointer_buffer_mark_set
= TRUE
;
4227 /* restore the original buffer */
4228 pStubMsg
->Buffer
= saved_buffer
;
4230 array_read_conformance(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pFormat
);
4231 array_read_variance_and_unmarshall(RPC_FC_BOGUS_ARRAY
, pStubMsg
, ppMemory
, pFormat
, fMustAlloc
,
4232 TRUE
/* fUseBufferMemoryServer */, TRUE
/* fUnmarshall */);
4234 if (pointer_buffer_mark_set
)
4236 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4237 pStubMsg
->PointerBufferMark
= NULL
;
4243 /***********************************************************************
4244 * NdrComplexArrayBufferSize [RPCRT4.@]
4246 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4247 unsigned char *pMemory
,
4248 PFORMAT_STRING pFormat
)
4250 int pointer_length_set
= 0;
4252 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4254 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4256 ERR("invalid format type %x\n", pFormat
[0]);
4257 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4261 if (!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
4263 /* save buffer fields that may be changed by buffer sizer functions
4264 * and that may be needed later on */
4265 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
4266 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
4267 ULONG_PTR saved_max_count
= pStubMsg
->MaxCount
;
4268 ULONG saved_offset
= pStubMsg
->Offset
;
4269 ULONG saved_actual_count
= pStubMsg
->ActualCount
;
4271 /* get the buffer pointer after complex array data, but before
4273 pStubMsg
->IgnoreEmbeddedPointers
= 1;
4274 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
4275 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
4277 /* save it for use by embedded pointer code later */
4278 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4279 pointer_length_set
= 1;
4281 /* restore fields */
4282 pStubMsg
->ActualCount
= saved_actual_count
;
4283 pStubMsg
->Offset
= saved_offset
;
4284 pStubMsg
->MaxCount
= saved_max_count
;
4285 pStubMsg
->BufferLength
= saved_buffer_length
;
4288 array_compute_and_size_conformance(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pMemory
, pFormat
);
4289 array_buffer_size(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pMemory
, pFormat
, TRUE
/* fHasPointers */);
4291 if(pointer_length_set
)
4293 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4294 pStubMsg
->PointerLength
= 0;
4298 /***********************************************************************
4299 * NdrComplexArrayMemorySize [RPCRT4.@]
4301 ULONG WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4302 PFORMAT_STRING pFormat
)
4304 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
4306 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4308 ERR("invalid format type %x\n", pFormat
[0]);
4309 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4313 array_read_conformance(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pFormat
);
4314 array_memory_size(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pFormat
, TRUE
/* fHasPointers */);
4315 return pStubMsg
->MemorySize
;
4318 /***********************************************************************
4319 * NdrComplexArrayFree [RPCRT4.@]
4321 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4322 unsigned char *pMemory
,
4323 PFORMAT_STRING pFormat
)
4325 ULONG i
, count
, def
;
4327 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4329 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4331 ERR("invalid format type %x\n", pFormat
[0]);
4332 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4336 def
= *(const WORD
*)&pFormat
[2];
4339 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
4340 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
4342 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
4343 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
4345 count
= pStubMsg
->ActualCount
;
4346 for (i
= 0; i
< count
; i
++)
4347 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
4350 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg
,
4351 USER_MARSHAL_CB_TYPE cbtype
, PFORMAT_STRING pFormat
,
4352 USER_MARSHAL_CB
*umcb
)
4354 umcb
->Flags
= MAKELONG(pStubMsg
->dwDestContext
,
4355 pStubMsg
->RpcMsg
->DataRepresentation
);
4356 umcb
->pStubMsg
= pStubMsg
;
4357 umcb
->pReserve
= NULL
;
4358 umcb
->Signature
= USER_MARSHAL_CB_SIGNATURE
;
4359 umcb
->CBType
= cbtype
;
4360 umcb
->pFormat
= pFormat
;
4361 umcb
->pTypeFormat
= NULL
/* FIXME */;
4364 #define USER_MARSHAL_PTR_PREFIX \
4365 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4366 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4368 /***********************************************************************
4369 * NdrUserMarshalMarshall [RPCRT4.@]
4371 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4372 unsigned char *pMemory
,
4373 PFORMAT_STRING pFormat
)
4375 unsigned flags
= pFormat
[1];
4376 unsigned index
= *(const WORD
*)&pFormat
[2];
4377 unsigned char *saved_buffer
= NULL
;
4378 USER_MARSHAL_CB umcb
;
4380 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4381 TRACE("index=%d\n", index
);
4383 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_MARSHALL
, pFormat
, &umcb
);
4385 if (flags
& USER_MARSHAL_POINTER
)
4387 align_pointer_clear(&pStubMsg
->Buffer
, 4);
4388 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, USER_MARSHAL_PTR_PREFIX
);
4389 pStubMsg
->Buffer
+= 4;
4390 if (pStubMsg
->PointerBufferMark
)
4392 saved_buffer
= pStubMsg
->Buffer
;
4393 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4394 pStubMsg
->PointerBufferMark
= NULL
;
4396 align_pointer_clear(&pStubMsg
->Buffer
, 8);
4399 align_pointer_clear(&pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4402 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
4403 &umcb
.Flags
, pStubMsg
->Buffer
, pMemory
);
4407 STD_OVERFLOW_CHECK(pStubMsg
);
4408 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4409 pStubMsg
->Buffer
= saved_buffer
;
4412 STD_OVERFLOW_CHECK(pStubMsg
);
4417 /***********************************************************************
4418 * NdrUserMarshalUnmarshall [RPCRT4.@]
4420 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4421 unsigned char **ppMemory
,
4422 PFORMAT_STRING pFormat
,
4423 unsigned char fMustAlloc
)
4425 unsigned flags
= pFormat
[1];
4426 unsigned index
= *(const WORD
*)&pFormat
[2];
4427 DWORD memsize
= *(const WORD
*)&pFormat
[4];
4428 unsigned char *saved_buffer
= NULL
;
4429 USER_MARSHAL_CB umcb
;
4431 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4432 TRACE("index=%d\n", index
);
4434 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_UNMARSHALL
, pFormat
, &umcb
);
4436 if (flags
& USER_MARSHAL_POINTER
)
4438 align_pointer(&pStubMsg
->Buffer
, 4);
4439 /* skip pointer prefix */
4440 pStubMsg
->Buffer
+= 4;
4441 if (pStubMsg
->PointerBufferMark
)
4443 saved_buffer
= pStubMsg
->Buffer
;
4444 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4445 pStubMsg
->PointerBufferMark
= NULL
;
4447 align_pointer(&pStubMsg
->Buffer
, 8);
4450 align_pointer(&pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4452 if (!fMustAlloc
&& !*ppMemory
)
4456 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
4457 memset(*ppMemory
, 0, memsize
);
4461 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
4462 &umcb
.Flags
, pStubMsg
->Buffer
, *ppMemory
);
4466 STD_OVERFLOW_CHECK(pStubMsg
);
4467 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4468 pStubMsg
->Buffer
= saved_buffer
;
4474 /***********************************************************************
4475 * NdrUserMarshalBufferSize [RPCRT4.@]
4477 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4478 unsigned char *pMemory
,
4479 PFORMAT_STRING pFormat
)
4481 unsigned flags
= pFormat
[1];
4482 unsigned index
= *(const WORD
*)&pFormat
[2];
4483 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
4484 USER_MARSHAL_CB umcb
;
4485 ULONG saved_buffer_length
= 0;
4487 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4488 TRACE("index=%d\n", index
);
4490 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_BUFFER_SIZE
, pFormat
, &umcb
);
4492 if (flags
& USER_MARSHAL_POINTER
)
4494 align_length(&pStubMsg
->BufferLength
, 4);
4495 /* skip pointer prefix */
4496 safe_buffer_length_increment(pStubMsg
, 4);
4497 if (pStubMsg
->IgnoreEmbeddedPointers
)
4499 if (pStubMsg
->PointerLength
)
4501 saved_buffer_length
= pStubMsg
->BufferLength
;
4502 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4503 pStubMsg
->PointerLength
= 0;
4505 align_length(&pStubMsg
->BufferLength
, 8);
4508 align_length(&pStubMsg
->BufferLength
, (flags
& 0xf) + 1);
4511 TRACE("size=%d\n", bufsize
);
4512 safe_buffer_length_increment(pStubMsg
, bufsize
);
4515 pStubMsg
->BufferLength
=
4516 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
4517 &umcb
.Flags
, pStubMsg
->BufferLength
, pMemory
);
4519 if (saved_buffer_length
)
4521 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4522 pStubMsg
->BufferLength
= saved_buffer_length
;
4527 /***********************************************************************
4528 * NdrUserMarshalMemorySize [RPCRT4.@]
4530 ULONG WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4531 PFORMAT_STRING pFormat
)
4533 unsigned flags
= pFormat
[1];
4534 unsigned index
= *(const WORD
*)&pFormat
[2];
4535 DWORD memsize
= *(const WORD
*)&pFormat
[4];
4536 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
4538 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
4539 TRACE("index=%d\n", index
);
4541 pStubMsg
->MemorySize
+= memsize
;
4543 if (flags
& USER_MARSHAL_POINTER
)
4545 align_pointer(&pStubMsg
->Buffer
, 4);
4546 /* skip pointer prefix */
4547 pStubMsg
->Buffer
+= 4;
4548 if (pStubMsg
->IgnoreEmbeddedPointers
)
4549 return pStubMsg
->MemorySize
;
4550 align_pointer(&pStubMsg
->Buffer
, 8);
4553 align_pointer(&pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4556 FIXME("not implemented for varying buffer size\n");
4558 pStubMsg
->Buffer
+= bufsize
;
4560 return pStubMsg
->MemorySize
;
4563 /***********************************************************************
4564 * NdrUserMarshalFree [RPCRT4.@]
4566 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
4567 unsigned char *pMemory
,
4568 PFORMAT_STRING pFormat
)
4570 /* unsigned flags = pFormat[1]; */
4571 unsigned index
= *(const WORD
*)&pFormat
[2];
4572 USER_MARSHAL_CB umcb
;
4574 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4575 TRACE("index=%d\n", index
);
4577 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_FREE
, pFormat
, &umcb
);
4579 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
4580 &umcb
.Flags
, pMemory
);
4583 /***********************************************************************
4584 * NdrGetUserMarshalInfo [RPCRT4.@]
4586 RPC_STATUS RPC_ENTRY
NdrGetUserMarshalInfo(ULONG
*flags
, ULONG level
, NDR_USER_MARSHAL_INFO
*umi
)
4588 USER_MARSHAL_CB
*umcb
= CONTAINING_RECORD(flags
, USER_MARSHAL_CB
, Flags
);
4590 TRACE("(%p,%u,%p)\n", flags
, level
, umi
);
4593 return RPC_S_INVALID_ARG
;
4595 memset(&umi
->u1
.Level1
, 0, sizeof(umi
->u1
.Level1
));
4596 umi
->InformationLevel
= level
;
4598 if (umcb
->Signature
!= USER_MARSHAL_CB_SIGNATURE
)
4599 return RPC_S_INVALID_ARG
;
4601 umi
->u1
.Level1
.pfnAllocate
= umcb
->pStubMsg
->pfnAllocate
;
4602 umi
->u1
.Level1
.pfnFree
= umcb
->pStubMsg
->pfnFree
;
4603 umi
->u1
.Level1
.pRpcChannelBuffer
= umcb
->pStubMsg
->pRpcChannelBuffer
;
4605 switch (umcb
->CBType
)
4607 case USER_MARSHAL_CB_MARSHALL
:
4608 case USER_MARSHAL_CB_UNMARSHALL
:
4610 RPC_MESSAGE
*msg
= umcb
->pStubMsg
->RpcMsg
;
4611 unsigned char *buffer_start
= msg
->Buffer
;
4612 unsigned char *buffer_end
=
4613 (unsigned char *)msg
->Buffer
+ msg
->BufferLength
;
4615 if (umcb
->pStubMsg
->Buffer
< buffer_start
||
4616 umcb
->pStubMsg
->Buffer
> buffer_end
)
4617 return ERROR_INVALID_USER_BUFFER
;
4619 umi
->u1
.Level1
.Buffer
= umcb
->pStubMsg
->Buffer
;
4620 umi
->u1
.Level1
.BufferSize
= buffer_end
- umcb
->pStubMsg
->Buffer
;
4623 case USER_MARSHAL_CB_BUFFER_SIZE
:
4624 case USER_MARSHAL_CB_FREE
:
4627 WARN("unrecognised CBType %d\n", umcb
->CBType
);
4633 /***********************************************************************
4634 * NdrClearOutParameters [RPCRT4.@]
4636 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
4637 PFORMAT_STRING pFormat
,
4640 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
4643 /***********************************************************************
4644 * NdrConvert [RPCRT4.@]
4646 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
4648 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
4649 /* FIXME: since this stub doesn't do any converting, the proper behavior
4650 is to raise an exception */
4653 /***********************************************************************
4654 * NdrConvert2 [RPCRT4.@]
4656 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, LONG NumberParams
)
4658 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4659 pStubMsg
, pFormat
, NumberParams
);
4660 /* FIXME: since this stub doesn't do any converting, the proper behavior
4661 is to raise an exception */
4664 #include "pshpack1.h"
4665 typedef struct _NDR_CSTRUCT_FORMAT
4668 unsigned char alignment
;
4669 unsigned short memory_size
;
4670 short offset_to_array_description
;
4671 } NDR_CSTRUCT_FORMAT
, NDR_CVSTRUCT_FORMAT
;
4672 #include "poppack.h"
4674 /***********************************************************************
4675 * NdrConformantStructMarshall [RPCRT4.@]
4677 unsigned char * WINAPI
NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4678 unsigned char *pMemory
,
4679 PFORMAT_STRING pFormat
)
4681 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4682 PFORMAT_STRING pCArrayFormat
;
4683 ULONG esize
, bufsize
;
4685 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4687 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4688 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4690 ERR("invalid format type %x\n", pCStructFormat
->type
);
4691 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4695 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4696 pCStructFormat
->offset_to_array_description
;
4697 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4699 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4700 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4703 esize
= *(const WORD
*)(pCArrayFormat
+2);
4705 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4706 pCArrayFormat
+ 4, 0);
4708 WriteConformance(pStubMsg
);
4710 align_pointer_clear(&pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4712 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4714 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4715 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4717 ERR("integer overflow of memory_size %u with bufsize %u\n",
4718 pCStructFormat
->memory_size
, bufsize
);
4719 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4721 /* copy constant sized part of struct */
4722 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4723 safe_copy_to_buffer(pStubMsg
, pMemory
, pCStructFormat
->memory_size
+ bufsize
);
4725 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4726 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4731 /***********************************************************************
4732 * NdrConformantStructUnmarshall [RPCRT4.@]
4734 unsigned char * WINAPI
NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4735 unsigned char **ppMemory
,
4736 PFORMAT_STRING pFormat
,
4737 unsigned char fMustAlloc
)
4739 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4740 PFORMAT_STRING pCArrayFormat
;
4741 ULONG esize
, bufsize
;
4742 unsigned char *saved_buffer
;
4744 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4746 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4747 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4749 ERR("invalid format type %x\n", pCStructFormat
->type
);
4750 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4753 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4754 pCStructFormat
->offset_to_array_description
;
4755 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4757 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4758 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4761 esize
= *(const WORD
*)(pCArrayFormat
+2);
4763 pCArrayFormat
= ReadConformance(pStubMsg
, pCArrayFormat
+ 4);
4765 align_pointer(&pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4767 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4769 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4770 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4772 ERR("integer overflow of memory_size %u with bufsize %u\n",
4773 pCStructFormat
->memory_size
, bufsize
);
4774 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4779 SIZE_T size
= pCStructFormat
->memory_size
+ bufsize
;
4780 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4784 if (!pStubMsg
->IsClient
&& !*ppMemory
)
4785 /* for servers, we just point straight into the RPC buffer */
4786 *ppMemory
= pStubMsg
->Buffer
;
4789 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4790 safe_buffer_increment(pStubMsg
, pCStructFormat
->memory_size
+ bufsize
);
4791 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4792 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4794 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
4795 if (*ppMemory
!= saved_buffer
)
4796 memcpy(*ppMemory
, saved_buffer
, pCStructFormat
->memory_size
+ bufsize
);
4801 /***********************************************************************
4802 * NdrConformantStructBufferSize [RPCRT4.@]
4804 void WINAPI
NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4805 unsigned char *pMemory
,
4806 PFORMAT_STRING pFormat
)
4808 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4809 PFORMAT_STRING pCArrayFormat
;
4812 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4814 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4815 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4817 ERR("invalid format type %x\n", pCStructFormat
->type
);
4818 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4821 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4822 pCStructFormat
->offset_to_array_description
;
4823 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4825 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4826 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4829 esize
= *(const WORD
*)(pCArrayFormat
+2);
4831 pCArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
, pCArrayFormat
+4, 0);
4832 SizeConformance(pStubMsg
);
4834 align_length(&pStubMsg
->BufferLength
, pCStructFormat
->alignment
+ 1);
4836 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4838 safe_buffer_length_increment(pStubMsg
, pCStructFormat
->memory_size
);
4839 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
4841 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4842 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4845 /***********************************************************************
4846 * NdrConformantStructMemorySize [RPCRT4.@]
4848 ULONG WINAPI
NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4849 PFORMAT_STRING pFormat
)
4855 /***********************************************************************
4856 * NdrConformantStructFree [RPCRT4.@]
4858 void WINAPI
NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
4859 unsigned char *pMemory
,
4860 PFORMAT_STRING pFormat
)
4862 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4863 PFORMAT_STRING pCArrayFormat
;
4865 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4867 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4868 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4870 ERR("invalid format type %x\n", pCStructFormat
->type
);
4871 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4875 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4876 pCStructFormat
->offset_to_array_description
;
4877 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4879 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4880 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4884 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4885 pCArrayFormat
+ 4, 0);
4887 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4889 /* copy constant sized part of struct */
4890 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4892 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4893 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4896 /***********************************************************************
4897 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4899 unsigned char * WINAPI
NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4900 unsigned char *pMemory
,
4901 PFORMAT_STRING pFormat
)
4903 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4904 PFORMAT_STRING pCVArrayFormat
;
4906 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4908 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4909 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4911 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4912 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4916 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4917 pCVStructFormat
->offset_to_array_description
;
4919 array_compute_and_write_conformance(*pCVArrayFormat
, pStubMsg
,
4920 pMemory
+ pCVStructFormat
->memory_size
,
4923 align_pointer_clear(&pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4925 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4927 /* write constant sized part */
4928 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4929 safe_copy_to_buffer(pStubMsg
, pMemory
, pCVStructFormat
->memory_size
);
4931 array_write_variance_and_marshall(*pCVArrayFormat
, pStubMsg
,
4932 pMemory
+ pCVStructFormat
->memory_size
,
4933 pCVArrayFormat
, FALSE
/* fHasPointers */);
4935 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4940 /***********************************************************************
4941 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4943 unsigned char * WINAPI
NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4944 unsigned char **ppMemory
,
4945 PFORMAT_STRING pFormat
,
4946 unsigned char fMustAlloc
)
4948 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4949 PFORMAT_STRING pCVArrayFormat
;
4950 ULONG memsize
, bufsize
;
4951 unsigned char *saved_buffer
, *saved_array_buffer
;
4953 unsigned char *array_memory
;
4955 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4957 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4958 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4960 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4961 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4965 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4966 pCVStructFormat
->offset_to_array_description
;
4968 memsize
= array_read_conformance(*pCVArrayFormat
, pStubMsg
,
4971 align_pointer(&pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4973 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4975 /* work out how much memory to allocate if we need to do so */
4976 if (!fMustAlloc
&& !*ppMemory
)
4980 SIZE_T size
= pCVStructFormat
->memory_size
+ memsize
;
4981 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4984 /* mark the start of the constant data */
4985 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4986 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4988 array_memory
= *ppMemory
+ pCVStructFormat
->memory_size
;
4989 bufsize
= array_read_variance_and_unmarshall(*pCVArrayFormat
, pStubMsg
,
4990 &array_memory
, pCVArrayFormat
,
4991 FALSE
/* fMustAlloc */,
4992 FALSE
/* fUseServerBufferMemory */,
4993 FALSE
/* fUnmarshall */);
4995 /* save offset in case unmarshalling pointers changes it */
4996 offset
= pStubMsg
->Offset
;
4998 /* mark the start of the array data */
4999 saved_array_buffer
= pStubMsg
->Buffer
;
5000 safe_buffer_increment(pStubMsg
, bufsize
);
5002 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
5004 /* copy the constant data */
5005 memcpy(*ppMemory
, saved_buffer
, pCVStructFormat
->memory_size
);
5006 /* copy the array data */
5007 TRACE("copying %p to %p\n", saved_array_buffer
, *ppMemory
+ pCVStructFormat
->memory_size
);
5008 memcpy(*ppMemory
+ pCVStructFormat
->memory_size
+ offset
,
5009 saved_array_buffer
, bufsize
);
5011 if (*pCVArrayFormat
== RPC_FC_C_CSTRING
)
5012 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory
+ pCVStructFormat
->memory_size
)));
5013 else if (*pCVArrayFormat
== RPC_FC_C_WSTRING
)
5014 TRACE("string=%s\n", debugstr_w((WCHAR
*)(*ppMemory
+ pCVStructFormat
->memory_size
)));
5019 /***********************************************************************
5020 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
5022 void WINAPI
NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5023 unsigned char *pMemory
,
5024 PFORMAT_STRING pFormat
)
5026 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
5027 PFORMAT_STRING pCVArrayFormat
;
5029 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5031 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
5032 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
5034 ERR("invalid format type %x\n", pCVStructFormat
->type
);
5035 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5039 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
5040 pCVStructFormat
->offset_to_array_description
;
5041 array_compute_and_size_conformance(*pCVArrayFormat
, pStubMsg
,
5042 pMemory
+ pCVStructFormat
->memory_size
,
5045 align_length(&pStubMsg
->BufferLength
, pCVStructFormat
->alignment
+ 1);
5047 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
5049 safe_buffer_length_increment(pStubMsg
, pCVStructFormat
->memory_size
);
5051 array_buffer_size(*pCVArrayFormat
, pStubMsg
,
5052 pMemory
+ pCVStructFormat
->memory_size
, pCVArrayFormat
,
5053 FALSE
/* fHasPointers */);
5055 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5058 /***********************************************************************
5059 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
5061 ULONG WINAPI
NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5062 PFORMAT_STRING pFormat
)
5064 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
5065 PFORMAT_STRING pCVArrayFormat
;
5067 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5069 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
5070 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
5072 ERR("invalid format type %x\n", pCVStructFormat
->type
);
5073 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5077 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
5078 pCVStructFormat
->offset_to_array_description
;
5079 array_read_conformance(*pCVArrayFormat
, pStubMsg
, pCVArrayFormat
);
5081 align_pointer(&pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
5083 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
5085 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
5086 array_memory_size(*pCVArrayFormat
, pStubMsg
, pCVArrayFormat
,
5087 FALSE
/* fHasPointers */);
5089 pStubMsg
->MemorySize
+= pCVStructFormat
->memory_size
;
5091 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5093 return pStubMsg
->MemorySize
;
5096 /***********************************************************************
5097 * NdrConformantVaryingStructFree [RPCRT4.@]
5099 void WINAPI
NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
5100 unsigned char *pMemory
,
5101 PFORMAT_STRING pFormat
)
5103 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
5104 PFORMAT_STRING pCVArrayFormat
;
5106 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5108 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
5109 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
5111 ERR("invalid format type %x\n", pCVStructFormat
->type
);
5112 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5116 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
5117 pCVStructFormat
->offset_to_array_description
;
5118 array_free(*pCVArrayFormat
, pStubMsg
,
5119 pMemory
+ pCVStructFormat
->memory_size
, pCVArrayFormat
,
5120 FALSE
/* fHasPointers */);
5122 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
5124 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5127 #include "pshpack1.h"
5131 unsigned char alignment
;
5132 unsigned short total_size
;
5133 } NDR_SMFARRAY_FORMAT
;
5138 unsigned char alignment
;
5140 } NDR_LGFARRAY_FORMAT
;
5141 #include "poppack.h"
5143 /***********************************************************************
5144 * NdrFixedArrayMarshall [RPCRT4.@]
5146 unsigned char * WINAPI
NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5147 unsigned char *pMemory
,
5148 PFORMAT_STRING pFormat
)
5150 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5153 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5155 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5156 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5158 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5159 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5163 align_pointer_clear(&pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
5165 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5167 total_size
= pSmFArrayFormat
->total_size
;
5168 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5172 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5173 total_size
= pLgFArrayFormat
->total_size
;
5174 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5177 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5178 safe_copy_to_buffer(pStubMsg
, pMemory
, total_size
);
5180 pFormat
= EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
5185 /***********************************************************************
5186 * NdrFixedArrayUnmarshall [RPCRT4.@]
5188 unsigned char * WINAPI
NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5189 unsigned char **ppMemory
,
5190 PFORMAT_STRING pFormat
,
5191 unsigned char fMustAlloc
)
5193 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5195 unsigned char *saved_buffer
;
5197 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5199 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5200 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5202 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5203 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5207 align_pointer(&pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
5209 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5211 total_size
= pSmFArrayFormat
->total_size
;
5212 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5216 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5217 total_size
= pLgFArrayFormat
->total_size
;
5218 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5222 *ppMemory
= NdrAllocate(pStubMsg
, total_size
);
5225 if (!pStubMsg
->IsClient
&& !*ppMemory
)
5226 /* for servers, we just point straight into the RPC buffer */
5227 *ppMemory
= pStubMsg
->Buffer
;
5230 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5231 safe_buffer_increment(pStubMsg
, total_size
);
5232 pFormat
= EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
5234 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
5235 if (*ppMemory
!= saved_buffer
)
5236 memcpy(*ppMemory
, saved_buffer
, total_size
);
5241 /***********************************************************************
5242 * NdrFixedArrayBufferSize [RPCRT4.@]
5244 void WINAPI
NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5245 unsigned char *pMemory
,
5246 PFORMAT_STRING pFormat
)
5248 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5251 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5253 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5254 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5256 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5257 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5261 align_length(&pStubMsg
->BufferLength
, pSmFArrayFormat
->alignment
+ 1);
5263 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5265 total_size
= pSmFArrayFormat
->total_size
;
5266 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5270 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5271 total_size
= pLgFArrayFormat
->total_size
;
5272 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5274 safe_buffer_length_increment(pStubMsg
, total_size
);
5276 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5279 /***********************************************************************
5280 * NdrFixedArrayMemorySize [RPCRT4.@]
5282 ULONG WINAPI
NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5283 PFORMAT_STRING pFormat
)
5285 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5288 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5290 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5291 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5293 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5294 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5298 align_pointer(&pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
5300 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5302 total_size
= pSmFArrayFormat
->total_size
;
5303 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5307 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5308 total_size
= pLgFArrayFormat
->total_size
;
5309 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5311 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5312 safe_buffer_increment(pStubMsg
, total_size
);
5313 pStubMsg
->MemorySize
+= total_size
;
5315 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5320 /***********************************************************************
5321 * NdrFixedArrayFree [RPCRT4.@]
5323 void WINAPI
NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
5324 unsigned char *pMemory
,
5325 PFORMAT_STRING pFormat
)
5327 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5329 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5331 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5332 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5334 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5335 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5339 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5340 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5343 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5344 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5347 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5350 /***********************************************************************
5351 * NdrVaryingArrayMarshall [RPCRT4.@]
5353 unsigned char * WINAPI
NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5354 unsigned char *pMemory
,
5355 PFORMAT_STRING pFormat
)
5357 unsigned char alignment
;
5358 DWORD elements
, esize
;
5361 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5363 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5364 (pFormat
[0] != RPC_FC_LGVARRAY
))
5366 ERR("invalid format type %x\n", pFormat
[0]);
5367 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5371 alignment
= pFormat
[1] + 1;
5373 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5376 pFormat
+= sizeof(WORD
);
5377 elements
= *(const WORD
*)pFormat
;
5378 pFormat
+= sizeof(WORD
);
5383 pFormat
+= sizeof(DWORD
);
5384 elements
= *(const DWORD
*)pFormat
;
5385 pFormat
+= sizeof(DWORD
);
5388 esize
= *(const WORD
*)pFormat
;
5389 pFormat
+= sizeof(WORD
);
5391 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5392 if ((pStubMsg
->ActualCount
> elements
) ||
5393 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5395 RpcRaiseException(RPC_S_INVALID_BOUND
);
5399 WriteVariance(pStubMsg
);
5401 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
5403 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
5404 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5405 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
5407 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
5412 /***********************************************************************
5413 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5415 unsigned char * WINAPI
NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5416 unsigned char **ppMemory
,
5417 PFORMAT_STRING pFormat
,
5418 unsigned char fMustAlloc
)
5420 unsigned char alignment
;
5421 DWORD size
, elements
, esize
;
5423 unsigned char *saved_buffer
;
5426 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5428 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5429 (pFormat
[0] != RPC_FC_LGVARRAY
))
5431 ERR("invalid format type %x\n", pFormat
[0]);
5432 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5436 alignment
= pFormat
[1] + 1;
5438 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5441 size
= *(const WORD
*)pFormat
;
5442 pFormat
+= sizeof(WORD
);
5443 elements
= *(const WORD
*)pFormat
;
5444 pFormat
+= sizeof(WORD
);
5449 size
= *(const DWORD
*)pFormat
;
5450 pFormat
+= sizeof(DWORD
);
5451 elements
= *(const DWORD
*)pFormat
;
5452 pFormat
+= sizeof(DWORD
);
5455 esize
= *(const WORD
*)pFormat
;
5456 pFormat
+= sizeof(WORD
);
5458 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
5460 align_pointer(&pStubMsg
->Buffer
, alignment
);
5462 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
5463 offset
= pStubMsg
->Offset
;
5465 if (!fMustAlloc
&& !*ppMemory
)
5468 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5469 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5470 safe_buffer_increment(pStubMsg
, bufsize
);
5472 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
5474 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
5479 /***********************************************************************
5480 * NdrVaryingArrayBufferSize [RPCRT4.@]
5482 void WINAPI
NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5483 unsigned char *pMemory
,
5484 PFORMAT_STRING pFormat
)
5486 unsigned char alignment
;
5487 DWORD elements
, esize
;
5489 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5491 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5492 (pFormat
[0] != RPC_FC_LGVARRAY
))
5494 ERR("invalid format type %x\n", pFormat
[0]);
5495 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5499 alignment
= pFormat
[1] + 1;
5501 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5504 pFormat
+= sizeof(WORD
);
5505 elements
= *(const WORD
*)pFormat
;
5506 pFormat
+= sizeof(WORD
);
5511 pFormat
+= sizeof(DWORD
);
5512 elements
= *(const DWORD
*)pFormat
;
5513 pFormat
+= sizeof(DWORD
);
5516 esize
= *(const WORD
*)pFormat
;
5517 pFormat
+= sizeof(WORD
);
5519 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5520 if ((pStubMsg
->ActualCount
> elements
) ||
5521 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5523 RpcRaiseException(RPC_S_INVALID_BOUND
);
5527 SizeVariance(pStubMsg
);
5529 align_length(&pStubMsg
->BufferLength
, alignment
);
5531 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
5533 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5536 /***********************************************************************
5537 * NdrVaryingArrayMemorySize [RPCRT4.@]
5539 ULONG WINAPI
NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5540 PFORMAT_STRING pFormat
)
5542 unsigned char alignment
;
5543 DWORD size
, elements
, esize
;
5545 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5547 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5548 (pFormat
[0] != RPC_FC_LGVARRAY
))
5550 ERR("invalid format type %x\n", pFormat
[0]);
5551 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5555 alignment
= pFormat
[1] + 1;
5557 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5560 size
= *(const WORD
*)pFormat
;
5561 pFormat
+= sizeof(WORD
);
5562 elements
= *(const WORD
*)pFormat
;
5563 pFormat
+= sizeof(WORD
);
5568 size
= *(const DWORD
*)pFormat
;
5569 pFormat
+= sizeof(DWORD
);
5570 elements
= *(const DWORD
*)pFormat
;
5571 pFormat
+= sizeof(DWORD
);
5574 esize
= *(const WORD
*)pFormat
;
5575 pFormat
+= sizeof(WORD
);
5577 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
5579 align_pointer(&pStubMsg
->Buffer
, alignment
);
5581 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
5582 pStubMsg
->MemorySize
+= size
;
5584 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5586 return pStubMsg
->MemorySize
;
5589 /***********************************************************************
5590 * NdrVaryingArrayFree [RPCRT4.@]
5592 void WINAPI
NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
5593 unsigned char *pMemory
,
5594 PFORMAT_STRING pFormat
)
5598 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5600 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5601 (pFormat
[0] != RPC_FC_LGVARRAY
))
5603 ERR("invalid format type %x\n", pFormat
[0]);
5604 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5608 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5611 pFormat
+= sizeof(WORD
);
5612 elements
= *(const WORD
*)pFormat
;
5613 pFormat
+= sizeof(WORD
);
5618 pFormat
+= sizeof(DWORD
);
5619 elements
= *(const DWORD
*)pFormat
;
5620 pFormat
+= sizeof(DWORD
);
5623 pFormat
+= sizeof(WORD
);
5625 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5626 if ((pStubMsg
->ActualCount
> elements
) ||
5627 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5629 RpcRaiseException(RPC_S_INVALID_BOUND
);
5633 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5636 static ULONG
get_discriminant(unsigned char fc
, const unsigned char *pMemory
)
5649 return *(const USHORT
*)pMemory
;
5653 return *(const ULONG
*)pMemory
;
5654 case RPC_FC_INT3264
:
5655 case RPC_FC_UINT3264
:
5656 return *(const ULONG_PTR
*)pMemory
;
5658 FIXME("Unhandled base type: 0x%02x\n", fc
);
5663 static PFORMAT_STRING
get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg
,
5665 PFORMAT_STRING pFormat
)
5667 unsigned short num_arms
, arm
, type
;
5669 num_arms
= *(const SHORT
*)pFormat
& 0x0fff;
5671 for(arm
= 0; arm
< num_arms
; arm
++)
5673 if(discriminant
== *(const ULONG
*)pFormat
)
5681 type
= *(const unsigned short*)pFormat
;
5682 TRACE("type %04x\n", type
);
5683 if(arm
== num_arms
) /* default arm extras */
5687 ERR("no arm for 0x%x and no default case\n", discriminant
);
5688 RpcRaiseException(RPC_S_INVALID_TAG
);
5693 TRACE("falling back to empty default case for 0x%x\n", discriminant
);
5700 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
, ULONG discriminant
, PFORMAT_STRING pFormat
)
5702 unsigned short type
;
5706 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5710 type
= *(const unsigned short*)pFormat
;
5711 if((type
& 0xff00) == 0x8000)
5713 unsigned char basetype
= LOBYTE(type
);
5714 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &basetype
);
5718 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5719 NDR_MARSHALL m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
5722 unsigned char *saved_buffer
= NULL
;
5723 BOOL pointer_buffer_mark_set
= FALSE
;
5730 align_pointer_clear(&pStubMsg
->Buffer
, 4);
5731 saved_buffer
= pStubMsg
->Buffer
;
5732 if (pStubMsg
->PointerBufferMark
)
5734 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5735 pStubMsg
->PointerBufferMark
= NULL
;
5736 pointer_buffer_mark_set
= TRUE
;
5739 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
5741 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char **)pMemory
, desc
);
5742 if (pointer_buffer_mark_set
)
5744 STD_OVERFLOW_CHECK(pStubMsg
);
5745 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5746 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5748 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5749 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
5750 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5752 pStubMsg
->Buffer
= saved_buffer
+ 4;
5756 m(pStubMsg
, pMemory
, desc
);
5759 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5764 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5765 unsigned char **ppMemory
,
5767 PFORMAT_STRING pFormat
,
5768 unsigned char fMustAlloc
)
5770 unsigned short type
;
5774 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5778 type
= *(const unsigned short*)pFormat
;
5779 if((type
& 0xff00) == 0x8000)
5781 unsigned char basetype
= LOBYTE(type
);
5782 return NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &basetype
, FALSE
);
5786 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5787 NDR_UNMARSHALL m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
5790 unsigned char *saved_buffer
= NULL
;
5791 BOOL pointer_buffer_mark_set
= FALSE
;
5798 align_pointer(&pStubMsg
->Buffer
, 4);
5799 saved_buffer
= pStubMsg
->Buffer
;
5800 if (pStubMsg
->PointerBufferMark
)
5802 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5803 pStubMsg
->PointerBufferMark
= NULL
;
5804 pointer_buffer_mark_set
= TRUE
;
5807 pStubMsg
->Buffer
+= 4; /* for pointer ID */
5809 if (saved_buffer
+ 4 > pStubMsg
->BufferEnd
)
5811 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5812 saved_buffer
, pStubMsg
->BufferEnd
);
5813 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5816 PointerUnmarshall(pStubMsg
, saved_buffer
, *(unsigned char ***)ppMemory
, **(unsigned char ***)ppMemory
, desc
, fMustAlloc
);
5817 if (pointer_buffer_mark_set
)
5819 STD_OVERFLOW_CHECK(pStubMsg
);
5820 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5821 pStubMsg
->Buffer
= saved_buffer
+ 4;
5825 m(pStubMsg
, ppMemory
, desc
, fMustAlloc
);
5828 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5833 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg
,
5834 unsigned char *pMemory
,
5836 PFORMAT_STRING pFormat
)
5838 unsigned short type
;
5842 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5846 type
= *(const unsigned short*)pFormat
;
5847 if((type
& 0xff00) == 0x8000)
5849 unsigned char basetype
= LOBYTE(type
);
5850 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &basetype
);
5854 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5855 NDR_BUFFERSIZE m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
5864 align_length(&pStubMsg
->BufferLength
, 4);
5865 safe_buffer_length_increment(pStubMsg
, 4); /* for pointer ID */
5866 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5868 int saved_buffer_length
= pStubMsg
->BufferLength
;
5869 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
5870 pStubMsg
->PointerLength
= 0;
5871 if(!pStubMsg
->BufferLength
)
5872 ERR("BufferLength == 0??\n");
5873 PointerBufferSize(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5874 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
5875 pStubMsg
->BufferLength
= saved_buffer_length
;
5879 m(pStubMsg
, pMemory
, desc
);
5882 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
5886 static ULONG
union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg
,
5888 PFORMAT_STRING pFormat
)
5890 unsigned short type
, size
;
5892 size
= *(const unsigned short*)pFormat
;
5893 pStubMsg
->Memory
+= size
;
5896 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5900 type
= *(const unsigned short*)pFormat
;
5901 if((type
& 0xff00) == 0x8000)
5903 return NdrBaseTypeMemorySize(pStubMsg
, pFormat
);
5907 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5908 NDR_MEMORYSIZE m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
5909 unsigned char *saved_buffer
;
5918 align_pointer(&pStubMsg
->Buffer
, 4);
5919 saved_buffer
= pStubMsg
->Buffer
;
5920 safe_buffer_increment(pStubMsg
, 4);
5921 align_length(&pStubMsg
->MemorySize
, sizeof(void *));
5922 pStubMsg
->MemorySize
+= sizeof(void *);
5923 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5924 PointerMemorySize(pStubMsg
, saved_buffer
, pFormat
);
5927 return m(pStubMsg
, desc
);
5930 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5933 TRACE("size %d\n", size
);
5937 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg
,
5938 unsigned char *pMemory
,
5940 PFORMAT_STRING pFormat
)
5942 unsigned short type
;
5946 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5950 type
= *(const unsigned short*)pFormat
;
5951 if((type
& 0xff00) != 0x8000)
5953 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5954 NDR_FREE m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
5963 PointerFree(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5966 m(pStubMsg
, pMemory
, desc
);
5972 /***********************************************************************
5973 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5975 unsigned char * WINAPI
NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5976 unsigned char *pMemory
,
5977 PFORMAT_STRING pFormat
)
5979 unsigned char switch_type
;
5980 unsigned char increment
;
5983 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5986 switch_type
= *pFormat
& 0xf;
5987 increment
= (*pFormat
& 0xf0) >> 4;
5990 align_pointer_clear(&pStubMsg
->Buffer
, increment
);
5992 switch_value
= get_discriminant(switch_type
, pMemory
);
5993 TRACE("got switch value 0x%x\n", switch_value
);
5995 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &switch_type
);
5996 pMemory
+= increment
;
5998 return union_arm_marshall(pStubMsg
, pMemory
, switch_value
, pFormat
);
6001 /***********************************************************************
6002 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
6004 unsigned char * WINAPI
NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6005 unsigned char **ppMemory
,
6006 PFORMAT_STRING pFormat
,
6007 unsigned char fMustAlloc
)
6009 unsigned char switch_type
;
6010 unsigned char increment
;
6012 unsigned short size
;
6013 unsigned char *pMemoryArm
;
6015 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
6018 switch_type
= *pFormat
& 0xf;
6019 increment
= (*pFormat
& 0xf0) >> 4;
6022 align_pointer(&pStubMsg
->Buffer
, increment
);
6023 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
6024 TRACE("got switch value 0x%x\n", switch_value
);
6026 size
= *(const unsigned short*)pFormat
+ increment
;
6027 if (!fMustAlloc
&& !*ppMemory
)
6030 *ppMemory
= NdrAllocate(pStubMsg
, size
);
6032 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6033 * since the arm is part of the memory block that is encompassed by
6034 * the whole union. Memory is forced to allocate when pointers
6035 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6036 * clearing the memory we pass in to the unmarshaller */
6038 memset(*ppMemory
, 0, size
);
6040 NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &switch_type
, FALSE
);
6041 pMemoryArm
= *ppMemory
+ increment
;
6043 return union_arm_unmarshall(pStubMsg
, &pMemoryArm
, switch_value
, pFormat
, FALSE
);
6046 /***********************************************************************
6047 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
6049 void WINAPI
NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6050 unsigned char *pMemory
,
6051 PFORMAT_STRING pFormat
)
6053 unsigned char switch_type
;
6054 unsigned char increment
;
6057 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6060 switch_type
= *pFormat
& 0xf;
6061 increment
= (*pFormat
& 0xf0) >> 4;
6064 align_length(&pStubMsg
->BufferLength
, increment
);
6065 switch_value
= get_discriminant(switch_type
, pMemory
);
6066 TRACE("got switch value 0x%x\n", switch_value
);
6068 /* Add discriminant size */
6069 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&switch_value
, &switch_type
);
6070 pMemory
+= increment
;
6072 union_arm_buffer_size(pStubMsg
, pMemory
, switch_value
, pFormat
);
6075 /***********************************************************************
6076 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
6078 ULONG WINAPI
NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6079 PFORMAT_STRING pFormat
)
6081 unsigned char switch_type
;
6082 unsigned char increment
;
6085 switch_type
= *pFormat
& 0xf;
6086 increment
= (*pFormat
& 0xf0) >> 4;
6089 align_pointer(&pStubMsg
->Buffer
, increment
);
6090 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
6091 TRACE("got switch value 0x%x\n", switch_value
);
6093 pStubMsg
->Memory
+= increment
;
6095 return increment
+ union_arm_memory_size(pStubMsg
, switch_value
, pFormat
+ *(const SHORT
*)pFormat
);
6098 /***********************************************************************
6099 * NdrEncapsulatedUnionFree [RPCRT4.@]
6101 void WINAPI
NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
6102 unsigned char *pMemory
,
6103 PFORMAT_STRING pFormat
)
6105 unsigned char switch_type
;
6106 unsigned char increment
;
6109 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6112 switch_type
= *pFormat
& 0xf;
6113 increment
= (*pFormat
& 0xf0) >> 4;
6116 switch_value
= get_discriminant(switch_type
, pMemory
);
6117 TRACE("got switch value 0x%x\n", switch_value
);
6119 pMemory
+= increment
;
6121 union_arm_free(pStubMsg
, pMemory
, switch_value
, pFormat
);
6124 /***********************************************************************
6125 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
6127 unsigned char * WINAPI
NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6128 unsigned char *pMemory
,
6129 PFORMAT_STRING pFormat
)
6131 unsigned char switch_type
;
6133 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6136 switch_type
= *pFormat
;
6139 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6140 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6141 /* Marshall discriminant */
6142 NdrBaseTypeMarshall(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
6144 return union_arm_marshall(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6147 static LONG
unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg
,
6148 PFORMAT_STRING
*ppFormat
)
6150 LONG discriminant
= 0;
6160 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
6170 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6171 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
6179 align_pointer(&pStubMsg
->Buffer
, sizeof(ULONG
));
6180 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
6185 FIXME("Unhandled base type: 0x%02x\n", **ppFormat
);
6189 if (pStubMsg
->fHasNewCorrDesc
)
6193 return discriminant
;
6196 /**********************************************************************
6197 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
6199 unsigned char * WINAPI
NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6200 unsigned char **ppMemory
,
6201 PFORMAT_STRING pFormat
,
6202 unsigned char fMustAlloc
)
6205 unsigned short size
;
6207 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
6210 /* Unmarshall discriminant */
6211 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
6212 TRACE("unmarshalled discriminant %x\n", discriminant
);
6214 pFormat
+= *(const SHORT
*)pFormat
;
6216 size
= *(const unsigned short*)pFormat
;
6218 if (!fMustAlloc
&& !*ppMemory
)
6221 *ppMemory
= NdrAllocate(pStubMsg
, size
);
6223 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6224 * since the arm is part of the memory block that is encompassed by
6225 * the whole union. Memory is forced to allocate when pointers
6226 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6227 * clearing the memory we pass in to the unmarshaller */
6229 memset(*ppMemory
, 0, size
);
6231 return union_arm_unmarshall(pStubMsg
, ppMemory
, discriminant
, pFormat
, FALSE
);
6234 /***********************************************************************
6235 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
6237 void WINAPI
NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6238 unsigned char *pMemory
,
6239 PFORMAT_STRING pFormat
)
6241 unsigned char switch_type
;
6243 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6246 switch_type
= *pFormat
;
6249 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6250 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6251 /* Add discriminant size */
6252 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
6254 union_arm_buffer_size(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6257 /***********************************************************************
6258 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
6260 ULONG WINAPI
NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6261 PFORMAT_STRING pFormat
)
6266 /* Unmarshall discriminant */
6267 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
6268 TRACE("unmarshalled discriminant 0x%x\n", discriminant
);
6270 return union_arm_memory_size(pStubMsg
, discriminant
, pFormat
+ *(const SHORT
*)pFormat
);
6273 /***********************************************************************
6274 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6276 void WINAPI
NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
6277 unsigned char *pMemory
,
6278 PFORMAT_STRING pFormat
)
6280 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6284 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6285 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6287 union_arm_free(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6290 /***********************************************************************
6291 * NdrByteCountPointerMarshall [RPCRT4.@]
6293 unsigned char * WINAPI
NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6294 unsigned char *pMemory
,
6295 PFORMAT_STRING pFormat
)
6301 /***********************************************************************
6302 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6304 unsigned char * WINAPI
NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6305 unsigned char **ppMemory
,
6306 PFORMAT_STRING pFormat
,
6307 unsigned char fMustAlloc
)
6313 /***********************************************************************
6314 * NdrByteCountPointerBufferSize [RPCRT4.@]
6316 void WINAPI
NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6317 unsigned char *pMemory
,
6318 PFORMAT_STRING pFormat
)
6323 /***********************************************************************
6324 * NdrByteCountPointerMemorySize [internal]
6326 static ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6327 PFORMAT_STRING pFormat
)
6333 /***********************************************************************
6334 * NdrByteCountPointerFree [RPCRT4.@]
6336 void WINAPI
NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
6337 unsigned char *pMemory
,
6338 PFORMAT_STRING pFormat
)
6343 /***********************************************************************
6344 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6346 unsigned char * WINAPI
NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6347 unsigned char *pMemory
,
6348 PFORMAT_STRING pFormat
)
6354 /***********************************************************************
6355 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6357 unsigned char * WINAPI
NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6358 unsigned char **ppMemory
,
6359 PFORMAT_STRING pFormat
,
6360 unsigned char fMustAlloc
)
6366 /***********************************************************************
6367 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6369 void WINAPI
NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6370 unsigned char *pMemory
,
6371 PFORMAT_STRING pFormat
)
6376 /***********************************************************************
6377 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6379 ULONG WINAPI
NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6380 PFORMAT_STRING pFormat
)
6386 /***********************************************************************
6387 * NdrXmitOrRepAsFree [RPCRT4.@]
6389 void WINAPI
NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg
,
6390 unsigned char *pMemory
,
6391 PFORMAT_STRING pFormat
)
6396 /***********************************************************************
6397 * NdrRangeMarshall [internal]
6399 static unsigned char *WINAPI
NdrRangeMarshall(
6400 PMIDL_STUB_MESSAGE pStubMsg
,
6401 unsigned char *pMemory
,
6402 PFORMAT_STRING pFormat
)
6404 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6405 unsigned char base_type
;
6407 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6409 if (pRange
->type
!= RPC_FC_RANGE
)
6411 ERR("invalid format type %x\n", pRange
->type
);
6412 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6416 base_type
= pRange
->flags_type
& 0xf;
6418 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &base_type
);
6421 /***********************************************************************
6422 * NdrRangeUnmarshall [RPCRT4.@]
6424 unsigned char *WINAPI
NdrRangeUnmarshall(
6425 PMIDL_STUB_MESSAGE pStubMsg
,
6426 unsigned char **ppMemory
,
6427 PFORMAT_STRING pFormat
,
6428 unsigned char fMustAlloc
)
6430 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6431 unsigned char base_type
;
6433 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6435 if (pRange
->type
!= RPC_FC_RANGE
)
6437 ERR("invalid format type %x\n", pRange
->type
);
6438 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6441 base_type
= pRange
->flags_type
& 0xf;
6443 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6444 base_type
, pRange
->low_value
, pRange
->high_value
);
6446 #define RANGE_UNMARSHALL(mem_type, wire_type, format_spec) \
6449 align_pointer(&pStubMsg->Buffer, sizeof(wire_type)); \
6450 if (!fMustAlloc && !*ppMemory) \
6451 fMustAlloc = TRUE; \
6453 *ppMemory = NdrAllocate(pStubMsg, sizeof(mem_type)); \
6454 if (pStubMsg->Buffer + sizeof(wire_type) > pStubMsg->BufferEnd) \
6456 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6457 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6458 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6460 if ((*(wire_type *)pStubMsg->Buffer < (mem_type)pRange->low_value) || \
6461 (*(wire_type *)pStubMsg->Buffer > (mem_type)pRange->high_value)) \
6463 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6464 *(wire_type *)pStubMsg->Buffer, (mem_type)pRange->low_value, \
6465 (mem_type)pRange->high_value); \
6466 RpcRaiseException(RPC_S_INVALID_BOUND); \
6469 TRACE("*ppMemory: %p\n", *ppMemory); \
6470 **(mem_type **)ppMemory = *(wire_type *)pStubMsg->Buffer; \
6471 pStubMsg->Buffer += sizeof(wire_type); \
6478 RANGE_UNMARSHALL(UCHAR
, UCHAR
, "%d");
6479 TRACE("value: 0x%02x\n", **ppMemory
);
6483 RANGE_UNMARSHALL(CHAR
, CHAR
, "%u");
6484 TRACE("value: 0x%02x\n", **ppMemory
);
6486 case RPC_FC_WCHAR
: /* FIXME: valid? */
6488 RANGE_UNMARSHALL(USHORT
, USHORT
, "%u");
6489 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6492 RANGE_UNMARSHALL(SHORT
, SHORT
, "%d");
6493 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6497 RANGE_UNMARSHALL(LONG
, LONG
, "%d");
6498 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6501 RANGE_UNMARSHALL(ULONG
, ULONG
, "%u");
6502 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6505 RANGE_UNMARSHALL(UINT
, USHORT
, "%u");
6506 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
6512 ERR("invalid range base type: 0x%02x\n", base_type
);
6513 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6519 /***********************************************************************
6520 * NdrRangeBufferSize [internal]
6522 static void WINAPI
NdrRangeBufferSize(
6523 PMIDL_STUB_MESSAGE pStubMsg
,
6524 unsigned char *pMemory
,
6525 PFORMAT_STRING pFormat
)
6527 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6528 unsigned char base_type
;
6530 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6532 if (pRange
->type
!= RPC_FC_RANGE
)
6534 ERR("invalid format type %x\n", pRange
->type
);
6535 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6537 base_type
= pRange
->flags_type
& 0xf;
6539 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &base_type
);
6542 /***********************************************************************
6543 * NdrRangeMemorySize [internal]
6545 static ULONG WINAPI
NdrRangeMemorySize(
6546 PMIDL_STUB_MESSAGE pStubMsg
,
6547 PFORMAT_STRING pFormat
)
6549 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6550 unsigned char base_type
;
6552 if (pRange
->type
!= RPC_FC_RANGE
)
6554 ERR("invalid format type %x\n", pRange
->type
);
6555 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6558 base_type
= pRange
->flags_type
& 0xf;
6560 return NdrBaseTypeMemorySize(pStubMsg
, &base_type
);
6563 /***********************************************************************
6564 * NdrRangeFree [internal]
6566 static void WINAPI
NdrRangeFree(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
);
6575 /***********************************************************************
6576 * NdrBaseTypeMarshall [internal]
6578 static unsigned char *WINAPI
NdrBaseTypeMarshall(
6579 PMIDL_STUB_MESSAGE pStubMsg
,
6580 unsigned char *pMemory
,
6581 PFORMAT_STRING pFormat
)
6583 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6591 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(UCHAR
));
6592 TRACE("value: 0x%02x\n", *pMemory
);
6597 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(USHORT
));
6598 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(USHORT
));
6599 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
6603 case RPC_FC_ERROR_STATUS_T
:
6605 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(ULONG
));
6606 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONG
));
6607 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
6610 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(float));
6611 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
6614 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(double));
6615 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
6618 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(ULONGLONG
));
6619 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONGLONG
));
6620 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
6624 USHORT val
= *(UINT
*)pMemory
;
6625 /* only 16-bits on the wire, so do a sanity check */
6626 if (*(UINT
*)pMemory
> SHRT_MAX
)
6627 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
6628 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(USHORT
));
6629 safe_copy_to_buffer(pStubMsg
, &val
, sizeof(val
));
6630 TRACE("value: 0x%04x\n", *(UINT
*)pMemory
);
6633 case RPC_FC_INT3264
:
6634 case RPC_FC_UINT3264
:
6636 UINT val
= *(UINT_PTR
*)pMemory
;
6637 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(UINT
));
6638 safe_copy_to_buffer(pStubMsg
, &val
, sizeof(val
));
6644 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6647 /* FIXME: what is the correct return value? */
6651 /***********************************************************************
6652 * NdrBaseTypeUnmarshall [internal]
6654 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(
6655 PMIDL_STUB_MESSAGE pStubMsg
,
6656 unsigned char **ppMemory
,
6657 PFORMAT_STRING pFormat
,
6658 unsigned char fMustAlloc
)
6660 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6662 #define BASE_TYPE_UNMARSHALL(type) do { \
6663 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
6664 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6666 *ppMemory = pStubMsg->Buffer; \
6667 TRACE("*ppMemory: %p\n", *ppMemory); \
6668 safe_buffer_increment(pStubMsg, sizeof(type)); \
6673 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6674 TRACE("*ppMemory: %p\n", *ppMemory); \
6675 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6685 BASE_TYPE_UNMARSHALL(UCHAR
);
6686 TRACE("value: 0x%02x\n", **ppMemory
);
6691 BASE_TYPE_UNMARSHALL(USHORT
);
6692 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6696 case RPC_FC_ERROR_STATUS_T
:
6698 BASE_TYPE_UNMARSHALL(ULONG
);
6699 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6702 BASE_TYPE_UNMARSHALL(float);
6703 TRACE("value: %f\n", **(float **)ppMemory
);
6706 BASE_TYPE_UNMARSHALL(double);
6707 TRACE("value: %f\n", **(double **)ppMemory
);
6710 BASE_TYPE_UNMARSHALL(ULONGLONG
);
6711 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG
**)ppMemory
));
6716 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6717 if (!fMustAlloc
&& !*ppMemory
)
6720 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT
));
6721 safe_copy_from_buffer(pStubMsg
, &val
, sizeof(USHORT
));
6722 /* 16-bits on the wire, but int in memory */
6723 **(UINT
**)ppMemory
= val
;
6724 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
6727 case RPC_FC_INT3264
:
6728 if (sizeof(INT_PTR
) == sizeof(INT
)) BASE_TYPE_UNMARSHALL(INT
);
6732 align_pointer(&pStubMsg
->Buffer
, sizeof(INT
));
6733 if (!fMustAlloc
&& !*ppMemory
)
6736 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(INT_PTR
));
6737 safe_copy_from_buffer(pStubMsg
, &val
, sizeof(INT
));
6738 **(INT_PTR
**)ppMemory
= val
;
6739 TRACE("value: 0x%08lx\n", **(INT_PTR
**)ppMemory
);
6742 case RPC_FC_UINT3264
:
6743 if (sizeof(UINT_PTR
) == sizeof(UINT
)) BASE_TYPE_UNMARSHALL(UINT
);
6747 align_pointer(&pStubMsg
->Buffer
, sizeof(UINT
));
6748 if (!fMustAlloc
&& !*ppMemory
)
6751 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT_PTR
));
6752 safe_copy_from_buffer(pStubMsg
, &val
, sizeof(UINT
));
6753 **(UINT_PTR
**)ppMemory
= val
;
6754 TRACE("value: 0x%08lx\n", **(UINT_PTR
**)ppMemory
);
6760 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6762 #undef BASE_TYPE_UNMARSHALL
6764 /* FIXME: what is the correct return value? */
6769 /***********************************************************************
6770 * NdrBaseTypeBufferSize [internal]
6772 static void WINAPI
NdrBaseTypeBufferSize(
6773 PMIDL_STUB_MESSAGE pStubMsg
,
6774 unsigned char *pMemory
,
6775 PFORMAT_STRING pFormat
)
6777 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6785 safe_buffer_length_increment(pStubMsg
, sizeof(UCHAR
));
6791 align_length(&pStubMsg
->BufferLength
, sizeof(USHORT
));
6792 safe_buffer_length_increment(pStubMsg
, sizeof(USHORT
));
6797 case RPC_FC_INT3264
:
6798 case RPC_FC_UINT3264
:
6799 align_length(&pStubMsg
->BufferLength
, sizeof(ULONG
));
6800 safe_buffer_length_increment(pStubMsg
, sizeof(ULONG
));
6803 align_length(&pStubMsg
->BufferLength
, sizeof(float));
6804 safe_buffer_length_increment(pStubMsg
, sizeof(float));
6807 align_length(&pStubMsg
->BufferLength
, sizeof(double));
6808 safe_buffer_length_increment(pStubMsg
, sizeof(double));
6811 align_length(&pStubMsg
->BufferLength
, sizeof(ULONGLONG
));
6812 safe_buffer_length_increment(pStubMsg
, sizeof(ULONGLONG
));
6814 case RPC_FC_ERROR_STATUS_T
:
6815 align_length(&pStubMsg
->BufferLength
, sizeof(error_status_t
));
6816 safe_buffer_length_increment(pStubMsg
, sizeof(error_status_t
));
6821 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6825 /***********************************************************************
6826 * NdrBaseTypeMemorySize [internal]
6828 static ULONG WINAPI
NdrBaseTypeMemorySize(
6829 PMIDL_STUB_MESSAGE pStubMsg
,
6830 PFORMAT_STRING pFormat
)
6832 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg
, *pFormat
);
6840 safe_buffer_increment(pStubMsg
, sizeof(UCHAR
));
6841 pStubMsg
->MemorySize
+= sizeof(UCHAR
);
6842 return sizeof(UCHAR
);
6846 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6847 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6848 align_length(&pStubMsg
->MemorySize
, sizeof(USHORT
));
6849 pStubMsg
->MemorySize
+= sizeof(USHORT
);
6850 return sizeof(USHORT
);
6854 align_pointer(&pStubMsg
->Buffer
, sizeof(ULONG
));
6855 safe_buffer_increment(pStubMsg
, sizeof(ULONG
));
6856 align_length(&pStubMsg
->MemorySize
, sizeof(ULONG
));
6857 pStubMsg
->MemorySize
+= sizeof(ULONG
);
6858 return sizeof(ULONG
);
6860 align_pointer(&pStubMsg
->Buffer
, sizeof(float));
6861 safe_buffer_increment(pStubMsg
, sizeof(float));
6862 align_length(&pStubMsg
->MemorySize
, sizeof(float));
6863 pStubMsg
->MemorySize
+= sizeof(float);
6864 return sizeof(float);
6866 align_pointer(&pStubMsg
->Buffer
, sizeof(double));
6867 safe_buffer_increment(pStubMsg
, sizeof(double));
6868 align_length(&pStubMsg
->MemorySize
, sizeof(double));
6869 pStubMsg
->MemorySize
+= sizeof(double);
6870 return sizeof(double);
6872 align_pointer(&pStubMsg
->Buffer
, sizeof(ULONGLONG
));
6873 safe_buffer_increment(pStubMsg
, sizeof(ULONGLONG
));
6874 align_length(&pStubMsg
->MemorySize
, sizeof(ULONGLONG
));
6875 pStubMsg
->MemorySize
+= sizeof(ULONGLONG
);
6876 return sizeof(ULONGLONG
);
6877 case RPC_FC_ERROR_STATUS_T
:
6878 align_pointer(&pStubMsg
->Buffer
, sizeof(error_status_t
));
6879 safe_buffer_increment(pStubMsg
, sizeof(error_status_t
));
6880 align_length(&pStubMsg
->MemorySize
, sizeof(error_status_t
));
6881 pStubMsg
->MemorySize
+= sizeof(error_status_t
);
6882 return sizeof(error_status_t
);
6884 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6885 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6886 align_length(&pStubMsg
->MemorySize
, sizeof(UINT
));
6887 pStubMsg
->MemorySize
+= sizeof(UINT
);
6888 return sizeof(UINT
);
6889 case RPC_FC_INT3264
:
6890 case RPC_FC_UINT3264
:
6891 align_pointer(&pStubMsg
->Buffer
, sizeof(UINT
));
6892 safe_buffer_increment(pStubMsg
, sizeof(UINT
));
6893 align_length(&pStubMsg
->MemorySize
, sizeof(UINT_PTR
));
6894 pStubMsg
->MemorySize
+= sizeof(UINT_PTR
);
6895 return sizeof(UINT_PTR
);
6897 align_length(&pStubMsg
->MemorySize
, sizeof(void *));
6898 pStubMsg
->MemorySize
+= sizeof(void *);
6899 return sizeof(void *);
6901 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6906 /***********************************************************************
6907 * NdrBaseTypeFree [internal]
6909 static void WINAPI
NdrBaseTypeFree(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
);
6918 /***********************************************************************
6919 * NdrContextHandleBufferSize [internal]
6921 static void WINAPI
NdrContextHandleBufferSize(
6922 PMIDL_STUB_MESSAGE pStubMsg
,
6923 unsigned char *pMemory
,
6924 PFORMAT_STRING pFormat
)
6926 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6928 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6930 ERR("invalid format type %x\n", *pFormat
);
6931 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6933 align_length(&pStubMsg
->BufferLength
, 4);
6934 safe_buffer_length_increment(pStubMsg
, cbNDRContext
);
6937 /***********************************************************************
6938 * NdrContextHandleMarshall [internal]
6940 static unsigned char *WINAPI
NdrContextHandleMarshall(
6941 PMIDL_STUB_MESSAGE pStubMsg
,
6942 unsigned char *pMemory
,
6943 PFORMAT_STRING pFormat
)
6945 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6947 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6949 ERR("invalid format type %x\n", *pFormat
);
6950 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6952 TRACE("flags: 0x%02x\n", pFormat
[1]);
6954 if (pStubMsg
->IsClient
)
6956 if (pFormat
[1] & HANDLE_PARAM_IS_VIA_PTR
)
6957 NdrClientContextMarshall(pStubMsg
, *(NDR_CCONTEXT
**)pMemory
, FALSE
);
6959 NdrClientContextMarshall(pStubMsg
, pMemory
, FALSE
);
6963 NDR_SCONTEXT ctxt
= NDRSContextFromValue(pMemory
);
6964 NDR_RUNDOWN rundown
= pStubMsg
->StubDesc
->apfnNdrRundownRoutines
[pFormat
[2]];
6965 NdrServerContextNewMarshall(pStubMsg
, ctxt
, rundown
, pFormat
);
6971 /***********************************************************************
6972 * NdrContextHandleUnmarshall [internal]
6974 static unsigned char *WINAPI
NdrContextHandleUnmarshall(
6975 PMIDL_STUB_MESSAGE pStubMsg
,
6976 unsigned char **ppMemory
,
6977 PFORMAT_STRING pFormat
,
6978 unsigned char fMustAlloc
)
6980 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg
,
6981 ppMemory
, pFormat
, fMustAlloc
? "TRUE": "FALSE");
6983 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6985 ERR("invalid format type %x\n", *pFormat
);
6986 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6988 TRACE("flags: 0x%02x\n", pFormat
[1]);
6990 if (pStubMsg
->IsClient
)
6992 /* [out]-only or [ret] param */
6993 if ((pFormat
[1] & (HANDLE_PARAM_IS_IN
|HANDLE_PARAM_IS_OUT
)) == HANDLE_PARAM_IS_OUT
)
6994 **(NDR_CCONTEXT
**)ppMemory
= NULL
;
6995 NdrClientContextUnmarshall(pStubMsg
, *(NDR_CCONTEXT
**)ppMemory
, pStubMsg
->RpcMsg
->Handle
);
7000 ctxt
= NdrServerContextNewUnmarshall(pStubMsg
, pFormat
);
7001 if (pFormat
[1] & HANDLE_PARAM_IS_VIA_PTR
)
7002 *(void **)ppMemory
= NDRSContextValue(ctxt
);
7004 *(void **)ppMemory
= *NDRSContextValue(ctxt
);
7010 /***********************************************************************
7011 * NdrClientContextMarshall [RPCRT4.@]
7013 void WINAPI
NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7014 NDR_CCONTEXT ContextHandle
,
7017 TRACE("(%p, %p, %d)\n", pStubMsg
, ContextHandle
, fCheck
);
7019 align_pointer_clear(&pStubMsg
->Buffer
, 4);
7021 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7023 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7024 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7025 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7028 /* FIXME: what does fCheck do? */
7029 NDRCContextMarshall(ContextHandle
,
7032 pStubMsg
->Buffer
+= cbNDRContext
;
7035 /***********************************************************************
7036 * NdrClientContextUnmarshall [RPCRT4.@]
7038 void WINAPI
NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7039 NDR_CCONTEXT
* pContextHandle
,
7040 RPC_BINDING_HANDLE BindHandle
)
7042 TRACE("(%p, %p, %p)\n", pStubMsg
, pContextHandle
, BindHandle
);
7044 align_pointer(&pStubMsg
->Buffer
, 4);
7046 if (pStubMsg
->Buffer
+ cbNDRContext
> pStubMsg
->BufferEnd
)
7047 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7049 NDRCContextUnmarshall(pContextHandle
,
7052 pStubMsg
->RpcMsg
->DataRepresentation
);
7054 pStubMsg
->Buffer
+= cbNDRContext
;
7057 void WINAPI
NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7058 NDR_SCONTEXT ContextHandle
,
7059 NDR_RUNDOWN RundownRoutine
)
7061 TRACE("(%p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
);
7063 align_pointer(&pStubMsg
->Buffer
, 4);
7065 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7067 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7068 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7069 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7072 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
7073 pStubMsg
->Buffer
, RundownRoutine
, NULL
,
7074 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
7075 pStubMsg
->Buffer
+= cbNDRContext
;
7078 NDR_SCONTEXT WINAPI
NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
)
7080 NDR_SCONTEXT ContextHandle
;
7082 TRACE("(%p)\n", pStubMsg
);
7084 align_pointer(&pStubMsg
->Buffer
, 4);
7086 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7088 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7089 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7090 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7093 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
7095 pStubMsg
->RpcMsg
->DataRepresentation
,
7096 NULL
, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
7097 pStubMsg
->Buffer
+= cbNDRContext
;
7099 return ContextHandle
;
7102 void WINAPI
NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg
,
7103 unsigned char* pMemory
,
7104 PFORMAT_STRING pFormat
)
7106 FIXME("(%p, %p, %p): stub\n", pStubMsg
, pMemory
, pFormat
);
7109 NDR_SCONTEXT WINAPI
NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg
,
7110 PFORMAT_STRING pFormat
)
7112 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
7113 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
7115 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
7117 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
7118 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
7119 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
7120 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
7121 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
7123 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
7124 if_id
= &sif
->InterfaceId
;
7127 return NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
, NULL
,
7128 pStubMsg
->RpcMsg
->DataRepresentation
, if_id
,
7132 void WINAPI
NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7133 NDR_SCONTEXT ContextHandle
,
7134 NDR_RUNDOWN RundownRoutine
,
7135 PFORMAT_STRING pFormat
)
7137 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
7138 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
7140 TRACE("(%p, %p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
, pFormat
);
7142 align_pointer(&pStubMsg
->Buffer
, 4);
7144 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7146 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7147 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7148 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7151 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
7152 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
7153 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
7154 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
7155 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
7157 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
7158 if_id
= &sif
->InterfaceId
;
7161 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
7162 pStubMsg
->Buffer
, RundownRoutine
, if_id
, flags
);
7163 pStubMsg
->Buffer
+= cbNDRContext
;
7166 NDR_SCONTEXT WINAPI
NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7167 PFORMAT_STRING pFormat
)
7169 NDR_SCONTEXT ContextHandle
;
7170 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
7171 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
7173 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
7175 align_pointer(&pStubMsg
->Buffer
, 4);
7177 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7179 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7180 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7181 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7184 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
7185 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
7186 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
7187 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
7188 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
7190 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
7191 if_id
= &sif
->InterfaceId
;
7194 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
7196 pStubMsg
->RpcMsg
->DataRepresentation
,
7198 pStubMsg
->Buffer
+= cbNDRContext
;
7200 return ContextHandle
;
7203 /***********************************************************************
7204 * NdrCorrelationInitialize [RPCRT4.@]
7206 * Initializes correlation validity checking.
7209 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7210 * pMemory [I] Pointer to memory to use as a cache.
7211 * CacheSize [I] Size of the memory pointed to by pMemory.
7212 * Flags [I] Reserved. Set to zero.
7217 void WINAPI
NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg
, void *pMemory
, ULONG CacheSize
, ULONG Flags
)
7219 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg
, pMemory
, CacheSize
, Flags
);
7220 pStubMsg
->fHasNewCorrDesc
= TRUE
;
7223 /***********************************************************************
7224 * NdrCorrelationPass [RPCRT4.@]
7226 * Performs correlation validity checking.
7229 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7234 void WINAPI
NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg
)
7236 FIXME("(%p): stub\n", pStubMsg
);
7239 /***********************************************************************
7240 * NdrCorrelationFree [RPCRT4.@]
7242 * Frees any resources used while unmarshalling parameters that need
7243 * correlation validity checking.
7246 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7251 void WINAPI
NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg
)
7253 FIXME("(%p): stub\n", pStubMsg
);