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 int 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
= 1;
827 case RPC_FC_UP
: /* unique pointer */
828 case RPC_FC_OP
: /* object pointer - same as unique here */
830 pointer_needs_marshaling
= 1;
832 pointer_needs_marshaling
= 0;
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 int 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
= 1;
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
= 1;
897 pointer_needs_unmarshaling
= 0;
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
= 1;
913 pointer_needs_unmarshaling
= 0;
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 int 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 int 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
= 1;
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
= 1;
1067 pointer_needs_sizing
= 0;
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\n", pFormat
[0]);
1183 case RPC_FC_NO_REPEAT
:
1189 case RPC_FC_FIXED_REPEAT
:
1190 rep
= *(const WORD
*)&pFormat
[2];
1191 stride
= *(const WORD
*)&pFormat
[4];
1192 count
= *(const WORD
*)&pFormat
[8];
1195 case RPC_FC_VARIABLE_REPEAT
:
1196 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1197 stride
= *(const WORD
*)&pFormat
[2];
1198 count
= *(const WORD
*)&pFormat
[6];
1202 for (i
= 0; i
< rep
; i
++) {
1203 PFORMAT_STRING info
= pFormat
;
1204 unsigned char *membase
= pMemory
+ (i
* stride
);
1205 unsigned char *bufbase
= Mark
+ (i
* stride
);
1208 for (u
=0; u
<count
; u
++,info
+=8) {
1209 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1210 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1211 unsigned char *saved_memory
= pStubMsg
->Memory
;
1213 pStubMsg
->Memory
= pMemory
;
1214 PointerMarshall(pStubMsg
, bufptr
, *(unsigned char**)memptr
, info
+4);
1215 pStubMsg
->Memory
= saved_memory
;
1218 pFormat
+= 8 * count
;
1223 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1224 pStubMsg
->Buffer
= saved_buffer
;
1227 STD_OVERFLOW_CHECK(pStubMsg
);
1232 /***********************************************************************
1233 * EmbeddedPointerUnmarshall
1235 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1236 unsigned char *pDstBuffer
,
1237 unsigned char *pSrcMemoryPtrs
,
1238 PFORMAT_STRING pFormat
,
1239 unsigned char fMustAlloc
)
1241 unsigned char *Mark
= pStubMsg
->BufferMark
;
1242 unsigned rep
, count
, stride
;
1244 unsigned char *saved_buffer
= NULL
;
1246 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg
, pDstBuffer
, pSrcMemoryPtrs
, pFormat
, fMustAlloc
);
1248 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1251 if (pStubMsg
->PointerBufferMark
)
1253 saved_buffer
= pStubMsg
->Buffer
;
1254 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1255 pStubMsg
->PointerBufferMark
= NULL
;
1258 while (pFormat
[0] != RPC_FC_END
) {
1259 TRACE("pFormat[0] = 0x%x\n", pFormat
[0]);
1260 switch (pFormat
[0]) {
1262 FIXME("unknown repeat type %d\n", pFormat
[0]);
1263 case RPC_FC_NO_REPEAT
:
1269 case RPC_FC_FIXED_REPEAT
:
1270 rep
= *(const WORD
*)&pFormat
[2];
1271 stride
= *(const WORD
*)&pFormat
[4];
1272 count
= *(const WORD
*)&pFormat
[8];
1275 case RPC_FC_VARIABLE_REPEAT
:
1276 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1277 stride
= *(const WORD
*)&pFormat
[2];
1278 count
= *(const WORD
*)&pFormat
[6];
1282 for (i
= 0; i
< rep
; i
++) {
1283 PFORMAT_STRING info
= pFormat
;
1284 unsigned char *bufdstbase
= pDstBuffer
+ (i
* stride
);
1285 unsigned char *memsrcbase
= pSrcMemoryPtrs
+ (i
* stride
);
1286 unsigned char *bufbase
= Mark
+ (i
* stride
);
1289 for (u
=0; u
<count
; u
++,info
+=8) {
1290 unsigned char **bufdstptr
= (unsigned char **)(bufdstbase
+ *(const SHORT
*)&info
[2]);
1291 unsigned char **memsrcptr
= (unsigned char **)(memsrcbase
+ *(const SHORT
*)&info
[0]);
1292 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1293 PointerUnmarshall(pStubMsg
, bufptr
, bufdstptr
, *memsrcptr
, info
+4, fMustAlloc
);
1296 pFormat
+= 8 * count
;
1301 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1302 pStubMsg
->Buffer
= saved_buffer
;
1308 /***********************************************************************
1309 * EmbeddedPointerBufferSize
1311 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1312 unsigned char *pMemory
,
1313 PFORMAT_STRING pFormat
)
1315 unsigned rep
, count
, stride
;
1317 ULONG saved_buffer_length
= 0;
1319 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1321 if (pStubMsg
->IgnoreEmbeddedPointers
) return;
1323 if (*pFormat
!= RPC_FC_PP
) return;
1326 if (pStubMsg
->PointerLength
)
1328 saved_buffer_length
= pStubMsg
->BufferLength
;
1329 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
1330 pStubMsg
->PointerLength
= 0;
1333 while (pFormat
[0] != RPC_FC_END
) {
1334 switch (pFormat
[0]) {
1336 FIXME("unknown repeat type %d\n", pFormat
[0]);
1337 case RPC_FC_NO_REPEAT
:
1343 case RPC_FC_FIXED_REPEAT
:
1344 rep
= *(const WORD
*)&pFormat
[2];
1345 stride
= *(const WORD
*)&pFormat
[4];
1346 count
= *(const WORD
*)&pFormat
[8];
1349 case RPC_FC_VARIABLE_REPEAT
:
1350 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1351 stride
= *(const WORD
*)&pFormat
[2];
1352 count
= *(const WORD
*)&pFormat
[6];
1356 for (i
= 0; i
< rep
; i
++) {
1357 PFORMAT_STRING info
= pFormat
;
1358 unsigned char *membase
= pMemory
+ (i
* stride
);
1361 for (u
=0; u
<count
; u
++,info
+=8) {
1362 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1363 unsigned char *saved_memory
= pStubMsg
->Memory
;
1365 pStubMsg
->Memory
= pMemory
;
1366 PointerBufferSize(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1367 pStubMsg
->Memory
= saved_memory
;
1370 pFormat
+= 8 * count
;
1373 if (saved_buffer_length
)
1375 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
1376 pStubMsg
->BufferLength
= saved_buffer_length
;
1380 /***********************************************************************
1381 * EmbeddedPointerMemorySize [internal]
1383 static ULONG
EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1384 PFORMAT_STRING pFormat
)
1386 unsigned char *Mark
= pStubMsg
->BufferMark
;
1387 unsigned rep
, count
, stride
;
1389 unsigned char *saved_buffer
= NULL
;
1391 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1393 if (pStubMsg
->IgnoreEmbeddedPointers
) return 0;
1395 if (pStubMsg
->PointerBufferMark
)
1397 saved_buffer
= pStubMsg
->Buffer
;
1398 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1399 pStubMsg
->PointerBufferMark
= NULL
;
1402 if (*pFormat
!= RPC_FC_PP
) return 0;
1405 while (pFormat
[0] != RPC_FC_END
) {
1406 switch (pFormat
[0]) {
1408 FIXME("unknown repeat type %d\n", pFormat
[0]);
1409 case RPC_FC_NO_REPEAT
:
1415 case RPC_FC_FIXED_REPEAT
:
1416 rep
= *(const WORD
*)&pFormat
[2];
1417 stride
= *(const WORD
*)&pFormat
[4];
1418 count
= *(const WORD
*)&pFormat
[8];
1421 case RPC_FC_VARIABLE_REPEAT
:
1422 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1423 stride
= *(const WORD
*)&pFormat
[2];
1424 count
= *(const WORD
*)&pFormat
[6];
1428 for (i
= 0; i
< rep
; i
++) {
1429 PFORMAT_STRING info
= pFormat
;
1430 unsigned char *bufbase
= Mark
+ (i
* stride
);
1432 for (u
=0; u
<count
; u
++,info
+=8) {
1433 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1434 PointerMemorySize(pStubMsg
, bufptr
, info
+4);
1437 pFormat
+= 8 * count
;
1442 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1443 pStubMsg
->Buffer
= saved_buffer
;
1449 /***********************************************************************
1450 * EmbeddedPointerFree [internal]
1452 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1453 unsigned char *pMemory
,
1454 PFORMAT_STRING pFormat
)
1456 unsigned rep
, count
, stride
;
1459 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1460 if (*pFormat
!= RPC_FC_PP
) return;
1463 while (pFormat
[0] != RPC_FC_END
) {
1464 switch (pFormat
[0]) {
1466 FIXME("unknown repeat type %d\n", pFormat
[0]);
1467 case RPC_FC_NO_REPEAT
:
1473 case RPC_FC_FIXED_REPEAT
:
1474 rep
= *(const WORD
*)&pFormat
[2];
1475 stride
= *(const WORD
*)&pFormat
[4];
1476 count
= *(const WORD
*)&pFormat
[8];
1479 case RPC_FC_VARIABLE_REPEAT
:
1480 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1481 stride
= *(const WORD
*)&pFormat
[2];
1482 count
= *(const WORD
*)&pFormat
[6];
1486 for (i
= 0; i
< rep
; i
++) {
1487 PFORMAT_STRING info
= pFormat
;
1488 unsigned char *membase
= pMemory
+ (i
* stride
);
1491 for (u
=0; u
<count
; u
++,info
+=8) {
1492 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1493 unsigned char *saved_memory
= pStubMsg
->Memory
;
1495 pStubMsg
->Memory
= pMemory
;
1496 PointerFree(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1497 pStubMsg
->Memory
= saved_memory
;
1500 pFormat
+= 8 * count
;
1504 /***********************************************************************
1505 * NdrPointerMarshall [RPCRT4.@]
1507 unsigned char * WINAPI
NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1508 unsigned char *pMemory
,
1509 PFORMAT_STRING pFormat
)
1511 unsigned char *Buffer
;
1513 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1515 /* Increment the buffer here instead of in PointerMarshall,
1516 * as that is used by embedded pointers which already handle the incrementing
1517 * the buffer, and shouldn't write any additional pointer data to the wire */
1518 if (*pFormat
!= RPC_FC_RP
)
1520 align_pointer_clear(&pStubMsg
->Buffer
, 4);
1521 Buffer
= pStubMsg
->Buffer
;
1522 safe_buffer_increment(pStubMsg
, 4);
1525 Buffer
= pStubMsg
->Buffer
;
1527 PointerMarshall(pStubMsg
, Buffer
, pMemory
, pFormat
);
1532 /***********************************************************************
1533 * NdrPointerUnmarshall [RPCRT4.@]
1535 unsigned char * WINAPI
NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1536 unsigned char **ppMemory
,
1537 PFORMAT_STRING pFormat
,
1538 unsigned char fMustAlloc
)
1540 unsigned char *Buffer
;
1542 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1544 if (*pFormat
== RPC_FC_RP
)
1546 Buffer
= pStubMsg
->Buffer
;
1547 /* Do the NULL ref pointer check here because embedded pointers can be
1548 * NULL if the type the pointer is embedded in was allocated rather than
1549 * being passed in by the client */
1550 if (pStubMsg
->IsClient
&& !*ppMemory
)
1552 ERR("NULL ref pointer is not allowed\n");
1553 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
1558 /* Increment the buffer here instead of in PointerUnmarshall,
1559 * as that is used by embedded pointers which already handle the incrementing
1560 * the buffer, and shouldn't read any additional pointer data from the
1562 align_pointer(&pStubMsg
->Buffer
, 4);
1563 Buffer
= pStubMsg
->Buffer
;
1564 safe_buffer_increment(pStubMsg
, 4);
1567 PointerUnmarshall(pStubMsg
, Buffer
, ppMemory
, *ppMemory
, pFormat
, fMustAlloc
);
1572 /***********************************************************************
1573 * NdrPointerBufferSize [RPCRT4.@]
1575 void WINAPI
NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1576 unsigned char *pMemory
,
1577 PFORMAT_STRING pFormat
)
1579 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1581 /* Increment the buffer length here instead of in PointerBufferSize,
1582 * as that is used by embedded pointers which already handle the buffer
1583 * length, and shouldn't write anything more to the wire */
1584 if (*pFormat
!= RPC_FC_RP
)
1586 align_length(&pStubMsg
->BufferLength
, 4);
1587 safe_buffer_length_increment(pStubMsg
, 4);
1590 PointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1593 /***********************************************************************
1594 * NdrPointerMemorySize [RPCRT4.@]
1596 ULONG WINAPI
NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1597 PFORMAT_STRING pFormat
)
1599 unsigned char *Buffer
= pStubMsg
->Buffer
;
1600 if (*pFormat
!= RPC_FC_RP
)
1602 align_pointer(&pStubMsg
->Buffer
, 4);
1603 safe_buffer_increment(pStubMsg
, 4);
1605 align_length(&pStubMsg
->MemorySize
, sizeof(void *));
1606 return PointerMemorySize(pStubMsg
, Buffer
, pFormat
);
1609 /***********************************************************************
1610 * NdrPointerFree [RPCRT4.@]
1612 void WINAPI
NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1613 unsigned char *pMemory
,
1614 PFORMAT_STRING pFormat
)
1616 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1617 PointerFree(pStubMsg
, pMemory
, pFormat
);
1620 /***********************************************************************
1621 * NdrSimpleTypeMarshall [RPCRT4.@]
1623 void WINAPI
NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1624 unsigned char FormatChar
)
1626 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &FormatChar
);
1629 /***********************************************************************
1630 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1632 * Unmarshall a base type.
1635 * Doesn't check that the buffer is long enough before copying, so the caller
1638 void WINAPI
NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1639 unsigned char FormatChar
)
1641 #define BASE_TYPE_UNMARSHALL(type) \
1642 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
1643 TRACE("pMemory: %p\n", pMemory); \
1644 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1645 pStubMsg->Buffer += sizeof(type);
1653 BASE_TYPE_UNMARSHALL(UCHAR
);
1654 TRACE("value: 0x%02x\n", *pMemory
);
1659 BASE_TYPE_UNMARSHALL(USHORT
);
1660 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
1664 case RPC_FC_ERROR_STATUS_T
:
1666 BASE_TYPE_UNMARSHALL(ULONG
);
1667 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
1670 BASE_TYPE_UNMARSHALL(float);
1671 TRACE("value: %f\n", *(float *)pMemory
);
1674 BASE_TYPE_UNMARSHALL(double);
1675 TRACE("value: %f\n", *(double *)pMemory
);
1678 BASE_TYPE_UNMARSHALL(ULONGLONG
);
1679 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
1682 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
1683 TRACE("pMemory: %p\n", pMemory
);
1684 /* 16-bits on the wire, but int in memory */
1685 *(UINT
*)pMemory
= *(USHORT
*)pStubMsg
->Buffer
;
1686 pStubMsg
->Buffer
+= sizeof(USHORT
);
1687 TRACE("value: 0x%08x\n", *(UINT
*)pMemory
);
1689 case RPC_FC_INT3264
:
1690 align_pointer(&pStubMsg
->Buffer
, sizeof(INT
));
1691 /* 32-bits on the wire, but int_ptr in memory */
1692 *(INT_PTR
*)pMemory
= *(INT
*)pStubMsg
->Buffer
;
1693 pStubMsg
->Buffer
+= sizeof(INT
);
1694 TRACE("value: 0x%08lx\n", *(INT_PTR
*)pMemory
);
1696 case RPC_FC_UINT3264
:
1697 align_pointer(&pStubMsg
->Buffer
, sizeof(UINT
));
1698 /* 32-bits on the wire, but int_ptr in memory */
1699 *(UINT_PTR
*)pMemory
= *(UINT
*)pStubMsg
->Buffer
;
1700 pStubMsg
->Buffer
+= sizeof(UINT
);
1701 TRACE("value: 0x%08lx\n", *(UINT_PTR
*)pMemory
);
1706 FIXME("Unhandled base type: 0x%02x\n", FormatChar
);
1708 #undef BASE_TYPE_UNMARSHALL
1711 /***********************************************************************
1712 * NdrSimpleStructMarshall [RPCRT4.@]
1714 unsigned char * WINAPI
NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1715 unsigned char *pMemory
,
1716 PFORMAT_STRING pFormat
)
1718 unsigned size
= *(const WORD
*)(pFormat
+2);
1719 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1721 align_pointer_clear(&pStubMsg
->Buffer
, pFormat
[1] + 1);
1723 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1724 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
1726 if (pFormat
[0] != RPC_FC_STRUCT
)
1727 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
+4);
1732 /***********************************************************************
1733 * NdrSimpleStructUnmarshall [RPCRT4.@]
1735 unsigned char * WINAPI
NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1736 unsigned char **ppMemory
,
1737 PFORMAT_STRING pFormat
,
1738 unsigned char fMustAlloc
)
1740 unsigned size
= *(const WORD
*)(pFormat
+2);
1741 unsigned char *saved_buffer
;
1742 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1744 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
1747 *ppMemory
= NdrAllocate(pStubMsg
, size
);
1750 if (!pStubMsg
->IsClient
&& !*ppMemory
)
1751 /* for servers, we just point straight into the RPC buffer */
1752 *ppMemory
= pStubMsg
->Buffer
;
1755 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1756 safe_buffer_increment(pStubMsg
, size
);
1757 if (pFormat
[0] == RPC_FC_PSTRUCT
)
1758 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
+4, fMustAlloc
);
1760 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
1761 if (*ppMemory
!= saved_buffer
)
1762 memcpy(*ppMemory
, saved_buffer
, size
);
1767 /***********************************************************************
1768 * NdrSimpleStructBufferSize [RPCRT4.@]
1770 void WINAPI
NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1771 unsigned char *pMemory
,
1772 PFORMAT_STRING pFormat
)
1774 unsigned size
= *(const WORD
*)(pFormat
+2);
1775 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1777 align_length(&pStubMsg
->BufferLength
, pFormat
[1] + 1);
1779 safe_buffer_length_increment(pStubMsg
, size
);
1780 if (pFormat
[0] != RPC_FC_STRUCT
)
1781 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
+4);
1784 /***********************************************************************
1785 * NdrSimpleStructMemorySize [RPCRT4.@]
1787 ULONG WINAPI
NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1788 PFORMAT_STRING pFormat
)
1790 unsigned short size
= *(const WORD
*)(pFormat
+2);
1792 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1794 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
1795 pStubMsg
->MemorySize
+= size
;
1796 safe_buffer_increment(pStubMsg
, size
);
1798 if (pFormat
[0] != RPC_FC_STRUCT
)
1799 EmbeddedPointerMemorySize(pStubMsg
, pFormat
+4);
1800 return pStubMsg
->MemorySize
;
1803 /***********************************************************************
1804 * NdrSimpleStructFree [RPCRT4.@]
1806 void WINAPI
NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
1807 unsigned char *pMemory
,
1808 PFORMAT_STRING pFormat
)
1810 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1811 if (pFormat
[0] != RPC_FC_STRUCT
)
1812 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
+4);
1817 static inline void array_compute_and_size_conformance(
1818 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1819 PFORMAT_STRING pFormat
)
1826 ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1827 SizeConformance(pStubMsg
);
1829 case RPC_FC_CVARRAY
:
1830 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, 0);
1831 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
1832 SizeConformance(pStubMsg
);
1834 case RPC_FC_C_CSTRING
:
1835 case RPC_FC_C_WSTRING
:
1836 if (fc
== RPC_FC_C_CSTRING
)
1838 TRACE("string=%s\n", debugstr_a((const char *)pMemory
));
1839 pStubMsg
->ActualCount
= strlen((const char *)pMemory
)+1;
1843 TRACE("string=%s\n", debugstr_w((LPCWSTR
)pMemory
));
1844 pStubMsg
->ActualCount
= strlenW((LPCWSTR
)pMemory
)+1;
1847 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
1848 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
1850 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
1852 SizeConformance(pStubMsg
);
1854 case RPC_FC_BOGUS_ARRAY
:
1855 count
= *(const WORD
*)(pFormat
+ 2);
1857 if (IsConformanceOrVariancePresent(pFormat
)) SizeConformance(pStubMsg
);
1858 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, count
);
1859 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
1862 ERR("unknown array format 0x%x\n", fc
);
1863 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1867 static inline void array_buffer_size(
1868 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1869 PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
1873 unsigned char alignment
;
1878 esize
= *(const WORD
*)(pFormat
+2);
1879 alignment
= pFormat
[1] + 1;
1881 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1883 align_length(&pStubMsg
->BufferLength
, alignment
);
1885 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
1886 /* conformance value plus array */
1887 safe_buffer_length_increment(pStubMsg
, size
);
1890 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1892 case RPC_FC_CVARRAY
:
1893 esize
= *(const WORD
*)(pFormat
+2);
1894 alignment
= pFormat
[1] + 1;
1896 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1897 pFormat
= SkipVariance(pStubMsg
, pFormat
);
1899 SizeVariance(pStubMsg
);
1901 align_length(&pStubMsg
->BufferLength
, alignment
);
1903 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1904 safe_buffer_length_increment(pStubMsg
, size
);
1907 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1909 case RPC_FC_C_CSTRING
:
1910 case RPC_FC_C_WSTRING
:
1911 if (fc
== RPC_FC_C_CSTRING
)
1916 SizeVariance(pStubMsg
);
1918 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1919 safe_buffer_length_increment(pStubMsg
, size
);
1921 case RPC_FC_BOGUS_ARRAY
:
1922 alignment
= pFormat
[1] + 1;
1923 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1924 if (IsConformanceOrVariancePresent(pFormat
)) SizeVariance(pStubMsg
);
1925 pFormat
= SkipVariance(pStubMsg
, pFormat
);
1927 align_length(&pStubMsg
->BufferLength
, alignment
);
1929 size
= pStubMsg
->ActualCount
;
1930 for (i
= 0; i
< size
; i
++)
1931 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
1934 ERR("unknown array format 0x%x\n", fc
);
1935 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1939 static inline void array_compute_and_write_conformance(
1940 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1941 PFORMAT_STRING pFormat
)
1944 BOOL conformance_present
;
1949 ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1950 WriteConformance(pStubMsg
);
1952 case RPC_FC_CVARRAY
:
1953 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, 0);
1954 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
1955 WriteConformance(pStubMsg
);
1957 case RPC_FC_C_CSTRING
:
1958 case RPC_FC_C_WSTRING
:
1959 if (fc
== RPC_FC_C_CSTRING
)
1961 TRACE("string=%s\n", debugstr_a((const char *)pMemory
));
1962 pStubMsg
->ActualCount
= strlen((const char *)pMemory
)+1;
1966 TRACE("string=%s\n", debugstr_w((LPCWSTR
)pMemory
));
1967 pStubMsg
->ActualCount
= strlenW((LPCWSTR
)pMemory
)+1;
1969 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
1970 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
1972 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
1973 pStubMsg
->Offset
= 0;
1974 WriteConformance(pStubMsg
);
1976 case RPC_FC_BOGUS_ARRAY
:
1977 def
= *(const WORD
*)(pFormat
+ 2);
1979 conformance_present
= IsConformanceOrVariancePresent(pFormat
);
1980 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
1981 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
1982 if (conformance_present
) WriteConformance(pStubMsg
);
1985 ERR("unknown array format 0x%x\n", fc
);
1986 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1990 static inline void array_write_variance_and_marshall(
1991 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1992 PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
1996 unsigned char alignment
;
2001 esize
= *(const WORD
*)(pFormat
+2);
2002 alignment
= pFormat
[1] + 1;
2004 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2006 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
2008 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2010 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2011 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
2014 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2016 case RPC_FC_CVARRAY
:
2017 esize
= *(const WORD
*)(pFormat
+2);
2018 alignment
= pFormat
[1] + 1;
2020 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2021 pFormat
= SkipVariance(pStubMsg
, pFormat
);
2023 WriteVariance(pStubMsg
);
2025 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
2027 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2030 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2031 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, size
);
2034 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2036 case RPC_FC_C_CSTRING
:
2037 case RPC_FC_C_WSTRING
:
2038 if (fc
== RPC_FC_C_CSTRING
)
2043 WriteVariance(pStubMsg
);
2045 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2046 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
2048 case RPC_FC_BOGUS_ARRAY
:
2049 alignment
= pFormat
[1] + 1;
2050 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2051 if (IsConformanceOrVariancePresent(pFormat
)) WriteVariance(pStubMsg
);
2052 pFormat
= SkipVariance(pStubMsg
, pFormat
);
2054 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
2056 size
= pStubMsg
->ActualCount
;
2057 for (i
= 0; i
< size
; i
++)
2058 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
2061 ERR("unknown array format 0x%x\n", fc
);
2062 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2066 static inline ULONG
array_read_conformance(
2067 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
2074 esize
= *(const WORD
*)(pFormat
+2);
2075 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2076 return safe_multiply(esize
, pStubMsg
->MaxCount
);
2077 case RPC_FC_CVARRAY
:
2078 esize
= *(const WORD
*)(pFormat
+2);
2079 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2080 return safe_multiply(esize
, pStubMsg
->MaxCount
);
2081 case RPC_FC_C_CSTRING
:
2082 case RPC_FC_C_WSTRING
:
2083 if (fc
== RPC_FC_C_CSTRING
)
2088 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
2089 ReadConformance(pStubMsg
, pFormat
+ 2);
2091 ReadConformance(pStubMsg
, NULL
);
2092 return safe_multiply(esize
, pStubMsg
->MaxCount
);
2093 case RPC_FC_BOGUS_ARRAY
:
2094 def
= *(const WORD
*)(pFormat
+ 2);
2096 if (IsConformanceOrVariancePresent(pFormat
)) pFormat
= ReadConformance(pStubMsg
, pFormat
);
2099 pStubMsg
->MaxCount
= def
;
2100 pFormat
= SkipConformance( pStubMsg
, pFormat
);
2102 pFormat
= SkipVariance( pStubMsg
, pFormat
);
2104 esize
= ComplexStructSize(pStubMsg
, pFormat
);
2105 return safe_multiply(pStubMsg
->MaxCount
, esize
);
2107 ERR("unknown array format 0x%x\n", fc
);
2108 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2112 static inline ULONG
array_read_variance_and_unmarshall(
2113 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char **ppMemory
,
2114 PFORMAT_STRING pFormat
, unsigned char fMustAlloc
,
2115 unsigned char fUseBufferMemoryServer
, unsigned char fUnmarshall
)
2117 ULONG bufsize
, memsize
;
2119 unsigned char alignment
;
2120 unsigned char *saved_buffer
, *pMemory
;
2121 ULONG i
, offset
, count
;
2126 esize
= *(const WORD
*)(pFormat
+2);
2127 alignment
= pFormat
[1] + 1;
2129 bufsize
= memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2131 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2133 align_pointer(&pStubMsg
->Buffer
, alignment
);
2138 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2141 if (fUseBufferMemoryServer
&& !pStubMsg
->IsClient
&& !*ppMemory
)
2142 /* for servers, we just point straight into the RPC buffer */
2143 *ppMemory
= pStubMsg
->Buffer
;
2146 saved_buffer
= pStubMsg
->Buffer
;
2147 safe_buffer_increment(pStubMsg
, bufsize
);
2149 pStubMsg
->BufferMark
= saved_buffer
;
2150 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
2152 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
2153 if (*ppMemory
!= saved_buffer
)
2154 memcpy(*ppMemory
, saved_buffer
, bufsize
);
2157 case RPC_FC_CVARRAY
:
2158 esize
= *(const WORD
*)(pFormat
+2);
2159 alignment
= pFormat
[1] + 1;
2161 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2163 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2165 align_pointer(&pStubMsg
->Buffer
, alignment
);
2167 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2168 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2172 offset
= pStubMsg
->Offset
;
2174 if (!fMustAlloc
&& !*ppMemory
)
2177 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2178 saved_buffer
= pStubMsg
->Buffer
;
2179 safe_buffer_increment(pStubMsg
, bufsize
);
2181 pStubMsg
->BufferMark
= saved_buffer
;
2182 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
,
2185 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
2188 case RPC_FC_C_CSTRING
:
2189 case RPC_FC_C_WSTRING
:
2190 if (fc
== RPC_FC_C_CSTRING
)
2195 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
2197 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
2199 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2200 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
2201 RpcRaiseException(RPC_S_INVALID_BOUND
);
2203 if (pStubMsg
->Offset
)
2205 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2206 RpcRaiseException(RPC_S_INVALID_BOUND
);
2209 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2210 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2212 validate_string_data(pStubMsg
, bufsize
, esize
);
2217 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2220 if (fUseBufferMemoryServer
&& !pStubMsg
->IsClient
&&
2221 !*ppMemory
&& (pStubMsg
->MaxCount
== pStubMsg
->ActualCount
))
2222 /* if the data in the RPC buffer is big enough, we just point
2223 * straight into it */
2224 *ppMemory
= pStubMsg
->Buffer
;
2225 else if (!*ppMemory
)
2226 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2229 if (*ppMemory
== pStubMsg
->Buffer
)
2230 safe_buffer_increment(pStubMsg
, bufsize
);
2232 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
2234 if (*pFormat
== RPC_FC_C_CSTRING
)
2235 TRACE("string=%s\n", debugstr_a((char*)*ppMemory
));
2237 TRACE("string=%s\n", debugstr_w((LPWSTR
)*ppMemory
));
2241 case RPC_FC_BOGUS_ARRAY
:
2242 alignment
= pFormat
[1] + 1;
2243 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2244 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2246 esize
= ComplexStructSize(pStubMsg
, pFormat
);
2247 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2249 assert( fUnmarshall
);
2251 if (!fMustAlloc
&& !*ppMemory
)
2254 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2256 align_pointer(&pStubMsg
->Buffer
, alignment
);
2257 saved_buffer
= pStubMsg
->Buffer
;
2259 pMemory
= *ppMemory
;
2260 count
= pStubMsg
->ActualCount
;
2261 for (i
= 0; i
< count
; i
++)
2262 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
, fMustAlloc
);
2263 return pStubMsg
->Buffer
- saved_buffer
;
2266 ERR("unknown array format 0x%x\n", fc
);
2267 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2271 static inline void array_memory_size(
2272 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
,
2273 unsigned char fHasPointers
)
2275 ULONG i
, count
, SavedMemorySize
;
2276 ULONG bufsize
, memsize
;
2278 unsigned char alignment
;
2283 esize
= *(const WORD
*)(pFormat
+2);
2284 alignment
= pFormat
[1] + 1;
2286 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2288 bufsize
= memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2289 pStubMsg
->MemorySize
+= memsize
;
2291 align_pointer(&pStubMsg
->Buffer
, alignment
);
2293 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2294 safe_buffer_increment(pStubMsg
, bufsize
);
2297 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2299 case RPC_FC_CVARRAY
:
2300 esize
= *(const WORD
*)(pFormat
+2);
2301 alignment
= pFormat
[1] + 1;
2303 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2305 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2307 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2308 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2309 pStubMsg
->MemorySize
+= memsize
;
2311 align_pointer(&pStubMsg
->Buffer
, alignment
);
2313 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2314 safe_buffer_increment(pStubMsg
, bufsize
);
2317 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2319 case RPC_FC_C_CSTRING
:
2320 case RPC_FC_C_WSTRING
:
2321 if (fc
== RPC_FC_C_CSTRING
)
2326 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
2328 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
2330 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2331 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
2332 RpcRaiseException(RPC_S_INVALID_BOUND
);
2334 if (pStubMsg
->Offset
)
2336 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2337 RpcRaiseException(RPC_S_INVALID_BOUND
);
2340 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2341 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2343 validate_string_data(pStubMsg
, bufsize
, esize
);
2345 safe_buffer_increment(pStubMsg
, bufsize
);
2346 pStubMsg
->MemorySize
+= memsize
;
2348 case RPC_FC_BOGUS_ARRAY
:
2349 alignment
= pFormat
[1] + 1;
2350 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2351 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2353 align_pointer(&pStubMsg
->Buffer
, alignment
);
2355 SavedMemorySize
= pStubMsg
->MemorySize
;
2357 esize
= ComplexStructSize(pStubMsg
, pFormat
);
2358 memsize
= safe_multiply(pStubMsg
->MaxCount
, esize
);
2360 count
= pStubMsg
->ActualCount
;
2361 for (i
= 0; i
< count
; i
++)
2362 ComplexStructMemorySize(pStubMsg
, pFormat
, NULL
);
2364 pStubMsg
->MemorySize
= SavedMemorySize
+ memsize
;
2367 ERR("unknown array format 0x%x\n", fc
);
2368 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2372 static inline void array_free(
2373 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
,
2374 unsigned char *pMemory
, PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
2381 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2383 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2385 case RPC_FC_CVARRAY
:
2386 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2387 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2389 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2391 case RPC_FC_C_CSTRING
:
2392 case RPC_FC_C_WSTRING
:
2393 /* No embedded pointers so nothing to do */
2395 case RPC_FC_BOGUS_ARRAY
:
2396 count
= *(const WORD
*)(pFormat
+ 2);
2397 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, count
);
2398 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
2400 count
= pStubMsg
->ActualCount
;
2401 for (i
= 0; i
< count
; i
++)
2402 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
2405 ERR("unknown array format 0x%x\n", fc
);
2406 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2411 * NdrConformantString:
2413 * What MS calls a ConformantString is, in DCE terminology,
2414 * a Varying-Conformant String.
2416 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2417 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2418 * into unmarshalled string)
2419 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2421 * data: CHARTYPE[maxlen]
2423 * ], where CHARTYPE is the appropriate character type (specified externally)
2427 /***********************************************************************
2428 * NdrConformantStringMarshall [RPCRT4.@]
2430 unsigned char *WINAPI
NdrConformantStringMarshall(MIDL_STUB_MESSAGE
*pStubMsg
,
2431 unsigned char *pszMessage
, PFORMAT_STRING pFormat
)
2433 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg
, pszMessage
, pFormat
);
2435 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2436 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2437 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2440 /* allow compiler to optimise inline function by passing constant into
2441 * these functions */
2442 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2443 array_compute_and_write_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pszMessage
,
2445 array_write_variance_and_marshall(RPC_FC_C_CSTRING
, pStubMsg
, pszMessage
,
2446 pFormat
, TRUE
/* fHasPointers */);
2448 array_compute_and_write_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pszMessage
,
2450 array_write_variance_and_marshall(RPC_FC_C_WSTRING
, pStubMsg
, pszMessage
,
2451 pFormat
, TRUE
/* fHasPointers */);
2457 /***********************************************************************
2458 * NdrConformantStringBufferSize [RPCRT4.@]
2460 void WINAPI
NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2461 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
2463 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2465 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2466 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2467 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2470 /* allow compiler to optimise inline function by passing constant into
2471 * these functions */
2472 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2473 array_compute_and_size_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pMemory
,
2475 array_buffer_size(RPC_FC_C_CSTRING
, pStubMsg
, pMemory
, pFormat
,
2476 TRUE
/* fHasPointers */);
2478 array_compute_and_size_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pMemory
,
2480 array_buffer_size(RPC_FC_C_WSTRING
, pStubMsg
, pMemory
, pFormat
,
2481 TRUE
/* fHasPointers */);
2485 /************************************************************************
2486 * NdrConformantStringMemorySize [RPCRT4.@]
2488 ULONG WINAPI
NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
2489 PFORMAT_STRING pFormat
)
2491 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
2493 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2494 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2495 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2498 /* allow compiler to optimise inline function by passing constant into
2499 * these functions */
2500 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2501 array_read_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
);
2502 array_memory_size(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
,
2503 TRUE
/* fHasPointers */);
2505 array_read_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
);
2506 array_memory_size(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
,
2507 TRUE
/* fHasPointers */);
2510 return pStubMsg
->MemorySize
;
2513 /************************************************************************
2514 * NdrConformantStringUnmarshall [RPCRT4.@]
2516 unsigned char *WINAPI
NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2517 unsigned char** ppMemory
, PFORMAT_STRING pFormat
, unsigned char fMustAlloc
)
2519 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2520 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
2522 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2523 ERR("Unhandled string type: %#x\n", *pFormat
);
2524 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2527 /* allow compiler to optimise inline function by passing constant into
2528 * these functions */
2529 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2530 array_read_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
);
2531 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING
, pStubMsg
, ppMemory
,
2532 pFormat
, fMustAlloc
,
2533 TRUE
/* fUseBufferMemoryServer */,
2534 TRUE
/* fUnmarshall */);
2536 array_read_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
);
2537 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING
, pStubMsg
, ppMemory
,
2538 pFormat
, fMustAlloc
,
2539 TRUE
/* fUseBufferMemoryServer */,
2540 TRUE
/* fUnmarshall */);
2546 /***********************************************************************
2547 * NdrNonConformantStringMarshall [RPCRT4.@]
2549 unsigned char * WINAPI
NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2550 unsigned char *pMemory
,
2551 PFORMAT_STRING pFormat
)
2553 ULONG esize
, size
, maxsize
;
2555 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2557 maxsize
= *(const USHORT
*)&pFormat
[2];
2559 if (*pFormat
== RPC_FC_CSTRING
)
2562 const char *str
= (const char *)pMemory
;
2563 while (i
< maxsize
&& str
[i
]) i
++;
2564 TRACE("string=%s\n", debugstr_an(str
, i
));
2565 pStubMsg
->ActualCount
= i
+ 1;
2568 else if (*pFormat
== RPC_FC_WSTRING
)
2571 const WCHAR
*str
= (const WCHAR
*)pMemory
;
2572 while (i
< maxsize
&& str
[i
]) i
++;
2573 TRACE("string=%s\n", debugstr_wn(str
, i
));
2574 pStubMsg
->ActualCount
= i
+ 1;
2579 ERR("Unhandled string type: %#x\n", *pFormat
);
2580 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2583 pStubMsg
->Offset
= 0;
2584 WriteVariance(pStubMsg
);
2586 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2587 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
2592 /***********************************************************************
2593 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2595 unsigned char * WINAPI
NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2596 unsigned char **ppMemory
,
2597 PFORMAT_STRING pFormat
,
2598 unsigned char fMustAlloc
)
2600 ULONG bufsize
, memsize
, esize
, maxsize
;
2602 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2603 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
2605 maxsize
= *(const USHORT
*)&pFormat
[2];
2607 ReadVariance(pStubMsg
, NULL
, maxsize
);
2608 if (pStubMsg
->Offset
)
2610 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2611 RpcRaiseException(RPC_S_INVALID_BOUND
);
2614 if (*pFormat
== RPC_FC_CSTRING
) esize
= 1;
2615 else if (*pFormat
== RPC_FC_WSTRING
) esize
= 2;
2618 ERR("Unhandled string type: %#x\n", *pFormat
);
2619 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2622 memsize
= esize
* maxsize
;
2623 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2625 validate_string_data(pStubMsg
, bufsize
, esize
);
2627 if (!fMustAlloc
&& !*ppMemory
)
2630 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2632 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
2634 if (*pFormat
== RPC_FC_CSTRING
) {
2635 TRACE("string=%s\n", debugstr_an((char*)*ppMemory
, pStubMsg
->ActualCount
));
2637 else if (*pFormat
== RPC_FC_WSTRING
) {
2638 TRACE("string=%s\n", debugstr_wn((LPWSTR
)*ppMemory
, pStubMsg
->ActualCount
));
2644 /***********************************************************************
2645 * NdrNonConformantStringBufferSize [RPCRT4.@]
2647 void WINAPI
NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2648 unsigned char *pMemory
,
2649 PFORMAT_STRING pFormat
)
2651 ULONG esize
, maxsize
;
2653 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2655 maxsize
= *(const USHORT
*)&pFormat
[2];
2657 SizeVariance(pStubMsg
);
2659 if (*pFormat
== RPC_FC_CSTRING
)
2662 const char *str
= (const char *)pMemory
;
2663 while (i
< maxsize
&& str
[i
]) i
++;
2664 TRACE("string=%s\n", debugstr_an(str
, i
));
2665 pStubMsg
->ActualCount
= i
+ 1;
2668 else if (*pFormat
== RPC_FC_WSTRING
)
2671 const WCHAR
*str
= (const WCHAR
*)pMemory
;
2672 while (i
< maxsize
&& str
[i
]) i
++;
2673 TRACE("string=%s\n", debugstr_wn(str
, i
));
2674 pStubMsg
->ActualCount
= i
+ 1;
2679 ERR("Unhandled string type: %#x\n", *pFormat
);
2680 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2683 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
2686 /***********************************************************************
2687 * NdrNonConformantStringMemorySize [RPCRT4.@]
2689 ULONG WINAPI
NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2690 PFORMAT_STRING pFormat
)
2692 ULONG bufsize
, memsize
, esize
, maxsize
;
2694 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
2696 maxsize
= *(const USHORT
*)&pFormat
[2];
2698 ReadVariance(pStubMsg
, NULL
, maxsize
);
2700 if (pStubMsg
->Offset
)
2702 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2703 RpcRaiseException(RPC_S_INVALID_BOUND
);
2706 if (*pFormat
== RPC_FC_CSTRING
) esize
= 1;
2707 else if (*pFormat
== RPC_FC_WSTRING
) esize
= 2;
2710 ERR("Unhandled string type: %#x\n", *pFormat
);
2711 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2714 memsize
= esize
* maxsize
;
2715 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2717 validate_string_data(pStubMsg
, bufsize
, esize
);
2719 safe_buffer_increment(pStubMsg
, bufsize
);
2720 pStubMsg
->MemorySize
+= memsize
;
2722 return pStubMsg
->MemorySize
;
2727 #include "pshpack1.h"
2731 unsigned char flags_type
; /* flags in upper nibble, type in lower nibble */
2735 #include "poppack.h"
2737 static ULONG
EmbeddedComplexSize(MIDL_STUB_MESSAGE
*pStubMsg
,
2738 PFORMAT_STRING pFormat
)
2742 case RPC_FC_PSTRUCT
:
2743 case RPC_FC_CSTRUCT
:
2744 case RPC_FC_BOGUS_STRUCT
:
2745 case RPC_FC_SMFARRAY
:
2746 case RPC_FC_SMVARRAY
:
2747 case RPC_FC_CSTRING
:
2748 return *(const WORD
*)&pFormat
[2];
2749 case RPC_FC_USER_MARSHAL
:
2750 return *(const WORD
*)&pFormat
[4];
2751 case RPC_FC_RANGE
: {
2752 switch (((const NDR_RANGE
*)pFormat
)->flags_type
& 0xf) {
2757 return sizeof(UCHAR
);
2761 return sizeof(USHORT
);
2765 case RPC_FC_INT3264
:
2766 case RPC_FC_UINT3264
:
2767 return sizeof(ULONG
);
2769 return sizeof(float);
2771 return sizeof(double);
2773 return sizeof(ULONGLONG
);
2775 return sizeof(UINT
);
2777 ERR("unknown type 0x%x\n", ((const NDR_RANGE
*)pFormat
)->flags_type
& 0xf);
2778 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2781 case RPC_FC_NON_ENCAPSULATED_UNION
:
2783 if (pStubMsg
->fHasNewCorrDesc
)
2788 pFormat
+= *(const SHORT
*)pFormat
;
2789 return *(const SHORT
*)pFormat
;
2791 return sizeof(void *);
2792 case RPC_FC_WSTRING
:
2793 return *(const WORD
*)&pFormat
[2] * 2;
2795 FIXME("unhandled embedded type %02x\n", *pFormat
);
2801 static ULONG
EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2802 PFORMAT_STRING pFormat
)
2804 NDR_MEMORYSIZE m
= NdrMemorySizer
[*pFormat
& NDR_TABLE_MASK
];
2808 FIXME("no memorysizer for data type=%02x\n", *pFormat
);
2812 return m(pStubMsg
, pFormat
);
2816 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2817 unsigned char *pMemory
,
2818 PFORMAT_STRING pFormat
,
2819 PFORMAT_STRING pPointer
)
2821 PFORMAT_STRING desc
;
2825 while (*pFormat
!= RPC_FC_END
) {
2831 TRACE("byte=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2832 safe_copy_to_buffer(pStubMsg
, pMemory
, 1);
2838 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2839 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
2844 USHORT val
= *(DWORD
*)pMemory
;
2845 TRACE("enum16=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2846 if (32767 < *(DWORD
*)pMemory
)
2847 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
2848 safe_copy_to_buffer(pStubMsg
, &val
, 2);
2855 TRACE("long=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2856 safe_copy_to_buffer(pStubMsg
, pMemory
, 4);
2859 case RPC_FC_INT3264
:
2860 case RPC_FC_UINT3264
:
2862 UINT val
= *(UINT_PTR
*)pMemory
;
2863 TRACE("int3264=%ld <= %p\n", *(UINT_PTR
*)pMemory
, pMemory
);
2864 safe_copy_to_buffer(pStubMsg
, &val
, sizeof(UINT
));
2865 pMemory
+= sizeof(UINT_PTR
);
2869 TRACE("float=%f <= %p\n", *(float*)pMemory
, pMemory
);
2870 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
2871 pMemory
+= sizeof(float);
2874 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2875 safe_copy_to_buffer(pStubMsg
, pMemory
, 8);
2879 TRACE("double=%f <= %p\n", *(double*)pMemory
, pMemory
);
2880 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
2881 pMemory
+= sizeof(double);
2887 case RPC_FC_POINTER
:
2889 unsigned char *saved_buffer
;
2890 int pointer_buffer_mark_set
= 0;
2891 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
2892 TRACE("pStubMsg->Buffer before %p\n", pStubMsg
->Buffer
);
2893 if (*pFormat
!= RPC_FC_POINTER
)
2895 if (*pPointer
!= RPC_FC_RP
)
2896 align_pointer_clear(&pStubMsg
->Buffer
, 4);
2897 saved_buffer
= pStubMsg
->Buffer
;
2898 if (pStubMsg
->PointerBufferMark
)
2900 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2901 pStubMsg
->PointerBufferMark
= NULL
;
2902 pointer_buffer_mark_set
= 1;
2904 else if (*pPointer
!= RPC_FC_RP
)
2905 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2906 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char**)pMemory
, pPointer
);
2907 if (pointer_buffer_mark_set
)
2909 STD_OVERFLOW_CHECK(pStubMsg
);
2910 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2911 pStubMsg
->Buffer
= saved_buffer
;
2912 if (*pPointer
!= RPC_FC_RP
)
2913 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2915 TRACE("pStubMsg->Buffer after %p\n", pStubMsg
->Buffer
);
2916 if (*pFormat
== RPC_FC_POINTER
)
2920 pMemory
+= sizeof(void *);
2923 case RPC_FC_ALIGNM2
:
2924 align_pointer(&pMemory
, 2);
2926 case RPC_FC_ALIGNM4
:
2927 align_pointer(&pMemory
, 4);
2929 case RPC_FC_ALIGNM8
:
2930 align_pointer(&pMemory
, 8);
2932 case RPC_FC_STRUCTPAD1
:
2933 case RPC_FC_STRUCTPAD2
:
2934 case RPC_FC_STRUCTPAD3
:
2935 case RPC_FC_STRUCTPAD4
:
2936 case RPC_FC_STRUCTPAD5
:
2937 case RPC_FC_STRUCTPAD6
:
2938 case RPC_FC_STRUCTPAD7
:
2939 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2941 case RPC_FC_EMBEDDED_COMPLEX
:
2942 pMemory
+= pFormat
[1];
2944 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2945 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2946 TRACE("embedded complex (size=%d) <= %p\n", size
, pMemory
);
2947 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
2950 /* for some reason interface pointers aren't generated as
2951 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2952 * they still need the derefencing treatment that pointers are
2954 if (*desc
== RPC_FC_IP
)
2955 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2957 m(pStubMsg
, pMemory
, desc
);
2959 else FIXME("no marshaller for embedded type %02x\n", *desc
);
2966 FIXME("unhandled format 0x%02x\n", *pFormat
);
2974 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2975 unsigned char *pMemory
,
2976 PFORMAT_STRING pFormat
,
2977 PFORMAT_STRING pPointer
,
2978 unsigned char fMustAlloc
)
2980 PFORMAT_STRING desc
;
2984 while (*pFormat
!= RPC_FC_END
) {
2990 safe_copy_from_buffer(pStubMsg
, pMemory
, 1);
2991 TRACE("byte=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2997 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
2998 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
3004 safe_copy_from_buffer(pStubMsg
, &val
, 2);
3005 *(DWORD
*)pMemory
= val
;
3006 TRACE("enum16=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
3007 if (32767 < *(DWORD
*)pMemory
)
3008 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
3015 safe_copy_from_buffer(pStubMsg
, pMemory
, 4);
3016 TRACE("long=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
3019 case RPC_FC_INT3264
:
3022 safe_copy_from_buffer(pStubMsg
, &val
, 4);
3023 *(INT_PTR
*)pMemory
= val
;
3024 TRACE("int3264=%ld => %p\n", *(INT_PTR
*)pMemory
, pMemory
);
3025 pMemory
+= sizeof(INT_PTR
);
3028 case RPC_FC_UINT3264
:
3031 safe_copy_from_buffer(pStubMsg
, &val
, 4);
3032 *(UINT_PTR
*)pMemory
= val
;
3033 TRACE("uint3264=%ld => %p\n", *(UINT_PTR
*)pMemory
, pMemory
);
3034 pMemory
+= sizeof(UINT_PTR
);
3038 safe_copy_from_buffer(pStubMsg
, pMemory
, sizeof(float));
3039 TRACE("float=%f => %p\n", *(float*)pMemory
, pMemory
);
3040 pMemory
+= sizeof(float);
3043 safe_copy_from_buffer(pStubMsg
, pMemory
, 8);
3044 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
3048 safe_copy_from_buffer(pStubMsg
, pMemory
, sizeof(double));
3049 TRACE("double=%f => %p\n", *(double*)pMemory
, pMemory
);
3050 pMemory
+= sizeof(double);
3056 case RPC_FC_POINTER
:
3058 unsigned char *saved_buffer
;
3059 int pointer_buffer_mark_set
= 0;
3060 TRACE("pointer => %p\n", pMemory
);
3061 if (*pFormat
!= RPC_FC_POINTER
)
3063 if (*pPointer
!= RPC_FC_RP
)
3064 align_pointer(&pStubMsg
->Buffer
, 4);
3065 saved_buffer
= pStubMsg
->Buffer
;
3066 if (pStubMsg
->PointerBufferMark
)
3068 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3069 pStubMsg
->PointerBufferMark
= NULL
;
3070 pointer_buffer_mark_set
= 1;
3072 else if (*pPointer
!= RPC_FC_RP
)
3073 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3075 PointerUnmarshall(pStubMsg
, saved_buffer
, (unsigned char**)pMemory
, *(unsigned char**)pMemory
, pPointer
, fMustAlloc
);
3076 if (pointer_buffer_mark_set
)
3078 STD_OVERFLOW_CHECK(pStubMsg
);
3079 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3080 pStubMsg
->Buffer
= saved_buffer
;
3081 if (*pPointer
!= RPC_FC_RP
)
3082 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3084 if (*pFormat
== RPC_FC_POINTER
)
3088 pMemory
+= sizeof(void *);
3091 case RPC_FC_ALIGNM2
:
3092 align_pointer_clear(&pMemory
, 2);
3094 case RPC_FC_ALIGNM4
:
3095 align_pointer_clear(&pMemory
, 4);
3097 case RPC_FC_ALIGNM8
:
3098 align_pointer_clear(&pMemory
, 8);
3100 case RPC_FC_STRUCTPAD1
:
3101 case RPC_FC_STRUCTPAD2
:
3102 case RPC_FC_STRUCTPAD3
:
3103 case RPC_FC_STRUCTPAD4
:
3104 case RPC_FC_STRUCTPAD5
:
3105 case RPC_FC_STRUCTPAD6
:
3106 case RPC_FC_STRUCTPAD7
:
3107 memset(pMemory
, 0, *pFormat
- RPC_FC_STRUCTPAD1
+ 1);
3108 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3110 case RPC_FC_EMBEDDED_COMPLEX
:
3111 pMemory
+= pFormat
[1];
3113 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3114 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3115 TRACE("embedded complex (size=%d) => %p\n", size
, pMemory
);
3117 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
3118 * since the type is part of the memory block that is encompassed by
3119 * the whole complex type. Memory is forced to allocate when pointers
3120 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
3121 * clearing the memory we pass in to the unmarshaller */
3122 memset(pMemory
, 0, size
);
3123 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
3126 /* for some reason interface pointers aren't generated as
3127 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3128 * they still need the derefencing treatment that pointers are
3130 if (*desc
== RPC_FC_IP
)
3131 m(pStubMsg
, (unsigned char **)pMemory
, desc
, FALSE
);
3133 m(pStubMsg
, &pMemory
, desc
, FALSE
);
3135 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
3142 FIXME("unhandled format %d\n", *pFormat
);
3150 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3151 unsigned char *pMemory
,
3152 PFORMAT_STRING pFormat
,
3153 PFORMAT_STRING pPointer
)
3155 PFORMAT_STRING desc
;
3159 while (*pFormat
!= RPC_FC_END
) {
3165 safe_buffer_length_increment(pStubMsg
, 1);
3171 safe_buffer_length_increment(pStubMsg
, 2);
3175 safe_buffer_length_increment(pStubMsg
, 2);
3182 safe_buffer_length_increment(pStubMsg
, 4);
3185 case RPC_FC_INT3264
:
3186 case RPC_FC_UINT3264
:
3187 safe_buffer_length_increment(pStubMsg
, 4);
3188 pMemory
+= sizeof(INT_PTR
);
3192 safe_buffer_length_increment(pStubMsg
, 8);
3199 case RPC_FC_POINTER
:
3200 if (*pFormat
!= RPC_FC_POINTER
)
3202 if (!pStubMsg
->IgnoreEmbeddedPointers
)
3204 int saved_buffer_length
= pStubMsg
->BufferLength
;
3205 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3206 pStubMsg
->PointerLength
= 0;
3207 if(!pStubMsg
->BufferLength
)
3208 ERR("BufferLength == 0??\n");
3209 PointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
3210 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3211 pStubMsg
->BufferLength
= saved_buffer_length
;
3213 if (*pPointer
!= RPC_FC_RP
)
3215 align_length(&pStubMsg
->BufferLength
, 4);
3216 safe_buffer_length_increment(pStubMsg
, 4);
3218 if (*pFormat
== RPC_FC_POINTER
)
3222 pMemory
+= sizeof(void*);
3224 case RPC_FC_ALIGNM2
:
3225 align_pointer(&pMemory
, 2);
3227 case RPC_FC_ALIGNM4
:
3228 align_pointer(&pMemory
, 4);
3230 case RPC_FC_ALIGNM8
:
3231 align_pointer(&pMemory
, 8);
3233 case RPC_FC_STRUCTPAD1
:
3234 case RPC_FC_STRUCTPAD2
:
3235 case RPC_FC_STRUCTPAD3
:
3236 case RPC_FC_STRUCTPAD4
:
3237 case RPC_FC_STRUCTPAD5
:
3238 case RPC_FC_STRUCTPAD6
:
3239 case RPC_FC_STRUCTPAD7
:
3240 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3242 case RPC_FC_EMBEDDED_COMPLEX
:
3243 pMemory
+= pFormat
[1];
3245 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3246 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3247 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
3250 /* for some reason interface pointers aren't generated as
3251 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3252 * they still need the derefencing treatment that pointers are
3254 if (*desc
== RPC_FC_IP
)
3255 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
3257 m(pStubMsg
, pMemory
, desc
);
3259 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
3266 FIXME("unhandled format 0x%02x\n", *pFormat
);
3274 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
3275 unsigned char *pMemory
,
3276 PFORMAT_STRING pFormat
,
3277 PFORMAT_STRING pPointer
)
3279 PFORMAT_STRING desc
;
3283 while (*pFormat
!= RPC_FC_END
) {
3303 case RPC_FC_INT3264
:
3304 case RPC_FC_UINT3264
:
3305 pMemory
+= sizeof(INT_PTR
);
3315 case RPC_FC_POINTER
:
3316 if (*pFormat
!= RPC_FC_POINTER
)
3318 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
3319 if (*pFormat
== RPC_FC_POINTER
)
3323 pMemory
+= sizeof(void *);
3325 case RPC_FC_ALIGNM2
:
3326 align_pointer(&pMemory
, 2);
3328 case RPC_FC_ALIGNM4
:
3329 align_pointer(&pMemory
, 4);
3331 case RPC_FC_ALIGNM8
:
3332 align_pointer(&pMemory
, 8);
3334 case RPC_FC_STRUCTPAD1
:
3335 case RPC_FC_STRUCTPAD2
:
3336 case RPC_FC_STRUCTPAD3
:
3337 case RPC_FC_STRUCTPAD4
:
3338 case RPC_FC_STRUCTPAD5
:
3339 case RPC_FC_STRUCTPAD6
:
3340 case RPC_FC_STRUCTPAD7
:
3341 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3343 case RPC_FC_EMBEDDED_COMPLEX
:
3344 pMemory
+= pFormat
[1];
3346 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3347 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3348 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
3351 /* for some reason interface pointers aren't generated as
3352 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3353 * they still need the derefencing treatment that pointers are
3355 if (*desc
== RPC_FC_IP
)
3356 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
3358 m(pStubMsg
, pMemory
, desc
);
3366 FIXME("unhandled format 0x%02x\n", *pFormat
);
3374 static ULONG
ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3375 PFORMAT_STRING pFormat
,
3376 PFORMAT_STRING pPointer
)
3378 PFORMAT_STRING desc
;
3381 while (*pFormat
!= RPC_FC_END
) {
3388 safe_buffer_increment(pStubMsg
, 1);
3394 safe_buffer_increment(pStubMsg
, 2);
3398 safe_buffer_increment(pStubMsg
, 2);
3405 safe_buffer_increment(pStubMsg
, 4);
3407 case RPC_FC_INT3264
:
3408 case RPC_FC_UINT3264
:
3409 size
+= sizeof(INT_PTR
);
3410 safe_buffer_increment(pStubMsg
, 4);
3415 safe_buffer_increment(pStubMsg
, 8);
3421 case RPC_FC_POINTER
:
3423 unsigned char *saved_buffer
;
3424 int pointer_buffer_mark_set
= 0;
3425 if (*pFormat
!= RPC_FC_POINTER
)
3427 if (*pPointer
!= RPC_FC_RP
)
3428 align_pointer(&pStubMsg
->Buffer
, 4);
3429 saved_buffer
= pStubMsg
->Buffer
;
3430 if (pStubMsg
->PointerBufferMark
)
3432 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3433 pStubMsg
->PointerBufferMark
= NULL
;
3434 pointer_buffer_mark_set
= 1;
3436 else if (*pPointer
!= RPC_FC_RP
)
3437 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3439 if (!pStubMsg
->IgnoreEmbeddedPointers
)
3440 PointerMemorySize(pStubMsg
, saved_buffer
, pPointer
);
3441 if (pointer_buffer_mark_set
)
3443 STD_OVERFLOW_CHECK(pStubMsg
);
3444 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3445 pStubMsg
->Buffer
= saved_buffer
;
3446 if (*pPointer
!= RPC_FC_RP
)
3447 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3449 if (*pFormat
== RPC_FC_POINTER
)
3453 size
+= sizeof(void *);
3456 case RPC_FC_ALIGNM2
:
3457 align_length(&size
, 2);
3459 case RPC_FC_ALIGNM4
:
3460 align_length(&size
, 4);
3462 case RPC_FC_ALIGNM8
:
3463 align_length(&size
, 8);
3465 case RPC_FC_STRUCTPAD1
:
3466 case RPC_FC_STRUCTPAD2
:
3467 case RPC_FC_STRUCTPAD3
:
3468 case RPC_FC_STRUCTPAD4
:
3469 case RPC_FC_STRUCTPAD5
:
3470 case RPC_FC_STRUCTPAD6
:
3471 case RPC_FC_STRUCTPAD7
:
3472 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3474 case RPC_FC_EMBEDDED_COMPLEX
:
3477 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3478 size
+= EmbeddedComplexMemorySize(pStubMsg
, desc
);
3484 FIXME("unhandled format 0x%02x\n", *pFormat
);
3492 ULONG
ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
3494 PFORMAT_STRING desc
;
3497 while (*pFormat
!= RPC_FC_END
) {
3517 case RPC_FC_INT3264
:
3518 case RPC_FC_UINT3264
:
3519 size
+= sizeof(INT_PTR
);
3529 case RPC_FC_POINTER
:
3530 size
+= sizeof(void *);
3531 if (*pFormat
!= RPC_FC_POINTER
)
3534 case RPC_FC_ALIGNM2
:
3535 align_length(&size
, 2);
3537 case RPC_FC_ALIGNM4
:
3538 align_length(&size
, 4);
3540 case RPC_FC_ALIGNM8
:
3541 align_length(&size
, 8);
3543 case RPC_FC_STRUCTPAD1
:
3544 case RPC_FC_STRUCTPAD2
:
3545 case RPC_FC_STRUCTPAD3
:
3546 case RPC_FC_STRUCTPAD4
:
3547 case RPC_FC_STRUCTPAD5
:
3548 case RPC_FC_STRUCTPAD6
:
3549 case RPC_FC_STRUCTPAD7
:
3550 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3552 case RPC_FC_EMBEDDED_COMPLEX
:
3555 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3556 size
+= EmbeddedComplexSize(pStubMsg
, desc
);
3562 FIXME("unhandled format 0x%02x\n", *pFormat
);
3570 /***********************************************************************
3571 * NdrComplexStructMarshall [RPCRT4.@]
3573 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3574 unsigned char *pMemory
,
3575 PFORMAT_STRING pFormat
)
3577 PFORMAT_STRING conf_array
= NULL
;
3578 PFORMAT_STRING pointer_desc
= NULL
;
3579 unsigned char *OldMemory
= pStubMsg
->Memory
;
3580 int pointer_buffer_mark_set
= 0;
3582 ULONG max_count
= 0;
3585 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3587 if (!pStubMsg
->PointerBufferMark
)
3589 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3590 /* save buffer length */
3591 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
3593 /* get the buffer pointer after complex array data, but before
3595 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
;
3596 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3597 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
3598 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3600 /* save it for use by embedded pointer code later */
3601 pStubMsg
->PointerBufferMark
= (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
;
3602 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->PointerBufferMark
- pStubMsg
->Buffer
));
3603 pointer_buffer_mark_set
= 1;
3605 /* restore the original buffer length */
3606 pStubMsg
->BufferLength
= saved_buffer_length
;
3609 align_pointer_clear(&pStubMsg
->Buffer
, pFormat
[1] + 1);
3612 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3614 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3617 pStubMsg
->Memory
= pMemory
;
3621 ULONG struct_size
= ComplexStructSize(pStubMsg
, pFormat
);
3622 array_compute_and_write_conformance(conf_array
[0], pStubMsg
,
3623 pMemory
+ struct_size
, conf_array
);
3624 /* these could be changed in ComplexMarshall so save them for later */
3625 max_count
= pStubMsg
->MaxCount
;
3626 count
= pStubMsg
->ActualCount
;
3627 offset
= pStubMsg
->Offset
;
3630 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3634 pStubMsg
->MaxCount
= max_count
;
3635 pStubMsg
->ActualCount
= count
;
3636 pStubMsg
->Offset
= offset
;
3637 array_write_variance_and_marshall(conf_array
[0], pStubMsg
, pMemory
,
3638 conf_array
, TRUE
/* fHasPointers */);
3641 pStubMsg
->Memory
= OldMemory
;
3643 if (pointer_buffer_mark_set
)
3645 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3646 pStubMsg
->PointerBufferMark
= NULL
;
3649 STD_OVERFLOW_CHECK(pStubMsg
);
3654 /***********************************************************************
3655 * NdrComplexStructUnmarshall [RPCRT4.@]
3657 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3658 unsigned char **ppMemory
,
3659 PFORMAT_STRING pFormat
,
3660 unsigned char fMustAlloc
)
3662 unsigned size
= *(const WORD
*)(pFormat
+2);
3663 PFORMAT_STRING conf_array
= NULL
;
3664 PFORMAT_STRING pointer_desc
= NULL
;
3665 unsigned char *pMemory
;
3666 int pointer_buffer_mark_set
= 0;
3668 ULONG max_count
= 0;
3670 ULONG array_size
= 0;
3672 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3674 if (!pStubMsg
->PointerBufferMark
)
3676 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3677 /* save buffer pointer */
3678 unsigned char *saved_buffer
= pStubMsg
->Buffer
;
3680 /* get the buffer pointer after complex array data, but before
3682 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3683 NdrComplexStructMemorySize(pStubMsg
, pFormat
);
3684 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3686 /* save it for use by embedded pointer code later */
3687 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3688 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->PointerBufferMark
- saved_buffer
));
3689 pointer_buffer_mark_set
= 1;
3691 /* restore the original buffer */
3692 pStubMsg
->Buffer
= saved_buffer
;
3695 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
3698 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3700 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3705 array_size
= array_read_conformance(conf_array
[0], pStubMsg
, conf_array
);
3708 /* these could be changed in ComplexMarshall so save them for later */
3709 max_count
= pStubMsg
->MaxCount
;
3710 count
= pStubMsg
->ActualCount
;
3711 offset
= pStubMsg
->Offset
;
3714 if (!fMustAlloc
&& !*ppMemory
)
3717 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3719 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
, fMustAlloc
);
3723 pStubMsg
->MaxCount
= max_count
;
3724 pStubMsg
->ActualCount
= count
;
3725 pStubMsg
->Offset
= offset
;
3727 memset(pMemory
, 0, array_size
);
3728 array_read_variance_and_unmarshall(conf_array
[0], pStubMsg
, &pMemory
,
3730 FALSE
/* fUseBufferMemoryServer */,
3731 TRUE
/* fUnmarshall */);
3734 if (pointer_buffer_mark_set
)
3736 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3737 pStubMsg
->PointerBufferMark
= NULL
;
3743 /***********************************************************************
3744 * NdrComplexStructBufferSize [RPCRT4.@]
3746 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3747 unsigned char *pMemory
,
3748 PFORMAT_STRING pFormat
)
3750 PFORMAT_STRING conf_array
= NULL
;
3751 PFORMAT_STRING pointer_desc
= NULL
;
3752 unsigned char *OldMemory
= pStubMsg
->Memory
;
3753 int pointer_length_set
= 0;
3755 ULONG max_count
= 0;
3758 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3760 align_length(&pStubMsg
->BufferLength
, pFormat
[1] + 1);
3762 if(!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
3764 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3765 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
3767 /* get the buffer length after complex struct data, but before
3769 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3770 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
3771 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3773 /* save it for use by embedded pointer code later */
3774 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3775 pointer_length_set
= 1;
3776 TRACE("difference = 0x%x\n", pStubMsg
->PointerLength
- saved_buffer_length
);
3778 /* restore the original buffer length */
3779 pStubMsg
->BufferLength
= saved_buffer_length
;
3783 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3785 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3788 pStubMsg
->Memory
= pMemory
;
3792 ULONG struct_size
= ComplexStructSize(pStubMsg
, pFormat
);
3793 array_compute_and_size_conformance(conf_array
[0], pStubMsg
, pMemory
+ struct_size
,
3796 /* these could be changed in ComplexMarshall so save them for later */
3797 max_count
= pStubMsg
->MaxCount
;
3798 count
= pStubMsg
->ActualCount
;
3799 offset
= pStubMsg
->Offset
;
3802 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3806 pStubMsg
->MaxCount
= max_count
;
3807 pStubMsg
->ActualCount
= count
;
3808 pStubMsg
->Offset
= offset
;
3809 array_buffer_size(conf_array
[0], pStubMsg
, pMemory
, conf_array
,
3810 TRUE
/* fHasPointers */);
3813 pStubMsg
->Memory
= OldMemory
;
3815 if(pointer_length_set
)
3817 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3818 pStubMsg
->PointerLength
= 0;
3823 /***********************************************************************
3824 * NdrComplexStructMemorySize [RPCRT4.@]
3826 ULONG WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3827 PFORMAT_STRING pFormat
)
3829 unsigned size
= *(const WORD
*)(pFormat
+2);
3830 PFORMAT_STRING conf_array
= NULL
;
3831 PFORMAT_STRING pointer_desc
= NULL
;
3833 ULONG max_count
= 0;
3836 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3838 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
3841 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3843 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3848 array_read_conformance(conf_array
[0], pStubMsg
, conf_array
);
3850 /* these could be changed in ComplexStructMemorySize so save them for
3852 max_count
= pStubMsg
->MaxCount
;
3853 count
= pStubMsg
->ActualCount
;
3854 offset
= pStubMsg
->Offset
;
3857 ComplexStructMemorySize(pStubMsg
, pFormat
, pointer_desc
);
3861 pStubMsg
->MaxCount
= max_count
;
3862 pStubMsg
->ActualCount
= count
;
3863 pStubMsg
->Offset
= offset
;
3864 array_memory_size(conf_array
[0], pStubMsg
, conf_array
,
3865 TRUE
/* fHasPointers */);
3871 /***********************************************************************
3872 * NdrComplexStructFree [RPCRT4.@]
3874 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3875 unsigned char *pMemory
,
3876 PFORMAT_STRING pFormat
)
3878 PFORMAT_STRING conf_array
= NULL
;
3879 PFORMAT_STRING pointer_desc
= NULL
;
3880 unsigned char *OldMemory
= pStubMsg
->Memory
;
3882 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3885 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3887 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3890 pStubMsg
->Memory
= pMemory
;
3892 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3895 array_free(conf_array
[0], pStubMsg
, pMemory
, conf_array
,
3896 TRUE
/* fHasPointers */);
3898 pStubMsg
->Memory
= OldMemory
;
3901 /***********************************************************************
3902 * NdrConformantArrayMarshall [RPCRT4.@]
3904 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3905 unsigned char *pMemory
,
3906 PFORMAT_STRING pFormat
)
3908 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3909 if (pFormat
[0] != RPC_FC_CARRAY
)
3911 ERR("invalid format = 0x%x\n", pFormat
[0]);
3912 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3915 array_compute_and_write_conformance(RPC_FC_CARRAY
, pStubMsg
, pMemory
,
3917 array_write_variance_and_marshall(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3918 TRUE
/* fHasPointers */);
3923 /***********************************************************************
3924 * NdrConformantArrayUnmarshall [RPCRT4.@]
3926 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3927 unsigned char **ppMemory
,
3928 PFORMAT_STRING pFormat
,
3929 unsigned char fMustAlloc
)
3931 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3932 if (pFormat
[0] != RPC_FC_CARRAY
)
3934 ERR("invalid format = 0x%x\n", pFormat
[0]);
3935 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3938 array_read_conformance(RPC_FC_CARRAY
, pStubMsg
, pFormat
);
3939 array_read_variance_and_unmarshall(RPC_FC_CARRAY
, pStubMsg
, ppMemory
, pFormat
,
3941 TRUE
/* fUseBufferMemoryServer */,
3942 TRUE
/* fUnmarshall */);
3947 /***********************************************************************
3948 * NdrConformantArrayBufferSize [RPCRT4.@]
3950 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3951 unsigned char *pMemory
,
3952 PFORMAT_STRING pFormat
)
3954 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3955 if (pFormat
[0] != RPC_FC_CARRAY
)
3957 ERR("invalid format = 0x%x\n", pFormat
[0]);
3958 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3961 array_compute_and_size_conformance(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
);
3962 array_buffer_size(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3963 TRUE
/* fHasPointers */);
3966 /***********************************************************************
3967 * NdrConformantArrayMemorySize [RPCRT4.@]
3969 ULONG WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3970 PFORMAT_STRING pFormat
)
3972 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3973 if (pFormat
[0] != RPC_FC_CARRAY
)
3975 ERR("invalid format = 0x%x\n", pFormat
[0]);
3976 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3979 array_read_conformance(RPC_FC_CARRAY
, pStubMsg
, pFormat
);
3980 array_memory_size(RPC_FC_CARRAY
, pStubMsg
, pFormat
, TRUE
/* fHasPointers */);
3982 return pStubMsg
->MemorySize
;
3985 /***********************************************************************
3986 * NdrConformantArrayFree [RPCRT4.@]
3988 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3989 unsigned char *pMemory
,
3990 PFORMAT_STRING pFormat
)
3992 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3993 if (pFormat
[0] != RPC_FC_CARRAY
)
3995 ERR("invalid format = 0x%x\n", pFormat
[0]);
3996 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3999 array_free(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
4000 TRUE
/* fHasPointers */);
4004 /***********************************************************************
4005 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
4007 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
4008 unsigned char* pMemory
,
4009 PFORMAT_STRING pFormat
)
4011 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4013 if (pFormat
[0] != RPC_FC_CVARRAY
)
4015 ERR("invalid format type %x\n", pFormat
[0]);
4016 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4020 array_compute_and_write_conformance(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
4022 array_write_variance_and_marshall(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
4023 pFormat
, TRUE
/* fHasPointers */);
4029 /***********************************************************************
4030 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
4032 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
4033 unsigned char** ppMemory
,
4034 PFORMAT_STRING pFormat
,
4035 unsigned char fMustAlloc
)
4037 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4039 if (pFormat
[0] != RPC_FC_CVARRAY
)
4041 ERR("invalid format type %x\n", pFormat
[0]);
4042 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4046 array_read_conformance(RPC_FC_CVARRAY
, pStubMsg
, pFormat
);
4047 array_read_variance_and_unmarshall(RPC_FC_CVARRAY
, pStubMsg
, ppMemory
,
4048 pFormat
, fMustAlloc
,
4049 TRUE
/* fUseBufferMemoryServer */,
4050 TRUE
/* fUnmarshall */);
4056 /***********************************************************************
4057 * NdrConformantVaryingArrayFree [RPCRT4.@]
4059 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
4060 unsigned char* pMemory
,
4061 PFORMAT_STRING pFormat
)
4063 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4065 if (pFormat
[0] != RPC_FC_CVARRAY
)
4067 ERR("invalid format type %x\n", pFormat
[0]);
4068 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4072 array_free(RPC_FC_CVARRAY
, pStubMsg
, pMemory
, pFormat
,
4073 TRUE
/* fHasPointers */);
4077 /***********************************************************************
4078 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
4080 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
4081 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
4083 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4085 if (pFormat
[0] != RPC_FC_CVARRAY
)
4087 ERR("invalid format type %x\n", pFormat
[0]);
4088 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4092 array_compute_and_size_conformance(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
4094 array_buffer_size(RPC_FC_CVARRAY
, pStubMsg
, pMemory
, pFormat
,
4095 TRUE
/* fHasPointers */);
4099 /***********************************************************************
4100 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
4102 ULONG WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
4103 PFORMAT_STRING pFormat
)
4105 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4107 if (pFormat
[0] != RPC_FC_CVARRAY
)
4109 ERR("invalid format type %x\n", pFormat
[0]);
4110 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4111 return pStubMsg
->MemorySize
;
4114 array_read_conformance(RPC_FC_CVARRAY
, pStubMsg
, pFormat
);
4115 array_memory_size(RPC_FC_CVARRAY
, pStubMsg
, pFormat
,
4116 TRUE
/* fHasPointers */);
4118 return pStubMsg
->MemorySize
;
4122 /***********************************************************************
4123 * NdrComplexArrayMarshall [RPCRT4.@]
4125 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4126 unsigned char *pMemory
,
4127 PFORMAT_STRING pFormat
)
4129 int pointer_buffer_mark_set
= 0;
4131 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4133 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4135 ERR("invalid format type %x\n", pFormat
[0]);
4136 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4140 if (!pStubMsg
->PointerBufferMark
)
4142 /* save buffer fields that may be changed by buffer sizer functions
4143 * and that may be needed later on */
4144 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
4145 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
4146 ULONG_PTR saved_max_count
= pStubMsg
->MaxCount
;
4147 ULONG saved_offset
= pStubMsg
->Offset
;
4148 ULONG saved_actual_count
= pStubMsg
->ActualCount
;
4150 /* get the buffer pointer after complex array data, but before
4152 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
;
4153 pStubMsg
->IgnoreEmbeddedPointers
= 1;
4154 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
4155 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
4157 /* save it for use by embedded pointer code later */
4158 pStubMsg
->PointerBufferMark
= (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
;
4159 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
));
4160 pointer_buffer_mark_set
= 1;
4162 /* restore fields */
4163 pStubMsg
->ActualCount
= saved_actual_count
;
4164 pStubMsg
->Offset
= saved_offset
;
4165 pStubMsg
->MaxCount
= saved_max_count
;
4166 pStubMsg
->BufferLength
= saved_buffer_length
;
4169 array_compute_and_write_conformance(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pMemory
, pFormat
);
4170 array_write_variance_and_marshall(RPC_FC_BOGUS_ARRAY
, pStubMsg
,
4171 pMemory
, pFormat
, TRUE
/* fHasPointers */);
4173 STD_OVERFLOW_CHECK(pStubMsg
);
4175 if (pointer_buffer_mark_set
)
4177 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4178 pStubMsg
->PointerBufferMark
= NULL
;
4184 /***********************************************************************
4185 * NdrComplexArrayUnmarshall [RPCRT4.@]
4187 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4188 unsigned char **ppMemory
,
4189 PFORMAT_STRING pFormat
,
4190 unsigned char fMustAlloc
)
4192 unsigned char *saved_buffer
;
4193 int pointer_buffer_mark_set
= 0;
4194 int saved_ignore_embedded
;
4196 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4198 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4200 ERR("invalid format type %x\n", pFormat
[0]);
4201 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4205 saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
4206 /* save buffer pointer */
4207 saved_buffer
= pStubMsg
->Buffer
;
4208 /* get the buffer pointer after complex array data, but before
4210 pStubMsg
->IgnoreEmbeddedPointers
= 1;
4211 pStubMsg
->MemorySize
= 0;
4212 NdrComplexArrayMemorySize(pStubMsg
, pFormat
);
4213 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
4215 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->Buffer
- saved_buffer
));
4216 if (!pStubMsg
->PointerBufferMark
)
4218 /* save it for use by embedded pointer code later */
4219 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4220 pointer_buffer_mark_set
= 1;
4222 /* restore the original buffer */
4223 pStubMsg
->Buffer
= saved_buffer
;
4225 array_read_conformance(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pFormat
);
4226 array_read_variance_and_unmarshall(RPC_FC_BOGUS_ARRAY
, pStubMsg
, ppMemory
, pFormat
, fMustAlloc
,
4227 TRUE
/* fUseBufferMemoryServer */, TRUE
/* fUnmarshall */);
4229 if (pointer_buffer_mark_set
)
4231 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4232 pStubMsg
->PointerBufferMark
= NULL
;
4238 /***********************************************************************
4239 * NdrComplexArrayBufferSize [RPCRT4.@]
4241 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4242 unsigned char *pMemory
,
4243 PFORMAT_STRING pFormat
)
4245 int pointer_length_set
= 0;
4247 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4249 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4251 ERR("invalid format type %x\n", pFormat
[0]);
4252 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4256 if (!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
4258 /* save buffer fields that may be changed by buffer sizer functions
4259 * and that may be needed later on */
4260 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
4261 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
4262 ULONG_PTR saved_max_count
= pStubMsg
->MaxCount
;
4263 ULONG saved_offset
= pStubMsg
->Offset
;
4264 ULONG saved_actual_count
= pStubMsg
->ActualCount
;
4266 /* get the buffer pointer after complex array data, but before
4268 pStubMsg
->IgnoreEmbeddedPointers
= 1;
4269 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
4270 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
4272 /* save it for use by embedded pointer code later */
4273 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4274 pointer_length_set
= 1;
4276 /* restore fields */
4277 pStubMsg
->ActualCount
= saved_actual_count
;
4278 pStubMsg
->Offset
= saved_offset
;
4279 pStubMsg
->MaxCount
= saved_max_count
;
4280 pStubMsg
->BufferLength
= saved_buffer_length
;
4283 array_compute_and_size_conformance(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pMemory
, pFormat
);
4284 array_buffer_size(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pMemory
, pFormat
, TRUE
/* fHasPointers */);
4286 if(pointer_length_set
)
4288 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4289 pStubMsg
->PointerLength
= 0;
4293 /***********************************************************************
4294 * NdrComplexArrayMemorySize [RPCRT4.@]
4296 ULONG WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4297 PFORMAT_STRING pFormat
)
4299 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
4301 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4303 ERR("invalid format type %x\n", pFormat
[0]);
4304 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4308 array_read_conformance(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pFormat
);
4309 array_memory_size(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pFormat
, TRUE
/* fHasPointers */);
4310 return pStubMsg
->MemorySize
;
4313 /***********************************************************************
4314 * NdrComplexArrayFree [RPCRT4.@]
4316 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4317 unsigned char *pMemory
,
4318 PFORMAT_STRING pFormat
)
4320 ULONG i
, count
, def
;
4322 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4324 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4326 ERR("invalid format type %x\n", pFormat
[0]);
4327 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4331 def
= *(const WORD
*)&pFormat
[2];
4334 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
4335 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
4337 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
4338 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
4340 count
= pStubMsg
->ActualCount
;
4341 for (i
= 0; i
< count
; i
++)
4342 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
4345 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg
,
4346 USER_MARSHAL_CB_TYPE cbtype
, PFORMAT_STRING pFormat
,
4347 USER_MARSHAL_CB
*umcb
)
4349 umcb
->Flags
= MAKELONG(pStubMsg
->dwDestContext
,
4350 pStubMsg
->RpcMsg
->DataRepresentation
);
4351 umcb
->pStubMsg
= pStubMsg
;
4352 umcb
->pReserve
= NULL
;
4353 umcb
->Signature
= USER_MARSHAL_CB_SIGNATURE
;
4354 umcb
->CBType
= cbtype
;
4355 umcb
->pFormat
= pFormat
;
4356 umcb
->pTypeFormat
= NULL
/* FIXME */;
4359 #define USER_MARSHAL_PTR_PREFIX \
4360 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4361 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4363 /***********************************************************************
4364 * NdrUserMarshalMarshall [RPCRT4.@]
4366 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4367 unsigned char *pMemory
,
4368 PFORMAT_STRING pFormat
)
4370 unsigned flags
= pFormat
[1];
4371 unsigned index
= *(const WORD
*)&pFormat
[2];
4372 unsigned char *saved_buffer
= NULL
;
4373 USER_MARSHAL_CB umcb
;
4375 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4376 TRACE("index=%d\n", index
);
4378 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_MARSHALL
, pFormat
, &umcb
);
4380 if (flags
& USER_MARSHAL_POINTER
)
4382 align_pointer_clear(&pStubMsg
->Buffer
, 4);
4383 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, USER_MARSHAL_PTR_PREFIX
);
4384 pStubMsg
->Buffer
+= 4;
4385 if (pStubMsg
->PointerBufferMark
)
4387 saved_buffer
= pStubMsg
->Buffer
;
4388 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4389 pStubMsg
->PointerBufferMark
= NULL
;
4391 align_pointer_clear(&pStubMsg
->Buffer
, 8);
4394 align_pointer_clear(&pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4397 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
4398 &umcb
.Flags
, pStubMsg
->Buffer
, pMemory
);
4402 STD_OVERFLOW_CHECK(pStubMsg
);
4403 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4404 pStubMsg
->Buffer
= saved_buffer
;
4407 STD_OVERFLOW_CHECK(pStubMsg
);
4412 /***********************************************************************
4413 * NdrUserMarshalUnmarshall [RPCRT4.@]
4415 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4416 unsigned char **ppMemory
,
4417 PFORMAT_STRING pFormat
,
4418 unsigned char fMustAlloc
)
4420 unsigned flags
= pFormat
[1];
4421 unsigned index
= *(const WORD
*)&pFormat
[2];
4422 DWORD memsize
= *(const WORD
*)&pFormat
[4];
4423 unsigned char *saved_buffer
= NULL
;
4424 USER_MARSHAL_CB umcb
;
4426 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4427 TRACE("index=%d\n", index
);
4429 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_UNMARSHALL
, pFormat
, &umcb
);
4431 if (flags
& USER_MARSHAL_POINTER
)
4433 align_pointer(&pStubMsg
->Buffer
, 4);
4434 /* skip pointer prefix */
4435 pStubMsg
->Buffer
+= 4;
4436 if (pStubMsg
->PointerBufferMark
)
4438 saved_buffer
= pStubMsg
->Buffer
;
4439 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4440 pStubMsg
->PointerBufferMark
= NULL
;
4442 align_pointer(&pStubMsg
->Buffer
, 8);
4445 align_pointer(&pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4447 if (!fMustAlloc
&& !*ppMemory
)
4451 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
4452 memset(*ppMemory
, 0, memsize
);
4456 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
4457 &umcb
.Flags
, pStubMsg
->Buffer
, *ppMemory
);
4461 STD_OVERFLOW_CHECK(pStubMsg
);
4462 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4463 pStubMsg
->Buffer
= saved_buffer
;
4469 /***********************************************************************
4470 * NdrUserMarshalBufferSize [RPCRT4.@]
4472 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4473 unsigned char *pMemory
,
4474 PFORMAT_STRING pFormat
)
4476 unsigned flags
= pFormat
[1];
4477 unsigned index
= *(const WORD
*)&pFormat
[2];
4478 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
4479 USER_MARSHAL_CB umcb
;
4480 ULONG saved_buffer_length
= 0;
4482 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4483 TRACE("index=%d\n", index
);
4485 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_BUFFER_SIZE
, pFormat
, &umcb
);
4487 if (flags
& USER_MARSHAL_POINTER
)
4489 align_length(&pStubMsg
->BufferLength
, 4);
4490 /* skip pointer prefix */
4491 safe_buffer_length_increment(pStubMsg
, 4);
4492 if (pStubMsg
->IgnoreEmbeddedPointers
)
4494 if (pStubMsg
->PointerLength
)
4496 saved_buffer_length
= pStubMsg
->BufferLength
;
4497 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4498 pStubMsg
->PointerLength
= 0;
4500 align_length(&pStubMsg
->BufferLength
, 8);
4503 align_length(&pStubMsg
->BufferLength
, (flags
& 0xf) + 1);
4506 TRACE("size=%d\n", bufsize
);
4507 safe_buffer_length_increment(pStubMsg
, bufsize
);
4510 pStubMsg
->BufferLength
=
4511 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
4512 &umcb
.Flags
, pStubMsg
->BufferLength
, pMemory
);
4514 if (saved_buffer_length
)
4516 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4517 pStubMsg
->BufferLength
= saved_buffer_length
;
4522 /***********************************************************************
4523 * NdrUserMarshalMemorySize [RPCRT4.@]
4525 ULONG WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4526 PFORMAT_STRING pFormat
)
4528 unsigned flags
= pFormat
[1];
4529 unsigned index
= *(const WORD
*)&pFormat
[2];
4530 DWORD memsize
= *(const WORD
*)&pFormat
[4];
4531 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
4533 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
4534 TRACE("index=%d\n", index
);
4536 pStubMsg
->MemorySize
+= memsize
;
4538 if (flags
& USER_MARSHAL_POINTER
)
4540 align_pointer(&pStubMsg
->Buffer
, 4);
4541 /* skip pointer prefix */
4542 pStubMsg
->Buffer
+= 4;
4543 if (pStubMsg
->IgnoreEmbeddedPointers
)
4544 return pStubMsg
->MemorySize
;
4545 align_pointer(&pStubMsg
->Buffer
, 8);
4548 align_pointer(&pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4551 FIXME("not implemented for varying buffer size\n");
4553 pStubMsg
->Buffer
+= bufsize
;
4555 return pStubMsg
->MemorySize
;
4558 /***********************************************************************
4559 * NdrUserMarshalFree [RPCRT4.@]
4561 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
4562 unsigned char *pMemory
,
4563 PFORMAT_STRING pFormat
)
4565 /* unsigned flags = pFormat[1]; */
4566 unsigned index
= *(const WORD
*)&pFormat
[2];
4567 USER_MARSHAL_CB umcb
;
4569 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4570 TRACE("index=%d\n", index
);
4572 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_FREE
, pFormat
, &umcb
);
4574 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
4575 &umcb
.Flags
, pMemory
);
4578 /***********************************************************************
4579 * NdrGetUserMarshalInfo [RPCRT4.@]
4581 RPC_STATUS RPC_ENTRY
NdrGetUserMarshalInfo(ULONG
*flags
, ULONG level
, NDR_USER_MARSHAL_INFO
*umi
)
4583 USER_MARSHAL_CB
*umcb
= CONTAINING_RECORD(flags
, USER_MARSHAL_CB
, Flags
);
4585 TRACE("(%p,%u,%p)\n", flags
, level
, umi
);
4588 return RPC_S_INVALID_ARG
;
4590 memset(&umi
->u1
.Level1
, 0, sizeof(umi
->u1
.Level1
));
4591 umi
->InformationLevel
= level
;
4593 if (umcb
->Signature
!= USER_MARSHAL_CB_SIGNATURE
)
4594 return RPC_S_INVALID_ARG
;
4596 umi
->u1
.Level1
.pfnAllocate
= umcb
->pStubMsg
->pfnAllocate
;
4597 umi
->u1
.Level1
.pfnFree
= umcb
->pStubMsg
->pfnFree
;
4598 umi
->u1
.Level1
.pRpcChannelBuffer
= umcb
->pStubMsg
->pRpcChannelBuffer
;
4600 switch (umcb
->CBType
)
4602 case USER_MARSHAL_CB_MARSHALL
:
4603 case USER_MARSHAL_CB_UNMARSHALL
:
4605 RPC_MESSAGE
*msg
= umcb
->pStubMsg
->RpcMsg
;
4606 unsigned char *buffer_start
= msg
->Buffer
;
4607 unsigned char *buffer_end
=
4608 (unsigned char *)msg
->Buffer
+ msg
->BufferLength
;
4610 if (umcb
->pStubMsg
->Buffer
< buffer_start
||
4611 umcb
->pStubMsg
->Buffer
> buffer_end
)
4612 return ERROR_INVALID_USER_BUFFER
;
4614 umi
->u1
.Level1
.Buffer
= umcb
->pStubMsg
->Buffer
;
4615 umi
->u1
.Level1
.BufferSize
= buffer_end
- umcb
->pStubMsg
->Buffer
;
4618 case USER_MARSHAL_CB_BUFFER_SIZE
:
4619 case USER_MARSHAL_CB_FREE
:
4622 WARN("unrecognised CBType %d\n", umcb
->CBType
);
4628 /***********************************************************************
4629 * NdrClearOutParameters [RPCRT4.@]
4631 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
4632 PFORMAT_STRING pFormat
,
4635 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
4638 /***********************************************************************
4639 * NdrConvert [RPCRT4.@]
4641 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
4643 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
4644 /* FIXME: since this stub doesn't do any converting, the proper behavior
4645 is to raise an exception */
4648 /***********************************************************************
4649 * NdrConvert2 [RPCRT4.@]
4651 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, LONG NumberParams
)
4653 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4654 pStubMsg
, pFormat
, NumberParams
);
4655 /* FIXME: since this stub doesn't do any converting, the proper behavior
4656 is to raise an exception */
4659 #include "pshpack1.h"
4660 typedef struct _NDR_CSTRUCT_FORMAT
4663 unsigned char alignment
;
4664 unsigned short memory_size
;
4665 short offset_to_array_description
;
4666 } NDR_CSTRUCT_FORMAT
, NDR_CVSTRUCT_FORMAT
;
4667 #include "poppack.h"
4669 /***********************************************************************
4670 * NdrConformantStructMarshall [RPCRT4.@]
4672 unsigned char * WINAPI
NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4673 unsigned char *pMemory
,
4674 PFORMAT_STRING pFormat
)
4676 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4677 PFORMAT_STRING pCArrayFormat
;
4678 ULONG esize
, bufsize
;
4680 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4682 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4683 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4685 ERR("invalid format type %x\n", pCStructFormat
->type
);
4686 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4690 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4691 pCStructFormat
->offset_to_array_description
;
4692 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4694 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4695 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4698 esize
= *(const WORD
*)(pCArrayFormat
+2);
4700 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4701 pCArrayFormat
+ 4, 0);
4703 WriteConformance(pStubMsg
);
4705 align_pointer_clear(&pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4707 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4709 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4710 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4712 ERR("integer overflow of memory_size %u with bufsize %u\n",
4713 pCStructFormat
->memory_size
, bufsize
);
4714 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4716 /* copy constant sized part of struct */
4717 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4718 safe_copy_to_buffer(pStubMsg
, pMemory
, pCStructFormat
->memory_size
+ bufsize
);
4720 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4721 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4726 /***********************************************************************
4727 * NdrConformantStructUnmarshall [RPCRT4.@]
4729 unsigned char * WINAPI
NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4730 unsigned char **ppMemory
,
4731 PFORMAT_STRING pFormat
,
4732 unsigned char fMustAlloc
)
4734 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4735 PFORMAT_STRING pCArrayFormat
;
4736 ULONG esize
, bufsize
;
4737 unsigned char *saved_buffer
;
4739 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4741 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4742 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4744 ERR("invalid format type %x\n", pCStructFormat
->type
);
4745 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4748 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4749 pCStructFormat
->offset_to_array_description
;
4750 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4752 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4753 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4756 esize
= *(const WORD
*)(pCArrayFormat
+2);
4758 pCArrayFormat
= ReadConformance(pStubMsg
, pCArrayFormat
+ 4);
4760 align_pointer(&pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4762 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4764 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4765 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4767 ERR("integer overflow of memory_size %u with bufsize %u\n",
4768 pCStructFormat
->memory_size
, bufsize
);
4769 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4774 SIZE_T size
= pCStructFormat
->memory_size
+ bufsize
;
4775 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4779 if (!pStubMsg
->IsClient
&& !*ppMemory
)
4780 /* for servers, we just point straight into the RPC buffer */
4781 *ppMemory
= pStubMsg
->Buffer
;
4784 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4785 safe_buffer_increment(pStubMsg
, pCStructFormat
->memory_size
+ bufsize
);
4786 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4787 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4789 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
4790 if (*ppMemory
!= saved_buffer
)
4791 memcpy(*ppMemory
, saved_buffer
, pCStructFormat
->memory_size
+ bufsize
);
4796 /***********************************************************************
4797 * NdrConformantStructBufferSize [RPCRT4.@]
4799 void WINAPI
NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4800 unsigned char *pMemory
,
4801 PFORMAT_STRING pFormat
)
4803 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4804 PFORMAT_STRING pCArrayFormat
;
4807 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4809 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4810 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4812 ERR("invalid format type %x\n", pCStructFormat
->type
);
4813 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4816 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4817 pCStructFormat
->offset_to_array_description
;
4818 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4820 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4821 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4824 esize
= *(const WORD
*)(pCArrayFormat
+2);
4826 pCArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
, pCArrayFormat
+4, 0);
4827 SizeConformance(pStubMsg
);
4829 align_length(&pStubMsg
->BufferLength
, pCStructFormat
->alignment
+ 1);
4831 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4833 safe_buffer_length_increment(pStubMsg
, pCStructFormat
->memory_size
);
4834 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
4836 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4837 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4840 /***********************************************************************
4841 * NdrConformantStructMemorySize [RPCRT4.@]
4843 ULONG WINAPI
NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4844 PFORMAT_STRING pFormat
)
4850 /***********************************************************************
4851 * NdrConformantStructFree [RPCRT4.@]
4853 void WINAPI
NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
4854 unsigned char *pMemory
,
4855 PFORMAT_STRING pFormat
)
4857 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4858 PFORMAT_STRING pCArrayFormat
;
4860 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4862 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4863 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4865 ERR("invalid format type %x\n", pCStructFormat
->type
);
4866 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4870 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4871 pCStructFormat
->offset_to_array_description
;
4872 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4874 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4875 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4879 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4880 pCArrayFormat
+ 4, 0);
4882 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4884 /* copy constant sized part of struct */
4885 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4887 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4888 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4891 /***********************************************************************
4892 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4894 unsigned char * WINAPI
NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4895 unsigned char *pMemory
,
4896 PFORMAT_STRING pFormat
)
4898 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4899 PFORMAT_STRING pCVArrayFormat
;
4901 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4903 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4904 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4906 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4907 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4911 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4912 pCVStructFormat
->offset_to_array_description
;
4914 array_compute_and_write_conformance(*pCVArrayFormat
, pStubMsg
,
4915 pMemory
+ pCVStructFormat
->memory_size
,
4918 align_pointer_clear(&pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4920 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4922 /* write constant sized part */
4923 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4924 safe_copy_to_buffer(pStubMsg
, pMemory
, pCVStructFormat
->memory_size
);
4926 array_write_variance_and_marshall(*pCVArrayFormat
, pStubMsg
,
4927 pMemory
+ pCVStructFormat
->memory_size
,
4928 pCVArrayFormat
, FALSE
/* fHasPointers */);
4930 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4935 /***********************************************************************
4936 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4938 unsigned char * WINAPI
NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4939 unsigned char **ppMemory
,
4940 PFORMAT_STRING pFormat
,
4941 unsigned char fMustAlloc
)
4943 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4944 PFORMAT_STRING pCVArrayFormat
;
4945 ULONG memsize
, bufsize
;
4946 unsigned char *saved_buffer
, *saved_array_buffer
;
4948 unsigned char *array_memory
;
4950 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4952 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4953 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4955 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4956 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4960 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4961 pCVStructFormat
->offset_to_array_description
;
4963 memsize
= array_read_conformance(*pCVArrayFormat
, pStubMsg
,
4966 align_pointer(&pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4968 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4970 /* work out how much memory to allocate if we need to do so */
4971 if (!fMustAlloc
&& !*ppMemory
)
4975 SIZE_T size
= pCVStructFormat
->memory_size
+ memsize
;
4976 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4979 /* mark the start of the constant data */
4980 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4981 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4983 array_memory
= *ppMemory
+ pCVStructFormat
->memory_size
;
4984 bufsize
= array_read_variance_and_unmarshall(*pCVArrayFormat
, pStubMsg
,
4985 &array_memory
, pCVArrayFormat
,
4986 FALSE
/* fMustAlloc */,
4987 FALSE
/* fUseServerBufferMemory */,
4988 FALSE
/* fUnmarshall */);
4990 /* save offset in case unmarshalling pointers changes it */
4991 offset
= pStubMsg
->Offset
;
4993 /* mark the start of the array data */
4994 saved_array_buffer
= pStubMsg
->Buffer
;
4995 safe_buffer_increment(pStubMsg
, bufsize
);
4997 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4999 /* copy the constant data */
5000 memcpy(*ppMemory
, saved_buffer
, pCVStructFormat
->memory_size
);
5001 /* copy the array data */
5002 TRACE("copying %p to %p\n", saved_array_buffer
, *ppMemory
+ pCVStructFormat
->memory_size
);
5003 memcpy(*ppMemory
+ pCVStructFormat
->memory_size
+ offset
,
5004 saved_array_buffer
, bufsize
);
5006 if (*pCVArrayFormat
== RPC_FC_C_CSTRING
)
5007 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory
+ pCVStructFormat
->memory_size
)));
5008 else if (*pCVArrayFormat
== RPC_FC_C_WSTRING
)
5009 TRACE("string=%s\n", debugstr_w((WCHAR
*)(*ppMemory
+ pCVStructFormat
->memory_size
)));
5014 /***********************************************************************
5015 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
5017 void WINAPI
NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5018 unsigned char *pMemory
,
5019 PFORMAT_STRING pFormat
)
5021 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
5022 PFORMAT_STRING pCVArrayFormat
;
5024 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5026 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
5027 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
5029 ERR("invalid format type %x\n", pCVStructFormat
->type
);
5030 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5034 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
5035 pCVStructFormat
->offset_to_array_description
;
5036 array_compute_and_size_conformance(*pCVArrayFormat
, pStubMsg
,
5037 pMemory
+ pCVStructFormat
->memory_size
,
5040 align_length(&pStubMsg
->BufferLength
, pCVStructFormat
->alignment
+ 1);
5042 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
5044 safe_buffer_length_increment(pStubMsg
, pCVStructFormat
->memory_size
);
5046 array_buffer_size(*pCVArrayFormat
, pStubMsg
,
5047 pMemory
+ pCVStructFormat
->memory_size
, pCVArrayFormat
,
5048 FALSE
/* fHasPointers */);
5050 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5053 /***********************************************************************
5054 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
5056 ULONG WINAPI
NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5057 PFORMAT_STRING pFormat
)
5059 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
5060 PFORMAT_STRING pCVArrayFormat
;
5062 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5064 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
5065 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
5067 ERR("invalid format type %x\n", pCVStructFormat
->type
);
5068 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5072 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
5073 pCVStructFormat
->offset_to_array_description
;
5074 array_read_conformance(*pCVArrayFormat
, pStubMsg
, pCVArrayFormat
);
5076 align_pointer(&pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
5078 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
5080 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
5081 array_memory_size(*pCVArrayFormat
, pStubMsg
, pCVArrayFormat
,
5082 FALSE
/* fHasPointers */);
5084 pStubMsg
->MemorySize
+= pCVStructFormat
->memory_size
;
5086 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5088 return pStubMsg
->MemorySize
;
5091 /***********************************************************************
5092 * NdrConformantVaryingStructFree [RPCRT4.@]
5094 void WINAPI
NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
5095 unsigned char *pMemory
,
5096 PFORMAT_STRING pFormat
)
5098 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
5099 PFORMAT_STRING pCVArrayFormat
;
5101 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5103 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
5104 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
5106 ERR("invalid format type %x\n", pCVStructFormat
->type
);
5107 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5111 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
5112 pCVStructFormat
->offset_to_array_description
;
5113 array_free(*pCVArrayFormat
, pStubMsg
,
5114 pMemory
+ pCVStructFormat
->memory_size
, pCVArrayFormat
,
5115 FALSE
/* fHasPointers */);
5117 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
5119 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5122 #include "pshpack1.h"
5126 unsigned char alignment
;
5127 unsigned short total_size
;
5128 } NDR_SMFARRAY_FORMAT
;
5133 unsigned char alignment
;
5135 } NDR_LGFARRAY_FORMAT
;
5136 #include "poppack.h"
5138 /***********************************************************************
5139 * NdrFixedArrayMarshall [RPCRT4.@]
5141 unsigned char * WINAPI
NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5142 unsigned char *pMemory
,
5143 PFORMAT_STRING pFormat
)
5145 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5148 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5150 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5151 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5153 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5154 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5158 align_pointer_clear(&pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
5160 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5162 total_size
= pSmFArrayFormat
->total_size
;
5163 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5167 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5168 total_size
= pLgFArrayFormat
->total_size
;
5169 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5172 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5173 safe_copy_to_buffer(pStubMsg
, pMemory
, total_size
);
5175 pFormat
= EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
5180 /***********************************************************************
5181 * NdrFixedArrayUnmarshall [RPCRT4.@]
5183 unsigned char * WINAPI
NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5184 unsigned char **ppMemory
,
5185 PFORMAT_STRING pFormat
,
5186 unsigned char fMustAlloc
)
5188 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5190 unsigned char *saved_buffer
;
5192 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5194 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5195 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5197 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5198 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5202 align_pointer(&pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
5204 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5206 total_size
= pSmFArrayFormat
->total_size
;
5207 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5211 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5212 total_size
= pLgFArrayFormat
->total_size
;
5213 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5217 *ppMemory
= NdrAllocate(pStubMsg
, total_size
);
5220 if (!pStubMsg
->IsClient
&& !*ppMemory
)
5221 /* for servers, we just point straight into the RPC buffer */
5222 *ppMemory
= pStubMsg
->Buffer
;
5225 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5226 safe_buffer_increment(pStubMsg
, total_size
);
5227 pFormat
= EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
5229 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
5230 if (*ppMemory
!= saved_buffer
)
5231 memcpy(*ppMemory
, saved_buffer
, total_size
);
5236 /***********************************************************************
5237 * NdrFixedArrayBufferSize [RPCRT4.@]
5239 void WINAPI
NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5240 unsigned char *pMemory
,
5241 PFORMAT_STRING pFormat
)
5243 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5246 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5248 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5249 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5251 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5252 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5256 align_length(&pStubMsg
->BufferLength
, pSmFArrayFormat
->alignment
+ 1);
5258 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5260 total_size
= pSmFArrayFormat
->total_size
;
5261 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5265 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5266 total_size
= pLgFArrayFormat
->total_size
;
5267 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5269 safe_buffer_length_increment(pStubMsg
, total_size
);
5271 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5274 /***********************************************************************
5275 * NdrFixedArrayMemorySize [RPCRT4.@]
5277 ULONG WINAPI
NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5278 PFORMAT_STRING pFormat
)
5280 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5283 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5285 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5286 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5288 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5289 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5293 align_pointer(&pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
5295 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5297 total_size
= pSmFArrayFormat
->total_size
;
5298 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5302 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5303 total_size
= pLgFArrayFormat
->total_size
;
5304 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5306 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5307 safe_buffer_increment(pStubMsg
, total_size
);
5308 pStubMsg
->MemorySize
+= total_size
;
5310 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5315 /***********************************************************************
5316 * NdrFixedArrayFree [RPCRT4.@]
5318 void WINAPI
NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
5319 unsigned char *pMemory
,
5320 PFORMAT_STRING pFormat
)
5322 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5324 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5326 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5327 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5329 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5330 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5334 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5335 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5338 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5339 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5342 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5345 /***********************************************************************
5346 * NdrVaryingArrayMarshall [RPCRT4.@]
5348 unsigned char * WINAPI
NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5349 unsigned char *pMemory
,
5350 PFORMAT_STRING pFormat
)
5352 unsigned char alignment
;
5353 DWORD elements
, esize
;
5356 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5358 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5359 (pFormat
[0] != RPC_FC_LGVARRAY
))
5361 ERR("invalid format type %x\n", pFormat
[0]);
5362 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5366 alignment
= pFormat
[1] + 1;
5368 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5371 pFormat
+= sizeof(WORD
);
5372 elements
= *(const WORD
*)pFormat
;
5373 pFormat
+= sizeof(WORD
);
5378 pFormat
+= sizeof(DWORD
);
5379 elements
= *(const DWORD
*)pFormat
;
5380 pFormat
+= sizeof(DWORD
);
5383 esize
= *(const WORD
*)pFormat
;
5384 pFormat
+= sizeof(WORD
);
5386 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5387 if ((pStubMsg
->ActualCount
> elements
) ||
5388 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5390 RpcRaiseException(RPC_S_INVALID_BOUND
);
5394 WriteVariance(pStubMsg
);
5396 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
5398 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
5399 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5400 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
5402 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
5407 /***********************************************************************
5408 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5410 unsigned char * WINAPI
NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5411 unsigned char **ppMemory
,
5412 PFORMAT_STRING pFormat
,
5413 unsigned char fMustAlloc
)
5415 unsigned char alignment
;
5416 DWORD size
, elements
, esize
;
5418 unsigned char *saved_buffer
;
5421 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5423 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5424 (pFormat
[0] != RPC_FC_LGVARRAY
))
5426 ERR("invalid format type %x\n", pFormat
[0]);
5427 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5431 alignment
= pFormat
[1] + 1;
5433 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5436 size
= *(const WORD
*)pFormat
;
5437 pFormat
+= sizeof(WORD
);
5438 elements
= *(const WORD
*)pFormat
;
5439 pFormat
+= sizeof(WORD
);
5444 size
= *(const DWORD
*)pFormat
;
5445 pFormat
+= sizeof(DWORD
);
5446 elements
= *(const DWORD
*)pFormat
;
5447 pFormat
+= sizeof(DWORD
);
5450 esize
= *(const WORD
*)pFormat
;
5451 pFormat
+= sizeof(WORD
);
5453 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
5455 align_pointer(&pStubMsg
->Buffer
, alignment
);
5457 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
5458 offset
= pStubMsg
->Offset
;
5460 if (!fMustAlloc
&& !*ppMemory
)
5463 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5464 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5465 safe_buffer_increment(pStubMsg
, bufsize
);
5467 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
5469 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
5474 /***********************************************************************
5475 * NdrVaryingArrayBufferSize [RPCRT4.@]
5477 void WINAPI
NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5478 unsigned char *pMemory
,
5479 PFORMAT_STRING pFormat
)
5481 unsigned char alignment
;
5482 DWORD elements
, esize
;
5484 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5486 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5487 (pFormat
[0] != RPC_FC_LGVARRAY
))
5489 ERR("invalid format type %x\n", pFormat
[0]);
5490 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5494 alignment
= pFormat
[1] + 1;
5496 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5499 pFormat
+= sizeof(WORD
);
5500 elements
= *(const WORD
*)pFormat
;
5501 pFormat
+= sizeof(WORD
);
5506 pFormat
+= sizeof(DWORD
);
5507 elements
= *(const DWORD
*)pFormat
;
5508 pFormat
+= sizeof(DWORD
);
5511 esize
= *(const WORD
*)pFormat
;
5512 pFormat
+= sizeof(WORD
);
5514 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5515 if ((pStubMsg
->ActualCount
> elements
) ||
5516 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5518 RpcRaiseException(RPC_S_INVALID_BOUND
);
5522 SizeVariance(pStubMsg
);
5524 align_length(&pStubMsg
->BufferLength
, alignment
);
5526 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
5528 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5531 /***********************************************************************
5532 * NdrVaryingArrayMemorySize [RPCRT4.@]
5534 ULONG WINAPI
NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5535 PFORMAT_STRING pFormat
)
5537 unsigned char alignment
;
5538 DWORD size
, elements
, esize
;
5540 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5542 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5543 (pFormat
[0] != RPC_FC_LGVARRAY
))
5545 ERR("invalid format type %x\n", pFormat
[0]);
5546 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5550 alignment
= pFormat
[1] + 1;
5552 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5555 size
= *(const WORD
*)pFormat
;
5556 pFormat
+= sizeof(WORD
);
5557 elements
= *(const WORD
*)pFormat
;
5558 pFormat
+= sizeof(WORD
);
5563 size
= *(const DWORD
*)pFormat
;
5564 pFormat
+= sizeof(DWORD
);
5565 elements
= *(const DWORD
*)pFormat
;
5566 pFormat
+= sizeof(DWORD
);
5569 esize
= *(const WORD
*)pFormat
;
5570 pFormat
+= sizeof(WORD
);
5572 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
5574 align_pointer(&pStubMsg
->Buffer
, alignment
);
5576 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
5577 pStubMsg
->MemorySize
+= size
;
5579 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5581 return pStubMsg
->MemorySize
;
5584 /***********************************************************************
5585 * NdrVaryingArrayFree [RPCRT4.@]
5587 void WINAPI
NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
5588 unsigned char *pMemory
,
5589 PFORMAT_STRING pFormat
)
5593 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5595 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5596 (pFormat
[0] != RPC_FC_LGVARRAY
))
5598 ERR("invalid format type %x\n", pFormat
[0]);
5599 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5603 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5606 pFormat
+= sizeof(WORD
);
5607 elements
= *(const WORD
*)pFormat
;
5608 pFormat
+= sizeof(WORD
);
5613 pFormat
+= sizeof(DWORD
);
5614 elements
= *(const DWORD
*)pFormat
;
5615 pFormat
+= sizeof(DWORD
);
5618 pFormat
+= sizeof(WORD
);
5620 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5621 if ((pStubMsg
->ActualCount
> elements
) ||
5622 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5624 RpcRaiseException(RPC_S_INVALID_BOUND
);
5628 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5631 static ULONG
get_discriminant(unsigned char fc
, const unsigned char *pMemory
)
5644 return *(const USHORT
*)pMemory
;
5648 return *(const ULONG
*)pMemory
;
5649 case RPC_FC_INT3264
:
5650 case RPC_FC_UINT3264
:
5651 return *(const ULONG_PTR
*)pMemory
;
5653 FIXME("Unhandled base type: 0x%02x\n", fc
);
5658 static PFORMAT_STRING
get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg
,
5660 PFORMAT_STRING pFormat
)
5662 unsigned short num_arms
, arm
, type
;
5664 num_arms
= *(const SHORT
*)pFormat
& 0x0fff;
5666 for(arm
= 0; arm
< num_arms
; arm
++)
5668 if(discriminant
== *(const ULONG
*)pFormat
)
5676 type
= *(const unsigned short*)pFormat
;
5677 TRACE("type %04x\n", type
);
5678 if(arm
== num_arms
) /* default arm extras */
5682 ERR("no arm for 0x%x and no default case\n", discriminant
);
5683 RpcRaiseException(RPC_S_INVALID_TAG
);
5688 TRACE("falling back to empty default case for 0x%x\n", discriminant
);
5695 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
, ULONG discriminant
, PFORMAT_STRING pFormat
)
5697 unsigned short type
;
5701 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5705 type
= *(const unsigned short*)pFormat
;
5706 if((type
& 0xff00) == 0x8000)
5708 unsigned char basetype
= LOBYTE(type
);
5709 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &basetype
);
5713 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5714 NDR_MARSHALL m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
5717 unsigned char *saved_buffer
= NULL
;
5718 int pointer_buffer_mark_set
= 0;
5725 align_pointer_clear(&pStubMsg
->Buffer
, 4);
5726 saved_buffer
= pStubMsg
->Buffer
;
5727 if (pStubMsg
->PointerBufferMark
)
5729 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5730 pStubMsg
->PointerBufferMark
= NULL
;
5731 pointer_buffer_mark_set
= 1;
5734 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
5736 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char **)pMemory
, desc
);
5737 if (pointer_buffer_mark_set
)
5739 STD_OVERFLOW_CHECK(pStubMsg
);
5740 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5741 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5743 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5744 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
5745 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5747 pStubMsg
->Buffer
= saved_buffer
+ 4;
5751 m(pStubMsg
, pMemory
, desc
);
5754 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5759 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5760 unsigned char **ppMemory
,
5762 PFORMAT_STRING pFormat
,
5763 unsigned char fMustAlloc
)
5765 unsigned short type
;
5769 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5773 type
= *(const unsigned short*)pFormat
;
5774 if((type
& 0xff00) == 0x8000)
5776 unsigned char basetype
= LOBYTE(type
);
5777 return NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &basetype
, FALSE
);
5781 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5782 NDR_UNMARSHALL m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
5785 unsigned char *saved_buffer
= NULL
;
5786 int pointer_buffer_mark_set
= 0;
5793 align_pointer(&pStubMsg
->Buffer
, 4);
5794 saved_buffer
= pStubMsg
->Buffer
;
5795 if (pStubMsg
->PointerBufferMark
)
5797 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5798 pStubMsg
->PointerBufferMark
= NULL
;
5799 pointer_buffer_mark_set
= 1;
5802 pStubMsg
->Buffer
+= 4; /* for pointer ID */
5804 if (saved_buffer
+ 4 > pStubMsg
->BufferEnd
)
5806 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5807 saved_buffer
, pStubMsg
->BufferEnd
);
5808 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5811 PointerUnmarshall(pStubMsg
, saved_buffer
, *(unsigned char ***)ppMemory
, **(unsigned char ***)ppMemory
, desc
, fMustAlloc
);
5812 if (pointer_buffer_mark_set
)
5814 STD_OVERFLOW_CHECK(pStubMsg
);
5815 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5816 pStubMsg
->Buffer
= saved_buffer
+ 4;
5820 m(pStubMsg
, ppMemory
, desc
, fMustAlloc
);
5823 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5828 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg
,
5829 unsigned char *pMemory
,
5831 PFORMAT_STRING pFormat
)
5833 unsigned short type
;
5837 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5841 type
= *(const unsigned short*)pFormat
;
5842 if((type
& 0xff00) == 0x8000)
5844 unsigned char basetype
= LOBYTE(type
);
5845 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &basetype
);
5849 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5850 NDR_BUFFERSIZE m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
5859 align_length(&pStubMsg
->BufferLength
, 4);
5860 safe_buffer_length_increment(pStubMsg
, 4); /* for pointer ID */
5861 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5863 int saved_buffer_length
= pStubMsg
->BufferLength
;
5864 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
5865 pStubMsg
->PointerLength
= 0;
5866 if(!pStubMsg
->BufferLength
)
5867 ERR("BufferLength == 0??\n");
5868 PointerBufferSize(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5869 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
5870 pStubMsg
->BufferLength
= saved_buffer_length
;
5874 m(pStubMsg
, pMemory
, desc
);
5877 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
5881 static ULONG
union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg
,
5883 PFORMAT_STRING pFormat
)
5885 unsigned short type
, size
;
5887 size
= *(const unsigned short*)pFormat
;
5888 pStubMsg
->Memory
+= size
;
5891 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5895 type
= *(const unsigned short*)pFormat
;
5896 if((type
& 0xff00) == 0x8000)
5898 return NdrBaseTypeMemorySize(pStubMsg
, pFormat
);
5902 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5903 NDR_MEMORYSIZE m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
5904 unsigned char *saved_buffer
;
5913 align_pointer(&pStubMsg
->Buffer
, 4);
5914 saved_buffer
= pStubMsg
->Buffer
;
5915 safe_buffer_increment(pStubMsg
, 4);
5916 align_length(&pStubMsg
->MemorySize
, sizeof(void *));
5917 pStubMsg
->MemorySize
+= sizeof(void *);
5918 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5919 PointerMemorySize(pStubMsg
, saved_buffer
, pFormat
);
5922 return m(pStubMsg
, desc
);
5925 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5928 TRACE("size %d\n", size
);
5932 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg
,
5933 unsigned char *pMemory
,
5935 PFORMAT_STRING pFormat
)
5937 unsigned short type
;
5941 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5945 type
= *(const unsigned short*)pFormat
;
5946 if((type
& 0xff00) != 0x8000)
5948 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5949 NDR_FREE m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
5958 PointerFree(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5961 m(pStubMsg
, pMemory
, desc
);
5967 /***********************************************************************
5968 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5970 unsigned char * WINAPI
NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5971 unsigned char *pMemory
,
5972 PFORMAT_STRING pFormat
)
5974 unsigned char switch_type
;
5975 unsigned char increment
;
5978 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5981 switch_type
= *pFormat
& 0xf;
5982 increment
= (*pFormat
& 0xf0) >> 4;
5985 align_pointer_clear(&pStubMsg
->Buffer
, increment
);
5987 switch_value
= get_discriminant(switch_type
, pMemory
);
5988 TRACE("got switch value 0x%x\n", switch_value
);
5990 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &switch_type
);
5991 pMemory
+= increment
;
5993 return union_arm_marshall(pStubMsg
, pMemory
, switch_value
, pFormat
);
5996 /***********************************************************************
5997 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5999 unsigned char * WINAPI
NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6000 unsigned char **ppMemory
,
6001 PFORMAT_STRING pFormat
,
6002 unsigned char fMustAlloc
)
6004 unsigned char switch_type
;
6005 unsigned char increment
;
6007 unsigned short size
;
6008 unsigned char *pMemoryArm
;
6010 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
6013 switch_type
= *pFormat
& 0xf;
6014 increment
= (*pFormat
& 0xf0) >> 4;
6017 align_pointer(&pStubMsg
->Buffer
, increment
);
6018 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
6019 TRACE("got switch value 0x%x\n", switch_value
);
6021 size
= *(const unsigned short*)pFormat
+ increment
;
6022 if (!fMustAlloc
&& !*ppMemory
)
6025 *ppMemory
= NdrAllocate(pStubMsg
, size
);
6027 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6028 * since the arm is part of the memory block that is encompassed by
6029 * the whole union. Memory is forced to allocate when pointers
6030 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6031 * clearing the memory we pass in to the unmarshaller */
6033 memset(*ppMemory
, 0, size
);
6035 NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &switch_type
, FALSE
);
6036 pMemoryArm
= *ppMemory
+ increment
;
6038 return union_arm_unmarshall(pStubMsg
, &pMemoryArm
, switch_value
, pFormat
, FALSE
);
6041 /***********************************************************************
6042 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
6044 void WINAPI
NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6045 unsigned char *pMemory
,
6046 PFORMAT_STRING pFormat
)
6048 unsigned char switch_type
;
6049 unsigned char increment
;
6052 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6055 switch_type
= *pFormat
& 0xf;
6056 increment
= (*pFormat
& 0xf0) >> 4;
6059 align_length(&pStubMsg
->BufferLength
, increment
);
6060 switch_value
= get_discriminant(switch_type
, pMemory
);
6061 TRACE("got switch value 0x%x\n", switch_value
);
6063 /* Add discriminant size */
6064 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&switch_value
, &switch_type
);
6065 pMemory
+= increment
;
6067 union_arm_buffer_size(pStubMsg
, pMemory
, switch_value
, pFormat
);
6070 /***********************************************************************
6071 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
6073 ULONG WINAPI
NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6074 PFORMAT_STRING pFormat
)
6076 unsigned char switch_type
;
6077 unsigned char increment
;
6080 switch_type
= *pFormat
& 0xf;
6081 increment
= (*pFormat
& 0xf0) >> 4;
6084 align_pointer(&pStubMsg
->Buffer
, increment
);
6085 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
6086 TRACE("got switch value 0x%x\n", switch_value
);
6088 pStubMsg
->Memory
+= increment
;
6090 return increment
+ union_arm_memory_size(pStubMsg
, switch_value
, pFormat
+ *(const SHORT
*)pFormat
);
6093 /***********************************************************************
6094 * NdrEncapsulatedUnionFree [RPCRT4.@]
6096 void WINAPI
NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
6097 unsigned char *pMemory
,
6098 PFORMAT_STRING pFormat
)
6100 unsigned char switch_type
;
6101 unsigned char increment
;
6104 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6107 switch_type
= *pFormat
& 0xf;
6108 increment
= (*pFormat
& 0xf0) >> 4;
6111 switch_value
= get_discriminant(switch_type
, pMemory
);
6112 TRACE("got switch value 0x%x\n", switch_value
);
6114 pMemory
+= increment
;
6116 union_arm_free(pStubMsg
, pMemory
, switch_value
, pFormat
);
6119 /***********************************************************************
6120 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
6122 unsigned char * WINAPI
NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6123 unsigned char *pMemory
,
6124 PFORMAT_STRING pFormat
)
6126 unsigned char switch_type
;
6128 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6131 switch_type
= *pFormat
;
6134 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6135 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6136 /* Marshall discriminant */
6137 NdrBaseTypeMarshall(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
6139 return union_arm_marshall(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6142 static LONG
unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg
,
6143 PFORMAT_STRING
*ppFormat
)
6145 LONG discriminant
= 0;
6155 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
6165 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6166 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
6174 align_pointer(&pStubMsg
->Buffer
, sizeof(ULONG
));
6175 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
6180 FIXME("Unhandled base type: 0x%02x\n", **ppFormat
);
6184 if (pStubMsg
->fHasNewCorrDesc
)
6188 return discriminant
;
6191 /**********************************************************************
6192 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
6194 unsigned char * WINAPI
NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6195 unsigned char **ppMemory
,
6196 PFORMAT_STRING pFormat
,
6197 unsigned char fMustAlloc
)
6200 unsigned short size
;
6202 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
6205 /* Unmarshall discriminant */
6206 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
6207 TRACE("unmarshalled discriminant %x\n", discriminant
);
6209 pFormat
+= *(const SHORT
*)pFormat
;
6211 size
= *(const unsigned short*)pFormat
;
6213 if (!fMustAlloc
&& !*ppMemory
)
6216 *ppMemory
= NdrAllocate(pStubMsg
, size
);
6218 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6219 * since the arm is part of the memory block that is encompassed by
6220 * the whole union. Memory is forced to allocate when pointers
6221 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6222 * clearing the memory we pass in to the unmarshaller */
6224 memset(*ppMemory
, 0, size
);
6226 return union_arm_unmarshall(pStubMsg
, ppMemory
, discriminant
, pFormat
, FALSE
);
6229 /***********************************************************************
6230 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
6232 void WINAPI
NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6233 unsigned char *pMemory
,
6234 PFORMAT_STRING pFormat
)
6236 unsigned char switch_type
;
6238 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6241 switch_type
= *pFormat
;
6244 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6245 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6246 /* Add discriminant size */
6247 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
6249 union_arm_buffer_size(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6252 /***********************************************************************
6253 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
6255 ULONG WINAPI
NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6256 PFORMAT_STRING pFormat
)
6261 /* Unmarshall discriminant */
6262 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
6263 TRACE("unmarshalled discriminant 0x%x\n", discriminant
);
6265 return union_arm_memory_size(pStubMsg
, discriminant
, pFormat
+ *(const SHORT
*)pFormat
);
6268 /***********************************************************************
6269 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6271 void WINAPI
NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
6272 unsigned char *pMemory
,
6273 PFORMAT_STRING pFormat
)
6275 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6279 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6280 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6282 union_arm_free(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6285 /***********************************************************************
6286 * NdrByteCountPointerMarshall [RPCRT4.@]
6288 unsigned char * WINAPI
NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6289 unsigned char *pMemory
,
6290 PFORMAT_STRING pFormat
)
6296 /***********************************************************************
6297 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6299 unsigned char * WINAPI
NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6300 unsigned char **ppMemory
,
6301 PFORMAT_STRING pFormat
,
6302 unsigned char fMustAlloc
)
6308 /***********************************************************************
6309 * NdrByteCountPointerBufferSize [RPCRT4.@]
6311 void WINAPI
NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6312 unsigned char *pMemory
,
6313 PFORMAT_STRING pFormat
)
6318 /***********************************************************************
6319 * NdrByteCountPointerMemorySize [internal]
6321 static ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6322 PFORMAT_STRING pFormat
)
6328 /***********************************************************************
6329 * NdrByteCountPointerFree [RPCRT4.@]
6331 void WINAPI
NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
6332 unsigned char *pMemory
,
6333 PFORMAT_STRING pFormat
)
6338 /***********************************************************************
6339 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6341 unsigned char * WINAPI
NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6342 unsigned char *pMemory
,
6343 PFORMAT_STRING pFormat
)
6349 /***********************************************************************
6350 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6352 unsigned char * WINAPI
NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6353 unsigned char **ppMemory
,
6354 PFORMAT_STRING pFormat
,
6355 unsigned char fMustAlloc
)
6361 /***********************************************************************
6362 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6364 void WINAPI
NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6365 unsigned char *pMemory
,
6366 PFORMAT_STRING pFormat
)
6371 /***********************************************************************
6372 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6374 ULONG WINAPI
NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6375 PFORMAT_STRING pFormat
)
6381 /***********************************************************************
6382 * NdrXmitOrRepAsFree [RPCRT4.@]
6384 void WINAPI
NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg
,
6385 unsigned char *pMemory
,
6386 PFORMAT_STRING pFormat
)
6391 /***********************************************************************
6392 * NdrRangeMarshall [internal]
6394 static unsigned char *WINAPI
NdrRangeMarshall(
6395 PMIDL_STUB_MESSAGE pStubMsg
,
6396 unsigned char *pMemory
,
6397 PFORMAT_STRING pFormat
)
6399 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6400 unsigned char base_type
;
6402 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6404 if (pRange
->type
!= RPC_FC_RANGE
)
6406 ERR("invalid format type %x\n", pRange
->type
);
6407 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6411 base_type
= pRange
->flags_type
& 0xf;
6413 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &base_type
);
6416 /***********************************************************************
6417 * NdrRangeUnmarshall [RPCRT4.@]
6419 unsigned char *WINAPI
NdrRangeUnmarshall(
6420 PMIDL_STUB_MESSAGE pStubMsg
,
6421 unsigned char **ppMemory
,
6422 PFORMAT_STRING pFormat
,
6423 unsigned char fMustAlloc
)
6425 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6426 unsigned char base_type
;
6428 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6430 if (pRange
->type
!= RPC_FC_RANGE
)
6432 ERR("invalid format type %x\n", pRange
->type
);
6433 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6436 base_type
= pRange
->flags_type
& 0xf;
6438 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6439 base_type
, pRange
->low_value
, pRange
->high_value
);
6441 #define RANGE_UNMARSHALL(mem_type, wire_type, format_spec) \
6444 align_pointer(&pStubMsg->Buffer, sizeof(wire_type)); \
6445 if (!fMustAlloc && !*ppMemory) \
6446 fMustAlloc = TRUE; \
6448 *ppMemory = NdrAllocate(pStubMsg, sizeof(mem_type)); \
6449 if (pStubMsg->Buffer + sizeof(wire_type) > pStubMsg->BufferEnd) \
6451 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6452 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6453 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6455 if ((*(wire_type *)pStubMsg->Buffer < (mem_type)pRange->low_value) || \
6456 (*(wire_type *)pStubMsg->Buffer > (mem_type)pRange->high_value)) \
6458 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6459 *(wire_type *)pStubMsg->Buffer, (mem_type)pRange->low_value, \
6460 (mem_type)pRange->high_value); \
6461 RpcRaiseException(RPC_S_INVALID_BOUND); \
6464 TRACE("*ppMemory: %p\n", *ppMemory); \
6465 **(mem_type **)ppMemory = *(wire_type *)pStubMsg->Buffer; \
6466 pStubMsg->Buffer += sizeof(wire_type); \
6473 RANGE_UNMARSHALL(UCHAR
, UCHAR
, "%d");
6474 TRACE("value: 0x%02x\n", **ppMemory
);
6478 RANGE_UNMARSHALL(CHAR
, CHAR
, "%u");
6479 TRACE("value: 0x%02x\n", **ppMemory
);
6481 case RPC_FC_WCHAR
: /* FIXME: valid? */
6483 RANGE_UNMARSHALL(USHORT
, USHORT
, "%u");
6484 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6487 RANGE_UNMARSHALL(SHORT
, SHORT
, "%d");
6488 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6492 RANGE_UNMARSHALL(LONG
, LONG
, "%d");
6493 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6496 RANGE_UNMARSHALL(ULONG
, ULONG
, "%u");
6497 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6500 RANGE_UNMARSHALL(UINT
, USHORT
, "%u");
6501 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
6507 ERR("invalid range base type: 0x%02x\n", base_type
);
6508 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6514 /***********************************************************************
6515 * NdrRangeBufferSize [internal]
6517 static void WINAPI
NdrRangeBufferSize(
6518 PMIDL_STUB_MESSAGE pStubMsg
,
6519 unsigned char *pMemory
,
6520 PFORMAT_STRING pFormat
)
6522 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6523 unsigned char base_type
;
6525 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6527 if (pRange
->type
!= RPC_FC_RANGE
)
6529 ERR("invalid format type %x\n", pRange
->type
);
6530 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6532 base_type
= pRange
->flags_type
& 0xf;
6534 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &base_type
);
6537 /***********************************************************************
6538 * NdrRangeMemorySize [internal]
6540 static ULONG WINAPI
NdrRangeMemorySize(
6541 PMIDL_STUB_MESSAGE pStubMsg
,
6542 PFORMAT_STRING pFormat
)
6544 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6545 unsigned char base_type
;
6547 if (pRange
->type
!= RPC_FC_RANGE
)
6549 ERR("invalid format type %x\n", pRange
->type
);
6550 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6553 base_type
= pRange
->flags_type
& 0xf;
6555 return NdrBaseTypeMemorySize(pStubMsg
, &base_type
);
6558 /***********************************************************************
6559 * NdrRangeFree [internal]
6561 static void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6562 unsigned char *pMemory
,
6563 PFORMAT_STRING pFormat
)
6565 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6570 /***********************************************************************
6571 * NdrBaseTypeMarshall [internal]
6573 static unsigned char *WINAPI
NdrBaseTypeMarshall(
6574 PMIDL_STUB_MESSAGE pStubMsg
,
6575 unsigned char *pMemory
,
6576 PFORMAT_STRING pFormat
)
6578 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6586 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(UCHAR
));
6587 TRACE("value: 0x%02x\n", *pMemory
);
6592 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(USHORT
));
6593 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(USHORT
));
6594 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
6598 case RPC_FC_ERROR_STATUS_T
:
6600 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(ULONG
));
6601 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONG
));
6602 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
6605 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(float));
6606 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
6609 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(double));
6610 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
6613 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(ULONGLONG
));
6614 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONGLONG
));
6615 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
6619 USHORT val
= *(UINT
*)pMemory
;
6620 /* only 16-bits on the wire, so do a sanity check */
6621 if (*(UINT
*)pMemory
> SHRT_MAX
)
6622 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
6623 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(USHORT
));
6624 safe_copy_to_buffer(pStubMsg
, &val
, sizeof(val
));
6625 TRACE("value: 0x%04x\n", *(UINT
*)pMemory
);
6628 case RPC_FC_INT3264
:
6629 case RPC_FC_UINT3264
:
6631 UINT val
= *(UINT_PTR
*)pMemory
;
6632 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(UINT
));
6633 safe_copy_to_buffer(pStubMsg
, &val
, sizeof(val
));
6639 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6642 /* FIXME: what is the correct return value? */
6646 /***********************************************************************
6647 * NdrBaseTypeUnmarshall [internal]
6649 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(
6650 PMIDL_STUB_MESSAGE pStubMsg
,
6651 unsigned char **ppMemory
,
6652 PFORMAT_STRING pFormat
,
6653 unsigned char fMustAlloc
)
6655 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6657 #define BASE_TYPE_UNMARSHALL(type) do { \
6658 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
6659 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6661 *ppMemory = pStubMsg->Buffer; \
6662 TRACE("*ppMemory: %p\n", *ppMemory); \
6663 safe_buffer_increment(pStubMsg, sizeof(type)); \
6668 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6669 TRACE("*ppMemory: %p\n", *ppMemory); \
6670 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6680 BASE_TYPE_UNMARSHALL(UCHAR
);
6681 TRACE("value: 0x%02x\n", **ppMemory
);
6686 BASE_TYPE_UNMARSHALL(USHORT
);
6687 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6691 case RPC_FC_ERROR_STATUS_T
:
6693 BASE_TYPE_UNMARSHALL(ULONG
);
6694 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6697 BASE_TYPE_UNMARSHALL(float);
6698 TRACE("value: %f\n", **(float **)ppMemory
);
6701 BASE_TYPE_UNMARSHALL(double);
6702 TRACE("value: %f\n", **(double **)ppMemory
);
6705 BASE_TYPE_UNMARSHALL(ULONGLONG
);
6706 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG
**)ppMemory
));
6711 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6712 if (!fMustAlloc
&& !*ppMemory
)
6715 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT
));
6716 safe_copy_from_buffer(pStubMsg
, &val
, sizeof(USHORT
));
6717 /* 16-bits on the wire, but int in memory */
6718 **(UINT
**)ppMemory
= val
;
6719 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
6722 case RPC_FC_INT3264
:
6723 if (sizeof(INT_PTR
) == sizeof(INT
)) BASE_TYPE_UNMARSHALL(INT
);
6727 align_pointer(&pStubMsg
->Buffer
, sizeof(INT
));
6728 if (!fMustAlloc
&& !*ppMemory
)
6731 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(INT_PTR
));
6732 safe_copy_from_buffer(pStubMsg
, &val
, sizeof(INT
));
6733 **(INT_PTR
**)ppMemory
= val
;
6734 TRACE("value: 0x%08lx\n", **(INT_PTR
**)ppMemory
);
6737 case RPC_FC_UINT3264
:
6738 if (sizeof(UINT_PTR
) == sizeof(UINT
)) BASE_TYPE_UNMARSHALL(UINT
);
6742 align_pointer(&pStubMsg
->Buffer
, sizeof(UINT
));
6743 if (!fMustAlloc
&& !*ppMemory
)
6746 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT_PTR
));
6747 safe_copy_from_buffer(pStubMsg
, &val
, sizeof(UINT
));
6748 **(UINT_PTR
**)ppMemory
= val
;
6749 TRACE("value: 0x%08lx\n", **(UINT_PTR
**)ppMemory
);
6755 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6757 #undef BASE_TYPE_UNMARSHALL
6759 /* FIXME: what is the correct return value? */
6764 /***********************************************************************
6765 * NdrBaseTypeBufferSize [internal]
6767 static void WINAPI
NdrBaseTypeBufferSize(
6768 PMIDL_STUB_MESSAGE pStubMsg
,
6769 unsigned char *pMemory
,
6770 PFORMAT_STRING pFormat
)
6772 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6780 safe_buffer_length_increment(pStubMsg
, sizeof(UCHAR
));
6786 align_length(&pStubMsg
->BufferLength
, sizeof(USHORT
));
6787 safe_buffer_length_increment(pStubMsg
, sizeof(USHORT
));
6792 case RPC_FC_INT3264
:
6793 case RPC_FC_UINT3264
:
6794 align_length(&pStubMsg
->BufferLength
, sizeof(ULONG
));
6795 safe_buffer_length_increment(pStubMsg
, sizeof(ULONG
));
6798 align_length(&pStubMsg
->BufferLength
, sizeof(float));
6799 safe_buffer_length_increment(pStubMsg
, sizeof(float));
6802 align_length(&pStubMsg
->BufferLength
, sizeof(double));
6803 safe_buffer_length_increment(pStubMsg
, sizeof(double));
6806 align_length(&pStubMsg
->BufferLength
, sizeof(ULONGLONG
));
6807 safe_buffer_length_increment(pStubMsg
, sizeof(ULONGLONG
));
6809 case RPC_FC_ERROR_STATUS_T
:
6810 align_length(&pStubMsg
->BufferLength
, sizeof(error_status_t
));
6811 safe_buffer_length_increment(pStubMsg
, sizeof(error_status_t
));
6816 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6820 /***********************************************************************
6821 * NdrBaseTypeMemorySize [internal]
6823 static ULONG WINAPI
NdrBaseTypeMemorySize(
6824 PMIDL_STUB_MESSAGE pStubMsg
,
6825 PFORMAT_STRING pFormat
)
6827 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg
, *pFormat
);
6835 safe_buffer_increment(pStubMsg
, sizeof(UCHAR
));
6836 pStubMsg
->MemorySize
+= sizeof(UCHAR
);
6837 return sizeof(UCHAR
);
6841 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6842 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6843 align_length(&pStubMsg
->MemorySize
, sizeof(USHORT
));
6844 pStubMsg
->MemorySize
+= sizeof(USHORT
);
6845 return sizeof(USHORT
);
6849 align_pointer(&pStubMsg
->Buffer
, sizeof(ULONG
));
6850 safe_buffer_increment(pStubMsg
, sizeof(ULONG
));
6851 align_length(&pStubMsg
->MemorySize
, sizeof(ULONG
));
6852 pStubMsg
->MemorySize
+= sizeof(ULONG
);
6853 return sizeof(ULONG
);
6855 align_pointer(&pStubMsg
->Buffer
, sizeof(float));
6856 safe_buffer_increment(pStubMsg
, sizeof(float));
6857 align_length(&pStubMsg
->MemorySize
, sizeof(float));
6858 pStubMsg
->MemorySize
+= sizeof(float);
6859 return sizeof(float);
6861 align_pointer(&pStubMsg
->Buffer
, sizeof(double));
6862 safe_buffer_increment(pStubMsg
, sizeof(double));
6863 align_length(&pStubMsg
->MemorySize
, sizeof(double));
6864 pStubMsg
->MemorySize
+= sizeof(double);
6865 return sizeof(double);
6867 align_pointer(&pStubMsg
->Buffer
, sizeof(ULONGLONG
));
6868 safe_buffer_increment(pStubMsg
, sizeof(ULONGLONG
));
6869 align_length(&pStubMsg
->MemorySize
, sizeof(ULONGLONG
));
6870 pStubMsg
->MemorySize
+= sizeof(ULONGLONG
);
6871 return sizeof(ULONGLONG
);
6872 case RPC_FC_ERROR_STATUS_T
:
6873 align_pointer(&pStubMsg
->Buffer
, sizeof(error_status_t
));
6874 safe_buffer_increment(pStubMsg
, sizeof(error_status_t
));
6875 align_length(&pStubMsg
->MemorySize
, sizeof(error_status_t
));
6876 pStubMsg
->MemorySize
+= sizeof(error_status_t
);
6877 return sizeof(error_status_t
);
6879 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6880 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6881 align_length(&pStubMsg
->MemorySize
, sizeof(UINT
));
6882 pStubMsg
->MemorySize
+= sizeof(UINT
);
6883 return sizeof(UINT
);
6884 case RPC_FC_INT3264
:
6885 case RPC_FC_UINT3264
:
6886 align_pointer(&pStubMsg
->Buffer
, sizeof(UINT
));
6887 safe_buffer_increment(pStubMsg
, sizeof(UINT
));
6888 align_length(&pStubMsg
->MemorySize
, sizeof(UINT_PTR
));
6889 pStubMsg
->MemorySize
+= sizeof(UINT_PTR
);
6890 return sizeof(UINT_PTR
);
6892 align_length(&pStubMsg
->MemorySize
, sizeof(void *));
6893 pStubMsg
->MemorySize
+= sizeof(void *);
6894 return sizeof(void *);
6896 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6901 /***********************************************************************
6902 * NdrBaseTypeFree [internal]
6904 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6905 unsigned char *pMemory
,
6906 PFORMAT_STRING pFormat
)
6908 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6913 /***********************************************************************
6914 * NdrContextHandleBufferSize [internal]
6916 static void WINAPI
NdrContextHandleBufferSize(
6917 PMIDL_STUB_MESSAGE pStubMsg
,
6918 unsigned char *pMemory
,
6919 PFORMAT_STRING pFormat
)
6921 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6923 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6925 ERR("invalid format type %x\n", *pFormat
);
6926 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6928 align_length(&pStubMsg
->BufferLength
, 4);
6929 safe_buffer_length_increment(pStubMsg
, cbNDRContext
);
6932 /***********************************************************************
6933 * NdrContextHandleMarshall [internal]
6935 static unsigned char *WINAPI
NdrContextHandleMarshall(
6936 PMIDL_STUB_MESSAGE pStubMsg
,
6937 unsigned char *pMemory
,
6938 PFORMAT_STRING pFormat
)
6940 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6942 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6944 ERR("invalid format type %x\n", *pFormat
);
6945 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6947 TRACE("flags: 0x%02x\n", pFormat
[1]);
6949 if (pStubMsg
->IsClient
)
6951 if (pFormat
[1] & HANDLE_PARAM_IS_VIA_PTR
)
6952 NdrClientContextMarshall(pStubMsg
, *(NDR_CCONTEXT
**)pMemory
, FALSE
);
6954 NdrClientContextMarshall(pStubMsg
, pMemory
, FALSE
);
6958 NDR_SCONTEXT ctxt
= NDRSContextFromValue(pMemory
);
6959 NDR_RUNDOWN rundown
= pStubMsg
->StubDesc
->apfnNdrRundownRoutines
[pFormat
[2]];
6960 NdrServerContextNewMarshall(pStubMsg
, ctxt
, rundown
, pFormat
);
6966 /***********************************************************************
6967 * NdrContextHandleUnmarshall [internal]
6969 static unsigned char *WINAPI
NdrContextHandleUnmarshall(
6970 PMIDL_STUB_MESSAGE pStubMsg
,
6971 unsigned char **ppMemory
,
6972 PFORMAT_STRING pFormat
,
6973 unsigned char fMustAlloc
)
6975 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg
,
6976 ppMemory
, pFormat
, fMustAlloc
? "TRUE": "FALSE");
6978 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6980 ERR("invalid format type %x\n", *pFormat
);
6981 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6983 TRACE("flags: 0x%02x\n", pFormat
[1]);
6985 if (pStubMsg
->IsClient
)
6987 /* [out]-only or [ret] param */
6988 if ((pFormat
[1] & (HANDLE_PARAM_IS_IN
|HANDLE_PARAM_IS_OUT
)) == HANDLE_PARAM_IS_OUT
)
6989 **(NDR_CCONTEXT
**)ppMemory
= NULL
;
6990 NdrClientContextUnmarshall(pStubMsg
, *(NDR_CCONTEXT
**)ppMemory
, pStubMsg
->RpcMsg
->Handle
);
6995 ctxt
= NdrServerContextNewUnmarshall(pStubMsg
, pFormat
);
6996 if (pFormat
[1] & HANDLE_PARAM_IS_VIA_PTR
)
6997 *(void **)ppMemory
= NDRSContextValue(ctxt
);
6999 *(void **)ppMemory
= *NDRSContextValue(ctxt
);
7005 /***********************************************************************
7006 * NdrClientContextMarshall [RPCRT4.@]
7008 void WINAPI
NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7009 NDR_CCONTEXT ContextHandle
,
7012 TRACE("(%p, %p, %d)\n", pStubMsg
, ContextHandle
, fCheck
);
7014 align_pointer_clear(&pStubMsg
->Buffer
, 4);
7016 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7018 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7019 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7020 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7023 /* FIXME: what does fCheck do? */
7024 NDRCContextMarshall(ContextHandle
,
7027 pStubMsg
->Buffer
+= cbNDRContext
;
7030 /***********************************************************************
7031 * NdrClientContextUnmarshall [RPCRT4.@]
7033 void WINAPI
NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7034 NDR_CCONTEXT
* pContextHandle
,
7035 RPC_BINDING_HANDLE BindHandle
)
7037 TRACE("(%p, %p, %p)\n", pStubMsg
, pContextHandle
, BindHandle
);
7039 align_pointer(&pStubMsg
->Buffer
, 4);
7041 if (pStubMsg
->Buffer
+ cbNDRContext
> pStubMsg
->BufferEnd
)
7042 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7044 NDRCContextUnmarshall(pContextHandle
,
7047 pStubMsg
->RpcMsg
->DataRepresentation
);
7049 pStubMsg
->Buffer
+= cbNDRContext
;
7052 void WINAPI
NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7053 NDR_SCONTEXT ContextHandle
,
7054 NDR_RUNDOWN RundownRoutine
)
7056 TRACE("(%p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
);
7058 align_pointer(&pStubMsg
->Buffer
, 4);
7060 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7062 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7063 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7064 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7067 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
7068 pStubMsg
->Buffer
, RundownRoutine
, NULL
,
7069 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
7070 pStubMsg
->Buffer
+= cbNDRContext
;
7073 NDR_SCONTEXT WINAPI
NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
)
7075 NDR_SCONTEXT ContextHandle
;
7077 TRACE("(%p)\n", pStubMsg
);
7079 align_pointer(&pStubMsg
->Buffer
, 4);
7081 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7083 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7084 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7085 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7088 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
7090 pStubMsg
->RpcMsg
->DataRepresentation
,
7091 NULL
, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
7092 pStubMsg
->Buffer
+= cbNDRContext
;
7094 return ContextHandle
;
7097 void WINAPI
NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg
,
7098 unsigned char* pMemory
,
7099 PFORMAT_STRING pFormat
)
7101 FIXME("(%p, %p, %p): stub\n", pStubMsg
, pMemory
, pFormat
);
7104 NDR_SCONTEXT WINAPI
NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg
,
7105 PFORMAT_STRING pFormat
)
7107 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
7108 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
7110 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
7112 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
7113 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
7114 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
7115 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
7116 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
7118 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
7119 if_id
= &sif
->InterfaceId
;
7122 return NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
, NULL
,
7123 pStubMsg
->RpcMsg
->DataRepresentation
, if_id
,
7127 void WINAPI
NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7128 NDR_SCONTEXT ContextHandle
,
7129 NDR_RUNDOWN RundownRoutine
,
7130 PFORMAT_STRING pFormat
)
7132 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
7133 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
7135 TRACE("(%p, %p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
, pFormat
);
7137 align_pointer(&pStubMsg
->Buffer
, 4);
7139 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7141 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7142 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7143 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7146 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
7147 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
7148 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
7149 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
7150 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
7152 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
7153 if_id
= &sif
->InterfaceId
;
7156 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
7157 pStubMsg
->Buffer
, RundownRoutine
, if_id
, flags
);
7158 pStubMsg
->Buffer
+= cbNDRContext
;
7161 NDR_SCONTEXT WINAPI
NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7162 PFORMAT_STRING pFormat
)
7164 NDR_SCONTEXT ContextHandle
;
7165 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
7166 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
7168 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
7170 align_pointer(&pStubMsg
->Buffer
, 4);
7172 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7174 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7175 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7176 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7179 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
7180 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
7181 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
7182 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
7183 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
7185 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
7186 if_id
= &sif
->InterfaceId
;
7189 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
7191 pStubMsg
->RpcMsg
->DataRepresentation
,
7193 pStubMsg
->Buffer
+= cbNDRContext
;
7195 return ContextHandle
;
7198 /***********************************************************************
7199 * NdrCorrelationInitialize [RPCRT4.@]
7201 * Initializes correlation validity checking.
7204 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7205 * pMemory [I] Pointer to memory to use as a cache.
7206 * CacheSize [I] Size of the memory pointed to by pMemory.
7207 * Flags [I] Reserved. Set to zero.
7212 void WINAPI
NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg
, void *pMemory
, ULONG CacheSize
, ULONG Flags
)
7214 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg
, pMemory
, CacheSize
, Flags
);
7215 pStubMsg
->fHasNewCorrDesc
= TRUE
;
7218 /***********************************************************************
7219 * NdrCorrelationPass [RPCRT4.@]
7221 * Performs correlation validity checking.
7224 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7229 void WINAPI
NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg
)
7231 FIXME("(%p): stub\n", pStubMsg
);
7234 /***********************************************************************
7235 * NdrCorrelationFree [RPCRT4.@]
7237 * Frees any resources used while unmarshalling parameters that need
7238 * correlation validity checking.
7241 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7246 void WINAPI
NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg
)
7248 FIXME("(%p): stub\n", pStubMsg
);