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/debug.h"
47 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
50 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
51 (*((UINT32 *)(pchar)) = (uint32))
53 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
54 (*((UINT32 *)(pchar)))
56 /* these would work for i386 too, but less efficient */
57 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
58 (*(pchar) = LOBYTE(LOWORD(uint32)), \
59 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
60 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
61 *((pchar)+3) = HIBYTE(HIWORD(uint32)))
63 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
65 MAKEWORD(*(pchar), *((pchar)+1)), \
66 MAKEWORD(*((pchar)+2), *((pchar)+3))))
69 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
70 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
71 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
72 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
73 *(pchar) = HIBYTE(HIWORD(uint32)))
75 #define BIG_ENDIAN_UINT32_READ(pchar) \
77 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
78 MAKEWORD(*((pchar)+1), *(pchar))))
80 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
81 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
82 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
83 # define NDR_LOCAL_UINT32_READ(pchar) \
84 BIG_ENDIAN_UINT32_READ(pchar)
86 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
87 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
88 # define NDR_LOCAL_UINT32_READ(pchar) \
89 LITTLE_ENDIAN_UINT32_READ(pchar)
92 static inline void align_length( ULONG
*len
, unsigned int align
)
94 *len
= (*len
+ align
- 1) & ~(align
- 1);
97 static inline void align_pointer( unsigned char **ptr
, unsigned int align
)
99 ULONG_PTR mask
= align
- 1;
100 *ptr
= (unsigned char *)(((ULONG_PTR
)*ptr
+ mask
) & ~mask
);
103 static inline void align_pointer_clear( unsigned char **ptr
, unsigned int align
)
105 ULONG_PTR mask
= align
- 1;
106 memset( *ptr
, 0, (align
- (ULONG_PTR
)*ptr
) & mask
);
107 *ptr
= (unsigned char *)(((ULONG_PTR
)*ptr
+ mask
) & ~mask
);
110 static inline void align_pointer_offset( unsigned char **ptr
, unsigned char *base
, unsigned int align
)
112 ULONG_PTR mask
= align
- 1;
113 *ptr
= base
+ (((ULONG_PTR
)(*ptr
- base
) + mask
) & ~mask
);
116 static inline void align_pointer_offset_clear( unsigned char **ptr
, unsigned char *base
, unsigned int align
)
118 ULONG_PTR mask
= align
- 1;
119 memset( *ptr
, 0, (align
- (ULONG_PTR
)(*ptr
- base
)) & mask
);
120 *ptr
= base
+ (((ULONG_PTR
)(*ptr
- base
) + mask
) & ~mask
);
123 #define STD_OVERFLOW_CHECK(_Msg) do { \
124 TRACE("buffer=%d/%d\n", (ULONG)(_Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer), _Msg->BufferLength); \
125 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
126 ERR("buffer overflow %d bytes\n", (ULONG)(_Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength))); \
129 #define NDR_POINTER_ID_BASE 0x20000
130 #define NDR_POINTER_ID(pStubMsg) (NDR_POINTER_ID_BASE + ((pStubMsg)->UniquePtrCount++) * 4)
131 #define NDR_TABLE_SIZE 128
132 #define NDR_TABLE_MASK 127
134 static unsigned char *WINAPI
NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
135 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
136 static void WINAPI
NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
137 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
138 static ULONG WINAPI
NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
140 static unsigned char *WINAPI
NdrContextHandleMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
141 static void WINAPI
NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
142 static unsigned char *WINAPI
NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
144 static unsigned char *WINAPI
NdrRangeMarshall(PMIDL_STUB_MESSAGE
,unsigned char *, PFORMAT_STRING
);
145 static void WINAPI
NdrRangeBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
146 static ULONG WINAPI
NdrRangeMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
147 static void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
149 static ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
151 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
152 unsigned char *pMemory
,
153 PFORMAT_STRING pFormat
,
154 PFORMAT_STRING pPointer
);
155 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
156 unsigned char *pMemory
,
157 PFORMAT_STRING pFormat
,
158 PFORMAT_STRING pPointer
);
159 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
160 unsigned char *pMemory
,
161 PFORMAT_STRING pFormat
,
162 PFORMAT_STRING pPointer
,
163 unsigned char fMustAlloc
);
164 static ULONG
ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
165 PFORMAT_STRING pFormat
,
166 PFORMAT_STRING pPointer
);
167 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
168 unsigned char *pMemory
,
169 PFORMAT_STRING pFormat
,
170 PFORMAT_STRING pPointer
);
172 const NDR_MARSHALL NdrMarshaller
[NDR_TABLE_SIZE
] = {
174 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
175 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
176 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
177 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
181 NdrPointerMarshall
, NdrPointerMarshall
,
182 NdrPointerMarshall
, NdrPointerMarshall
,
184 NdrSimpleStructMarshall
, NdrSimpleStructMarshall
,
185 NdrConformantStructMarshall
, NdrConformantStructMarshall
,
186 NdrConformantVaryingStructMarshall
,
187 NdrComplexStructMarshall
,
189 NdrConformantArrayMarshall
,
190 NdrConformantVaryingArrayMarshall
,
191 NdrFixedArrayMarshall
, NdrFixedArrayMarshall
,
192 NdrVaryingArrayMarshall
, NdrVaryingArrayMarshall
,
193 NdrComplexArrayMarshall
,
195 NdrConformantStringMarshall
, 0, 0,
196 NdrConformantStringMarshall
,
197 NdrNonConformantStringMarshall
, 0, 0, 0,
199 NdrEncapsulatedUnionMarshall
,
200 NdrNonEncapsulatedUnionMarshall
,
201 NdrByteCountPointerMarshall
,
202 NdrXmitOrRepAsMarshall
, NdrXmitOrRepAsMarshall
,
204 NdrInterfacePointerMarshall
,
206 NdrContextHandleMarshall
,
209 NdrUserMarshalMarshall
,
216 const NDR_UNMARSHALL NdrUnmarshaller
[NDR_TABLE_SIZE
] = {
218 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
219 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
220 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
221 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
223 NdrBaseTypeUnmarshall
,
225 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
226 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
228 NdrSimpleStructUnmarshall
, NdrSimpleStructUnmarshall
,
229 NdrConformantStructUnmarshall
, NdrConformantStructUnmarshall
,
230 NdrConformantVaryingStructUnmarshall
,
231 NdrComplexStructUnmarshall
,
233 NdrConformantArrayUnmarshall
,
234 NdrConformantVaryingArrayUnmarshall
,
235 NdrFixedArrayUnmarshall
, NdrFixedArrayUnmarshall
,
236 NdrVaryingArrayUnmarshall
, NdrVaryingArrayUnmarshall
,
237 NdrComplexArrayUnmarshall
,
239 NdrConformantStringUnmarshall
, 0, 0,
240 NdrConformantStringUnmarshall
,
241 NdrNonConformantStringUnmarshall
, 0, 0, 0,
243 NdrEncapsulatedUnionUnmarshall
,
244 NdrNonEncapsulatedUnionUnmarshall
,
245 NdrByteCountPointerUnmarshall
,
246 NdrXmitOrRepAsUnmarshall
, NdrXmitOrRepAsUnmarshall
,
248 NdrInterfacePointerUnmarshall
,
250 NdrContextHandleUnmarshall
,
253 NdrUserMarshalUnmarshall
,
257 NdrBaseTypeUnmarshall
,
258 NdrBaseTypeUnmarshall
260 const NDR_BUFFERSIZE NdrBufferSizer
[NDR_TABLE_SIZE
] = {
262 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
263 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
264 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
265 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
267 NdrBaseTypeBufferSize
,
269 NdrPointerBufferSize
, NdrPointerBufferSize
,
270 NdrPointerBufferSize
, NdrPointerBufferSize
,
272 NdrSimpleStructBufferSize
, NdrSimpleStructBufferSize
,
273 NdrConformantStructBufferSize
, NdrConformantStructBufferSize
,
274 NdrConformantVaryingStructBufferSize
,
275 NdrComplexStructBufferSize
,
277 NdrConformantArrayBufferSize
,
278 NdrConformantVaryingArrayBufferSize
,
279 NdrFixedArrayBufferSize
, NdrFixedArrayBufferSize
,
280 NdrVaryingArrayBufferSize
, NdrVaryingArrayBufferSize
,
281 NdrComplexArrayBufferSize
,
283 NdrConformantStringBufferSize
, 0, 0,
284 NdrConformantStringBufferSize
,
285 NdrNonConformantStringBufferSize
, 0, 0, 0,
287 NdrEncapsulatedUnionBufferSize
,
288 NdrNonEncapsulatedUnionBufferSize
,
289 NdrByteCountPointerBufferSize
,
290 NdrXmitOrRepAsBufferSize
, NdrXmitOrRepAsBufferSize
,
292 NdrInterfacePointerBufferSize
,
294 NdrContextHandleBufferSize
,
297 NdrUserMarshalBufferSize
,
301 NdrBaseTypeBufferSize
,
302 NdrBaseTypeBufferSize
304 const NDR_MEMORYSIZE NdrMemorySizer
[NDR_TABLE_SIZE
] = {
306 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
307 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
308 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
309 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
311 NdrBaseTypeMemorySize
,
313 NdrPointerMemorySize
, NdrPointerMemorySize
,
314 NdrPointerMemorySize
, NdrPointerMemorySize
,
316 NdrSimpleStructMemorySize
, NdrSimpleStructMemorySize
,
317 NdrConformantStructMemorySize
, NdrConformantStructMemorySize
,
318 NdrConformantVaryingStructMemorySize
,
319 NdrComplexStructMemorySize
,
321 NdrConformantArrayMemorySize
,
322 NdrConformantVaryingArrayMemorySize
,
323 NdrFixedArrayMemorySize
, NdrFixedArrayMemorySize
,
324 NdrVaryingArrayMemorySize
, NdrVaryingArrayMemorySize
,
325 NdrComplexArrayMemorySize
,
327 NdrConformantStringMemorySize
, 0, 0,
328 NdrConformantStringMemorySize
,
329 NdrNonConformantStringMemorySize
, 0, 0, 0,
331 NdrEncapsulatedUnionMemorySize
,
332 NdrNonEncapsulatedUnionMemorySize
,
333 NdrByteCountPointerMemorySize
,
334 NdrXmitOrRepAsMemorySize
, NdrXmitOrRepAsMemorySize
,
336 NdrInterfacePointerMemorySize
,
341 NdrUserMarshalMemorySize
,
345 NdrBaseTypeMemorySize
,
346 NdrBaseTypeMemorySize
348 const NDR_FREE NdrFreer
[NDR_TABLE_SIZE
] = {
350 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
351 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
352 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
353 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
357 NdrPointerFree
, NdrPointerFree
,
358 NdrPointerFree
, NdrPointerFree
,
360 NdrSimpleStructFree
, NdrSimpleStructFree
,
361 NdrConformantStructFree
, NdrConformantStructFree
,
362 NdrConformantVaryingStructFree
,
363 NdrComplexStructFree
,
365 NdrConformantArrayFree
,
366 NdrConformantVaryingArrayFree
,
367 NdrFixedArrayFree
, NdrFixedArrayFree
,
368 NdrVaryingArrayFree
, NdrVaryingArrayFree
,
374 NdrEncapsulatedUnionFree
,
375 NdrNonEncapsulatedUnionFree
,
377 NdrXmitOrRepAsFree
, NdrXmitOrRepAsFree
,
379 NdrInterfacePointerFree
,
392 typedef struct _NDR_MEMORY_LIST
397 struct _NDR_MEMORY_LIST
*next
;
400 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
402 /***********************************************************************
403 * NdrAllocate [RPCRT4.@]
405 * Allocates a block of memory using pStubMsg->pfnAllocate.
408 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
409 * len [I] Size of memory block to allocate.
412 * The memory block of size len that was allocated.
415 * The memory block is always 8-byte aligned.
416 * If the function is unable to allocate memory an RPC_X_NO_MEMORY
417 * exception is raised.
419 void * WINAPI
NdrAllocate(MIDL_STUB_MESSAGE
*pStubMsg
, SIZE_T len
)
424 NDR_MEMORY_LIST
*mem_list
;
426 aligned_len
= (len
+ 7) & ~7;
427 adjusted_len
= aligned_len
+ sizeof(NDR_MEMORY_LIST
);
428 /* check for overflow */
429 if (adjusted_len
< len
)
431 ERR("overflow of adjusted_len %ld, len %ld\n", adjusted_len
, len
);
432 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
435 p
= pStubMsg
->pfnAllocate(adjusted_len
);
436 if (!p
) RpcRaiseException(RPC_X_NO_MEMORY
);
438 mem_list
= (NDR_MEMORY_LIST
*)((char *)p
+ aligned_len
);
439 mem_list
->magic
= MEML_MAGIC
;
440 mem_list
->size
= aligned_len
;
441 mem_list
->reserved
= 0;
442 mem_list
->next
= pStubMsg
->pMemoryList
;
443 pStubMsg
->pMemoryList
= mem_list
;
449 static void *NdrAllocateZero(MIDL_STUB_MESSAGE
*stubmsg
, SIZE_T len
)
451 void *mem
= NdrAllocate(stubmsg
, len
);
456 static void NdrFree(MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *Pointer
)
458 TRACE("(%p, %p)\n", pStubMsg
, Pointer
);
460 pStubMsg
->pfnFree(Pointer
);
463 static inline BOOL
IsConformanceOrVariancePresent(PFORMAT_STRING pFormat
)
465 return (*(const ULONG
*)pFormat
!= -1);
468 static inline PFORMAT_STRING
SkipConformance(const PMIDL_STUB_MESSAGE pStubMsg
, const PFORMAT_STRING pFormat
)
470 return pFormat
+ 4 + pStubMsg
->CorrDespIncrement
;
473 static PFORMAT_STRING
ReadConformance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
)
475 align_pointer(&pStubMsg
->Buffer
, 4);
476 if (pStubMsg
->Buffer
+ 4 > pStubMsg
->BufferEnd
)
477 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
478 pStubMsg
->MaxCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
479 pStubMsg
->Buffer
+= 4;
480 TRACE("unmarshalled conformance is %ld\n", pStubMsg
->MaxCount
);
481 return SkipConformance(pStubMsg
, pFormat
);
484 static inline PFORMAT_STRING
ReadVariance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
, ULONG MaxValue
)
486 if (pFormat
&& !IsConformanceOrVariancePresent(pFormat
))
488 pStubMsg
->Offset
= 0;
489 pStubMsg
->ActualCount
= pStubMsg
->MaxCount
;
493 align_pointer(&pStubMsg
->Buffer
, 4);
494 if (pStubMsg
->Buffer
+ 8 > pStubMsg
->BufferEnd
)
495 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
496 pStubMsg
->Offset
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
497 pStubMsg
->Buffer
+= 4;
498 TRACE("offset is %d\n", pStubMsg
->Offset
);
499 pStubMsg
->ActualCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
500 pStubMsg
->Buffer
+= 4;
501 TRACE("variance is %d\n", pStubMsg
->ActualCount
);
503 if ((pStubMsg
->ActualCount
> MaxValue
) ||
504 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> MaxValue
))
506 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
507 pStubMsg
->ActualCount
, pStubMsg
->Offset
, MaxValue
);
508 RpcRaiseException(RPC_S_INVALID_BOUND
);
513 return SkipConformance(pStubMsg
, pFormat
);
516 /* writes the conformance value to the buffer */
517 static inline void WriteConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
519 align_pointer_clear(&pStubMsg
->Buffer
, 4);
520 if (pStubMsg
->Buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
521 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
522 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->MaxCount
);
523 pStubMsg
->Buffer
+= 4;
526 /* writes the variance values to the buffer */
527 static inline void WriteVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
529 align_pointer_clear(&pStubMsg
->Buffer
, 4);
530 if (pStubMsg
->Buffer
+ 8 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
531 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
532 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->Offset
);
533 pStubMsg
->Buffer
+= 4;
534 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->ActualCount
);
535 pStubMsg
->Buffer
+= 4;
538 /* requests buffer space for the conformance value */
539 static inline void SizeConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
541 align_length(&pStubMsg
->BufferLength
, 4);
542 if (pStubMsg
->BufferLength
+ 4 < pStubMsg
->BufferLength
)
543 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
544 pStubMsg
->BufferLength
+= 4;
547 /* requests buffer space for the variance values */
548 static inline void SizeVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
550 align_length(&pStubMsg
->BufferLength
, 4);
551 if (pStubMsg
->BufferLength
+ 8 < pStubMsg
->BufferLength
)
552 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
553 pStubMsg
->BufferLength
+= 8;
556 PFORMAT_STRING
ComputeConformanceOrVariance(
557 MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *pMemory
,
558 PFORMAT_STRING pFormat
, ULONG_PTR def
, ULONG_PTR
*pCount
)
560 BYTE dtype
= pFormat
[0] & 0xf;
561 short ofs
= *(const short *)&pFormat
[2];
565 if (!IsConformanceOrVariancePresent(pFormat
)) {
566 /* null descriptor */
571 switch (pFormat
[0] & 0xf0) {
572 case FC_NORMAL_CONFORMANCE
:
573 TRACE("normal conformance, ofs=%d\n", ofs
);
576 case FC_POINTER_CONFORMANCE
:
577 TRACE("pointer conformance, ofs=%d\n", ofs
);
578 ptr
= pStubMsg
->Memory
;
580 case FC_TOP_LEVEL_CONFORMANCE
:
581 TRACE("toplevel conformance, ofs=%d\n", ofs
);
582 if (pStubMsg
->StackTop
) {
583 ptr
= pStubMsg
->StackTop
;
586 /* -Os mode, *pCount is already set */
590 case FC_CONSTANT_CONFORMANCE
:
591 data
= ofs
| ((DWORD
)pFormat
[1] << 16);
592 TRACE("constant conformance, val=%ld\n", data
);
595 case FC_TOP_LEVEL_MULTID_CONFORMANCE
:
596 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs
);
597 if (pStubMsg
->StackTop
) {
598 ptr
= pStubMsg
->StackTop
;
606 FIXME("unknown conformance type %x, expect crash.\n", pFormat
[0] & 0xf0);
610 switch (pFormat
[1]) {
612 ptr
= *(LPVOID
*)((char *)ptr
+ ofs
);
616 unsigned char *old_stack_top
= pStubMsg
->StackTop
;
617 ULONG_PTR max_count
, old_max_count
= pStubMsg
->MaxCount
;
619 pStubMsg
->StackTop
= ptr
;
621 /* ofs is index into StubDesc->apfnExprEval */
622 TRACE("callback conformance into apfnExprEval[%d]\n", ofs
);
623 pStubMsg
->StubDesc
->apfnExprEval
[ofs
](pStubMsg
);
625 pStubMsg
->StackTop
= old_stack_top
;
627 /* the callback function always stores the computed value in MaxCount */
628 max_count
= pStubMsg
->MaxCount
;
629 pStubMsg
->MaxCount
= old_max_count
;
634 ptr
= (char *)ptr
+ ofs
;
647 data
= *(USHORT
*)ptr
;
658 data
= *(ULONGLONG
*)ptr
;
661 FIXME("unknown conformance data type %x\n", dtype
);
664 TRACE("dereferenced data type %x at %p, got %ld\n", dtype
, ptr
, data
);
667 switch (pFormat
[1]) {
668 case FC_DEREFERENCE
: /* already handled */
685 FIXME("unknown conformance op %d\n", pFormat
[1]);
690 TRACE("resulting conformance is %ld\n", *pCount
);
692 return SkipConformance(pStubMsg
, pFormat
);
695 static inline PFORMAT_STRING
SkipVariance(PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
697 return SkipConformance( pStubMsg
, pFormat
);
700 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
701 * the result overflows 32-bits */
702 static inline ULONG
safe_multiply(ULONG a
, ULONG b
)
704 ULONGLONG ret
= (ULONGLONG
)a
* b
;
705 if (ret
> 0xffffffff)
707 RpcRaiseException(RPC_S_INVALID_BOUND
);
713 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
715 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
716 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
717 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
718 pStubMsg
->Buffer
+= size
;
721 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
723 if (pStubMsg
->BufferLength
+ size
< pStubMsg
->BufferLength
) /* integer overflow of pStubMsg->BufferSize */
725 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
726 pStubMsg
->BufferLength
, size
);
727 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
729 pStubMsg
->BufferLength
+= size
;
732 /* copies data from the buffer, checking that there is enough data in the buffer
734 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, void *p
, ULONG size
)
736 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
737 (pStubMsg
->Buffer
+ size
> pStubMsg
->BufferEnd
))
739 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
740 pStubMsg
->Buffer
, pStubMsg
->BufferEnd
, size
);
741 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
743 if (p
== pStubMsg
->Buffer
)
744 ERR("pointer is the same as the buffer\n");
745 memcpy(p
, pStubMsg
->Buffer
, size
);
746 pStubMsg
->Buffer
+= size
;
749 /* copies data to the buffer, checking that there is enough space to do so */
750 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, const void *p
, ULONG size
)
752 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
753 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
755 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
756 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
,
758 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
760 memcpy(pStubMsg
->Buffer
, p
, size
);
761 pStubMsg
->Buffer
+= size
;
764 /* verify that string data sitting in the buffer is valid and safe to
766 static void validate_string_data(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG bufsize
, ULONG esize
)
770 /* verify the buffer is safe to access */
771 if ((pStubMsg
->Buffer
+ bufsize
< pStubMsg
->Buffer
) ||
772 (pStubMsg
->Buffer
+ bufsize
> pStubMsg
->BufferEnd
))
774 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize
,
775 pStubMsg
->BufferEnd
, pStubMsg
->Buffer
);
776 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
779 /* strings must always have null terminating bytes */
782 ERR("invalid string length of %d\n", bufsize
/ esize
);
783 RpcRaiseException(RPC_S_INVALID_BOUND
);
786 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
787 if (pStubMsg
->Buffer
[i
] != 0)
789 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
790 i
, pStubMsg
->Buffer
[i
]);
791 RpcRaiseException(RPC_S_INVALID_BOUND
);
795 static inline void dump_pointer_attr(unsigned char attr
)
797 if (attr
& FC_ALLOCATE_ALL_NODES
)
798 TRACE(" FC_ALLOCATE_ALL_NODES");
799 if (attr
& FC_DONT_FREE
)
800 TRACE(" FC_DONT_FREE");
801 if (attr
& FC_ALLOCED_ON_STACK
)
802 TRACE(" FC_ALLOCED_ON_STACK");
803 if (attr
& FC_SIMPLE_POINTER
)
804 TRACE(" FC_SIMPLE_POINTER");
805 if (attr
& FC_POINTER_DEREF
)
806 TRACE(" FC_POINTER_DEREF");
810 /***********************************************************************
811 * PointerMarshall [internal]
813 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
814 unsigned char *Buffer
,
815 unsigned char *Pointer
,
816 PFORMAT_STRING pFormat
)
818 unsigned type
= pFormat
[0], attr
= pFormat
[1];
822 BOOL pointer_needs_marshaling
;
824 TRACE("(%p,%p,%p,%p)\n", pStubMsg
, Buffer
, Pointer
, pFormat
);
825 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
827 if (attr
& FC_SIMPLE_POINTER
) desc
= pFormat
;
828 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
831 case FC_RP
: /* ref pointer (always non-null) */
834 ERR("NULL ref pointer is not allowed\n");
835 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
837 pointer_needs_marshaling
= TRUE
;
839 case FC_UP
: /* unique pointer */
840 case FC_OP
: /* object pointer - same as unique here */
842 pointer_needs_marshaling
= TRUE
;
844 pointer_needs_marshaling
= FALSE
;
845 pointer_id
= Pointer
? NDR_POINTER_ID(pStubMsg
) : 0;
846 TRACE("writing 0x%08x to buffer\n", pointer_id
);
847 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
850 pointer_needs_marshaling
= !NdrFullPointerQueryPointer(
851 pStubMsg
->FullPtrXlatTables
, Pointer
, 1, &pointer_id
);
852 TRACE("writing 0x%08x to buffer\n", pointer_id
);
853 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
856 FIXME("unhandled ptr type=%02x\n", type
);
857 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
861 TRACE("calling marshaller for type 0x%x\n", (int)*desc
);
863 if (pointer_needs_marshaling
) {
864 if (attr
& FC_POINTER_DEREF
) {
865 Pointer
= *(unsigned char**)Pointer
;
866 TRACE("deref => %p\n", Pointer
);
868 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
869 if (m
) m(pStubMsg
, Pointer
, desc
);
870 else FIXME("no marshaller for data type=%02x\n", *desc
);
873 STD_OVERFLOW_CHECK(pStubMsg
);
876 /* pPointer is the pointer that we will unmarshal into; pSrcPointer is the
877 * pointer to memory which we may attempt to reuse if non-NULL. Usually these
878 * are the same; for the case when they aren't, see EmbeddedPointerUnmarshall().
880 * fMustAlloc seems to determine whether we can allocate from the buffer (if we
881 * are on the server side). It's ignored here, since we can't allocate a pointer
882 * from the buffer. */
883 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
884 unsigned char *Buffer
,
885 unsigned char **pPointer
,
886 unsigned char *pSrcPointer
,
887 PFORMAT_STRING pFormat
,
888 unsigned char fMustAlloc
)
890 unsigned type
= pFormat
[0], attr
= pFormat
[1];
893 DWORD pointer_id
= 0;
894 BOOL pointer_needs_unmarshaling
, need_alloc
= FALSE
, inner_must_alloc
= FALSE
;
896 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg
, Buffer
, pPointer
, pSrcPointer
, pFormat
, fMustAlloc
);
897 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
899 if (attr
& FC_SIMPLE_POINTER
) desc
= pFormat
;
900 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
903 case FC_RP
: /* ref pointer (always non-null) */
904 pointer_needs_unmarshaling
= TRUE
;
906 case FC_UP
: /* unique pointer */
907 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
908 TRACE("pointer_id is 0x%08x\n", pointer_id
);
910 pointer_needs_unmarshaling
= TRUE
;
913 pointer_needs_unmarshaling
= FALSE
;
916 case FC_OP
: /* object pointer - we must free data before overwriting it */
917 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
918 TRACE("pointer_id is 0x%08x\n", pointer_id
);
920 /* An object pointer always allocates new memory (it cannot point to the
922 inner_must_alloc
= TRUE
;
925 FIXME("free object pointer %p\n", pSrcPointer
);
927 pointer_needs_unmarshaling
= TRUE
;
931 pointer_needs_unmarshaling
= FALSE
;
935 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
936 TRACE("pointer_id is 0x%08x\n", pointer_id
);
937 pointer_needs_unmarshaling
= !NdrFullPointerQueryRefId(
938 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, (void **)pPointer
);
941 FIXME("unhandled ptr type=%02x\n", type
);
942 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
946 if (pointer_needs_unmarshaling
) {
947 unsigned char **current_ptr
= pPointer
;
948 if (pStubMsg
->IsClient
) {
950 /* Try to use the existing (source) pointer to unmarshall the data into
951 * so that [in, out] or [out, ref] parameters behave correctly. If the
952 * source pointer is NULL and we are not dereferencing, we must force the
953 * inner marshalling routine to allocate, since otherwise it will crash. */
956 TRACE("setting *pPointer to %p\n", pSrcPointer
);
957 *pPointer
= pSrcPointer
;
960 need_alloc
= inner_must_alloc
= TRUE
;
963 /* We can use an existing source pointer here only if it is on-stack,
964 * probably since otherwise NdrPointerFree() might later try to free a
965 * pointer we don't know the provenance of. Otherwise we must always
966 * allocate if we are dereferencing. We never need to force the inner
967 * routine to allocate here, since it will either write into an existing
968 * pointer, or use a pointer to the buffer. */
969 if (attr
& FC_POINTER_DEREF
)
971 if (pSrcPointer
&& (attr
& FC_ALLOCED_ON_STACK
))
972 *pPointer
= pSrcPointer
;
980 if (attr
& FC_ALLOCATE_ALL_NODES
)
981 FIXME("FC_ALLOCATE_ALL_NODES not implemented\n");
983 if (attr
& FC_POINTER_DEREF
) {
985 *pPointer
= NdrAllocateZero(pStubMsg
, sizeof(void *));
987 current_ptr
= *(unsigned char***)current_ptr
;
988 TRACE("deref => %p\n", current_ptr
);
990 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
991 if (m
) m(pStubMsg
, current_ptr
, desc
, inner_must_alloc
);
992 else FIXME("no unmarshaller for data type=%02x\n", *desc
);
995 NdrFullPointerInsertRefId(pStubMsg
->FullPtrXlatTables
, pointer_id
,
999 TRACE("pointer=%p\n", *pPointer
);
1002 /***********************************************************************
1003 * PointerBufferSize [internal]
1005 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1006 unsigned char *Pointer
,
1007 PFORMAT_STRING pFormat
)
1009 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1010 PFORMAT_STRING desc
;
1012 BOOL pointer_needs_sizing
;
1015 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1016 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1018 if (attr
& FC_SIMPLE_POINTER
) desc
= pFormat
;
1019 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1022 case FC_RP
: /* ref pointer (always non-null) */
1025 ERR("NULL ref pointer is not allowed\n");
1026 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
1031 /* NULL pointer has no further representation */
1036 pointer_needs_sizing
= !NdrFullPointerQueryPointer(
1037 pStubMsg
->FullPtrXlatTables
, Pointer
, 0, &pointer_id
);
1038 if (!pointer_needs_sizing
)
1042 FIXME("unhandled ptr type=%02x\n", type
);
1043 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1047 if (attr
& FC_POINTER_DEREF
) {
1048 Pointer
= *(unsigned char**)Pointer
;
1049 TRACE("deref => %p\n", Pointer
);
1052 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
1053 if (m
) m(pStubMsg
, Pointer
, desc
);
1054 else FIXME("no buffersizer for data type=%02x\n", *desc
);
1057 /***********************************************************************
1058 * PointerMemorySize [internal]
1060 static ULONG
PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1061 unsigned char *Buffer
, PFORMAT_STRING pFormat
)
1063 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1064 PFORMAT_STRING desc
;
1066 DWORD pointer_id
= 0;
1067 BOOL pointer_needs_sizing
;
1069 TRACE("(%p,%p,%p)\n", pStubMsg
, Buffer
, pFormat
);
1070 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1072 if (attr
& FC_SIMPLE_POINTER
) desc
= pFormat
;
1073 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1076 case FC_RP
: /* ref pointer (always non-null) */
1077 pointer_needs_sizing
= TRUE
;
1079 case FC_UP
: /* unique pointer */
1080 case FC_OP
: /* object pointer - we must free data before overwriting it */
1081 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1082 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1084 pointer_needs_sizing
= TRUE
;
1086 pointer_needs_sizing
= FALSE
;
1091 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1092 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1093 pointer_needs_sizing
= !NdrFullPointerQueryRefId(
1094 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, &pointer
);
1098 FIXME("unhandled ptr type=%02x\n", type
);
1099 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1103 if (attr
& FC_POINTER_DEREF
) {
1104 align_length(&pStubMsg
->MemorySize
, sizeof(void*));
1105 pStubMsg
->MemorySize
+= sizeof(void*);
1109 if (pointer_needs_sizing
) {
1110 m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
1111 if (m
) m(pStubMsg
, desc
);
1112 else FIXME("no memorysizer for data type=%02x\n", *desc
);
1115 return pStubMsg
->MemorySize
;
1118 /***********************************************************************
1119 * PointerFree [internal]
1121 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1122 unsigned char *Pointer
,
1123 PFORMAT_STRING pFormat
)
1125 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1126 PFORMAT_STRING desc
;
1128 unsigned char *current_pointer
= Pointer
;
1130 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1131 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1132 if (attr
& FC_DONT_FREE
) return;
1134 if (attr
& FC_SIMPLE_POINTER
) desc
= pFormat
;
1135 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1137 if (!Pointer
) return;
1139 if (type
== FC_FP
) {
1140 int pointer_needs_freeing
= NdrFullPointerFree(
1141 pStubMsg
->FullPtrXlatTables
, Pointer
);
1142 if (!pointer_needs_freeing
)
1146 if (attr
& FC_POINTER_DEREF
) {
1147 current_pointer
= *(unsigned char**)Pointer
;
1148 TRACE("deref => %p\n", current_pointer
);
1151 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
1152 if (m
) m(pStubMsg
, current_pointer
, desc
);
1154 /* this check stops us from trying to free buffer memory. we don't have to
1155 * worry about clients, since they won't call this function.
1156 * we don't have to check for the buffer being reallocated because
1157 * BufferStart and BufferEnd won't be reset when allocating memory for
1158 * sending the response. we don't have to check for the new buffer here as
1159 * it won't be used a type memory, only for buffer memory */
1160 if (Pointer
>= pStubMsg
->BufferStart
&& Pointer
<= pStubMsg
->BufferEnd
)
1163 if (attr
& FC_ALLOCED_ON_STACK
) {
1164 TRACE("not freeing stack ptr %p\n", Pointer
);
1167 TRACE("freeing %p\n", Pointer
);
1168 NdrFree(pStubMsg
, Pointer
);
1171 TRACE("not freeing %p\n", Pointer
);
1174 /***********************************************************************
1175 * EmbeddedPointerMarshall
1177 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1178 unsigned char *pMemory
,
1179 PFORMAT_STRING pFormat
)
1181 unsigned char *Mark
= pStubMsg
->BufferMark
;
1182 unsigned rep
, count
, stride
;
1184 unsigned char *saved_buffer
= NULL
;
1186 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1188 if (*pFormat
!= FC_PP
) return NULL
;
1191 if (pStubMsg
->PointerBufferMark
)
1193 saved_buffer
= pStubMsg
->Buffer
;
1194 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1195 pStubMsg
->PointerBufferMark
= NULL
;
1198 while (pFormat
[0] != FC_END
) {
1199 switch (pFormat
[0]) {
1201 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat
[0]);
1209 case FC_FIXED_REPEAT
:
1210 rep
= *(const WORD
*)&pFormat
[2];
1211 stride
= *(const WORD
*)&pFormat
[4];
1212 count
= *(const WORD
*)&pFormat
[8];
1215 case FC_VARIABLE_REPEAT
:
1216 rep
= (pFormat
[1] == FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1217 stride
= *(const WORD
*)&pFormat
[2];
1218 count
= *(const WORD
*)&pFormat
[6];
1222 for (i
= 0; i
< rep
; i
++) {
1223 PFORMAT_STRING info
= pFormat
;
1224 unsigned char *membase
= pMemory
+ (i
* stride
);
1225 unsigned char *bufbase
= Mark
+ (i
* stride
);
1228 for (u
=0; u
<count
; u
++,info
+=8) {
1229 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1230 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1231 unsigned char *saved_memory
= pStubMsg
->Memory
;
1233 pStubMsg
->Memory
= membase
;
1234 PointerMarshall(pStubMsg
, bufptr
, *(unsigned char**)memptr
, info
+4);
1235 pStubMsg
->Memory
= saved_memory
;
1238 pFormat
+= 8 * count
;
1243 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1244 pStubMsg
->Buffer
= saved_buffer
;
1247 STD_OVERFLOW_CHECK(pStubMsg
);
1252 /* rpcrt4 does something bizarre with embedded pointers: instead of copying the
1253 * struct/array/union from the buffer to memory and then unmarshalling pointers
1254 * into it, it unmarshals pointers into the buffer itself and then copies it to
1255 * memory. However, it will still attempt to use a user-supplied pointer where
1256 * appropriate (i.e. one on stack). Therefore we need to pass both pointers to
1257 * this function and to PointerUnmarshall: the pointer (to the buffer) that we
1258 * will actually unmarshal into (pDstBuffer), and the pointer (to memory) that
1259 * we will attempt to use for storage if possible (pSrcMemoryPtrs). */
1260 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1261 unsigned char *pDstBuffer
,
1262 unsigned char *pSrcMemoryPtrs
,
1263 PFORMAT_STRING pFormat
,
1264 unsigned char fMustAlloc
)
1266 unsigned char *Mark
= pStubMsg
->BufferMark
;
1267 unsigned rep
, count
, stride
;
1269 unsigned char *saved_buffer
= NULL
;
1271 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg
, pDstBuffer
, pSrcMemoryPtrs
, pFormat
, fMustAlloc
);
1273 if (*pFormat
!= FC_PP
) return NULL
;
1276 if (pStubMsg
->PointerBufferMark
)
1278 saved_buffer
= pStubMsg
->Buffer
;
1279 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1280 pStubMsg
->PointerBufferMark
= NULL
;
1283 while (pFormat
[0] != FC_END
) {
1284 TRACE("pFormat[0] = 0x%x\n", pFormat
[0]);
1285 switch (pFormat
[0]) {
1287 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat
[0]);
1295 case FC_FIXED_REPEAT
:
1296 rep
= *(const WORD
*)&pFormat
[2];
1297 stride
= *(const WORD
*)&pFormat
[4];
1298 count
= *(const WORD
*)&pFormat
[8];
1301 case FC_VARIABLE_REPEAT
:
1302 rep
= (pFormat
[1] == FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1303 stride
= *(const WORD
*)&pFormat
[2];
1304 count
= *(const WORD
*)&pFormat
[6];
1308 for (i
= 0; i
< rep
; i
++) {
1309 PFORMAT_STRING info
= pFormat
;
1310 unsigned char *bufdstbase
= pDstBuffer
+ (i
* stride
);
1311 unsigned char *memsrcbase
= pSrcMemoryPtrs
+ (i
* stride
);
1312 unsigned char *bufbase
= Mark
+ (i
* stride
);
1315 for (u
=0; u
<count
; u
++,info
+=8) {
1316 unsigned char **bufdstptr
= (unsigned char **)(bufdstbase
+ *(const SHORT
*)&info
[2]);
1317 unsigned char **memsrcptr
= (unsigned char **)(memsrcbase
+ *(const SHORT
*)&info
[0]);
1318 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1319 PointerUnmarshall(pStubMsg
, bufptr
, bufdstptr
, *memsrcptr
, info
+4, fMustAlloc
);
1322 pFormat
+= 8 * count
;
1327 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1328 pStubMsg
->Buffer
= saved_buffer
;
1334 /***********************************************************************
1335 * EmbeddedPointerBufferSize
1337 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1338 unsigned char *pMemory
,
1339 PFORMAT_STRING pFormat
)
1341 unsigned rep
, count
, stride
;
1343 ULONG saved_buffer_length
= 0;
1345 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1347 if (pStubMsg
->IgnoreEmbeddedPointers
) return;
1349 if (*pFormat
!= FC_PP
) return;
1352 if (pStubMsg
->PointerLength
)
1354 saved_buffer_length
= pStubMsg
->BufferLength
;
1355 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
1356 pStubMsg
->PointerLength
= 0;
1359 while (pFormat
[0] != FC_END
) {
1360 switch (pFormat
[0]) {
1362 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat
[0]);
1370 case FC_FIXED_REPEAT
:
1371 rep
= *(const WORD
*)&pFormat
[2];
1372 stride
= *(const WORD
*)&pFormat
[4];
1373 count
= *(const WORD
*)&pFormat
[8];
1376 case FC_VARIABLE_REPEAT
:
1377 rep
= (pFormat
[1] == FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1378 stride
= *(const WORD
*)&pFormat
[2];
1379 count
= *(const WORD
*)&pFormat
[6];
1383 for (i
= 0; i
< rep
; i
++) {
1384 PFORMAT_STRING info
= pFormat
;
1385 unsigned char *membase
= pMemory
+ (i
* stride
);
1388 for (u
=0; u
<count
; u
++,info
+=8) {
1389 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1390 unsigned char *saved_memory
= pStubMsg
->Memory
;
1392 pStubMsg
->Memory
= membase
;
1393 PointerBufferSize(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1394 pStubMsg
->Memory
= saved_memory
;
1397 pFormat
+= 8 * count
;
1400 if (saved_buffer_length
)
1402 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
1403 pStubMsg
->BufferLength
= saved_buffer_length
;
1407 /***********************************************************************
1408 * EmbeddedPointerMemorySize [internal]
1410 static ULONG
EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1411 PFORMAT_STRING pFormat
)
1413 unsigned char *Mark
= pStubMsg
->BufferMark
;
1414 unsigned rep
, count
, stride
;
1416 unsigned char *saved_buffer
= NULL
;
1418 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1420 if (pStubMsg
->IgnoreEmbeddedPointers
) return 0;
1422 if (pStubMsg
->PointerBufferMark
)
1424 saved_buffer
= pStubMsg
->Buffer
;
1425 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1426 pStubMsg
->PointerBufferMark
= NULL
;
1429 if (*pFormat
!= FC_PP
) return 0;
1432 while (pFormat
[0] != FC_END
) {
1433 switch (pFormat
[0]) {
1435 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat
[0]);
1443 case FC_FIXED_REPEAT
:
1444 rep
= *(const WORD
*)&pFormat
[2];
1445 stride
= *(const WORD
*)&pFormat
[4];
1446 count
= *(const WORD
*)&pFormat
[8];
1449 case FC_VARIABLE_REPEAT
:
1450 rep
= (pFormat
[1] == FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1451 stride
= *(const WORD
*)&pFormat
[2];
1452 count
= *(const WORD
*)&pFormat
[6];
1456 for (i
= 0; i
< rep
; i
++) {
1457 PFORMAT_STRING info
= pFormat
;
1458 unsigned char *bufbase
= Mark
+ (i
* stride
);
1460 for (u
=0; u
<count
; u
++,info
+=8) {
1461 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1462 PointerMemorySize(pStubMsg
, bufptr
, info
+4);
1465 pFormat
+= 8 * count
;
1470 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1471 pStubMsg
->Buffer
= saved_buffer
;
1477 /***********************************************************************
1478 * EmbeddedPointerFree [internal]
1480 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1481 unsigned char *pMemory
,
1482 PFORMAT_STRING pFormat
)
1484 unsigned rep
, count
, stride
;
1487 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1488 if (*pFormat
!= FC_PP
) return;
1491 while (pFormat
[0] != FC_END
) {
1492 switch (pFormat
[0]) {
1494 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat
[0]);
1502 case FC_FIXED_REPEAT
:
1503 rep
= *(const WORD
*)&pFormat
[2];
1504 stride
= *(const WORD
*)&pFormat
[4];
1505 count
= *(const WORD
*)&pFormat
[8];
1508 case FC_VARIABLE_REPEAT
:
1509 rep
= (pFormat
[1] == FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1510 stride
= *(const WORD
*)&pFormat
[2];
1511 count
= *(const WORD
*)&pFormat
[6];
1515 for (i
= 0; i
< rep
; i
++) {
1516 PFORMAT_STRING info
= pFormat
;
1517 unsigned char *membase
= pMemory
+ (i
* stride
);
1520 for (u
=0; u
<count
; u
++,info
+=8) {
1521 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1522 unsigned char *saved_memory
= pStubMsg
->Memory
;
1524 pStubMsg
->Memory
= membase
;
1525 PointerFree(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1526 pStubMsg
->Memory
= saved_memory
;
1529 pFormat
+= 8 * count
;
1533 /***********************************************************************
1534 * NdrPointerMarshall [RPCRT4.@]
1536 unsigned char * WINAPI
NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1537 unsigned char *pMemory
,
1538 PFORMAT_STRING pFormat
)
1540 unsigned char *Buffer
;
1542 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1544 /* Increment the buffer here instead of in PointerMarshall,
1545 * as that is used by embedded pointers which already handle the incrementing
1546 * the buffer, and shouldn't write any additional pointer data to the wire */
1547 if (*pFormat
!= FC_RP
)
1549 align_pointer_clear(&pStubMsg
->Buffer
, 4);
1550 Buffer
= pStubMsg
->Buffer
;
1551 safe_buffer_increment(pStubMsg
, 4);
1554 Buffer
= pStubMsg
->Buffer
;
1556 PointerMarshall(pStubMsg
, Buffer
, pMemory
, pFormat
);
1561 /***********************************************************************
1562 * NdrPointerUnmarshall [RPCRT4.@]
1564 unsigned char * WINAPI
NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1565 unsigned char **ppMemory
,
1566 PFORMAT_STRING pFormat
,
1567 unsigned char fMustAlloc
)
1569 unsigned char *Buffer
;
1571 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1573 if (*pFormat
== FC_RP
)
1575 Buffer
= pStubMsg
->Buffer
;
1576 /* Do the NULL ref pointer check here because embedded pointers can be
1577 * NULL if the type the pointer is embedded in was allocated rather than
1578 * being passed in by the client */
1579 if (pStubMsg
->IsClient
&& !*ppMemory
)
1581 ERR("NULL ref pointer is not allowed\n");
1582 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
1587 /* Increment the buffer here instead of in PointerUnmarshall,
1588 * as that is used by embedded pointers which already handle the incrementing
1589 * the buffer, and shouldn't read any additional pointer data from the
1591 align_pointer(&pStubMsg
->Buffer
, 4);
1592 Buffer
= pStubMsg
->Buffer
;
1593 safe_buffer_increment(pStubMsg
, 4);
1596 PointerUnmarshall(pStubMsg
, Buffer
, ppMemory
, *ppMemory
, pFormat
, fMustAlloc
);
1601 /***********************************************************************
1602 * NdrPointerBufferSize [RPCRT4.@]
1604 void WINAPI
NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1605 unsigned char *pMemory
,
1606 PFORMAT_STRING pFormat
)
1608 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1610 /* Increment the buffer length here instead of in PointerBufferSize,
1611 * as that is used by embedded pointers which already handle the buffer
1612 * length, and shouldn't write anything more to the wire */
1613 if (*pFormat
!= FC_RP
)
1615 align_length(&pStubMsg
->BufferLength
, 4);
1616 safe_buffer_length_increment(pStubMsg
, 4);
1619 PointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1622 /***********************************************************************
1623 * NdrPointerMemorySize [RPCRT4.@]
1625 ULONG WINAPI
NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1626 PFORMAT_STRING pFormat
)
1628 unsigned char *Buffer
= pStubMsg
->Buffer
;
1629 if (*pFormat
!= FC_RP
)
1631 align_pointer(&pStubMsg
->Buffer
, 4);
1632 safe_buffer_increment(pStubMsg
, 4);
1634 align_length(&pStubMsg
->MemorySize
, sizeof(void *));
1635 return PointerMemorySize(pStubMsg
, Buffer
, pFormat
);
1638 /***********************************************************************
1639 * NdrPointerFree [RPCRT4.@]
1641 void WINAPI
NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1642 unsigned char *pMemory
,
1643 PFORMAT_STRING pFormat
)
1645 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1646 PointerFree(pStubMsg
, pMemory
, pFormat
);
1649 /***********************************************************************
1650 * NdrSimpleTypeMarshall [RPCRT4.@]
1652 void WINAPI
NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1653 unsigned char FormatChar
)
1655 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &FormatChar
);
1658 /***********************************************************************
1659 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1661 * Unmarshall a base type.
1664 * Doesn't check that the buffer is long enough before copying, so the caller
1667 void WINAPI
NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1668 unsigned char FormatChar
)
1670 #define BASE_TYPE_UNMARSHALL(type) \
1671 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
1672 TRACE("pMemory: %p\n", pMemory); \
1673 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1674 pStubMsg->Buffer += sizeof(type);
1682 BASE_TYPE_UNMARSHALL(UCHAR
);
1683 TRACE("value: 0x%02x\n", *pMemory
);
1688 BASE_TYPE_UNMARSHALL(USHORT
);
1689 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
1693 case FC_ERROR_STATUS_T
:
1695 BASE_TYPE_UNMARSHALL(ULONG
);
1696 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
1699 BASE_TYPE_UNMARSHALL(float);
1700 TRACE("value: %f\n", *(float *)pMemory
);
1703 BASE_TYPE_UNMARSHALL(double);
1704 TRACE("value: %f\n", *(double *)pMemory
);
1707 BASE_TYPE_UNMARSHALL(ULONGLONG
);
1708 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
1711 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
1712 TRACE("pMemory: %p\n", pMemory
);
1713 /* 16-bits on the wire, but int in memory */
1714 *(UINT
*)pMemory
= *(USHORT
*)pStubMsg
->Buffer
;
1715 pStubMsg
->Buffer
+= sizeof(USHORT
);
1716 TRACE("value: 0x%08x\n", *(UINT
*)pMemory
);
1719 align_pointer(&pStubMsg
->Buffer
, sizeof(INT
));
1720 /* 32-bits on the wire, but int_ptr in memory */
1721 *(INT_PTR
*)pMemory
= *(INT
*)pStubMsg
->Buffer
;
1722 pStubMsg
->Buffer
+= sizeof(INT
);
1723 TRACE("value: 0x%08lx\n", *(INT_PTR
*)pMemory
);
1726 align_pointer(&pStubMsg
->Buffer
, sizeof(UINT
));
1727 /* 32-bits on the wire, but int_ptr in memory */
1728 *(UINT_PTR
*)pMemory
= *(UINT
*)pStubMsg
->Buffer
;
1729 pStubMsg
->Buffer
+= sizeof(UINT
);
1730 TRACE("value: 0x%08lx\n", *(UINT_PTR
*)pMemory
);
1735 FIXME("Unhandled base type: 0x%02x\n", FormatChar
);
1737 #undef BASE_TYPE_UNMARSHALL
1740 /***********************************************************************
1741 * NdrSimpleStructMarshall [RPCRT4.@]
1743 unsigned char * WINAPI
NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1744 unsigned char *pMemory
,
1745 PFORMAT_STRING pFormat
)
1747 unsigned size
= *(const WORD
*)(pFormat
+2);
1748 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1750 align_pointer_clear(&pStubMsg
->Buffer
, pFormat
[1] + 1);
1752 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1753 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
1755 if (pFormat
[0] != FC_STRUCT
)
1756 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
+4);
1761 /***********************************************************************
1762 * NdrSimpleStructUnmarshall [RPCRT4.@]
1764 unsigned char * WINAPI
NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1765 unsigned char **ppMemory
,
1766 PFORMAT_STRING pFormat
,
1767 unsigned char fMustAlloc
)
1769 unsigned size
= *(const WORD
*)(pFormat
+2);
1770 unsigned char *saved_buffer
;
1771 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1773 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
1776 *ppMemory
= NdrAllocateZero(pStubMsg
, size
);
1779 if (!pStubMsg
->IsClient
&& !*ppMemory
)
1780 /* for servers, we just point straight into the RPC buffer */
1781 *ppMemory
= pStubMsg
->Buffer
;
1784 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1785 safe_buffer_increment(pStubMsg
, size
);
1786 if (pFormat
[0] == FC_PSTRUCT
)
1787 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
+4, fMustAlloc
);
1789 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
1790 if (*ppMemory
!= saved_buffer
)
1791 memcpy(*ppMemory
, saved_buffer
, size
);
1796 /***********************************************************************
1797 * NdrSimpleStructBufferSize [RPCRT4.@]
1799 void WINAPI
NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1800 unsigned char *pMemory
,
1801 PFORMAT_STRING pFormat
)
1803 unsigned size
= *(const WORD
*)(pFormat
+2);
1804 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1806 align_length(&pStubMsg
->BufferLength
, pFormat
[1] + 1);
1808 safe_buffer_length_increment(pStubMsg
, size
);
1809 if (pFormat
[0] != FC_STRUCT
)
1810 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
+4);
1813 /***********************************************************************
1814 * NdrSimpleStructMemorySize [RPCRT4.@]
1816 ULONG WINAPI
NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1817 PFORMAT_STRING pFormat
)
1819 unsigned short size
= *(const WORD
*)(pFormat
+2);
1821 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1823 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
1824 pStubMsg
->MemorySize
+= size
;
1825 safe_buffer_increment(pStubMsg
, size
);
1827 if (pFormat
[0] != FC_STRUCT
)
1828 EmbeddedPointerMemorySize(pStubMsg
, pFormat
+4);
1829 return pStubMsg
->MemorySize
;
1832 /***********************************************************************
1833 * NdrSimpleStructFree [RPCRT4.@]
1835 void WINAPI
NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
1836 unsigned char *pMemory
,
1837 PFORMAT_STRING pFormat
)
1839 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1840 if (pFormat
[0] != FC_STRUCT
)
1841 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
+4);
1846 static inline void array_compute_and_size_conformance(
1847 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1848 PFORMAT_STRING pFormat
)
1855 ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1856 SizeConformance(pStubMsg
);
1859 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, 0);
1860 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
1861 SizeConformance(pStubMsg
);
1865 if (fc
== FC_C_CSTRING
)
1867 TRACE("string=%s\n", debugstr_a((const char *)pMemory
));
1868 pStubMsg
->ActualCount
= strlen((const char *)pMemory
)+1;
1872 TRACE("string=%s\n", debugstr_w((LPCWSTR
)pMemory
));
1873 pStubMsg
->ActualCount
= lstrlenW((LPCWSTR
)pMemory
)+1;
1876 if (pFormat
[1] == FC_STRING_SIZED
)
1877 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
1879 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
1881 SizeConformance(pStubMsg
);
1883 case FC_BOGUS_ARRAY
:
1884 count
= *(const WORD
*)(pFormat
+ 2);
1886 if (IsConformanceOrVariancePresent(pFormat
)) SizeConformance(pStubMsg
);
1887 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, count
);
1888 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
1891 ERR("unknown array format 0x%x\n", fc
);
1892 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1896 static inline void array_buffer_size(
1897 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1898 PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
1902 unsigned char alignment
;
1907 esize
= *(const WORD
*)(pFormat
+2);
1908 alignment
= pFormat
[1] + 1;
1910 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1912 align_length(&pStubMsg
->BufferLength
, alignment
);
1914 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
1915 /* conformance value plus array */
1916 safe_buffer_length_increment(pStubMsg
, size
);
1919 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1922 esize
= *(const WORD
*)(pFormat
+2);
1923 alignment
= pFormat
[1] + 1;
1925 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1926 pFormat
= SkipVariance(pStubMsg
, pFormat
);
1928 SizeVariance(pStubMsg
);
1930 align_length(&pStubMsg
->BufferLength
, alignment
);
1932 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1933 safe_buffer_length_increment(pStubMsg
, size
);
1936 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1940 if (fc
== FC_C_CSTRING
)
1945 SizeVariance(pStubMsg
);
1947 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1948 safe_buffer_length_increment(pStubMsg
, size
);
1950 case FC_BOGUS_ARRAY
:
1951 alignment
= pFormat
[1] + 1;
1952 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1953 if (IsConformanceOrVariancePresent(pFormat
)) SizeVariance(pStubMsg
);
1954 pFormat
= SkipVariance(pStubMsg
, pFormat
);
1956 align_length(&pStubMsg
->BufferLength
, alignment
);
1958 size
= pStubMsg
->ActualCount
;
1959 for (i
= 0; i
< size
; i
++)
1960 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
1963 ERR("unknown array format 0x%x\n", fc
);
1964 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1968 static inline void array_compute_and_write_conformance(
1969 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1970 PFORMAT_STRING pFormat
)
1973 BOOL conformance_present
;
1978 ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1979 WriteConformance(pStubMsg
);
1982 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, 0);
1983 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
1984 WriteConformance(pStubMsg
);
1988 if (fc
== FC_C_CSTRING
)
1990 TRACE("string=%s\n", debugstr_a((const char *)pMemory
));
1991 pStubMsg
->ActualCount
= strlen((const char *)pMemory
)+1;
1995 TRACE("string=%s\n", debugstr_w((LPCWSTR
)pMemory
));
1996 pStubMsg
->ActualCount
= lstrlenW((LPCWSTR
)pMemory
)+1;
1998 if (pFormat
[1] == FC_STRING_SIZED
)
1999 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
2001 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
2002 pStubMsg
->Offset
= 0;
2003 WriteConformance(pStubMsg
);
2005 case FC_BOGUS_ARRAY
:
2006 def
= *(const WORD
*)(pFormat
+ 2);
2008 conformance_present
= IsConformanceOrVariancePresent(pFormat
);
2009 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
2010 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
2011 if (conformance_present
) WriteConformance(pStubMsg
);
2014 ERR("unknown array format 0x%x\n", fc
);
2015 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2019 static inline void array_write_variance_and_marshall(
2020 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
2021 PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
2025 unsigned char alignment
;
2030 esize
= *(const WORD
*)(pFormat
+2);
2031 alignment
= pFormat
[1] + 1;
2033 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2035 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
2037 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2039 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2040 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
2043 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2046 esize
= *(const WORD
*)(pFormat
+2);
2047 alignment
= pFormat
[1] + 1;
2049 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2050 pFormat
= SkipVariance(pStubMsg
, pFormat
);
2052 WriteVariance(pStubMsg
);
2054 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
2056 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2059 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2060 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, size
);
2063 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2067 if (fc
== FC_C_CSTRING
)
2072 WriteVariance(pStubMsg
);
2074 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2075 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
2077 case FC_BOGUS_ARRAY
:
2078 alignment
= pFormat
[1] + 1;
2079 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2080 if (IsConformanceOrVariancePresent(pFormat
)) WriteVariance(pStubMsg
);
2081 pFormat
= SkipVariance(pStubMsg
, pFormat
);
2083 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
2085 size
= pStubMsg
->ActualCount
;
2086 for (i
= 0; i
< size
; i
++)
2087 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
2090 ERR("unknown array format 0x%x\n", fc
);
2091 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2095 static inline ULONG
array_read_conformance(
2096 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
2103 esize
= *(const WORD
*)(pFormat
+2);
2104 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2105 return safe_multiply(esize
, pStubMsg
->MaxCount
);
2107 esize
= *(const WORD
*)(pFormat
+2);
2108 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2109 return safe_multiply(esize
, pStubMsg
->MaxCount
);
2112 if (fc
== FC_C_CSTRING
)
2117 if (pFormat
[1] == FC_STRING_SIZED
)
2118 ReadConformance(pStubMsg
, pFormat
+ 2);
2120 ReadConformance(pStubMsg
, NULL
);
2121 return safe_multiply(esize
, pStubMsg
->MaxCount
);
2122 case FC_BOGUS_ARRAY
:
2123 def
= *(const WORD
*)(pFormat
+ 2);
2125 if (IsConformanceOrVariancePresent(pFormat
)) pFormat
= ReadConformance(pStubMsg
, pFormat
);
2128 pStubMsg
->MaxCount
= def
;
2129 pFormat
= SkipConformance( pStubMsg
, pFormat
);
2131 pFormat
= SkipVariance( pStubMsg
, pFormat
);
2133 esize
= ComplexStructSize(pStubMsg
, pFormat
);
2134 return safe_multiply(pStubMsg
->MaxCount
, esize
);
2136 ERR("unknown array format 0x%x\n", fc
);
2137 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2141 static inline ULONG
array_read_variance_and_unmarshall(
2142 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char **ppMemory
,
2143 PFORMAT_STRING pFormat
, unsigned char fMustAlloc
,
2144 unsigned char fUseBufferMemoryServer
, unsigned char fUnmarshall
)
2146 ULONG bufsize
, memsize
;
2148 unsigned char alignment
;
2149 unsigned char *saved_buffer
, *pMemory
;
2150 ULONG i
, offset
, count
;
2155 esize
= *(const WORD
*)(pFormat
+2);
2156 alignment
= pFormat
[1] + 1;
2158 bufsize
= memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2160 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2162 align_pointer(&pStubMsg
->Buffer
, alignment
);
2167 *ppMemory
= NdrAllocateZero(pStubMsg
, memsize
);
2170 if (fUseBufferMemoryServer
&& !pStubMsg
->IsClient
&& !*ppMemory
)
2171 /* for servers, we just point straight into the RPC buffer */
2172 *ppMemory
= pStubMsg
->Buffer
;
2175 saved_buffer
= pStubMsg
->Buffer
;
2176 safe_buffer_increment(pStubMsg
, bufsize
);
2178 pStubMsg
->BufferMark
= saved_buffer
;
2179 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
2181 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
2182 if (*ppMemory
!= saved_buffer
)
2183 memcpy(*ppMemory
, saved_buffer
, bufsize
);
2187 esize
= *(const WORD
*)(pFormat
+2);
2188 alignment
= pFormat
[1] + 1;
2190 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2192 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2194 align_pointer(&pStubMsg
->Buffer
, alignment
);
2196 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2197 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2201 offset
= pStubMsg
->Offset
;
2203 if (!fMustAlloc
&& !*ppMemory
)
2206 *ppMemory
= NdrAllocateZero(pStubMsg
, memsize
);
2207 saved_buffer
= pStubMsg
->Buffer
;
2208 safe_buffer_increment(pStubMsg
, bufsize
);
2210 pStubMsg
->BufferMark
= saved_buffer
;
2211 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
,
2214 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
2219 if (fc
== FC_C_CSTRING
)
2224 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
2226 if (pFormat
[1] != FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
2228 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2229 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
2230 RpcRaiseException(RPC_S_INVALID_BOUND
);
2232 if (pStubMsg
->Offset
)
2234 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2235 RpcRaiseException(RPC_S_INVALID_BOUND
);
2238 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2239 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2241 validate_string_data(pStubMsg
, bufsize
, esize
);
2246 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2249 if (fUseBufferMemoryServer
&& !pStubMsg
->IsClient
&&
2250 !*ppMemory
&& (pStubMsg
->MaxCount
== pStubMsg
->ActualCount
))
2251 /* if the data in the RPC buffer is big enough, we just point
2252 * straight into it */
2253 *ppMemory
= pStubMsg
->Buffer
;
2254 else if (!*ppMemory
)
2255 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2258 if (*ppMemory
== pStubMsg
->Buffer
)
2259 safe_buffer_increment(pStubMsg
, bufsize
);
2261 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
2263 if (*pFormat
== FC_C_CSTRING
)
2264 TRACE("string=%s\n", debugstr_a((char*)*ppMemory
));
2266 TRACE("string=%s\n", debugstr_w((LPWSTR
)*ppMemory
));
2270 case FC_BOGUS_ARRAY
:
2271 alignment
= pFormat
[1] + 1;
2272 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2273 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2275 esize
= ComplexStructSize(pStubMsg
, pFormat
);
2276 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2278 assert( fUnmarshall
);
2280 if (!fMustAlloc
&& !*ppMemory
)
2283 *ppMemory
= NdrAllocateZero(pStubMsg
, memsize
);
2285 align_pointer(&pStubMsg
->Buffer
, alignment
);
2286 saved_buffer
= pStubMsg
->Buffer
;
2288 pMemory
= *ppMemory
;
2289 count
= pStubMsg
->ActualCount
;
2290 for (i
= 0; i
< count
; i
++)
2291 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
, fMustAlloc
);
2292 return pStubMsg
->Buffer
- saved_buffer
;
2295 ERR("unknown array format 0x%x\n", fc
);
2296 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2300 static inline void array_memory_size(
2301 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
,
2302 unsigned char fHasPointers
)
2304 ULONG i
, count
, SavedMemorySize
;
2305 ULONG bufsize
, memsize
;
2307 unsigned char alignment
;
2312 esize
= *(const WORD
*)(pFormat
+2);
2313 alignment
= pFormat
[1] + 1;
2315 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2317 bufsize
= memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2318 pStubMsg
->MemorySize
+= memsize
;
2320 align_pointer(&pStubMsg
->Buffer
, alignment
);
2322 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2323 safe_buffer_increment(pStubMsg
, bufsize
);
2326 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2329 esize
= *(const WORD
*)(pFormat
+2);
2330 alignment
= pFormat
[1] + 1;
2332 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2334 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2336 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2337 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2338 pStubMsg
->MemorySize
+= memsize
;
2340 align_pointer(&pStubMsg
->Buffer
, alignment
);
2342 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2343 safe_buffer_increment(pStubMsg
, bufsize
);
2346 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2350 if (fc
== FC_C_CSTRING
)
2355 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
2357 if (pFormat
[1] != FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
2359 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2360 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
2361 RpcRaiseException(RPC_S_INVALID_BOUND
);
2363 if (pStubMsg
->Offset
)
2365 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2366 RpcRaiseException(RPC_S_INVALID_BOUND
);
2369 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2370 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2372 validate_string_data(pStubMsg
, bufsize
, esize
);
2374 safe_buffer_increment(pStubMsg
, bufsize
);
2375 pStubMsg
->MemorySize
+= memsize
;
2377 case FC_BOGUS_ARRAY
:
2378 alignment
= pFormat
[1] + 1;
2379 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2380 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2382 align_pointer(&pStubMsg
->Buffer
, alignment
);
2384 SavedMemorySize
= pStubMsg
->MemorySize
;
2386 esize
= ComplexStructSize(pStubMsg
, pFormat
);
2387 memsize
= safe_multiply(pStubMsg
->MaxCount
, esize
);
2389 count
= pStubMsg
->ActualCount
;
2390 for (i
= 0; i
< count
; i
++)
2391 ComplexStructMemorySize(pStubMsg
, pFormat
, NULL
);
2393 pStubMsg
->MemorySize
= SavedMemorySize
+ memsize
;
2396 ERR("unknown array format 0x%x\n", fc
);
2397 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2401 static inline void array_free(
2402 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
,
2403 unsigned char *pMemory
, PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
2410 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2412 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2415 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2416 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2418 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2422 /* No embedded pointers so nothing to do */
2424 case FC_BOGUS_ARRAY
:
2425 count
= *(const WORD
*)(pFormat
+ 2);
2426 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, count
);
2427 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
2429 count
= pStubMsg
->ActualCount
;
2430 for (i
= 0; i
< count
; i
++)
2431 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
2434 ERR("unknown array format 0x%x\n", fc
);
2435 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2440 * NdrConformantString:
2442 * What MS calls a ConformantString is, in DCE terminology,
2443 * a Varying-Conformant String.
2445 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2446 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2447 * into unmarshalled string)
2448 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2450 * data: CHARTYPE[maxlen]
2452 * ], where CHARTYPE is the appropriate character type (specified externally)
2456 /***********************************************************************
2457 * NdrConformantStringMarshall [RPCRT4.@]
2459 unsigned char *WINAPI
NdrConformantStringMarshall(MIDL_STUB_MESSAGE
*pStubMsg
,
2460 unsigned char *pszMessage
, PFORMAT_STRING pFormat
)
2462 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg
, pszMessage
, pFormat
);
2464 if (pFormat
[0] != FC_C_CSTRING
&& pFormat
[0] != FC_C_WSTRING
) {
2465 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2466 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2469 /* allow compiler to optimise inline function by passing constant into
2470 * these functions */
2471 if (pFormat
[0] == FC_C_CSTRING
) {
2472 array_compute_and_write_conformance(FC_C_CSTRING
, pStubMsg
, pszMessage
,
2474 array_write_variance_and_marshall(FC_C_CSTRING
, pStubMsg
, pszMessage
,
2475 pFormat
, TRUE
/* fHasPointers */);
2477 array_compute_and_write_conformance(FC_C_WSTRING
, pStubMsg
, pszMessage
,
2479 array_write_variance_and_marshall(FC_C_WSTRING
, pStubMsg
, pszMessage
,
2480 pFormat
, TRUE
/* fHasPointers */);
2486 /***********************************************************************
2487 * NdrConformantStringBufferSize [RPCRT4.@]
2489 void WINAPI
NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2490 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
2492 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2494 if (pFormat
[0] != FC_C_CSTRING
&& pFormat
[0] != FC_C_WSTRING
) {
2495 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2496 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2499 /* allow compiler to optimise inline function by passing constant into
2500 * these functions */
2501 if (pFormat
[0] == FC_C_CSTRING
) {
2502 array_compute_and_size_conformance(FC_C_CSTRING
, pStubMsg
, pMemory
,
2504 array_buffer_size(FC_C_CSTRING
, pStubMsg
, pMemory
, pFormat
,
2505 TRUE
/* fHasPointers */);
2507 array_compute_and_size_conformance(FC_C_WSTRING
, pStubMsg
, pMemory
,
2509 array_buffer_size(FC_C_WSTRING
, pStubMsg
, pMemory
, pFormat
,
2510 TRUE
/* fHasPointers */);
2514 /************************************************************************
2515 * NdrConformantStringMemorySize [RPCRT4.@]
2517 ULONG WINAPI
NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
2518 PFORMAT_STRING pFormat
)
2520 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
2522 if (pFormat
[0] != FC_C_CSTRING
&& pFormat
[0] != FC_C_WSTRING
) {
2523 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2524 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2527 /* allow compiler to optimise inline function by passing constant into
2528 * these functions */
2529 if (pFormat
[0] == FC_C_CSTRING
) {
2530 array_read_conformance(FC_C_CSTRING
, pStubMsg
, pFormat
);
2531 array_memory_size(FC_C_CSTRING
, pStubMsg
, pFormat
,
2532 TRUE
/* fHasPointers */);
2534 array_read_conformance(FC_C_WSTRING
, pStubMsg
, pFormat
);
2535 array_memory_size(FC_C_WSTRING
, pStubMsg
, pFormat
,
2536 TRUE
/* fHasPointers */);
2539 return pStubMsg
->MemorySize
;
2542 /************************************************************************
2543 * NdrConformantStringUnmarshall [RPCRT4.@]
2545 unsigned char *WINAPI
NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2546 unsigned char** ppMemory
, PFORMAT_STRING pFormat
, unsigned char fMustAlloc
)
2548 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2549 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
2551 if (pFormat
[0] != FC_C_CSTRING
&& pFormat
[0] != FC_C_WSTRING
) {
2552 ERR("Unhandled string type: %#x\n", *pFormat
);
2553 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2556 /* allow compiler to optimise inline function by passing constant into
2557 * these functions */
2558 if (pFormat
[0] == FC_C_CSTRING
) {
2559 array_read_conformance(FC_C_CSTRING
, pStubMsg
, pFormat
);
2560 array_read_variance_and_unmarshall(FC_C_CSTRING
, pStubMsg
, ppMemory
,
2561 pFormat
, fMustAlloc
,
2562 TRUE
/* fUseBufferMemoryServer */,
2563 TRUE
/* fUnmarshall */);
2565 array_read_conformance(FC_C_WSTRING
, pStubMsg
, pFormat
);
2566 array_read_variance_and_unmarshall(FC_C_WSTRING
, pStubMsg
, ppMemory
,
2567 pFormat
, fMustAlloc
,
2568 TRUE
/* fUseBufferMemoryServer */,
2569 TRUE
/* fUnmarshall */);
2575 /***********************************************************************
2576 * NdrNonConformantStringMarshall [RPCRT4.@]
2578 unsigned char * WINAPI
NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2579 unsigned char *pMemory
,
2580 PFORMAT_STRING pFormat
)
2582 ULONG esize
, size
, maxsize
;
2584 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2586 maxsize
= *(const USHORT
*)&pFormat
[2];
2588 if (*pFormat
== FC_CSTRING
)
2591 const char *str
= (const char *)pMemory
;
2592 while (i
< maxsize
&& str
[i
]) i
++;
2593 TRACE("string=%s\n", debugstr_an(str
, i
));
2594 pStubMsg
->ActualCount
= i
+ 1;
2597 else if (*pFormat
== FC_WSTRING
)
2600 const WCHAR
*str
= (const WCHAR
*)pMemory
;
2601 while (i
< maxsize
&& str
[i
]) i
++;
2602 TRACE("string=%s\n", debugstr_wn(str
, i
));
2603 pStubMsg
->ActualCount
= i
+ 1;
2608 ERR("Unhandled string type: %#x\n", *pFormat
);
2609 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2612 pStubMsg
->Offset
= 0;
2613 WriteVariance(pStubMsg
);
2615 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2616 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
2621 /***********************************************************************
2622 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2624 unsigned char * WINAPI
NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2625 unsigned char **ppMemory
,
2626 PFORMAT_STRING pFormat
,
2627 unsigned char fMustAlloc
)
2629 ULONG bufsize
, memsize
, esize
, maxsize
;
2631 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2632 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
2634 maxsize
= *(const USHORT
*)&pFormat
[2];
2636 ReadVariance(pStubMsg
, NULL
, maxsize
);
2637 if (pStubMsg
->Offset
)
2639 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2640 RpcRaiseException(RPC_S_INVALID_BOUND
);
2643 if (*pFormat
== FC_CSTRING
) esize
= 1;
2644 else if (*pFormat
== FC_WSTRING
) esize
= 2;
2647 ERR("Unhandled string type: %#x\n", *pFormat
);
2648 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2651 memsize
= esize
* maxsize
;
2652 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2654 validate_string_data(pStubMsg
, bufsize
, esize
);
2656 if (!fMustAlloc
&& !*ppMemory
)
2659 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2661 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
2663 if (*pFormat
== FC_CSTRING
) {
2664 TRACE("string=%s\n", debugstr_an((char*)*ppMemory
, pStubMsg
->ActualCount
));
2666 else if (*pFormat
== FC_WSTRING
) {
2667 TRACE("string=%s\n", debugstr_wn((LPWSTR
)*ppMemory
, pStubMsg
->ActualCount
));
2673 /***********************************************************************
2674 * NdrNonConformantStringBufferSize [RPCRT4.@]
2676 void WINAPI
NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2677 unsigned char *pMemory
,
2678 PFORMAT_STRING pFormat
)
2680 ULONG esize
, maxsize
;
2682 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2684 maxsize
= *(const USHORT
*)&pFormat
[2];
2686 SizeVariance(pStubMsg
);
2688 if (*pFormat
== FC_CSTRING
)
2691 const char *str
= (const char *)pMemory
;
2692 while (i
< maxsize
&& str
[i
]) i
++;
2693 TRACE("string=%s\n", debugstr_an(str
, i
));
2694 pStubMsg
->ActualCount
= i
+ 1;
2697 else if (*pFormat
== FC_WSTRING
)
2700 const WCHAR
*str
= (const WCHAR
*)pMemory
;
2701 while (i
< maxsize
&& str
[i
]) i
++;
2702 TRACE("string=%s\n", debugstr_wn(str
, i
));
2703 pStubMsg
->ActualCount
= i
+ 1;
2708 ERR("Unhandled string type: %#x\n", *pFormat
);
2709 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2712 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
2715 /***********************************************************************
2716 * NdrNonConformantStringMemorySize [RPCRT4.@]
2718 ULONG WINAPI
NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2719 PFORMAT_STRING pFormat
)
2721 ULONG bufsize
, memsize
, esize
, maxsize
;
2723 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
2725 maxsize
= *(const USHORT
*)&pFormat
[2];
2727 ReadVariance(pStubMsg
, NULL
, maxsize
);
2729 if (pStubMsg
->Offset
)
2731 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2732 RpcRaiseException(RPC_S_INVALID_BOUND
);
2735 if (*pFormat
== FC_CSTRING
) esize
= 1;
2736 else if (*pFormat
== FC_WSTRING
) esize
= 2;
2739 ERR("Unhandled string type: %#x\n", *pFormat
);
2740 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2743 memsize
= esize
* maxsize
;
2744 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2746 validate_string_data(pStubMsg
, bufsize
, esize
);
2748 safe_buffer_increment(pStubMsg
, bufsize
);
2749 pStubMsg
->MemorySize
+= memsize
;
2751 return pStubMsg
->MemorySize
;
2756 #include "pshpack1.h"
2760 unsigned char flags_type
; /* flags in upper nibble, type in lower nibble */
2764 #include "poppack.h"
2766 static ULONG
EmbeddedComplexSize(MIDL_STUB_MESSAGE
*pStubMsg
,
2767 PFORMAT_STRING pFormat
)
2773 case FC_BOGUS_STRUCT
:
2777 return *(const WORD
*)&pFormat
[2];
2780 return *(const ULONG
*)&pFormat
[2];
2781 case FC_USER_MARSHAL
:
2782 return *(const WORD
*)&pFormat
[4];
2784 switch (((const NDR_RANGE
*)pFormat
)->flags_type
& 0xf) {
2789 return sizeof(UCHAR
);
2793 return sizeof(USHORT
);
2797 return sizeof(ULONG
);
2799 return sizeof(float);
2801 return sizeof(double);
2803 return sizeof(ULONGLONG
);
2805 return sizeof(UINT
);
2807 ERR("unknown type 0x%x\n", ((const NDR_RANGE
*)pFormat
)->flags_type
& 0xf);
2808 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2811 case FC_NON_ENCAPSULATED_UNION
:
2813 pFormat
= SkipConformance(pStubMsg
, pFormat
);
2814 pFormat
+= *(const SHORT
*)pFormat
;
2815 return *(const SHORT
*)pFormat
;
2817 return sizeof(void *);
2819 return *(const WORD
*)&pFormat
[2] * 2;
2821 FIXME("unhandled embedded type %02x\n", *pFormat
);
2827 static ULONG
EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2828 PFORMAT_STRING pFormat
)
2830 NDR_MEMORYSIZE m
= NdrMemorySizer
[*pFormat
& NDR_TABLE_MASK
];
2834 FIXME("no memorysizer for data type=%02x\n", *pFormat
);
2838 return m(pStubMsg
, pFormat
);
2842 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2843 unsigned char *pMemory
,
2844 PFORMAT_STRING pFormat
,
2845 PFORMAT_STRING pPointer
)
2847 unsigned char *mem_base
= pMemory
;
2848 PFORMAT_STRING desc
;
2852 while (*pFormat
!= FC_END
) {
2858 TRACE("byte=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2859 safe_copy_to_buffer(pStubMsg
, pMemory
, 1);
2865 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2866 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
2871 USHORT val
= *(DWORD
*)pMemory
;
2872 TRACE("enum16=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2873 if (32767 < *(DWORD
*)pMemory
)
2874 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
2875 safe_copy_to_buffer(pStubMsg
, &val
, 2);
2882 TRACE("long=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2883 safe_copy_to_buffer(pStubMsg
, pMemory
, 4);
2889 UINT val
= *(UINT_PTR
*)pMemory
;
2890 TRACE("int3264=%ld <= %p\n", *(UINT_PTR
*)pMemory
, pMemory
);
2891 safe_copy_to_buffer(pStubMsg
, &val
, sizeof(UINT
));
2892 pMemory
+= sizeof(UINT_PTR
);
2896 TRACE("float=%f <= %p\n", *(float*)pMemory
, pMemory
);
2897 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
2898 pMemory
+= sizeof(float);
2901 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2902 safe_copy_to_buffer(pStubMsg
, pMemory
, 8);
2906 TRACE("double=%f <= %p\n", *(double*)pMemory
, pMemory
);
2907 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
2908 pMemory
+= sizeof(double);
2916 unsigned char *saved_buffer
;
2917 BOOL pointer_buffer_mark_set
= FALSE
;
2918 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
2919 TRACE("pStubMsg->Buffer before %p\n", pStubMsg
->Buffer
);
2920 if (*pFormat
!= FC_POINTER
)
2922 if (*pPointer
!= FC_RP
)
2923 align_pointer_clear(&pStubMsg
->Buffer
, 4);
2924 saved_buffer
= pStubMsg
->Buffer
;
2925 if (pStubMsg
->PointerBufferMark
)
2927 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2928 pStubMsg
->PointerBufferMark
= NULL
;
2929 pointer_buffer_mark_set
= TRUE
;
2931 else if (*pPointer
!= FC_RP
)
2932 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2933 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char**)pMemory
, pPointer
);
2934 if (pointer_buffer_mark_set
)
2936 STD_OVERFLOW_CHECK(pStubMsg
);
2937 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2938 pStubMsg
->Buffer
= saved_buffer
;
2939 if (*pPointer
!= FC_RP
)
2940 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2942 TRACE("pStubMsg->Buffer after %p\n", pStubMsg
->Buffer
);
2943 if (*pFormat
== FC_POINTER
)
2947 pMemory
+= sizeof(void *);
2951 align_pointer_offset(&pMemory
, mem_base
, 2);
2954 align_pointer_offset(&pMemory
, mem_base
, 4);
2957 align_pointer_offset(&pMemory
, mem_base
, 8);
2966 pMemory
+= *pFormat
- FC_STRUCTPAD1
+ 1;
2968 case FC_EMBEDDED_COMPLEX
:
2969 pMemory
+= pFormat
[1];
2971 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2972 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2973 TRACE("embedded complex (size=%d) <= %p\n", size
, pMemory
);
2974 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
2977 /* for some reason interface pointers aren't generated as
2978 * FC_POINTER, but instead as FC_EMBEDDED_COMPLEX, yet
2979 * they still need the dereferencing treatment that pointers are
2982 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2984 m(pStubMsg
, pMemory
, desc
);
2986 else FIXME("no marshaller for embedded type %02x\n", *desc
);
2993 FIXME("unhandled format 0x%02x\n", *pFormat
);
3001 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3002 unsigned char *pMemory
,
3003 PFORMAT_STRING pFormat
,
3004 PFORMAT_STRING pPointer
,
3005 unsigned char fMustAlloc
)
3007 unsigned char *mem_base
= pMemory
;
3008 PFORMAT_STRING desc
;
3012 while (*pFormat
!= FC_END
) {
3018 safe_copy_from_buffer(pStubMsg
, pMemory
, 1);
3019 TRACE("byte=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
3025 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
3026 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
3032 safe_copy_from_buffer(pStubMsg
, &val
, 2);
3033 *(DWORD
*)pMemory
= val
;
3034 TRACE("enum16=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
3035 if (32767 < *(DWORD
*)pMemory
)
3036 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
3043 safe_copy_from_buffer(pStubMsg
, pMemory
, 4);
3044 TRACE("long=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
3050 safe_copy_from_buffer(pStubMsg
, &val
, 4);
3051 *(INT_PTR
*)pMemory
= val
;
3052 TRACE("int3264=%ld => %p\n", *(INT_PTR
*)pMemory
, pMemory
);
3053 pMemory
+= sizeof(INT_PTR
);
3059 safe_copy_from_buffer(pStubMsg
, &val
, 4);
3060 *(UINT_PTR
*)pMemory
= val
;
3061 TRACE("uint3264=%ld => %p\n", *(UINT_PTR
*)pMemory
, pMemory
);
3062 pMemory
+= sizeof(UINT_PTR
);
3066 safe_copy_from_buffer(pStubMsg
, pMemory
, sizeof(float));
3067 TRACE("float=%f => %p\n", *(float*)pMemory
, pMemory
);
3068 pMemory
+= sizeof(float);
3071 safe_copy_from_buffer(pStubMsg
, pMemory
, 8);
3072 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
3076 safe_copy_from_buffer(pStubMsg
, pMemory
, sizeof(double));
3077 TRACE("double=%f => %p\n", *(double*)pMemory
, pMemory
);
3078 pMemory
+= sizeof(double);
3086 unsigned char *saved_buffer
;
3087 BOOL pointer_buffer_mark_set
= FALSE
;
3088 TRACE("pointer => %p\n", pMemory
);
3089 if (*pFormat
!= FC_POINTER
)
3091 if (*pPointer
!= FC_RP
)
3092 align_pointer(&pStubMsg
->Buffer
, 4);
3093 saved_buffer
= pStubMsg
->Buffer
;
3094 if (pStubMsg
->PointerBufferMark
)
3096 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3097 pStubMsg
->PointerBufferMark
= NULL
;
3098 pointer_buffer_mark_set
= TRUE
;
3100 else if (*pPointer
!= FC_RP
)
3101 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3103 PointerUnmarshall(pStubMsg
, saved_buffer
, (unsigned char**)pMemory
, *(unsigned char**)pMemory
, pPointer
, fMustAlloc
);
3104 if (pointer_buffer_mark_set
)
3106 STD_OVERFLOW_CHECK(pStubMsg
);
3107 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3108 pStubMsg
->Buffer
= saved_buffer
;
3109 if (*pPointer
!= FC_RP
)
3110 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3112 if (*pFormat
== FC_POINTER
)
3116 pMemory
+= sizeof(void *);
3120 align_pointer_offset_clear(&pMemory
, mem_base
, 2);
3123 align_pointer_offset_clear(&pMemory
, mem_base
, 4);
3126 align_pointer_offset_clear(&pMemory
, mem_base
, 8);
3135 memset(pMemory
, 0, *pFormat
- FC_STRUCTPAD1
+ 1);
3136 pMemory
+= *pFormat
- FC_STRUCTPAD1
+ 1;
3138 case FC_EMBEDDED_COMPLEX
:
3139 pMemory
+= pFormat
[1];
3141 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3142 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3143 TRACE("embedded complex (size=%d) => %p\n", size
, pMemory
);
3145 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
3146 * since the type is part of the memory block that is encompassed by
3147 * the whole complex type. Memory is forced to allocate when pointers
3148 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
3149 * clearing the memory we pass in to the unmarshaller */
3150 memset(pMemory
, 0, size
);
3151 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
3154 /* for some reason interface pointers aren't generated as
3155 * FC_POINTER, but instead as FC_EMBEDDED_COMPLEX, yet
3156 * they still need the dereferencing treatment that pointers are
3159 m(pStubMsg
, (unsigned char **)pMemory
, desc
, FALSE
);
3161 m(pStubMsg
, &pMemory
, desc
, FALSE
);
3163 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
3170 FIXME("unhandled format %d\n", *pFormat
);
3178 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3179 unsigned char *pMemory
,
3180 PFORMAT_STRING pFormat
,
3181 PFORMAT_STRING pPointer
)
3183 unsigned char *mem_base
= pMemory
;
3184 PFORMAT_STRING desc
;
3188 while (*pFormat
!= FC_END
) {
3194 safe_buffer_length_increment(pStubMsg
, 1);
3200 safe_buffer_length_increment(pStubMsg
, 2);
3204 safe_buffer_length_increment(pStubMsg
, 2);
3211 safe_buffer_length_increment(pStubMsg
, 4);
3216 safe_buffer_length_increment(pStubMsg
, 4);
3217 pMemory
+= sizeof(INT_PTR
);
3221 safe_buffer_length_increment(pStubMsg
, 8);
3229 if (*pFormat
!= FC_POINTER
)
3231 if (!pStubMsg
->IgnoreEmbeddedPointers
)
3233 int saved_buffer_length
= pStubMsg
->BufferLength
;
3234 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3235 pStubMsg
->PointerLength
= 0;
3236 if(!pStubMsg
->BufferLength
)
3237 ERR("BufferLength == 0??\n");
3238 PointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
3239 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3240 pStubMsg
->BufferLength
= saved_buffer_length
;
3242 if (*pPointer
!= FC_RP
)
3244 align_length(&pStubMsg
->BufferLength
, 4);
3245 safe_buffer_length_increment(pStubMsg
, 4);
3247 if (*pFormat
== FC_POINTER
)
3251 pMemory
+= sizeof(void*);
3254 align_pointer_offset(&pMemory
, mem_base
, 2);
3257 align_pointer_offset(&pMemory
, mem_base
, 4);
3260 align_pointer_offset(&pMemory
, mem_base
, 8);
3269 pMemory
+= *pFormat
- FC_STRUCTPAD1
+ 1;
3271 case FC_EMBEDDED_COMPLEX
:
3272 pMemory
+= pFormat
[1];
3274 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3275 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3276 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
3279 /* for some reason interface pointers aren't generated as
3280 * FC_POINTER, but instead as FC_EMBEDDED_COMPLEX, yet
3281 * they still need the dereferencing treatment that pointers are
3284 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
3286 m(pStubMsg
, pMemory
, desc
);
3288 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
3295 FIXME("unhandled format 0x%02x\n", *pFormat
);
3303 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
3304 unsigned char *pMemory
,
3305 PFORMAT_STRING pFormat
,
3306 PFORMAT_STRING pPointer
)
3308 unsigned char *mem_base
= pMemory
;
3309 PFORMAT_STRING desc
;
3313 while (*pFormat
!= FC_END
) {
3335 pMemory
+= sizeof(INT_PTR
);
3346 if (*pFormat
!= FC_POINTER
)
3348 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
3349 if (*pFormat
== FC_POINTER
)
3353 pMemory
+= sizeof(void *);
3356 align_pointer_offset(&pMemory
, mem_base
, 2);
3359 align_pointer_offset(&pMemory
, mem_base
, 4);
3362 align_pointer_offset(&pMemory
, mem_base
, 8);
3371 pMemory
+= *pFormat
- FC_STRUCTPAD1
+ 1;
3373 case FC_EMBEDDED_COMPLEX
:
3374 pMemory
+= pFormat
[1];
3376 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3377 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3378 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
3381 /* for some reason interface pointers aren't generated as
3382 * FC_POINTER, but instead as FC_EMBEDDED_COMPLEX, yet
3383 * they still need the dereferencing treatment that pointers are
3386 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
3388 m(pStubMsg
, pMemory
, desc
);
3396 FIXME("unhandled format 0x%02x\n", *pFormat
);
3404 static ULONG
ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3405 PFORMAT_STRING pFormat
,
3406 PFORMAT_STRING pPointer
)
3408 PFORMAT_STRING desc
;
3411 while (*pFormat
!= FC_END
) {
3418 safe_buffer_increment(pStubMsg
, 1);
3424 safe_buffer_increment(pStubMsg
, 2);
3428 safe_buffer_increment(pStubMsg
, 2);
3435 safe_buffer_increment(pStubMsg
, 4);
3439 size
+= sizeof(INT_PTR
);
3440 safe_buffer_increment(pStubMsg
, 4);
3445 safe_buffer_increment(pStubMsg
, 8);
3453 unsigned char *saved_buffer
;
3454 BOOL pointer_buffer_mark_set
= FALSE
;
3455 if (*pFormat
!= FC_POINTER
)
3457 if (*pPointer
!= FC_RP
)
3458 align_pointer(&pStubMsg
->Buffer
, 4);
3459 saved_buffer
= pStubMsg
->Buffer
;
3460 if (pStubMsg
->PointerBufferMark
)
3462 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3463 pStubMsg
->PointerBufferMark
= NULL
;
3464 pointer_buffer_mark_set
= TRUE
;
3466 else if (*pPointer
!= FC_RP
)
3467 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3469 if (!pStubMsg
->IgnoreEmbeddedPointers
)
3470 PointerMemorySize(pStubMsg
, saved_buffer
, pPointer
);
3471 if (pointer_buffer_mark_set
)
3473 STD_OVERFLOW_CHECK(pStubMsg
);
3474 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3475 pStubMsg
->Buffer
= saved_buffer
;
3476 if (*pPointer
!= FC_RP
)
3477 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3479 if (*pFormat
== FC_POINTER
)
3483 size
+= sizeof(void *);
3487 align_length(&size
, 2);
3490 align_length(&size
, 4);
3493 align_length(&size
, 8);
3502 size
+= *pFormat
- FC_STRUCTPAD1
+ 1;
3504 case FC_EMBEDDED_COMPLEX
:
3507 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3508 size
+= EmbeddedComplexMemorySize(pStubMsg
, desc
);
3514 FIXME("unhandled format 0x%02x\n", *pFormat
);
3522 ULONG
ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
3524 PFORMAT_STRING desc
;
3527 while (*pFormat
!= FC_END
) {
3549 size
+= sizeof(INT_PTR
);
3560 size
+= sizeof(void *);
3561 if (*pFormat
!= FC_POINTER
)
3565 align_length(&size
, 2);
3568 align_length(&size
, 4);
3571 align_length(&size
, 8);
3580 size
+= *pFormat
- FC_STRUCTPAD1
+ 1;
3582 case FC_EMBEDDED_COMPLEX
:
3585 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3586 size
+= EmbeddedComplexSize(pStubMsg
, desc
);
3592 FIXME("unhandled format 0x%02x\n", *pFormat
);
3600 /***********************************************************************
3601 * NdrComplexStructMarshall [RPCRT4.@]
3603 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3604 unsigned char *pMemory
,
3605 PFORMAT_STRING pFormat
)
3607 PFORMAT_STRING conf_array
= NULL
;
3608 PFORMAT_STRING pointer_desc
= NULL
;
3609 unsigned char *OldMemory
= pStubMsg
->Memory
;
3610 BOOL pointer_buffer_mark_set
= FALSE
;
3612 ULONG max_count
= 0;
3615 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3617 if (!pStubMsg
->PointerBufferMark
)
3619 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3620 /* save buffer length */
3621 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
3623 /* get the buffer pointer after complex array data, but before
3625 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
;
3626 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3627 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
3628 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3630 /* save it for use by embedded pointer code later */
3631 pStubMsg
->PointerBufferMark
= (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
;
3632 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->PointerBufferMark
- pStubMsg
->Buffer
));
3633 pointer_buffer_mark_set
= TRUE
;
3635 /* restore the original buffer length */
3636 pStubMsg
->BufferLength
= saved_buffer_length
;
3639 align_pointer_clear(&pStubMsg
->Buffer
, pFormat
[1] + 1);
3642 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3644 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3647 pStubMsg
->Memory
= pMemory
;
3651 ULONG struct_size
= ComplexStructSize(pStubMsg
, pFormat
);
3652 array_compute_and_write_conformance(conf_array
[0], pStubMsg
,
3653 pMemory
+ struct_size
, conf_array
);
3654 /* these could be changed in ComplexMarshall so save them for later */
3655 max_count
= pStubMsg
->MaxCount
;
3656 count
= pStubMsg
->ActualCount
;
3657 offset
= pStubMsg
->Offset
;
3660 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3664 pStubMsg
->MaxCount
= max_count
;
3665 pStubMsg
->ActualCount
= count
;
3666 pStubMsg
->Offset
= offset
;
3667 array_write_variance_and_marshall(conf_array
[0], pStubMsg
, pMemory
,
3668 conf_array
, TRUE
/* fHasPointers */);
3671 pStubMsg
->Memory
= OldMemory
;
3673 if (pointer_buffer_mark_set
)
3675 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3676 pStubMsg
->PointerBufferMark
= NULL
;
3679 STD_OVERFLOW_CHECK(pStubMsg
);
3684 /***********************************************************************
3685 * NdrComplexStructUnmarshall [RPCRT4.@]
3687 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3688 unsigned char **ppMemory
,
3689 PFORMAT_STRING pFormat
,
3690 unsigned char fMustAlloc
)
3692 unsigned size
= *(const WORD
*)(pFormat
+2);
3693 PFORMAT_STRING conf_array
= NULL
;
3694 PFORMAT_STRING pointer_desc
= NULL
;
3695 unsigned char *pMemory
;
3696 BOOL pointer_buffer_mark_set
= FALSE
;
3698 ULONG max_count
= 0;
3700 ULONG array_size
= 0;
3702 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3704 if (!pStubMsg
->PointerBufferMark
)
3706 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3707 /* save buffer pointer */
3708 unsigned char *saved_buffer
= pStubMsg
->Buffer
;
3710 /* get the buffer pointer after complex array data, but before
3712 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3713 NdrComplexStructMemorySize(pStubMsg
, pFormat
);
3714 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3716 /* save it for use by embedded pointer code later */
3717 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3718 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->PointerBufferMark
- saved_buffer
));
3719 pointer_buffer_mark_set
= TRUE
;
3721 /* restore the original buffer */
3722 pStubMsg
->Buffer
= saved_buffer
;
3725 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
3728 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3730 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3735 array_size
= array_read_conformance(conf_array
[0], pStubMsg
, conf_array
);
3738 /* these could be changed in ComplexMarshall so save them for later */
3739 max_count
= pStubMsg
->MaxCount
;
3740 count
= pStubMsg
->ActualCount
;
3741 offset
= pStubMsg
->Offset
;
3744 if (!fMustAlloc
&& !*ppMemory
)
3747 *ppMemory
= NdrAllocateZero(pStubMsg
, size
);
3749 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
, fMustAlloc
);
3753 pStubMsg
->MaxCount
= max_count
;
3754 pStubMsg
->ActualCount
= count
;
3755 pStubMsg
->Offset
= offset
;
3757 memset(pMemory
, 0, array_size
);
3758 array_read_variance_and_unmarshall(conf_array
[0], pStubMsg
, &pMemory
,
3760 FALSE
/* fUseBufferMemoryServer */,
3761 TRUE
/* fUnmarshall */);
3764 if (pointer_buffer_mark_set
)
3766 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3767 pStubMsg
->PointerBufferMark
= NULL
;
3773 /***********************************************************************
3774 * NdrComplexStructBufferSize [RPCRT4.@]
3776 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3777 unsigned char *pMemory
,
3778 PFORMAT_STRING pFormat
)
3780 PFORMAT_STRING conf_array
= NULL
;
3781 PFORMAT_STRING pointer_desc
= NULL
;
3782 unsigned char *OldMemory
= pStubMsg
->Memory
;
3783 int pointer_length_set
= 0;
3785 ULONG max_count
= 0;
3788 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3790 align_length(&pStubMsg
->BufferLength
, pFormat
[1] + 1);
3792 if(!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
3794 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3795 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
3797 /* get the buffer length after complex struct data, but before
3799 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3800 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
3801 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3803 /* save it for use by embedded pointer code later */
3804 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3805 pointer_length_set
= 1;
3806 TRACE("difference = 0x%x\n", pStubMsg
->PointerLength
- saved_buffer_length
);
3808 /* restore the original buffer length */
3809 pStubMsg
->BufferLength
= saved_buffer_length
;
3813 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3815 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3818 pStubMsg
->Memory
= pMemory
;
3822 ULONG struct_size
= ComplexStructSize(pStubMsg
, pFormat
);
3823 array_compute_and_size_conformance(conf_array
[0], pStubMsg
, pMemory
+ struct_size
,
3826 /* these could be changed in ComplexMarshall so save them for later */
3827 max_count
= pStubMsg
->MaxCount
;
3828 count
= pStubMsg
->ActualCount
;
3829 offset
= pStubMsg
->Offset
;
3832 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3836 pStubMsg
->MaxCount
= max_count
;
3837 pStubMsg
->ActualCount
= count
;
3838 pStubMsg
->Offset
= offset
;
3839 array_buffer_size(conf_array
[0], pStubMsg
, pMemory
, conf_array
,
3840 TRUE
/* fHasPointers */);
3843 pStubMsg
->Memory
= OldMemory
;
3845 if(pointer_length_set
)
3847 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3848 pStubMsg
->PointerLength
= 0;
3853 /***********************************************************************
3854 * NdrComplexStructMemorySize [RPCRT4.@]
3856 ULONG WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3857 PFORMAT_STRING pFormat
)
3859 unsigned size
= *(const WORD
*)(pFormat
+2);
3860 PFORMAT_STRING conf_array
= NULL
;
3861 PFORMAT_STRING pointer_desc
= NULL
;
3863 ULONG max_count
= 0;
3866 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3868 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
3871 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3873 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3878 array_read_conformance(conf_array
[0], pStubMsg
, conf_array
);
3880 /* these could be changed in ComplexStructMemorySize so save them for
3882 max_count
= pStubMsg
->MaxCount
;
3883 count
= pStubMsg
->ActualCount
;
3884 offset
= pStubMsg
->Offset
;
3887 ComplexStructMemorySize(pStubMsg
, pFormat
, pointer_desc
);
3891 pStubMsg
->MaxCount
= max_count
;
3892 pStubMsg
->ActualCount
= count
;
3893 pStubMsg
->Offset
= offset
;
3894 array_memory_size(conf_array
[0], pStubMsg
, conf_array
,
3895 TRUE
/* fHasPointers */);
3901 /***********************************************************************
3902 * NdrComplexStructFree [RPCRT4.@]
3904 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3905 unsigned char *pMemory
,
3906 PFORMAT_STRING pFormat
)
3908 PFORMAT_STRING conf_array
= NULL
;
3909 PFORMAT_STRING pointer_desc
= NULL
;
3910 unsigned char *OldMemory
= pStubMsg
->Memory
;
3912 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3915 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3917 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3920 pStubMsg
->Memory
= pMemory
;
3922 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3925 array_free(conf_array
[0], pStubMsg
, pMemory
, conf_array
,
3926 TRUE
/* fHasPointers */);
3928 pStubMsg
->Memory
= OldMemory
;
3931 /***********************************************************************
3932 * NdrConformantArrayMarshall [RPCRT4.@]
3934 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3935 unsigned char *pMemory
,
3936 PFORMAT_STRING pFormat
)
3938 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3939 if (pFormat
[0] != FC_CARRAY
)
3941 ERR("invalid format = 0x%x\n", pFormat
[0]);
3942 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3945 array_compute_and_write_conformance(FC_CARRAY
, pStubMsg
, pMemory
,
3947 array_write_variance_and_marshall(FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3948 TRUE
/* fHasPointers */);
3953 /***********************************************************************
3954 * NdrConformantArrayUnmarshall [RPCRT4.@]
3956 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3957 unsigned char **ppMemory
,
3958 PFORMAT_STRING pFormat
,
3959 unsigned char fMustAlloc
)
3961 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3962 if (pFormat
[0] != FC_CARRAY
)
3964 ERR("invalid format = 0x%x\n", pFormat
[0]);
3965 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3968 array_read_conformance(FC_CARRAY
, pStubMsg
, pFormat
);
3969 array_read_variance_and_unmarshall(FC_CARRAY
, pStubMsg
, ppMemory
, pFormat
,
3971 TRUE
/* fUseBufferMemoryServer */,
3972 TRUE
/* fUnmarshall */);
3977 /***********************************************************************
3978 * NdrConformantArrayBufferSize [RPCRT4.@]
3980 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3981 unsigned char *pMemory
,
3982 PFORMAT_STRING pFormat
)
3984 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3985 if (pFormat
[0] != FC_CARRAY
)
3987 ERR("invalid format = 0x%x\n", pFormat
[0]);
3988 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3991 array_compute_and_size_conformance(FC_CARRAY
, pStubMsg
, pMemory
, pFormat
);
3992 array_buffer_size(FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3993 TRUE
/* fHasPointers */);
3996 /***********************************************************************
3997 * NdrConformantArrayMemorySize [RPCRT4.@]
3999 ULONG WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4000 PFORMAT_STRING pFormat
)
4002 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
4003 if (pFormat
[0] != FC_CARRAY
)
4005 ERR("invalid format = 0x%x\n", pFormat
[0]);
4006 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4009 array_read_conformance(FC_CARRAY
, pStubMsg
, pFormat
);
4010 array_memory_size(FC_CARRAY
, pStubMsg
, pFormat
, TRUE
/* fHasPointers */);
4012 return pStubMsg
->MemorySize
;
4015 /***********************************************************************
4016 * NdrConformantArrayFree [RPCRT4.@]
4018 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4019 unsigned char *pMemory
,
4020 PFORMAT_STRING pFormat
)
4022 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4023 if (pFormat
[0] != FC_CARRAY
)
4025 ERR("invalid format = 0x%x\n", pFormat
[0]);
4026 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4029 array_free(FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
4030 TRUE
/* fHasPointers */);
4034 /***********************************************************************
4035 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
4037 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
4038 unsigned char* pMemory
,
4039 PFORMAT_STRING pFormat
)
4041 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4043 if (pFormat
[0] != FC_CVARRAY
)
4045 ERR("invalid format type %x\n", pFormat
[0]);
4046 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4050 array_compute_and_write_conformance(FC_CVARRAY
, pStubMsg
, pMemory
,
4052 array_write_variance_and_marshall(FC_CVARRAY
, pStubMsg
, pMemory
,
4053 pFormat
, TRUE
/* fHasPointers */);
4059 /***********************************************************************
4060 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
4062 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
4063 unsigned char** ppMemory
,
4064 PFORMAT_STRING pFormat
,
4065 unsigned char fMustAlloc
)
4067 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4069 if (pFormat
[0] != FC_CVARRAY
)
4071 ERR("invalid format type %x\n", pFormat
[0]);
4072 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4076 array_read_conformance(FC_CVARRAY
, pStubMsg
, pFormat
);
4077 array_read_variance_and_unmarshall(FC_CVARRAY
, pStubMsg
, ppMemory
,
4078 pFormat
, fMustAlloc
,
4079 TRUE
/* fUseBufferMemoryServer */,
4080 TRUE
/* fUnmarshall */);
4086 /***********************************************************************
4087 * NdrConformantVaryingArrayFree [RPCRT4.@]
4089 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
4090 unsigned char* pMemory
,
4091 PFORMAT_STRING pFormat
)
4093 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4095 if (pFormat
[0] != FC_CVARRAY
)
4097 ERR("invalid format type %x\n", pFormat
[0]);
4098 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4102 array_free(FC_CVARRAY
, pStubMsg
, pMemory
, pFormat
,
4103 TRUE
/* fHasPointers */);
4107 /***********************************************************************
4108 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
4110 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
4111 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
4113 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4115 if (pFormat
[0] != FC_CVARRAY
)
4117 ERR("invalid format type %x\n", pFormat
[0]);
4118 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4122 array_compute_and_size_conformance(FC_CVARRAY
, pStubMsg
, pMemory
,
4124 array_buffer_size(FC_CVARRAY
, pStubMsg
, pMemory
, pFormat
,
4125 TRUE
/* fHasPointers */);
4129 /***********************************************************************
4130 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
4132 ULONG WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
4133 PFORMAT_STRING pFormat
)
4135 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4137 if (pFormat
[0] != FC_CVARRAY
)
4139 ERR("invalid format type %x\n", pFormat
[0]);
4140 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4141 return pStubMsg
->MemorySize
;
4144 array_read_conformance(FC_CVARRAY
, pStubMsg
, pFormat
);
4145 array_memory_size(FC_CVARRAY
, pStubMsg
, pFormat
,
4146 TRUE
/* fHasPointers */);
4148 return pStubMsg
->MemorySize
;
4152 /***********************************************************************
4153 * NdrComplexArrayMarshall [RPCRT4.@]
4155 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4156 unsigned char *pMemory
,
4157 PFORMAT_STRING pFormat
)
4159 BOOL pointer_buffer_mark_set
= FALSE
;
4161 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4163 if (pFormat
[0] != FC_BOGUS_ARRAY
)
4165 ERR("invalid format type %x\n", pFormat
[0]);
4166 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4170 if (!pStubMsg
->PointerBufferMark
)
4172 /* save buffer fields that may be changed by buffer sizer functions
4173 * and that may be needed later on */
4174 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
4175 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
4176 ULONG_PTR saved_max_count
= pStubMsg
->MaxCount
;
4177 ULONG saved_offset
= pStubMsg
->Offset
;
4178 ULONG saved_actual_count
= pStubMsg
->ActualCount
;
4180 /* get the buffer pointer after complex array data, but before
4182 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
;
4183 pStubMsg
->IgnoreEmbeddedPointers
= 1;
4184 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
4185 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
4187 /* save it for use by embedded pointer code later */
4188 pStubMsg
->PointerBufferMark
= (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
;
4189 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
));
4190 pointer_buffer_mark_set
= TRUE
;
4192 /* restore fields */
4193 pStubMsg
->ActualCount
= saved_actual_count
;
4194 pStubMsg
->Offset
= saved_offset
;
4195 pStubMsg
->MaxCount
= saved_max_count
;
4196 pStubMsg
->BufferLength
= saved_buffer_length
;
4199 array_compute_and_write_conformance(FC_BOGUS_ARRAY
, pStubMsg
, pMemory
, pFormat
);
4200 array_write_variance_and_marshall(FC_BOGUS_ARRAY
, pStubMsg
,
4201 pMemory
, pFormat
, TRUE
/* fHasPointers */);
4203 STD_OVERFLOW_CHECK(pStubMsg
);
4205 if (pointer_buffer_mark_set
)
4207 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4208 pStubMsg
->PointerBufferMark
= NULL
;
4214 /***********************************************************************
4215 * NdrComplexArrayUnmarshall [RPCRT4.@]
4217 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4218 unsigned char **ppMemory
,
4219 PFORMAT_STRING pFormat
,
4220 unsigned char fMustAlloc
)
4222 unsigned char *saved_buffer
;
4223 BOOL pointer_buffer_mark_set
= FALSE
;
4224 int saved_ignore_embedded
;
4226 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4228 if (pFormat
[0] != FC_BOGUS_ARRAY
)
4230 ERR("invalid format type %x\n", pFormat
[0]);
4231 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4235 saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
4236 /* save buffer pointer */
4237 saved_buffer
= pStubMsg
->Buffer
;
4238 /* get the buffer pointer after complex array data, but before
4240 pStubMsg
->IgnoreEmbeddedPointers
= 1;
4241 pStubMsg
->MemorySize
= 0;
4242 NdrComplexArrayMemorySize(pStubMsg
, pFormat
);
4243 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
4245 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->Buffer
- saved_buffer
));
4246 if (!pStubMsg
->PointerBufferMark
)
4248 /* save it for use by embedded pointer code later */
4249 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4250 pointer_buffer_mark_set
= TRUE
;
4252 /* restore the original buffer */
4253 pStubMsg
->Buffer
= saved_buffer
;
4255 array_read_conformance(FC_BOGUS_ARRAY
, pStubMsg
, pFormat
);
4256 array_read_variance_and_unmarshall(FC_BOGUS_ARRAY
, pStubMsg
, ppMemory
, pFormat
, fMustAlloc
,
4257 TRUE
/* fUseBufferMemoryServer */, TRUE
/* fUnmarshall */);
4259 if (pointer_buffer_mark_set
)
4261 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4262 pStubMsg
->PointerBufferMark
= NULL
;
4268 /***********************************************************************
4269 * NdrComplexArrayBufferSize [RPCRT4.@]
4271 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4272 unsigned char *pMemory
,
4273 PFORMAT_STRING pFormat
)
4275 int pointer_length_set
= 0;
4277 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4279 if (pFormat
[0] != FC_BOGUS_ARRAY
)
4281 ERR("invalid format type %x\n", pFormat
[0]);
4282 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4286 if (!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
4288 /* save buffer fields that may be changed by buffer sizer functions
4289 * and that may be needed later on */
4290 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
4291 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
4292 ULONG_PTR saved_max_count
= pStubMsg
->MaxCount
;
4293 ULONG saved_offset
= pStubMsg
->Offset
;
4294 ULONG saved_actual_count
= pStubMsg
->ActualCount
;
4296 /* get the buffer pointer after complex array data, but before
4298 pStubMsg
->IgnoreEmbeddedPointers
= 1;
4299 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
4300 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
4302 /* save it for use by embedded pointer code later */
4303 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4304 pointer_length_set
= 1;
4306 /* restore fields */
4307 pStubMsg
->ActualCount
= saved_actual_count
;
4308 pStubMsg
->Offset
= saved_offset
;
4309 pStubMsg
->MaxCount
= saved_max_count
;
4310 pStubMsg
->BufferLength
= saved_buffer_length
;
4313 array_compute_and_size_conformance(FC_BOGUS_ARRAY
, pStubMsg
, pMemory
, pFormat
);
4314 array_buffer_size(FC_BOGUS_ARRAY
, pStubMsg
, pMemory
, pFormat
, TRUE
/* fHasPointers */);
4316 if(pointer_length_set
)
4318 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4319 pStubMsg
->PointerLength
= 0;
4323 /***********************************************************************
4324 * NdrComplexArrayMemorySize [RPCRT4.@]
4326 ULONG WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4327 PFORMAT_STRING pFormat
)
4329 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
4331 if (pFormat
[0] != FC_BOGUS_ARRAY
)
4333 ERR("invalid format type %x\n", pFormat
[0]);
4334 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4338 array_read_conformance(FC_BOGUS_ARRAY
, pStubMsg
, pFormat
);
4339 array_memory_size(FC_BOGUS_ARRAY
, pStubMsg
, pFormat
, TRUE
/* fHasPointers */);
4340 return pStubMsg
->MemorySize
;
4343 /***********************************************************************
4344 * NdrComplexArrayFree [RPCRT4.@]
4346 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4347 unsigned char *pMemory
,
4348 PFORMAT_STRING pFormat
)
4350 ULONG i
, count
, def
;
4352 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4354 if (pFormat
[0] != FC_BOGUS_ARRAY
)
4356 ERR("invalid format type %x\n", pFormat
[0]);
4357 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4361 def
= *(const WORD
*)&pFormat
[2];
4364 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
4365 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
4367 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
4368 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
4370 count
= pStubMsg
->ActualCount
;
4371 for (i
= 0; i
< count
; i
++)
4372 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
4375 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg
,
4376 USER_MARSHAL_CB_TYPE cbtype
, PFORMAT_STRING pFormat
,
4377 USER_MARSHAL_CB
*umcb
)
4379 umcb
->Flags
= MAKELONG(pStubMsg
->dwDestContext
,
4380 pStubMsg
->RpcMsg
->DataRepresentation
);
4381 umcb
->pStubMsg
= pStubMsg
;
4382 umcb
->pReserve
= NULL
;
4383 umcb
->Signature
= USER_MARSHAL_CB_SIGNATURE
;
4384 umcb
->CBType
= cbtype
;
4385 umcb
->pFormat
= pFormat
;
4386 umcb
->pTypeFormat
= NULL
/* FIXME */;
4389 #define USER_MARSHAL_PTR_PREFIX \
4390 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4391 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4393 /***********************************************************************
4394 * NdrUserMarshalMarshall [RPCRT4.@]
4396 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4397 unsigned char *pMemory
,
4398 PFORMAT_STRING pFormat
)
4400 unsigned flags
= pFormat
[1];
4401 unsigned index
= *(const WORD
*)&pFormat
[2];
4402 unsigned char *saved_buffer
= NULL
;
4403 USER_MARSHAL_CB umcb
;
4405 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4406 TRACE("index=%d\n", index
);
4408 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_MARSHALL
, pFormat
, &umcb
);
4410 if (flags
& USER_MARSHAL_POINTER
)
4412 align_pointer_clear(&pStubMsg
->Buffer
, 4);
4413 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, USER_MARSHAL_PTR_PREFIX
);
4414 pStubMsg
->Buffer
+= 4;
4415 if (pStubMsg
->PointerBufferMark
)
4417 saved_buffer
= pStubMsg
->Buffer
;
4418 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4419 pStubMsg
->PointerBufferMark
= NULL
;
4421 align_pointer_clear(&pStubMsg
->Buffer
, 8);
4424 align_pointer_clear(&pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4427 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
4428 &umcb
.Flags
, pStubMsg
->Buffer
, pMemory
);
4432 STD_OVERFLOW_CHECK(pStubMsg
);
4433 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4434 pStubMsg
->Buffer
= saved_buffer
;
4437 STD_OVERFLOW_CHECK(pStubMsg
);
4442 /***********************************************************************
4443 * NdrUserMarshalUnmarshall [RPCRT4.@]
4445 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4446 unsigned char **ppMemory
,
4447 PFORMAT_STRING pFormat
,
4448 unsigned char fMustAlloc
)
4450 unsigned flags
= pFormat
[1];
4451 unsigned index
= *(const WORD
*)&pFormat
[2];
4452 DWORD memsize
= *(const WORD
*)&pFormat
[4];
4453 unsigned char *saved_buffer
= NULL
;
4454 USER_MARSHAL_CB umcb
;
4456 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4457 TRACE("index=%d\n", index
);
4459 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_UNMARSHALL
, pFormat
, &umcb
);
4461 if (flags
& USER_MARSHAL_POINTER
)
4463 align_pointer(&pStubMsg
->Buffer
, 4);
4464 /* skip pointer prefix */
4465 pStubMsg
->Buffer
+= 4;
4466 if (pStubMsg
->PointerBufferMark
)
4468 saved_buffer
= pStubMsg
->Buffer
;
4469 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4470 pStubMsg
->PointerBufferMark
= NULL
;
4472 align_pointer(&pStubMsg
->Buffer
, 8);
4475 align_pointer(&pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4477 if (!fMustAlloc
&& !*ppMemory
)
4481 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
4482 memset(*ppMemory
, 0, memsize
);
4486 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
4487 &umcb
.Flags
, pStubMsg
->Buffer
, *ppMemory
);
4491 STD_OVERFLOW_CHECK(pStubMsg
);
4492 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4493 pStubMsg
->Buffer
= saved_buffer
;
4499 /***********************************************************************
4500 * NdrUserMarshalBufferSize [RPCRT4.@]
4502 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4503 unsigned char *pMemory
,
4504 PFORMAT_STRING pFormat
)
4506 unsigned flags
= pFormat
[1];
4507 unsigned index
= *(const WORD
*)&pFormat
[2];
4508 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
4509 USER_MARSHAL_CB umcb
;
4510 ULONG saved_buffer_length
= 0;
4512 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4513 TRACE("index=%d\n", index
);
4515 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_BUFFER_SIZE
, pFormat
, &umcb
);
4517 if (flags
& USER_MARSHAL_POINTER
)
4519 align_length(&pStubMsg
->BufferLength
, 4);
4520 /* skip pointer prefix */
4521 safe_buffer_length_increment(pStubMsg
, 4);
4522 if (pStubMsg
->IgnoreEmbeddedPointers
)
4524 if (pStubMsg
->PointerLength
)
4526 saved_buffer_length
= pStubMsg
->BufferLength
;
4527 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4528 pStubMsg
->PointerLength
= 0;
4530 align_length(&pStubMsg
->BufferLength
, 8);
4533 align_length(&pStubMsg
->BufferLength
, (flags
& 0xf) + 1);
4536 TRACE("size=%d\n", bufsize
);
4537 safe_buffer_length_increment(pStubMsg
, bufsize
);
4540 pStubMsg
->BufferLength
=
4541 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
4542 &umcb
.Flags
, pStubMsg
->BufferLength
, pMemory
);
4544 if (saved_buffer_length
)
4546 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4547 pStubMsg
->BufferLength
= saved_buffer_length
;
4552 /***********************************************************************
4553 * NdrUserMarshalMemorySize [RPCRT4.@]
4555 ULONG WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4556 PFORMAT_STRING pFormat
)
4558 unsigned flags
= pFormat
[1];
4559 unsigned index
= *(const WORD
*)&pFormat
[2];
4560 DWORD memsize
= *(const WORD
*)&pFormat
[4];
4561 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
4563 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
4564 TRACE("index=%d\n", index
);
4566 pStubMsg
->MemorySize
+= memsize
;
4568 if (flags
& USER_MARSHAL_POINTER
)
4570 align_pointer(&pStubMsg
->Buffer
, 4);
4571 /* skip pointer prefix */
4572 pStubMsg
->Buffer
+= 4;
4573 if (pStubMsg
->IgnoreEmbeddedPointers
)
4574 return pStubMsg
->MemorySize
;
4575 align_pointer(&pStubMsg
->Buffer
, 8);
4578 align_pointer(&pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4581 FIXME("not implemented for varying buffer size\n");
4583 pStubMsg
->Buffer
+= bufsize
;
4585 return pStubMsg
->MemorySize
;
4588 /***********************************************************************
4589 * NdrUserMarshalFree [RPCRT4.@]
4591 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
4592 unsigned char *pMemory
,
4593 PFORMAT_STRING pFormat
)
4595 /* unsigned flags = pFormat[1]; */
4596 unsigned index
= *(const WORD
*)&pFormat
[2];
4597 USER_MARSHAL_CB umcb
;
4599 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4600 TRACE("index=%d\n", index
);
4602 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_FREE
, pFormat
, &umcb
);
4604 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
4605 &umcb
.Flags
, pMemory
);
4608 /***********************************************************************
4609 * NdrGetUserMarshalInfo [RPCRT4.@]
4611 RPC_STATUS RPC_ENTRY
NdrGetUserMarshalInfo(ULONG
*flags
, ULONG level
, NDR_USER_MARSHAL_INFO
*umi
)
4613 USER_MARSHAL_CB
*umcb
= CONTAINING_RECORD(flags
, USER_MARSHAL_CB
, Flags
);
4615 TRACE("(%p,%u,%p)\n", flags
, level
, umi
);
4618 return RPC_S_INVALID_ARG
;
4620 memset(&umi
->u1
.Level1
, 0, sizeof(umi
->u1
.Level1
));
4621 umi
->InformationLevel
= level
;
4623 if (umcb
->Signature
!= USER_MARSHAL_CB_SIGNATURE
)
4624 return RPC_S_INVALID_ARG
;
4626 umi
->u1
.Level1
.pfnAllocate
= umcb
->pStubMsg
->pfnAllocate
;
4627 umi
->u1
.Level1
.pfnFree
= umcb
->pStubMsg
->pfnFree
;
4628 umi
->u1
.Level1
.pRpcChannelBuffer
= umcb
->pStubMsg
->pRpcChannelBuffer
;
4630 switch (umcb
->CBType
)
4632 case USER_MARSHAL_CB_MARSHALL
:
4633 case USER_MARSHAL_CB_UNMARSHALL
:
4635 RPC_MESSAGE
*msg
= umcb
->pStubMsg
->RpcMsg
;
4636 unsigned char *buffer_start
= msg
->Buffer
;
4637 unsigned char *buffer_end
=
4638 (unsigned char *)msg
->Buffer
+ msg
->BufferLength
;
4640 if (umcb
->pStubMsg
->Buffer
< buffer_start
||
4641 umcb
->pStubMsg
->Buffer
> buffer_end
)
4642 return RPC_X_INVALID_BUFFER
;
4644 umi
->u1
.Level1
.Buffer
= umcb
->pStubMsg
->Buffer
;
4645 umi
->u1
.Level1
.BufferSize
= buffer_end
- umcb
->pStubMsg
->Buffer
;
4648 case USER_MARSHAL_CB_BUFFER_SIZE
:
4649 case USER_MARSHAL_CB_FREE
:
4652 WARN("unrecognised CBType %d\n", umcb
->CBType
);
4658 /***********************************************************************
4659 * NdrClearOutParameters [RPCRT4.@]
4661 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
4662 PFORMAT_STRING pFormat
,
4665 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
4668 /***********************************************************************
4669 * NdrConvert [RPCRT4.@]
4671 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
4673 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
4674 /* FIXME: since this stub doesn't do any converting, the proper behavior
4675 is to raise an exception */
4678 /***********************************************************************
4679 * NdrConvert2 [RPCRT4.@]
4681 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, LONG NumberParams
)
4683 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4684 pStubMsg
, pFormat
, NumberParams
);
4685 /* FIXME: since this stub doesn't do any converting, the proper behavior
4686 is to raise an exception */
4689 #include "pshpack1.h"
4690 typedef struct _NDR_CSTRUCT_FORMAT
4693 unsigned char alignment
;
4694 unsigned short memory_size
;
4695 short offset_to_array_description
;
4696 } NDR_CSTRUCT_FORMAT
, NDR_CVSTRUCT_FORMAT
;
4697 #include "poppack.h"
4699 /***********************************************************************
4700 * NdrConformantStructMarshall [RPCRT4.@]
4702 unsigned char * WINAPI
NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4703 unsigned char *pMemory
,
4704 PFORMAT_STRING pFormat
)
4706 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4707 PFORMAT_STRING pCArrayFormat
;
4708 ULONG esize
, bufsize
;
4710 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4712 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4713 if ((pCStructFormat
->type
!= FC_CPSTRUCT
) && (pCStructFormat
->type
!= FC_CSTRUCT
))
4715 ERR("invalid format type %x\n", pCStructFormat
->type
);
4716 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4720 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4721 pCStructFormat
->offset_to_array_description
;
4722 if (*pCArrayFormat
!= FC_CARRAY
)
4724 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4725 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4728 esize
= *(const WORD
*)(pCArrayFormat
+2);
4730 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4731 pCArrayFormat
+ 4, 0);
4733 WriteConformance(pStubMsg
);
4735 align_pointer_clear(&pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4737 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4739 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4740 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4742 ERR("integer overflow of memory_size %u with bufsize %u\n",
4743 pCStructFormat
->memory_size
, bufsize
);
4744 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4746 /* copy constant sized part of struct */
4747 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4748 safe_copy_to_buffer(pStubMsg
, pMemory
, pCStructFormat
->memory_size
+ bufsize
);
4750 if (pCStructFormat
->type
== FC_CPSTRUCT
)
4751 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4756 /***********************************************************************
4757 * NdrConformantStructUnmarshall [RPCRT4.@]
4759 unsigned char * WINAPI
NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4760 unsigned char **ppMemory
,
4761 PFORMAT_STRING pFormat
,
4762 unsigned char fMustAlloc
)
4764 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4765 PFORMAT_STRING pCArrayFormat
;
4766 ULONG esize
, bufsize
;
4767 unsigned char *saved_buffer
;
4769 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4771 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4772 if ((pCStructFormat
->type
!= FC_CPSTRUCT
) && (pCStructFormat
->type
!= FC_CSTRUCT
))
4774 ERR("invalid format type %x\n", pCStructFormat
->type
);
4775 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4778 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4779 pCStructFormat
->offset_to_array_description
;
4780 if (*pCArrayFormat
!= FC_CARRAY
)
4782 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4783 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4786 esize
= *(const WORD
*)(pCArrayFormat
+2);
4788 pCArrayFormat
= ReadConformance(pStubMsg
, pCArrayFormat
+ 4);
4790 align_pointer(&pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4792 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4794 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4795 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4797 ERR("integer overflow of memory_size %u with bufsize %u\n",
4798 pCStructFormat
->memory_size
, bufsize
);
4799 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4804 SIZE_T size
= pCStructFormat
->memory_size
+ bufsize
;
4805 *ppMemory
= NdrAllocateZero(pStubMsg
, size
);
4809 if (!pStubMsg
->IsClient
&& !*ppMemory
)
4810 /* for servers, we just point straight into the RPC buffer */
4811 *ppMemory
= pStubMsg
->Buffer
;
4814 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4815 safe_buffer_increment(pStubMsg
, pCStructFormat
->memory_size
+ bufsize
);
4816 if (pCStructFormat
->type
== FC_CPSTRUCT
)
4817 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4819 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
4820 if (*ppMemory
!= saved_buffer
)
4821 memcpy(*ppMemory
, saved_buffer
, pCStructFormat
->memory_size
+ bufsize
);
4826 /***********************************************************************
4827 * NdrConformantStructBufferSize [RPCRT4.@]
4829 void WINAPI
NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4830 unsigned char *pMemory
,
4831 PFORMAT_STRING pFormat
)
4833 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4834 PFORMAT_STRING pCArrayFormat
;
4837 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4839 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4840 if ((pCStructFormat
->type
!= FC_CPSTRUCT
) && (pCStructFormat
->type
!= FC_CSTRUCT
))
4842 ERR("invalid format type %x\n", pCStructFormat
->type
);
4843 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4846 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4847 pCStructFormat
->offset_to_array_description
;
4848 if (*pCArrayFormat
!= FC_CARRAY
)
4850 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4851 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4854 esize
= *(const WORD
*)(pCArrayFormat
+2);
4856 pCArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
, pCArrayFormat
+4, 0);
4857 SizeConformance(pStubMsg
);
4859 align_length(&pStubMsg
->BufferLength
, pCStructFormat
->alignment
+ 1);
4861 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4863 safe_buffer_length_increment(pStubMsg
, pCStructFormat
->memory_size
);
4864 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
4866 if (pCStructFormat
->type
== FC_CPSTRUCT
)
4867 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4870 /***********************************************************************
4871 * NdrConformantStructMemorySize [RPCRT4.@]
4873 ULONG WINAPI
NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4874 PFORMAT_STRING pFormat
)
4880 /***********************************************************************
4881 * NdrConformantStructFree [RPCRT4.@]
4883 void WINAPI
NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
4884 unsigned char *pMemory
,
4885 PFORMAT_STRING pFormat
)
4887 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4888 PFORMAT_STRING pCArrayFormat
;
4890 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4892 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4893 if ((pCStructFormat
->type
!= FC_CPSTRUCT
) && (pCStructFormat
->type
!= FC_CSTRUCT
))
4895 ERR("invalid format type %x\n", pCStructFormat
->type
);
4896 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4900 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4901 pCStructFormat
->offset_to_array_description
;
4902 if (*pCArrayFormat
!= FC_CARRAY
)
4904 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4905 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4909 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4910 pCArrayFormat
+ 4, 0);
4912 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4914 /* copy constant sized part of struct */
4915 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4917 if (pCStructFormat
->type
== FC_CPSTRUCT
)
4918 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4921 /***********************************************************************
4922 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4924 unsigned char * WINAPI
NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4925 unsigned char *pMemory
,
4926 PFORMAT_STRING pFormat
)
4928 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4929 PFORMAT_STRING pCVArrayFormat
;
4931 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4933 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4934 if (pCVStructFormat
->type
!= FC_CVSTRUCT
)
4936 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4937 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4941 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4942 pCVStructFormat
->offset_to_array_description
;
4944 array_compute_and_write_conformance(*pCVArrayFormat
, pStubMsg
,
4945 pMemory
+ pCVStructFormat
->memory_size
,
4948 align_pointer_clear(&pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4950 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4952 /* write constant sized part */
4953 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4954 safe_copy_to_buffer(pStubMsg
, pMemory
, pCVStructFormat
->memory_size
);
4956 array_write_variance_and_marshall(*pCVArrayFormat
, pStubMsg
,
4957 pMemory
+ pCVStructFormat
->memory_size
,
4958 pCVArrayFormat
, FALSE
/* fHasPointers */);
4960 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4965 /***********************************************************************
4966 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4968 unsigned char * WINAPI
NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4969 unsigned char **ppMemory
,
4970 PFORMAT_STRING pFormat
,
4971 unsigned char fMustAlloc
)
4973 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4974 PFORMAT_STRING pCVArrayFormat
;
4975 ULONG memsize
, bufsize
;
4976 unsigned char *saved_buffer
, *saved_array_buffer
;
4978 unsigned char *array_memory
;
4980 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4982 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4983 if (pCVStructFormat
->type
!= FC_CVSTRUCT
)
4985 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4986 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4990 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4991 pCVStructFormat
->offset_to_array_description
;
4993 memsize
= array_read_conformance(*pCVArrayFormat
, pStubMsg
,
4996 align_pointer(&pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4998 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
5000 /* work out how much memory to allocate if we need to do so */
5001 if (!fMustAlloc
&& !*ppMemory
)
5005 SIZE_T size
= pCVStructFormat
->memory_size
+ memsize
;
5006 *ppMemory
= NdrAllocateZero(pStubMsg
, size
);
5009 /* mark the start of the constant data */
5010 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5011 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
5013 array_memory
= *ppMemory
+ pCVStructFormat
->memory_size
;
5014 bufsize
= array_read_variance_and_unmarshall(*pCVArrayFormat
, pStubMsg
,
5015 &array_memory
, pCVArrayFormat
,
5016 FALSE
/* fMustAlloc */,
5017 FALSE
/* fUseServerBufferMemory */,
5018 FALSE
/* fUnmarshall */);
5020 /* save offset in case unmarshalling pointers changes it */
5021 offset
= pStubMsg
->Offset
;
5023 /* mark the start of the array data */
5024 saved_array_buffer
= pStubMsg
->Buffer
;
5025 safe_buffer_increment(pStubMsg
, bufsize
);
5027 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
5029 /* copy the constant data */
5030 memcpy(*ppMemory
, saved_buffer
, pCVStructFormat
->memory_size
);
5031 /* copy the array data */
5032 TRACE("copying %p to %p\n", saved_array_buffer
, *ppMemory
+ pCVStructFormat
->memory_size
);
5033 memcpy(*ppMemory
+ pCVStructFormat
->memory_size
+ offset
,
5034 saved_array_buffer
, bufsize
);
5036 if (*pCVArrayFormat
== FC_C_CSTRING
)
5037 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory
+ pCVStructFormat
->memory_size
)));
5038 else if (*pCVArrayFormat
== FC_C_WSTRING
)
5039 TRACE("string=%s\n", debugstr_w((WCHAR
*)(*ppMemory
+ pCVStructFormat
->memory_size
)));
5044 /***********************************************************************
5045 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
5047 void WINAPI
NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5048 unsigned char *pMemory
,
5049 PFORMAT_STRING pFormat
)
5051 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
5052 PFORMAT_STRING pCVArrayFormat
;
5054 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5056 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
5057 if (pCVStructFormat
->type
!= FC_CVSTRUCT
)
5059 ERR("invalid format type %x\n", pCVStructFormat
->type
);
5060 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5064 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
5065 pCVStructFormat
->offset_to_array_description
;
5066 array_compute_and_size_conformance(*pCVArrayFormat
, pStubMsg
,
5067 pMemory
+ pCVStructFormat
->memory_size
,
5070 align_length(&pStubMsg
->BufferLength
, pCVStructFormat
->alignment
+ 1);
5072 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
5074 safe_buffer_length_increment(pStubMsg
, pCVStructFormat
->memory_size
);
5076 array_buffer_size(*pCVArrayFormat
, pStubMsg
,
5077 pMemory
+ pCVStructFormat
->memory_size
, pCVArrayFormat
,
5078 FALSE
/* fHasPointers */);
5080 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5083 /***********************************************************************
5084 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
5086 ULONG WINAPI
NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5087 PFORMAT_STRING pFormat
)
5089 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
5090 PFORMAT_STRING pCVArrayFormat
;
5092 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5094 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
5095 if (pCVStructFormat
->type
!= FC_CVSTRUCT
)
5097 ERR("invalid format type %x\n", pCVStructFormat
->type
);
5098 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5102 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
5103 pCVStructFormat
->offset_to_array_description
;
5104 array_read_conformance(*pCVArrayFormat
, pStubMsg
, pCVArrayFormat
);
5106 align_pointer(&pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
5108 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
5110 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
5111 array_memory_size(*pCVArrayFormat
, pStubMsg
, pCVArrayFormat
,
5112 FALSE
/* fHasPointers */);
5114 pStubMsg
->MemorySize
+= pCVStructFormat
->memory_size
;
5116 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5118 return pStubMsg
->MemorySize
;
5121 /***********************************************************************
5122 * NdrConformantVaryingStructFree [RPCRT4.@]
5124 void WINAPI
NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
5125 unsigned char *pMemory
,
5126 PFORMAT_STRING pFormat
)
5128 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
5129 PFORMAT_STRING pCVArrayFormat
;
5131 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5133 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
5134 if (pCVStructFormat
->type
!= FC_CVSTRUCT
)
5136 ERR("invalid format type %x\n", pCVStructFormat
->type
);
5137 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5141 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
5142 pCVStructFormat
->offset_to_array_description
;
5143 array_free(*pCVArrayFormat
, pStubMsg
,
5144 pMemory
+ pCVStructFormat
->memory_size
, pCVArrayFormat
,
5145 FALSE
/* fHasPointers */);
5147 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
5149 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5152 #include "pshpack1.h"
5156 unsigned char alignment
;
5157 unsigned short total_size
;
5158 } NDR_SMFARRAY_FORMAT
;
5163 unsigned char alignment
;
5165 } NDR_LGFARRAY_FORMAT
;
5166 #include "poppack.h"
5168 /***********************************************************************
5169 * NdrFixedArrayMarshall [RPCRT4.@]
5171 unsigned char * WINAPI
NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5172 unsigned char *pMemory
,
5173 PFORMAT_STRING pFormat
)
5175 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5178 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5180 if ((pSmFArrayFormat
->type
!= FC_SMFARRAY
) &&
5181 (pSmFArrayFormat
->type
!= FC_LGFARRAY
))
5183 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5184 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5188 align_pointer_clear(&pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
5190 if (pSmFArrayFormat
->type
== FC_SMFARRAY
)
5192 total_size
= pSmFArrayFormat
->total_size
;
5193 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5197 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5198 total_size
= pLgFArrayFormat
->total_size
;
5199 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5202 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5203 safe_copy_to_buffer(pStubMsg
, pMemory
, total_size
);
5205 pFormat
= EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
5210 /***********************************************************************
5211 * NdrFixedArrayUnmarshall [RPCRT4.@]
5213 unsigned char * WINAPI
NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5214 unsigned char **ppMemory
,
5215 PFORMAT_STRING pFormat
,
5216 unsigned char fMustAlloc
)
5218 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5220 unsigned char *saved_buffer
;
5222 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5224 if ((pSmFArrayFormat
->type
!= FC_SMFARRAY
) &&
5225 (pSmFArrayFormat
->type
!= FC_LGFARRAY
))
5227 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5228 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5232 align_pointer(&pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
5234 if (pSmFArrayFormat
->type
== FC_SMFARRAY
)
5236 total_size
= pSmFArrayFormat
->total_size
;
5237 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5241 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5242 total_size
= pLgFArrayFormat
->total_size
;
5243 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5247 *ppMemory
= NdrAllocateZero(pStubMsg
, total_size
);
5250 if (!pStubMsg
->IsClient
&& !*ppMemory
)
5251 /* for servers, we just point straight into the RPC buffer */
5252 *ppMemory
= pStubMsg
->Buffer
;
5255 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5256 safe_buffer_increment(pStubMsg
, total_size
);
5257 pFormat
= EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
5259 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
5260 if (*ppMemory
!= saved_buffer
)
5261 memcpy(*ppMemory
, saved_buffer
, total_size
);
5266 /***********************************************************************
5267 * NdrFixedArrayBufferSize [RPCRT4.@]
5269 void WINAPI
NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5270 unsigned char *pMemory
,
5271 PFORMAT_STRING pFormat
)
5273 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5276 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5278 if ((pSmFArrayFormat
->type
!= FC_SMFARRAY
) &&
5279 (pSmFArrayFormat
->type
!= FC_LGFARRAY
))
5281 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5282 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5286 align_length(&pStubMsg
->BufferLength
, pSmFArrayFormat
->alignment
+ 1);
5288 if (pSmFArrayFormat
->type
== FC_SMFARRAY
)
5290 total_size
= pSmFArrayFormat
->total_size
;
5291 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5295 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5296 total_size
= pLgFArrayFormat
->total_size
;
5297 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5299 safe_buffer_length_increment(pStubMsg
, total_size
);
5301 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5304 /***********************************************************************
5305 * NdrFixedArrayMemorySize [RPCRT4.@]
5307 ULONG WINAPI
NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5308 PFORMAT_STRING pFormat
)
5310 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5313 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5315 if ((pSmFArrayFormat
->type
!= FC_SMFARRAY
) &&
5316 (pSmFArrayFormat
->type
!= FC_LGFARRAY
))
5318 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5319 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5323 align_pointer(&pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
5325 if (pSmFArrayFormat
->type
== FC_SMFARRAY
)
5327 total_size
= pSmFArrayFormat
->total_size
;
5328 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5332 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5333 total_size
= pLgFArrayFormat
->total_size
;
5334 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5336 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5337 safe_buffer_increment(pStubMsg
, total_size
);
5338 pStubMsg
->MemorySize
+= total_size
;
5340 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5345 /***********************************************************************
5346 * NdrFixedArrayFree [RPCRT4.@]
5348 void WINAPI
NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
5349 unsigned char *pMemory
,
5350 PFORMAT_STRING pFormat
)
5352 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5354 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5356 if ((pSmFArrayFormat
->type
!= FC_SMFARRAY
) &&
5357 (pSmFArrayFormat
->type
!= FC_LGFARRAY
))
5359 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5360 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5364 if (pSmFArrayFormat
->type
== FC_SMFARRAY
)
5365 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5368 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5369 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5372 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5375 /***********************************************************************
5376 * NdrVaryingArrayMarshall [RPCRT4.@]
5378 unsigned char * WINAPI
NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5379 unsigned char *pMemory
,
5380 PFORMAT_STRING pFormat
)
5382 unsigned char alignment
;
5383 DWORD elements
, esize
;
5386 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5388 if ((pFormat
[0] != FC_SMVARRAY
) &&
5389 (pFormat
[0] != FC_LGVARRAY
))
5391 ERR("invalid format type %x\n", pFormat
[0]);
5392 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5396 alignment
= pFormat
[1] + 1;
5398 if (pFormat
[0] == FC_SMVARRAY
)
5401 pFormat
+= sizeof(WORD
);
5402 elements
= *(const WORD
*)pFormat
;
5403 pFormat
+= sizeof(WORD
);
5408 pFormat
+= sizeof(DWORD
);
5409 elements
= *(const DWORD
*)pFormat
;
5410 pFormat
+= sizeof(DWORD
);
5413 esize
= *(const WORD
*)pFormat
;
5414 pFormat
+= sizeof(WORD
);
5416 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5417 if ((pStubMsg
->ActualCount
> elements
) ||
5418 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5420 RpcRaiseException(RPC_S_INVALID_BOUND
);
5424 WriteVariance(pStubMsg
);
5426 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
5428 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
5429 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5430 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
5432 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
5437 /***********************************************************************
5438 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5440 unsigned char * WINAPI
NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5441 unsigned char **ppMemory
,
5442 PFORMAT_STRING pFormat
,
5443 unsigned char fMustAlloc
)
5445 unsigned char alignment
;
5446 DWORD size
, elements
, esize
;
5448 unsigned char *saved_buffer
;
5451 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5453 if ((pFormat
[0] != FC_SMVARRAY
) &&
5454 (pFormat
[0] != FC_LGVARRAY
))
5456 ERR("invalid format type %x\n", pFormat
[0]);
5457 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5461 alignment
= pFormat
[1] + 1;
5463 if (pFormat
[0] == FC_SMVARRAY
)
5466 size
= *(const WORD
*)pFormat
;
5467 pFormat
+= sizeof(WORD
);
5468 elements
= *(const WORD
*)pFormat
;
5469 pFormat
+= sizeof(WORD
);
5474 size
= *(const DWORD
*)pFormat
;
5475 pFormat
+= sizeof(DWORD
);
5476 elements
= *(const DWORD
*)pFormat
;
5477 pFormat
+= sizeof(DWORD
);
5480 esize
= *(const WORD
*)pFormat
;
5481 pFormat
+= sizeof(WORD
);
5483 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
5485 align_pointer(&pStubMsg
->Buffer
, alignment
);
5487 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
5488 offset
= pStubMsg
->Offset
;
5490 if (!fMustAlloc
&& !*ppMemory
)
5493 *ppMemory
= NdrAllocateZero(pStubMsg
, size
);
5494 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5495 safe_buffer_increment(pStubMsg
, bufsize
);
5497 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
5499 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
5504 /***********************************************************************
5505 * NdrVaryingArrayBufferSize [RPCRT4.@]
5507 void WINAPI
NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5508 unsigned char *pMemory
,
5509 PFORMAT_STRING pFormat
)
5511 unsigned char alignment
;
5512 DWORD elements
, esize
;
5514 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5516 if ((pFormat
[0] != FC_SMVARRAY
) &&
5517 (pFormat
[0] != FC_LGVARRAY
))
5519 ERR("invalid format type %x\n", pFormat
[0]);
5520 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5524 alignment
= pFormat
[1] + 1;
5526 if (pFormat
[0] == FC_SMVARRAY
)
5529 pFormat
+= sizeof(WORD
);
5530 elements
= *(const WORD
*)pFormat
;
5531 pFormat
+= sizeof(WORD
);
5536 pFormat
+= sizeof(DWORD
);
5537 elements
= *(const DWORD
*)pFormat
;
5538 pFormat
+= sizeof(DWORD
);
5541 esize
= *(const WORD
*)pFormat
;
5542 pFormat
+= sizeof(WORD
);
5544 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5545 if ((pStubMsg
->ActualCount
> elements
) ||
5546 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5548 RpcRaiseException(RPC_S_INVALID_BOUND
);
5552 SizeVariance(pStubMsg
);
5554 align_length(&pStubMsg
->BufferLength
, alignment
);
5556 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
5558 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5561 /***********************************************************************
5562 * NdrVaryingArrayMemorySize [RPCRT4.@]
5564 ULONG WINAPI
NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5565 PFORMAT_STRING pFormat
)
5567 unsigned char alignment
;
5568 DWORD size
, elements
, esize
;
5570 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5572 if ((pFormat
[0] != FC_SMVARRAY
) &&
5573 (pFormat
[0] != FC_LGVARRAY
))
5575 ERR("invalid format type %x\n", pFormat
[0]);
5576 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5580 alignment
= pFormat
[1] + 1;
5582 if (pFormat
[0] == FC_SMVARRAY
)
5585 size
= *(const WORD
*)pFormat
;
5586 pFormat
+= sizeof(WORD
);
5587 elements
= *(const WORD
*)pFormat
;
5588 pFormat
+= sizeof(WORD
);
5593 size
= *(const DWORD
*)pFormat
;
5594 pFormat
+= sizeof(DWORD
);
5595 elements
= *(const DWORD
*)pFormat
;
5596 pFormat
+= sizeof(DWORD
);
5599 esize
= *(const WORD
*)pFormat
;
5600 pFormat
+= sizeof(WORD
);
5602 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
5604 align_pointer(&pStubMsg
->Buffer
, alignment
);
5606 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
5607 pStubMsg
->MemorySize
+= size
;
5609 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5611 return pStubMsg
->MemorySize
;
5614 /***********************************************************************
5615 * NdrVaryingArrayFree [RPCRT4.@]
5617 void WINAPI
NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
5618 unsigned char *pMemory
,
5619 PFORMAT_STRING pFormat
)
5623 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5625 if ((pFormat
[0] != FC_SMVARRAY
) &&
5626 (pFormat
[0] != FC_LGVARRAY
))
5628 ERR("invalid format type %x\n", pFormat
[0]);
5629 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5633 if (pFormat
[0] == FC_SMVARRAY
)
5636 pFormat
+= sizeof(WORD
);
5637 elements
= *(const WORD
*)pFormat
;
5638 pFormat
+= sizeof(WORD
);
5643 pFormat
+= sizeof(DWORD
);
5644 elements
= *(const DWORD
*)pFormat
;
5645 pFormat
+= sizeof(DWORD
);
5648 pFormat
+= sizeof(WORD
);
5650 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5651 if ((pStubMsg
->ActualCount
> elements
) ||
5652 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5654 RpcRaiseException(RPC_S_INVALID_BOUND
);
5658 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5661 static ULONG
get_discriminant(unsigned char fc
, const unsigned char *pMemory
)
5674 return *(const USHORT
*)pMemory
;
5678 return *(const ULONG
*)pMemory
;
5680 FIXME("Unhandled base type: 0x%02x\n", fc
);
5685 static PFORMAT_STRING
get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg
,
5687 PFORMAT_STRING pFormat
)
5689 unsigned short num_arms
, arm
, type
;
5691 num_arms
= *(const SHORT
*)pFormat
& 0x0fff;
5693 for(arm
= 0; arm
< num_arms
; arm
++)
5695 if(discriminant
== *(const ULONG
*)pFormat
)
5703 type
= *(const unsigned short*)pFormat
;
5704 TRACE("type %04x\n", type
);
5705 if(arm
== num_arms
) /* default arm extras */
5709 ERR("no arm for 0x%x and no default case\n", discriminant
);
5710 RpcRaiseException(RPC_S_INVALID_TAG
);
5715 TRACE("falling back to empty default case for 0x%x\n", discriminant
);
5722 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
, ULONG discriminant
, PFORMAT_STRING pFormat
)
5724 unsigned short type
;
5728 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5732 type
= *(const unsigned short*)pFormat
;
5733 if((type
& 0xff00) == 0x8000)
5735 unsigned char basetype
= LOBYTE(type
);
5736 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &basetype
);
5740 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5741 NDR_MARSHALL m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
5744 unsigned char *saved_buffer
= NULL
;
5745 BOOL pointer_buffer_mark_set
= FALSE
;
5752 align_pointer_clear(&pStubMsg
->Buffer
, 4);
5753 saved_buffer
= pStubMsg
->Buffer
;
5754 if (pStubMsg
->PointerBufferMark
)
5756 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5757 pStubMsg
->PointerBufferMark
= NULL
;
5758 pointer_buffer_mark_set
= TRUE
;
5761 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
5763 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char **)pMemory
, desc
);
5764 if (pointer_buffer_mark_set
)
5766 STD_OVERFLOW_CHECK(pStubMsg
);
5767 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5768 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5770 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5771 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
5772 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5774 pStubMsg
->Buffer
= saved_buffer
+ 4;
5778 /* must be dereferenced first */
5779 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5782 m(pStubMsg
, pMemory
, desc
);
5786 FIXME("no marshaller for embedded type %02x\n", *desc
);
5791 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5792 unsigned char **ppMemory
,
5794 PFORMAT_STRING pFormat
,
5795 unsigned char fMustAlloc
)
5797 unsigned short type
;
5801 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5805 type
= *(const unsigned short*)pFormat
;
5806 if((type
& 0xff00) == 0x8000)
5808 unsigned char basetype
= LOBYTE(type
);
5809 return NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &basetype
, FALSE
);
5813 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5814 NDR_UNMARSHALL m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
5817 unsigned char *saved_buffer
= NULL
;
5818 BOOL pointer_buffer_mark_set
= FALSE
;
5825 align_pointer(&pStubMsg
->Buffer
, 4);
5826 saved_buffer
= pStubMsg
->Buffer
;
5827 if (pStubMsg
->PointerBufferMark
)
5829 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5830 pStubMsg
->PointerBufferMark
= NULL
;
5831 pointer_buffer_mark_set
= TRUE
;
5834 pStubMsg
->Buffer
+= 4; /* for pointer ID */
5836 if (saved_buffer
+ 4 > pStubMsg
->BufferEnd
)
5838 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5839 saved_buffer
, pStubMsg
->BufferEnd
);
5840 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5843 PointerUnmarshall(pStubMsg
, saved_buffer
, *(unsigned char ***)ppMemory
, **(unsigned char ***)ppMemory
, desc
, fMustAlloc
);
5844 if (pointer_buffer_mark_set
)
5846 STD_OVERFLOW_CHECK(pStubMsg
);
5847 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5848 pStubMsg
->Buffer
= saved_buffer
+ 4;
5852 /* must be dereferenced first */
5853 m(pStubMsg
, *(unsigned char ***)ppMemory
, desc
, fMustAlloc
);
5856 m(pStubMsg
, ppMemory
, desc
, fMustAlloc
);
5860 FIXME("no marshaller for embedded type %02x\n", *desc
);
5865 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg
,
5866 unsigned char *pMemory
,
5868 PFORMAT_STRING pFormat
)
5870 unsigned short type
;
5874 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5878 type
= *(const unsigned short*)pFormat
;
5879 if((type
& 0xff00) == 0x8000)
5881 unsigned char basetype
= LOBYTE(type
);
5882 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &basetype
);
5886 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5887 NDR_BUFFERSIZE m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
5896 align_length(&pStubMsg
->BufferLength
, 4);
5897 safe_buffer_length_increment(pStubMsg
, 4); /* for pointer ID */
5898 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5900 int saved_buffer_length
= pStubMsg
->BufferLength
;
5901 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
5902 pStubMsg
->PointerLength
= 0;
5903 if(!pStubMsg
->BufferLength
)
5904 ERR("BufferLength == 0??\n");
5905 PointerBufferSize(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5906 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
5907 pStubMsg
->BufferLength
= saved_buffer_length
;
5911 /* must be dereferenced first */
5912 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5915 m(pStubMsg
, pMemory
, desc
);
5919 FIXME("no buffersizer for embedded type %02x\n", *desc
);
5923 static ULONG
union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg
,
5925 PFORMAT_STRING pFormat
)
5927 unsigned short type
, size
;
5929 size
= *(const unsigned short*)pFormat
;
5930 pStubMsg
->Memory
+= size
;
5933 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5937 type
= *(const unsigned short*)pFormat
;
5938 if((type
& 0xff00) == 0x8000)
5940 return NdrBaseTypeMemorySize(pStubMsg
, pFormat
);
5944 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5945 NDR_MEMORYSIZE m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
5946 unsigned char *saved_buffer
;
5955 align_pointer(&pStubMsg
->Buffer
, 4);
5956 saved_buffer
= pStubMsg
->Buffer
;
5957 safe_buffer_increment(pStubMsg
, 4);
5958 align_length(&pStubMsg
->MemorySize
, sizeof(void *));
5959 pStubMsg
->MemorySize
+= sizeof(void *);
5960 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5961 PointerMemorySize(pStubMsg
, saved_buffer
, pFormat
);
5964 return m(pStubMsg
, desc
);
5968 FIXME("no marshaller for embedded type %02x\n", *desc
);
5971 TRACE("size %d\n", size
);
5975 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg
,
5976 unsigned char *pMemory
,
5978 PFORMAT_STRING pFormat
)
5980 unsigned short type
;
5984 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5988 type
= *(const unsigned short*)pFormat
;
5989 if((type
& 0xff00) != 0x8000)
5991 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5992 NDR_FREE m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
6001 PointerFree(pStubMsg
, *(unsigned char **)pMemory
, desc
);
6004 /* must be dereferenced first */
6005 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
6008 m(pStubMsg
, pMemory
, desc
);
6014 /***********************************************************************
6015 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
6017 unsigned char * WINAPI
NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6018 unsigned char *pMemory
,
6019 PFORMAT_STRING pFormat
)
6021 unsigned char switch_type
;
6022 unsigned char increment
;
6025 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6028 switch_type
= *pFormat
& 0xf;
6029 increment
= (*pFormat
& 0xf0) >> 4;
6032 align_pointer_clear(&pStubMsg
->Buffer
, increment
);
6034 switch_value
= get_discriminant(switch_type
, pMemory
);
6035 TRACE("got switch value 0x%x\n", switch_value
);
6037 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &switch_type
);
6038 pMemory
+= increment
;
6040 return union_arm_marshall(pStubMsg
, pMemory
, switch_value
, pFormat
);
6043 /***********************************************************************
6044 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
6046 unsigned char * WINAPI
NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6047 unsigned char **ppMemory
,
6048 PFORMAT_STRING pFormat
,
6049 unsigned char fMustAlloc
)
6051 unsigned char switch_type
;
6052 unsigned char increment
;
6054 unsigned short size
;
6055 unsigned char *pMemoryArm
;
6057 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
6060 switch_type
= *pFormat
& 0xf;
6061 increment
= (*pFormat
& 0xf0) >> 4;
6064 align_pointer(&pStubMsg
->Buffer
, increment
);
6065 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
6066 TRACE("got switch value 0x%x\n", switch_value
);
6068 size
= *(const unsigned short*)pFormat
+ increment
;
6069 if (!fMustAlloc
&& !*ppMemory
)
6072 *ppMemory
= NdrAllocate(pStubMsg
, size
);
6074 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6075 * since the arm is part of the memory block that is encompassed by
6076 * the whole union. Memory is forced to allocate when pointers
6077 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6078 * clearing the memory we pass in to the unmarshaller */
6080 memset(*ppMemory
, 0, size
);
6082 NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &switch_type
, FALSE
);
6083 pMemoryArm
= *ppMemory
+ increment
;
6085 return union_arm_unmarshall(pStubMsg
, &pMemoryArm
, switch_value
, pFormat
, FALSE
);
6088 /***********************************************************************
6089 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
6091 void WINAPI
NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6092 unsigned char *pMemory
,
6093 PFORMAT_STRING pFormat
)
6095 unsigned char switch_type
;
6096 unsigned char increment
;
6099 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6102 switch_type
= *pFormat
& 0xf;
6103 increment
= (*pFormat
& 0xf0) >> 4;
6106 align_length(&pStubMsg
->BufferLength
, increment
);
6107 switch_value
= get_discriminant(switch_type
, pMemory
);
6108 TRACE("got switch value 0x%x\n", switch_value
);
6110 /* Add discriminant size */
6111 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&switch_value
, &switch_type
);
6112 pMemory
+= increment
;
6114 union_arm_buffer_size(pStubMsg
, pMemory
, switch_value
, pFormat
);
6117 /***********************************************************************
6118 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
6120 ULONG WINAPI
NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6121 PFORMAT_STRING pFormat
)
6123 unsigned char switch_type
;
6124 unsigned char increment
;
6127 switch_type
= *pFormat
& 0xf;
6128 increment
= (*pFormat
& 0xf0) >> 4;
6131 align_pointer(&pStubMsg
->Buffer
, increment
);
6132 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
6133 TRACE("got switch value 0x%x\n", switch_value
);
6135 pStubMsg
->Memory
+= increment
;
6137 return increment
+ union_arm_memory_size(pStubMsg
, switch_value
, pFormat
+ *(const SHORT
*)pFormat
);
6140 /***********************************************************************
6141 * NdrEncapsulatedUnionFree [RPCRT4.@]
6143 void WINAPI
NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
6144 unsigned char *pMemory
,
6145 PFORMAT_STRING pFormat
)
6147 unsigned char switch_type
;
6148 unsigned char increment
;
6151 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6154 switch_type
= *pFormat
& 0xf;
6155 increment
= (*pFormat
& 0xf0) >> 4;
6158 switch_value
= get_discriminant(switch_type
, pMemory
);
6159 TRACE("got switch value 0x%x\n", switch_value
);
6161 pMemory
+= increment
;
6163 union_arm_free(pStubMsg
, pMemory
, switch_value
, pFormat
);
6166 /***********************************************************************
6167 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
6169 unsigned char * WINAPI
NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6170 unsigned char *pMemory
,
6171 PFORMAT_STRING pFormat
)
6173 unsigned char switch_type
;
6175 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6178 switch_type
= *pFormat
;
6181 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6182 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6183 /* Marshall discriminant */
6184 NdrBaseTypeMarshall(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
6186 return union_arm_marshall(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6189 static LONG
unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg
,
6190 PFORMAT_STRING
*ppFormat
)
6192 LONG discriminant
= 0;
6202 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
6212 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6213 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
6221 align_pointer(&pStubMsg
->Buffer
, sizeof(ULONG
));
6222 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
6227 FIXME("Unhandled base type: 0x%02x\n", **ppFormat
);
6231 *ppFormat
= SkipConformance(pStubMsg
, *ppFormat
);
6232 return discriminant
;
6235 /**********************************************************************
6236 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
6238 unsigned char * WINAPI
NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6239 unsigned char **ppMemory
,
6240 PFORMAT_STRING pFormat
,
6241 unsigned char fMustAlloc
)
6244 unsigned short size
;
6246 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
6249 /* Unmarshall discriminant */
6250 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
6251 TRACE("unmarshalled discriminant %x\n", discriminant
);
6253 pFormat
+= *(const SHORT
*)pFormat
;
6255 size
= *(const unsigned short*)pFormat
;
6257 if (!fMustAlloc
&& !*ppMemory
)
6260 *ppMemory
= NdrAllocate(pStubMsg
, size
);
6262 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6263 * since the arm is part of the memory block that is encompassed by
6264 * the whole union. Memory is forced to allocate when pointers
6265 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6266 * clearing the memory we pass in to the unmarshaller */
6268 memset(*ppMemory
, 0, size
);
6270 return union_arm_unmarshall(pStubMsg
, ppMemory
, discriminant
, pFormat
, FALSE
);
6273 /***********************************************************************
6274 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
6276 void WINAPI
NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6277 unsigned char *pMemory
,
6278 PFORMAT_STRING pFormat
)
6280 unsigned char switch_type
;
6282 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6285 switch_type
= *pFormat
;
6288 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6289 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6290 /* Add discriminant size */
6291 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
6293 union_arm_buffer_size(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6296 /***********************************************************************
6297 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
6299 ULONG WINAPI
NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6300 PFORMAT_STRING pFormat
)
6305 /* Unmarshall discriminant */
6306 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
6307 TRACE("unmarshalled discriminant 0x%x\n", discriminant
);
6309 return union_arm_memory_size(pStubMsg
, discriminant
, pFormat
+ *(const SHORT
*)pFormat
);
6312 /***********************************************************************
6313 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6315 void WINAPI
NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
6316 unsigned char *pMemory
,
6317 PFORMAT_STRING pFormat
)
6319 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6323 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6324 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6326 union_arm_free(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6329 /***********************************************************************
6330 * NdrByteCountPointerMarshall [RPCRT4.@]
6332 unsigned char * WINAPI
NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6333 unsigned char *pMemory
,
6334 PFORMAT_STRING pFormat
)
6340 /***********************************************************************
6341 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6343 unsigned char * WINAPI
NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6344 unsigned char **ppMemory
,
6345 PFORMAT_STRING pFormat
,
6346 unsigned char fMustAlloc
)
6352 /***********************************************************************
6353 * NdrByteCountPointerBufferSize [RPCRT4.@]
6355 void WINAPI
NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6356 unsigned char *pMemory
,
6357 PFORMAT_STRING pFormat
)
6362 /***********************************************************************
6363 * NdrByteCountPointerMemorySize [internal]
6365 static ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6366 PFORMAT_STRING pFormat
)
6372 /***********************************************************************
6373 * NdrByteCountPointerFree [RPCRT4.@]
6375 void WINAPI
NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
6376 unsigned char *pMemory
,
6377 PFORMAT_STRING pFormat
)
6382 /***********************************************************************
6383 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6385 unsigned char * WINAPI
NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6386 unsigned char *pMemory
,
6387 PFORMAT_STRING pFormat
)
6393 /***********************************************************************
6394 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6396 unsigned char * WINAPI
NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6397 unsigned char **ppMemory
,
6398 PFORMAT_STRING pFormat
,
6399 unsigned char fMustAlloc
)
6405 /***********************************************************************
6406 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6408 void WINAPI
NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6409 unsigned char *pMemory
,
6410 PFORMAT_STRING pFormat
)
6415 /***********************************************************************
6416 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6418 ULONG WINAPI
NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6419 PFORMAT_STRING pFormat
)
6425 /***********************************************************************
6426 * NdrXmitOrRepAsFree [RPCRT4.@]
6428 void WINAPI
NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg
,
6429 unsigned char *pMemory
,
6430 PFORMAT_STRING pFormat
)
6435 /***********************************************************************
6436 * NdrRangeMarshall [internal]
6438 static unsigned char *WINAPI
NdrRangeMarshall(
6439 PMIDL_STUB_MESSAGE pStubMsg
,
6440 unsigned char *pMemory
,
6441 PFORMAT_STRING pFormat
)
6443 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6444 unsigned char base_type
;
6446 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6448 if (pRange
->type
!= FC_RANGE
)
6450 ERR("invalid format type %x\n", pRange
->type
);
6451 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6455 base_type
= pRange
->flags_type
& 0xf;
6457 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &base_type
);
6460 /***********************************************************************
6461 * NdrRangeUnmarshall [RPCRT4.@]
6463 unsigned char *WINAPI
NdrRangeUnmarshall(
6464 PMIDL_STUB_MESSAGE pStubMsg
,
6465 unsigned char **ppMemory
,
6466 PFORMAT_STRING pFormat
,
6467 unsigned char fMustAlloc
)
6469 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6470 unsigned char base_type
;
6472 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6474 if (pRange
->type
!= FC_RANGE
)
6476 ERR("invalid format type %x\n", pRange
->type
);
6477 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6480 base_type
= pRange
->flags_type
& 0xf;
6482 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6483 base_type
, pRange
->low_value
, pRange
->high_value
);
6485 #define RANGE_UNMARSHALL(mem_type, wire_type, format_spec) \
6488 align_pointer(&pStubMsg->Buffer, sizeof(wire_type)); \
6489 if (!fMustAlloc && !*ppMemory) \
6490 fMustAlloc = TRUE; \
6492 *ppMemory = NdrAllocate(pStubMsg, sizeof(mem_type)); \
6493 if (pStubMsg->Buffer + sizeof(wire_type) > pStubMsg->BufferEnd) \
6495 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6496 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6497 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6499 if ((*(wire_type *)pStubMsg->Buffer < (mem_type)pRange->low_value) || \
6500 (*(wire_type *)pStubMsg->Buffer > (mem_type)pRange->high_value)) \
6502 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6503 *(wire_type *)pStubMsg->Buffer, (mem_type)pRange->low_value, \
6504 (mem_type)pRange->high_value); \
6505 RpcRaiseException(RPC_S_INVALID_BOUND); \
6508 TRACE("*ppMemory: %p\n", *ppMemory); \
6509 **(mem_type **)ppMemory = *(wire_type *)pStubMsg->Buffer; \
6510 pStubMsg->Buffer += sizeof(wire_type); \
6517 RANGE_UNMARSHALL(UCHAR
, UCHAR
, "%d");
6518 TRACE("value: 0x%02x\n", **ppMemory
);
6522 RANGE_UNMARSHALL(CHAR
, CHAR
, "%u");
6523 TRACE("value: 0x%02x\n", **ppMemory
);
6525 case FC_WCHAR
: /* FIXME: valid? */
6527 RANGE_UNMARSHALL(USHORT
, USHORT
, "%u");
6528 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6531 RANGE_UNMARSHALL(SHORT
, SHORT
, "%d");
6532 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6536 RANGE_UNMARSHALL(LONG
, LONG
, "%d");
6537 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6540 RANGE_UNMARSHALL(ULONG
, ULONG
, "%u");
6541 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6544 RANGE_UNMARSHALL(UINT
, USHORT
, "%u");
6545 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
6551 ERR("invalid range base type: 0x%02x\n", base_type
);
6552 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6558 /***********************************************************************
6559 * NdrRangeBufferSize [internal]
6561 static void WINAPI
NdrRangeBufferSize(
6562 PMIDL_STUB_MESSAGE pStubMsg
,
6563 unsigned char *pMemory
,
6564 PFORMAT_STRING pFormat
)
6566 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6567 unsigned char base_type
;
6569 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6571 if (pRange
->type
!= FC_RANGE
)
6573 ERR("invalid format type %x\n", pRange
->type
);
6574 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6576 base_type
= pRange
->flags_type
& 0xf;
6578 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &base_type
);
6581 /***********************************************************************
6582 * NdrRangeMemorySize [internal]
6584 static ULONG WINAPI
NdrRangeMemorySize(
6585 PMIDL_STUB_MESSAGE pStubMsg
,
6586 PFORMAT_STRING pFormat
)
6588 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6589 unsigned char base_type
;
6591 if (pRange
->type
!= FC_RANGE
)
6593 ERR("invalid format type %x\n", pRange
->type
);
6594 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6597 base_type
= pRange
->flags_type
& 0xf;
6599 return NdrBaseTypeMemorySize(pStubMsg
, &base_type
);
6602 /***********************************************************************
6603 * NdrRangeFree [internal]
6605 static void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6606 unsigned char *pMemory
,
6607 PFORMAT_STRING pFormat
)
6609 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6614 /***********************************************************************
6615 * NdrBaseTypeMarshall [internal]
6617 static unsigned char *WINAPI
NdrBaseTypeMarshall(
6618 PMIDL_STUB_MESSAGE pStubMsg
,
6619 unsigned char *pMemory
,
6620 PFORMAT_STRING pFormat
)
6622 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6630 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(UCHAR
));
6631 TRACE("value: 0x%02x\n", *pMemory
);
6636 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(USHORT
));
6637 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(USHORT
));
6638 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
6642 case FC_ERROR_STATUS_T
:
6644 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(ULONG
));
6645 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONG
));
6646 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
6649 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(float));
6650 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
6653 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(double));
6654 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
6657 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(ULONGLONG
));
6658 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONGLONG
));
6659 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
6663 USHORT val
= *(UINT
*)pMemory
;
6664 /* only 16-bits on the wire, so do a sanity check */
6665 if (*(UINT
*)pMemory
> SHRT_MAX
)
6666 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
6667 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(USHORT
));
6668 safe_copy_to_buffer(pStubMsg
, &val
, sizeof(val
));
6669 TRACE("value: 0x%04x\n", *(UINT
*)pMemory
);
6675 UINT val
= *(UINT_PTR
*)pMemory
;
6676 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(UINT
));
6677 safe_copy_to_buffer(pStubMsg
, &val
, sizeof(val
));
6683 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6686 /* FIXME: what is the correct return value? */
6690 /***********************************************************************
6691 * NdrBaseTypeUnmarshall [internal]
6693 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(
6694 PMIDL_STUB_MESSAGE pStubMsg
,
6695 unsigned char **ppMemory
,
6696 PFORMAT_STRING pFormat
,
6697 unsigned char fMustAlloc
)
6699 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6701 #define BASE_TYPE_UNMARSHALL(type) do { \
6702 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
6703 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6705 *ppMemory = pStubMsg->Buffer; \
6706 TRACE("*ppMemory: %p\n", *ppMemory); \
6707 safe_buffer_increment(pStubMsg, sizeof(type)); \
6712 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6713 TRACE("*ppMemory: %p\n", *ppMemory); \
6714 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6724 BASE_TYPE_UNMARSHALL(UCHAR
);
6725 TRACE("value: 0x%02x\n", **ppMemory
);
6730 BASE_TYPE_UNMARSHALL(USHORT
);
6731 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6735 case FC_ERROR_STATUS_T
:
6737 BASE_TYPE_UNMARSHALL(ULONG
);
6738 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6741 BASE_TYPE_UNMARSHALL(float);
6742 TRACE("value: %f\n", **(float **)ppMemory
);
6745 BASE_TYPE_UNMARSHALL(double);
6746 TRACE("value: %f\n", **(double **)ppMemory
);
6749 BASE_TYPE_UNMARSHALL(ULONGLONG
);
6750 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG
**)ppMemory
));
6755 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6756 if (!fMustAlloc
&& !*ppMemory
)
6759 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT
));
6760 safe_copy_from_buffer(pStubMsg
, &val
, sizeof(USHORT
));
6761 /* 16-bits on the wire, but int in memory */
6762 **(UINT
**)ppMemory
= val
;
6763 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
6767 if (sizeof(INT_PTR
) == sizeof(INT
)) BASE_TYPE_UNMARSHALL(INT
);
6771 align_pointer(&pStubMsg
->Buffer
, sizeof(INT
));
6772 if (!fMustAlloc
&& !*ppMemory
)
6775 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(INT_PTR
));
6776 safe_copy_from_buffer(pStubMsg
, &val
, sizeof(INT
));
6777 **(INT_PTR
**)ppMemory
= val
;
6778 TRACE("value: 0x%08lx\n", **(INT_PTR
**)ppMemory
);
6782 if (sizeof(UINT_PTR
) == sizeof(UINT
)) BASE_TYPE_UNMARSHALL(UINT
);
6786 align_pointer(&pStubMsg
->Buffer
, sizeof(UINT
));
6787 if (!fMustAlloc
&& !*ppMemory
)
6790 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT_PTR
));
6791 safe_copy_from_buffer(pStubMsg
, &val
, sizeof(UINT
));
6792 **(UINT_PTR
**)ppMemory
= val
;
6793 TRACE("value: 0x%08lx\n", **(UINT_PTR
**)ppMemory
);
6799 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6801 #undef BASE_TYPE_UNMARSHALL
6803 /* FIXME: what is the correct return value? */
6808 /***********************************************************************
6809 * NdrBaseTypeBufferSize [internal]
6811 static void WINAPI
NdrBaseTypeBufferSize(
6812 PMIDL_STUB_MESSAGE pStubMsg
,
6813 unsigned char *pMemory
,
6814 PFORMAT_STRING pFormat
)
6816 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6824 safe_buffer_length_increment(pStubMsg
, sizeof(UCHAR
));
6830 align_length(&pStubMsg
->BufferLength
, sizeof(USHORT
));
6831 safe_buffer_length_increment(pStubMsg
, sizeof(USHORT
));
6838 align_length(&pStubMsg
->BufferLength
, sizeof(ULONG
));
6839 safe_buffer_length_increment(pStubMsg
, sizeof(ULONG
));
6842 align_length(&pStubMsg
->BufferLength
, sizeof(float));
6843 safe_buffer_length_increment(pStubMsg
, sizeof(float));
6846 align_length(&pStubMsg
->BufferLength
, sizeof(double));
6847 safe_buffer_length_increment(pStubMsg
, sizeof(double));
6850 align_length(&pStubMsg
->BufferLength
, sizeof(ULONGLONG
));
6851 safe_buffer_length_increment(pStubMsg
, sizeof(ULONGLONG
));
6853 case FC_ERROR_STATUS_T
:
6854 align_length(&pStubMsg
->BufferLength
, sizeof(error_status_t
));
6855 safe_buffer_length_increment(pStubMsg
, sizeof(error_status_t
));
6860 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6864 /***********************************************************************
6865 * NdrBaseTypeMemorySize [internal]
6867 static ULONG WINAPI
NdrBaseTypeMemorySize(
6868 PMIDL_STUB_MESSAGE pStubMsg
,
6869 PFORMAT_STRING pFormat
)
6871 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg
, *pFormat
);
6879 safe_buffer_increment(pStubMsg
, sizeof(UCHAR
));
6880 pStubMsg
->MemorySize
+= sizeof(UCHAR
);
6881 return sizeof(UCHAR
);
6885 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6886 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6887 align_length(&pStubMsg
->MemorySize
, sizeof(USHORT
));
6888 pStubMsg
->MemorySize
+= sizeof(USHORT
);
6889 return sizeof(USHORT
);
6893 align_pointer(&pStubMsg
->Buffer
, sizeof(ULONG
));
6894 safe_buffer_increment(pStubMsg
, sizeof(ULONG
));
6895 align_length(&pStubMsg
->MemorySize
, sizeof(ULONG
));
6896 pStubMsg
->MemorySize
+= sizeof(ULONG
);
6897 return sizeof(ULONG
);
6899 align_pointer(&pStubMsg
->Buffer
, sizeof(float));
6900 safe_buffer_increment(pStubMsg
, sizeof(float));
6901 align_length(&pStubMsg
->MemorySize
, sizeof(float));
6902 pStubMsg
->MemorySize
+= sizeof(float);
6903 return sizeof(float);
6905 align_pointer(&pStubMsg
->Buffer
, sizeof(double));
6906 safe_buffer_increment(pStubMsg
, sizeof(double));
6907 align_length(&pStubMsg
->MemorySize
, sizeof(double));
6908 pStubMsg
->MemorySize
+= sizeof(double);
6909 return sizeof(double);
6911 align_pointer(&pStubMsg
->Buffer
, sizeof(ULONGLONG
));
6912 safe_buffer_increment(pStubMsg
, sizeof(ULONGLONG
));
6913 align_length(&pStubMsg
->MemorySize
, sizeof(ULONGLONG
));
6914 pStubMsg
->MemorySize
+= sizeof(ULONGLONG
);
6915 return sizeof(ULONGLONG
);
6916 case FC_ERROR_STATUS_T
:
6917 align_pointer(&pStubMsg
->Buffer
, sizeof(error_status_t
));
6918 safe_buffer_increment(pStubMsg
, sizeof(error_status_t
));
6919 align_length(&pStubMsg
->MemorySize
, sizeof(error_status_t
));
6920 pStubMsg
->MemorySize
+= sizeof(error_status_t
);
6921 return sizeof(error_status_t
);
6923 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6924 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6925 align_length(&pStubMsg
->MemorySize
, sizeof(UINT
));
6926 pStubMsg
->MemorySize
+= sizeof(UINT
);
6927 return sizeof(UINT
);
6930 align_pointer(&pStubMsg
->Buffer
, sizeof(UINT
));
6931 safe_buffer_increment(pStubMsg
, sizeof(UINT
));
6932 align_length(&pStubMsg
->MemorySize
, sizeof(UINT_PTR
));
6933 pStubMsg
->MemorySize
+= sizeof(UINT_PTR
);
6934 return sizeof(UINT_PTR
);
6936 align_length(&pStubMsg
->MemorySize
, sizeof(void *));
6937 pStubMsg
->MemorySize
+= sizeof(void *);
6938 return sizeof(void *);
6940 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6945 /***********************************************************************
6946 * NdrBaseTypeFree [internal]
6948 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6949 unsigned char *pMemory
,
6950 PFORMAT_STRING pFormat
)
6952 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6957 /***********************************************************************
6958 * NdrContextHandleBufferSize [internal]
6960 static void WINAPI
NdrContextHandleBufferSize(
6961 PMIDL_STUB_MESSAGE pStubMsg
,
6962 unsigned char *pMemory
,
6963 PFORMAT_STRING pFormat
)
6965 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6967 if (*pFormat
!= FC_BIND_CONTEXT
)
6969 ERR("invalid format type %x\n", *pFormat
);
6970 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6972 align_length(&pStubMsg
->BufferLength
, 4);
6973 safe_buffer_length_increment(pStubMsg
, cbNDRContext
);
6976 /***********************************************************************
6977 * NdrContextHandleMarshall [internal]
6979 static unsigned char *WINAPI
NdrContextHandleMarshall(
6980 PMIDL_STUB_MESSAGE pStubMsg
,
6981 unsigned char *pMemory
,
6982 PFORMAT_STRING pFormat
)
6984 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6986 if (*pFormat
!= FC_BIND_CONTEXT
)
6988 ERR("invalid format type %x\n", *pFormat
);
6989 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6991 TRACE("flags: 0x%02x\n", pFormat
[1]);
6993 if (pStubMsg
->IsClient
)
6995 if (pFormat
[1] & HANDLE_PARAM_IS_VIA_PTR
)
6996 NdrClientContextMarshall(pStubMsg
, *(NDR_CCONTEXT
**)pMemory
, FALSE
);
6998 NdrClientContextMarshall(pStubMsg
, pMemory
, FALSE
);
7002 NDR_SCONTEXT ctxt
= CONTAINING_RECORD(pMemory
, struct _NDR_SCONTEXT
, userContext
);
7003 NDR_RUNDOWN rundown
= pStubMsg
->StubDesc
->apfnNdrRundownRoutines
[pFormat
[2]];
7004 NdrServerContextNewMarshall(pStubMsg
, ctxt
, rundown
, pFormat
);
7010 /***********************************************************************
7011 * NdrContextHandleUnmarshall [internal]
7013 static unsigned char *WINAPI
NdrContextHandleUnmarshall(
7014 PMIDL_STUB_MESSAGE pStubMsg
,
7015 unsigned char **ppMemory
,
7016 PFORMAT_STRING pFormat
,
7017 unsigned char fMustAlloc
)
7019 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg
,
7020 ppMemory
, pFormat
, fMustAlloc
? "TRUE": "FALSE");
7022 if (*pFormat
!= FC_BIND_CONTEXT
)
7024 ERR("invalid format type %x\n", *pFormat
);
7025 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
7027 TRACE("flags: 0x%02x\n", pFormat
[1]);
7029 if (pStubMsg
->IsClient
)
7031 NDR_CCONTEXT
*ccontext
;
7032 if (pFormat
[1] & HANDLE_PARAM_IS_VIA_PTR
)
7033 ccontext
= *(NDR_CCONTEXT
**)ppMemory
;
7035 ccontext
= (NDR_CCONTEXT
*)ppMemory
;
7036 /* [out]-only or [ret] param */
7037 if ((pFormat
[1] & (HANDLE_PARAM_IS_IN
|HANDLE_PARAM_IS_OUT
)) == HANDLE_PARAM_IS_OUT
)
7039 NdrClientContextUnmarshall(pStubMsg
, ccontext
, pStubMsg
->RpcMsg
->Handle
);
7044 ctxt
= NdrServerContextNewUnmarshall(pStubMsg
, pFormat
);
7045 if (pFormat
[1] & HANDLE_PARAM_IS_VIA_PTR
)
7046 *(void **)ppMemory
= NDRSContextValue(ctxt
);
7048 *(void **)ppMemory
= *NDRSContextValue(ctxt
);
7054 /***********************************************************************
7055 * NdrClientContextMarshall [RPCRT4.@]
7057 void WINAPI
NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7058 NDR_CCONTEXT ContextHandle
,
7061 TRACE("(%p, %p, %d)\n", pStubMsg
, ContextHandle
, fCheck
);
7063 align_pointer_clear(&pStubMsg
->Buffer
, 4);
7065 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7067 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7068 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7069 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7072 /* FIXME: what does fCheck do? */
7073 NDRCContextMarshall(ContextHandle
,
7076 pStubMsg
->Buffer
+= cbNDRContext
;
7079 /***********************************************************************
7080 * NdrClientContextUnmarshall [RPCRT4.@]
7082 void WINAPI
NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7083 NDR_CCONTEXT
* pContextHandle
,
7084 RPC_BINDING_HANDLE BindHandle
)
7086 TRACE("(%p, %p, %p)\n", pStubMsg
, pContextHandle
, BindHandle
);
7088 align_pointer(&pStubMsg
->Buffer
, 4);
7090 if (pStubMsg
->Buffer
+ cbNDRContext
> pStubMsg
->BufferEnd
)
7091 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7093 NDRCContextUnmarshall(pContextHandle
,
7096 pStubMsg
->RpcMsg
->DataRepresentation
);
7098 pStubMsg
->Buffer
+= cbNDRContext
;
7101 void WINAPI
NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7102 NDR_SCONTEXT ContextHandle
,
7103 NDR_RUNDOWN RundownRoutine
)
7105 TRACE("(%p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
);
7107 align_pointer(&pStubMsg
->Buffer
, 4);
7109 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7111 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7112 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7113 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7116 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
7117 pStubMsg
->Buffer
, RundownRoutine
, NULL
,
7118 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
7119 pStubMsg
->Buffer
+= cbNDRContext
;
7122 NDR_SCONTEXT WINAPI
NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
)
7124 NDR_SCONTEXT ContextHandle
;
7126 TRACE("(%p)\n", pStubMsg
);
7128 align_pointer(&pStubMsg
->Buffer
, 4);
7130 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7132 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7133 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7134 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7137 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
7139 pStubMsg
->RpcMsg
->DataRepresentation
,
7140 NULL
, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
7141 pStubMsg
->Buffer
+= cbNDRContext
;
7143 return ContextHandle
;
7146 void WINAPI
NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg
,
7147 unsigned char* pMemory
,
7148 PFORMAT_STRING pFormat
)
7150 FIXME("(%p, %p, %p): stub\n", pStubMsg
, pMemory
, pFormat
);
7153 NDR_SCONTEXT WINAPI
NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg
,
7154 PFORMAT_STRING pFormat
)
7156 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
7157 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
7159 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
7161 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
7162 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
7163 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NOSERIALIZE
)
7164 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
7165 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
7167 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
7168 if_id
= &sif
->InterfaceId
;
7171 return NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
, NULL
,
7172 pStubMsg
->RpcMsg
->DataRepresentation
, if_id
,
7176 void WINAPI
NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7177 NDR_SCONTEXT ContextHandle
,
7178 NDR_RUNDOWN RundownRoutine
,
7179 PFORMAT_STRING pFormat
)
7181 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
7182 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
7184 TRACE("(%p, %p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
, pFormat
);
7186 align_pointer(&pStubMsg
->Buffer
, 4);
7188 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7190 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7191 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7192 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7195 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
7196 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
7197 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NOSERIALIZE
)
7198 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
7199 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
7201 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
7202 if_id
= &sif
->InterfaceId
;
7205 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
7206 pStubMsg
->Buffer
, RundownRoutine
, if_id
, flags
);
7207 pStubMsg
->Buffer
+= cbNDRContext
;
7210 NDR_SCONTEXT WINAPI
NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7211 PFORMAT_STRING pFormat
)
7213 NDR_SCONTEXT ContextHandle
;
7214 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
7215 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
7217 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
7219 align_pointer(&pStubMsg
->Buffer
, 4);
7221 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7223 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7224 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7225 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7228 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
7229 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
7230 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NOSERIALIZE
)
7231 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
7232 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
7234 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
7235 if_id
= &sif
->InterfaceId
;
7238 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
7240 pStubMsg
->RpcMsg
->DataRepresentation
,
7242 pStubMsg
->Buffer
+= cbNDRContext
;
7244 return ContextHandle
;
7247 /***********************************************************************
7248 * NdrCorrelationInitialize [RPCRT4.@]
7250 * Initializes correlation validity checking.
7253 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7254 * pMemory [I] Pointer to memory to use as a cache.
7255 * CacheSize [I] Size of the memory pointed to by pMemory.
7256 * Flags [I] Reserved. Set to zero.
7261 void WINAPI
NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg
, void *pMemory
, ULONG CacheSize
, ULONG Flags
)
7266 FIXME("(%p, %p, %d, 0x%x): semi-stub\n", pStubMsg
, pMemory
, CacheSize
, Flags
);
7268 if (pStubMsg
->CorrDespIncrement
== 0)
7269 pStubMsg
->CorrDespIncrement
= 2; /* size of the normal (non-range) /robust payload */
7271 pStubMsg
->fHasNewCorrDesc
= TRUE
;
7274 /***********************************************************************
7275 * NdrCorrelationPass [RPCRT4.@]
7277 * Performs correlation validity checking.
7280 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7285 void WINAPI
NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg
)
7287 FIXME("(%p): stub\n", pStubMsg
);
7290 /***********************************************************************
7291 * NdrCorrelationFree [RPCRT4.@]
7293 * Frees any resources used while unmarshalling parameters that need
7294 * correlation validity checking.
7297 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7302 void WINAPI
NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg
)
7307 FIXME("(%p): stub\n", pStubMsg
);