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
32 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
35 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
36 (*((UINT32 *)(pchar)) = (uint32))
38 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
39 (*((UINT32 *)(pchar)))
41 /* these would work for i386 too, but less efficient */
42 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
43 (*(pchar) = LOBYTE(LOWORD(uint32)), \
44 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
45 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
46 *((pchar)+3) = HIBYTE(HIWORD(uint32)))
48 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
50 MAKEWORD(*(pchar), *((pchar)+1)), \
51 MAKEWORD(*((pchar)+2), *((pchar)+3))))
54 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
55 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
56 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
57 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
58 *(pchar) = HIBYTE(HIWORD(uint32)))
60 #define BIG_ENDIAN_UINT32_READ(pchar) \
62 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
63 MAKEWORD(*((pchar)+1), *(pchar))))
65 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
66 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
67 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
68 # define NDR_LOCAL_UINT32_READ(pchar) \
69 BIG_ENDIAN_UINT32_READ(pchar)
71 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
72 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
73 # define NDR_LOCAL_UINT32_READ(pchar) \
74 LITTLE_ENDIAN_UINT32_READ(pchar)
77 static inline void align_length( ULONG
*len
, unsigned int align
)
79 *len
= (*len
+ align
- 1) & ~(align
- 1);
82 static inline void align_pointer( unsigned char **ptr
, unsigned int align
)
84 ULONG_PTR mask
= align
- 1;
85 *ptr
= (unsigned char *)(((ULONG_PTR
)*ptr
+ mask
) & ~mask
);
88 static inline void align_pointer_clear( unsigned char **ptr
, unsigned int align
)
90 ULONG_PTR mask
= align
- 1;
91 memset( *ptr
, 0, (align
- (ULONG_PTR
)*ptr
) & mask
);
92 *ptr
= (unsigned char *)(((ULONG_PTR
)*ptr
+ mask
) & ~mask
);
95 #define STD_OVERFLOW_CHECK(_Msg) do { \
96 TRACE("buffer=%d/%d\n", (ULONG)(_Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer), _Msg->BufferLength); \
97 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
98 ERR("buffer overflow %d bytes\n", (ULONG)(_Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength))); \
101 #define NDR_POINTER_ID_BASE 0x20000
102 #define NDR_POINTER_ID(pStubMsg) (NDR_POINTER_ID_BASE + ((pStubMsg)->UniquePtrCount++) * 4)
103 #define NDR_TABLE_SIZE 128
104 #define NDR_TABLE_MASK 127
106 #define NDRSContextFromValue(user_context) (NDR_SCONTEXT)((char *)(user_context) - (char *)NDRSContextValue((NDR_SCONTEXT)NULL))
108 static unsigned char *WINAPI
NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
109 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
110 static void WINAPI
NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
111 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
112 static ULONG WINAPI
NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
114 static unsigned char *WINAPI
NdrContextHandleMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
115 static void WINAPI
NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
116 static unsigned char *WINAPI
NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
118 static unsigned char *WINAPI
NdrRangeMarshall(PMIDL_STUB_MESSAGE
,unsigned char *, PFORMAT_STRING
);
119 static void WINAPI
NdrRangeBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
120 static ULONG WINAPI
NdrRangeMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
121 static void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
123 static ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
125 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
126 unsigned char *pMemory
,
127 PFORMAT_STRING pFormat
,
128 PFORMAT_STRING pPointer
);
129 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
130 unsigned char *pMemory
,
131 PFORMAT_STRING pFormat
,
132 PFORMAT_STRING pPointer
);
133 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
134 unsigned char *pMemory
,
135 PFORMAT_STRING pFormat
,
136 PFORMAT_STRING pPointer
,
137 unsigned char fMustAlloc
);
138 static ULONG
ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
139 PFORMAT_STRING pFormat
,
140 PFORMAT_STRING pPointer
);
141 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
142 unsigned char *pMemory
,
143 PFORMAT_STRING pFormat
,
144 PFORMAT_STRING pPointer
);
146 const NDR_MARSHALL NdrMarshaller
[NDR_TABLE_SIZE
] = {
148 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
149 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
150 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
151 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
155 NdrPointerMarshall
, NdrPointerMarshall
,
156 NdrPointerMarshall
, NdrPointerMarshall
,
158 NdrSimpleStructMarshall
, NdrSimpleStructMarshall
,
159 NdrConformantStructMarshall
, NdrConformantStructMarshall
,
160 NdrConformantVaryingStructMarshall
,
161 NdrComplexStructMarshall
,
163 NdrConformantArrayMarshall
,
164 NdrConformantVaryingArrayMarshall
,
165 NdrFixedArrayMarshall
, NdrFixedArrayMarshall
,
166 NdrVaryingArrayMarshall
, NdrVaryingArrayMarshall
,
167 NdrComplexArrayMarshall
,
169 NdrConformantStringMarshall
, 0, 0,
170 NdrConformantStringMarshall
,
171 NdrNonConformantStringMarshall
, 0, 0, 0,
173 NdrEncapsulatedUnionMarshall
,
174 NdrNonEncapsulatedUnionMarshall
,
175 NdrByteCountPointerMarshall
,
176 NdrXmitOrRepAsMarshall
, NdrXmitOrRepAsMarshall
,
178 NdrInterfacePointerMarshall
,
180 NdrContextHandleMarshall
,
183 NdrUserMarshalMarshall
,
188 const NDR_UNMARSHALL NdrUnmarshaller
[NDR_TABLE_SIZE
] = {
190 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
191 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
192 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
193 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
195 NdrBaseTypeUnmarshall
,
197 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
198 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
200 NdrSimpleStructUnmarshall
, NdrSimpleStructUnmarshall
,
201 NdrConformantStructUnmarshall
, NdrConformantStructUnmarshall
,
202 NdrConformantVaryingStructUnmarshall
,
203 NdrComplexStructUnmarshall
,
205 NdrConformantArrayUnmarshall
,
206 NdrConformantVaryingArrayUnmarshall
,
207 NdrFixedArrayUnmarshall
, NdrFixedArrayUnmarshall
,
208 NdrVaryingArrayUnmarshall
, NdrVaryingArrayUnmarshall
,
209 NdrComplexArrayUnmarshall
,
211 NdrConformantStringUnmarshall
, 0, 0,
212 NdrConformantStringUnmarshall
,
213 NdrNonConformantStringUnmarshall
, 0, 0, 0,
215 NdrEncapsulatedUnionUnmarshall
,
216 NdrNonEncapsulatedUnionUnmarshall
,
217 NdrByteCountPointerUnmarshall
,
218 NdrXmitOrRepAsUnmarshall
, NdrXmitOrRepAsUnmarshall
,
220 NdrInterfacePointerUnmarshall
,
222 NdrContextHandleUnmarshall
,
225 NdrUserMarshalUnmarshall
,
230 const NDR_BUFFERSIZE NdrBufferSizer
[NDR_TABLE_SIZE
] = {
232 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
233 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
234 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
235 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
237 NdrBaseTypeBufferSize
,
239 NdrPointerBufferSize
, NdrPointerBufferSize
,
240 NdrPointerBufferSize
, NdrPointerBufferSize
,
242 NdrSimpleStructBufferSize
, NdrSimpleStructBufferSize
,
243 NdrConformantStructBufferSize
, NdrConformantStructBufferSize
,
244 NdrConformantVaryingStructBufferSize
,
245 NdrComplexStructBufferSize
,
247 NdrConformantArrayBufferSize
,
248 NdrConformantVaryingArrayBufferSize
,
249 NdrFixedArrayBufferSize
, NdrFixedArrayBufferSize
,
250 NdrVaryingArrayBufferSize
, NdrVaryingArrayBufferSize
,
251 NdrComplexArrayBufferSize
,
253 NdrConformantStringBufferSize
, 0, 0,
254 NdrConformantStringBufferSize
,
255 NdrNonConformantStringBufferSize
, 0, 0, 0,
257 NdrEncapsulatedUnionBufferSize
,
258 NdrNonEncapsulatedUnionBufferSize
,
259 NdrByteCountPointerBufferSize
,
260 NdrXmitOrRepAsBufferSize
, NdrXmitOrRepAsBufferSize
,
262 NdrInterfacePointerBufferSize
,
264 NdrContextHandleBufferSize
,
267 NdrUserMarshalBufferSize
,
272 const NDR_MEMORYSIZE NdrMemorySizer
[NDR_TABLE_SIZE
] = {
274 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
275 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
276 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
277 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
279 NdrBaseTypeMemorySize
,
281 NdrPointerMemorySize
, NdrPointerMemorySize
,
282 NdrPointerMemorySize
, NdrPointerMemorySize
,
284 NdrSimpleStructMemorySize
, NdrSimpleStructMemorySize
,
285 NdrConformantStructMemorySize
, NdrConformantStructMemorySize
,
286 NdrConformantVaryingStructMemorySize
,
287 NdrComplexStructMemorySize
,
289 NdrConformantArrayMemorySize
,
290 NdrConformantVaryingArrayMemorySize
,
291 NdrFixedArrayMemorySize
, NdrFixedArrayMemorySize
,
292 NdrVaryingArrayMemorySize
, NdrVaryingArrayMemorySize
,
293 NdrComplexArrayMemorySize
,
295 NdrConformantStringMemorySize
, 0, 0,
296 NdrConformantStringMemorySize
,
297 NdrNonConformantStringMemorySize
, 0, 0, 0,
299 NdrEncapsulatedUnionMemorySize
,
300 NdrNonEncapsulatedUnionMemorySize
,
301 NdrByteCountPointerMemorySize
,
302 NdrXmitOrRepAsMemorySize
, NdrXmitOrRepAsMemorySize
,
304 NdrInterfacePointerMemorySize
,
309 NdrUserMarshalMemorySize
,
314 const NDR_FREE NdrFreer
[NDR_TABLE_SIZE
] = {
316 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
317 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
318 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
319 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
323 NdrPointerFree
, NdrPointerFree
,
324 NdrPointerFree
, NdrPointerFree
,
326 NdrSimpleStructFree
, NdrSimpleStructFree
,
327 NdrConformantStructFree
, NdrConformantStructFree
,
328 NdrConformantVaryingStructFree
,
329 NdrComplexStructFree
,
331 NdrConformantArrayFree
,
332 NdrConformantVaryingArrayFree
,
333 NdrFixedArrayFree
, NdrFixedArrayFree
,
334 NdrVaryingArrayFree
, NdrVaryingArrayFree
,
340 NdrEncapsulatedUnionFree
,
341 NdrNonEncapsulatedUnionFree
,
343 NdrXmitOrRepAsFree
, NdrXmitOrRepAsFree
,
345 NdrInterfacePointerFree
,
356 typedef struct _NDR_MEMORY_LIST
361 struct _NDR_MEMORY_LIST
*next
;
364 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
366 /***********************************************************************
367 * NdrAllocate [RPCRT4.@]
369 * Allocates a block of memory using pStubMsg->pfnAllocate.
372 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
373 * len [I] Size of memory block to allocate.
376 * The memory block of size len that was allocated.
379 * The memory block is always 8-byte aligned.
380 * If the function is unable to allocate memory an ERROR_OUTOFMEMORY
381 * exception is raised.
383 void * WINAPI
NdrAllocate(MIDL_STUB_MESSAGE
*pStubMsg
, SIZE_T len
)
388 NDR_MEMORY_LIST
*mem_list
;
390 aligned_len
= (len
+ 7) & ~7;
391 adjusted_len
= aligned_len
+ sizeof(NDR_MEMORY_LIST
);
392 /* check for overflow */
393 if (adjusted_len
< len
)
395 ERR("overflow of adjusted_len %ld, len %ld\n", adjusted_len
, len
);
396 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
399 p
= pStubMsg
->pfnAllocate(adjusted_len
);
400 if (!p
) RpcRaiseException(ERROR_OUTOFMEMORY
);
402 mem_list
= (NDR_MEMORY_LIST
*)((char *)p
+ aligned_len
);
403 mem_list
->magic
= MEML_MAGIC
;
404 mem_list
->size
= aligned_len
;
405 mem_list
->reserved
= 0;
406 mem_list
->next
= pStubMsg
->pMemoryList
;
407 pStubMsg
->pMemoryList
= mem_list
;
413 static void NdrFree(MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *Pointer
)
415 TRACE("(%p, %p)\n", pStubMsg
, Pointer
);
417 pStubMsg
->pfnFree(Pointer
);
420 static inline BOOL
IsConformanceOrVariancePresent(PFORMAT_STRING pFormat
)
422 return (*(const ULONG
*)pFormat
!= -1);
425 static PFORMAT_STRING
ReadConformance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
)
427 align_pointer(&pStubMsg
->Buffer
, 4);
428 if (pStubMsg
->Buffer
+ 4 > pStubMsg
->BufferEnd
)
429 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
430 pStubMsg
->MaxCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
431 pStubMsg
->Buffer
+= 4;
432 TRACE("unmarshalled conformance is %ld\n", pStubMsg
->MaxCount
);
433 if (pStubMsg
->fHasNewCorrDesc
)
439 static inline PFORMAT_STRING
ReadVariance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
, ULONG MaxValue
)
441 if (pFormat
&& !IsConformanceOrVariancePresent(pFormat
))
443 pStubMsg
->Offset
= 0;
444 pStubMsg
->ActualCount
= pStubMsg
->MaxCount
;
448 align_pointer(&pStubMsg
->Buffer
, 4);
449 if (pStubMsg
->Buffer
+ 8 > pStubMsg
->BufferEnd
)
450 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
451 pStubMsg
->Offset
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
452 pStubMsg
->Buffer
+= 4;
453 TRACE("offset is %d\n", pStubMsg
->Offset
);
454 pStubMsg
->ActualCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
455 pStubMsg
->Buffer
+= 4;
456 TRACE("variance is %d\n", pStubMsg
->ActualCount
);
458 if ((pStubMsg
->ActualCount
> MaxValue
) ||
459 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> MaxValue
))
461 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
462 pStubMsg
->ActualCount
, pStubMsg
->Offset
, MaxValue
);
463 RpcRaiseException(RPC_S_INVALID_BOUND
);
468 if (pStubMsg
->fHasNewCorrDesc
)
474 /* writes the conformance value to the buffer */
475 static inline void WriteConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
477 align_pointer_clear(&pStubMsg
->Buffer
, 4);
478 if (pStubMsg
->Buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
479 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
480 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->MaxCount
);
481 pStubMsg
->Buffer
+= 4;
484 /* writes the variance values to the buffer */
485 static inline void WriteVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
487 align_pointer_clear(&pStubMsg
->Buffer
, 4);
488 if (pStubMsg
->Buffer
+ 8 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
489 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
490 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->Offset
);
491 pStubMsg
->Buffer
+= 4;
492 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->ActualCount
);
493 pStubMsg
->Buffer
+= 4;
496 /* requests buffer space for the conformance value */
497 static inline void SizeConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
499 align_length(&pStubMsg
->BufferLength
, 4);
500 if (pStubMsg
->BufferLength
+ 4 < pStubMsg
->BufferLength
)
501 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
502 pStubMsg
->BufferLength
+= 4;
505 /* requests buffer space for the variance values */
506 static inline void SizeVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
508 align_length(&pStubMsg
->BufferLength
, 4);
509 if (pStubMsg
->BufferLength
+ 8 < pStubMsg
->BufferLength
)
510 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
511 pStubMsg
->BufferLength
+= 8;
514 PFORMAT_STRING
ComputeConformanceOrVariance(
515 MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *pMemory
,
516 PFORMAT_STRING pFormat
, ULONG_PTR def
, ULONG_PTR
*pCount
)
518 BYTE dtype
= pFormat
[0] & 0xf;
519 short ofs
= *(const short *)&pFormat
[2];
523 if (!IsConformanceOrVariancePresent(pFormat
)) {
524 /* null descriptor */
529 switch (pFormat
[0] & 0xf0) {
530 case RPC_FC_NORMAL_CONFORMANCE
:
531 TRACE("normal conformance, ofs=%d\n", ofs
);
534 case RPC_FC_POINTER_CONFORMANCE
:
535 TRACE("pointer conformance, ofs=%d\n", ofs
);
536 ptr
= pStubMsg
->Memory
;
538 case RPC_FC_TOP_LEVEL_CONFORMANCE
:
539 TRACE("toplevel conformance, ofs=%d\n", ofs
);
540 if (pStubMsg
->StackTop
) {
541 ptr
= pStubMsg
->StackTop
;
544 /* -Os mode, *pCount is already set */
548 case RPC_FC_CONSTANT_CONFORMANCE
:
549 data
= ofs
| ((DWORD
)pFormat
[1] << 16);
550 TRACE("constant conformance, val=%ld\n", data
);
553 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE
:
554 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs
);
555 if (pStubMsg
->StackTop
) {
556 ptr
= pStubMsg
->StackTop
;
564 FIXME("unknown conformance type %x, expect crash.\n", pFormat
[0] & 0xf0);
568 switch (pFormat
[1]) {
569 case RPC_FC_DEREFERENCE
:
570 ptr
= *(LPVOID
*)((char *)ptr
+ ofs
);
572 case RPC_FC_CALLBACK
:
574 unsigned char *old_stack_top
= pStubMsg
->StackTop
;
575 ULONG_PTR max_count
, old_max_count
= pStubMsg
->MaxCount
;
577 pStubMsg
->StackTop
= ptr
;
579 /* ofs is index into StubDesc->apfnExprEval */
580 TRACE("callback conformance into apfnExprEval[%d]\n", ofs
);
581 pStubMsg
->StubDesc
->apfnExprEval
[ofs
](pStubMsg
);
583 pStubMsg
->StackTop
= old_stack_top
;
585 /* the callback function always stores the computed value in MaxCount */
586 max_count
= pStubMsg
->MaxCount
;
587 pStubMsg
->MaxCount
= old_max_count
;
592 ptr
= (char *)ptr
+ ofs
;
605 data
= *(USHORT
*)ptr
;
616 data
= *(ULONGLONG
*)ptr
;
619 FIXME("unknown conformance data type %x\n", dtype
);
622 TRACE("dereferenced data type %x at %p, got %ld\n", dtype
, ptr
, data
);
625 switch (pFormat
[1]) {
626 case RPC_FC_DEREFERENCE
: /* already handled */
643 FIXME("unknown conformance op %d\n", pFormat
[1]);
648 TRACE("resulting conformance is %ld\n", *pCount
);
649 if (pStubMsg
->fHasNewCorrDesc
)
655 static inline PFORMAT_STRING
SkipConformance(PMIDL_STUB_MESSAGE pStubMsg
,
656 PFORMAT_STRING pFormat
)
658 if (pStubMsg
->fHasNewCorrDesc
)
665 static inline PFORMAT_STRING
SkipVariance(PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
667 return SkipConformance( pStubMsg
, pFormat
);
670 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
671 * the result overflows 32-bits */
672 static inline ULONG
safe_multiply(ULONG a
, ULONG b
)
674 ULONGLONG ret
= (ULONGLONG
)a
* b
;
675 if (ret
> 0xffffffff)
677 RpcRaiseException(RPC_S_INVALID_BOUND
);
683 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
685 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
686 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
687 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
688 pStubMsg
->Buffer
+= size
;
691 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
693 if (pStubMsg
->BufferLength
+ size
< pStubMsg
->BufferLength
) /* integer overflow of pStubMsg->BufferSize */
695 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
696 pStubMsg
->BufferLength
, size
);
697 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
699 pStubMsg
->BufferLength
+= size
;
702 /* copies data from the buffer, checking that there is enough data in the buffer
704 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, void *p
, ULONG size
)
706 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
707 (pStubMsg
->Buffer
+ size
> pStubMsg
->BufferEnd
))
709 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
710 pStubMsg
->Buffer
, pStubMsg
->BufferEnd
, size
);
711 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
713 if (p
== pStubMsg
->Buffer
)
714 ERR("pointer is the same as the buffer\n");
715 memcpy(p
, pStubMsg
->Buffer
, size
);
716 pStubMsg
->Buffer
+= size
;
719 /* copies data to the buffer, checking that there is enough space to do so */
720 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, const void *p
, ULONG size
)
722 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
723 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
725 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
726 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
,
728 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
730 memcpy(pStubMsg
->Buffer
, p
, size
);
731 pStubMsg
->Buffer
+= size
;
734 /* verify that string data sitting in the buffer is valid and safe to
736 static void validate_string_data(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG bufsize
, ULONG esize
)
740 /* verify the buffer is safe to access */
741 if ((pStubMsg
->Buffer
+ bufsize
< pStubMsg
->Buffer
) ||
742 (pStubMsg
->Buffer
+ bufsize
> pStubMsg
->BufferEnd
))
744 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize
,
745 pStubMsg
->BufferEnd
, pStubMsg
->Buffer
);
746 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
749 /* strings must always have null terminating bytes */
752 ERR("invalid string length of %d\n", bufsize
/ esize
);
753 RpcRaiseException(RPC_S_INVALID_BOUND
);
756 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
757 if (pStubMsg
->Buffer
[i
] != 0)
759 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
760 i
, pStubMsg
->Buffer
[i
]);
761 RpcRaiseException(RPC_S_INVALID_BOUND
);
765 static inline void dump_pointer_attr(unsigned char attr
)
767 if (attr
& RPC_FC_P_ALLOCALLNODES
)
768 TRACE(" RPC_FC_P_ALLOCALLNODES");
769 if (attr
& RPC_FC_P_DONTFREE
)
770 TRACE(" RPC_FC_P_DONTFREE");
771 if (attr
& RPC_FC_P_ONSTACK
)
772 TRACE(" RPC_FC_P_ONSTACK");
773 if (attr
& RPC_FC_P_SIMPLEPOINTER
)
774 TRACE(" RPC_FC_P_SIMPLEPOINTER");
775 if (attr
& RPC_FC_P_DEREF
)
776 TRACE(" RPC_FC_P_DEREF");
780 /***********************************************************************
781 * PointerMarshall [internal]
783 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
784 unsigned char *Buffer
,
785 unsigned char *Pointer
,
786 PFORMAT_STRING pFormat
)
788 unsigned type
= pFormat
[0], attr
= pFormat
[1];
792 BOOL pointer_needs_marshaling
;
794 TRACE("(%p,%p,%p,%p)\n", pStubMsg
, Buffer
, Pointer
, pFormat
);
795 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
797 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
798 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
801 case RPC_FC_RP
: /* ref pointer (always non-null) */
804 ERR("NULL ref pointer is not allowed\n");
805 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
807 pointer_needs_marshaling
= TRUE
;
809 case RPC_FC_UP
: /* unique pointer */
810 case RPC_FC_OP
: /* object pointer - same as unique here */
812 pointer_needs_marshaling
= TRUE
;
814 pointer_needs_marshaling
= FALSE
;
815 pointer_id
= Pointer
? NDR_POINTER_ID(pStubMsg
) : 0;
816 TRACE("writing 0x%08x to buffer\n", pointer_id
);
817 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
820 pointer_needs_marshaling
= !NdrFullPointerQueryPointer(
821 pStubMsg
->FullPtrXlatTables
, Pointer
, 1, &pointer_id
);
822 TRACE("writing 0x%08x to buffer\n", pointer_id
);
823 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
826 FIXME("unhandled ptr type=%02x\n", type
);
827 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
831 TRACE("calling marshaller for type 0x%x\n", (int)*desc
);
833 if (pointer_needs_marshaling
) {
834 if (attr
& RPC_FC_P_DEREF
) {
835 Pointer
= *(unsigned char**)Pointer
;
836 TRACE("deref => %p\n", Pointer
);
838 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
839 if (m
) m(pStubMsg
, Pointer
, desc
);
840 else FIXME("no marshaller for data type=%02x\n", *desc
);
843 STD_OVERFLOW_CHECK(pStubMsg
);
846 /***********************************************************************
847 * PointerUnmarshall [internal]
849 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
850 unsigned char *Buffer
,
851 unsigned char **pPointer
,
852 unsigned char *pSrcPointer
,
853 PFORMAT_STRING pFormat
,
854 unsigned char fMustAlloc
)
856 unsigned type
= pFormat
[0], attr
= pFormat
[1];
859 DWORD pointer_id
= 0;
860 BOOL pointer_needs_unmarshaling
;
862 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg
, Buffer
, pPointer
, pSrcPointer
, pFormat
, fMustAlloc
);
863 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
865 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
866 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
869 case RPC_FC_RP
: /* ref pointer (always non-null) */
870 pointer_needs_unmarshaling
= TRUE
;
872 case RPC_FC_UP
: /* unique pointer */
873 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
874 TRACE("pointer_id is 0x%08x\n", pointer_id
);
876 pointer_needs_unmarshaling
= TRUE
;
879 pointer_needs_unmarshaling
= FALSE
;
882 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
883 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
884 TRACE("pointer_id is 0x%08x\n", pointer_id
);
885 if (!fMustAlloc
&& pSrcPointer
)
887 FIXME("free object pointer %p\n", pSrcPointer
);
891 pointer_needs_unmarshaling
= TRUE
;
895 pointer_needs_unmarshaling
= FALSE
;
899 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
900 TRACE("pointer_id is 0x%08x\n", pointer_id
);
901 pointer_needs_unmarshaling
= !NdrFullPointerQueryRefId(
902 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, (void **)pPointer
);
905 FIXME("unhandled ptr type=%02x\n", type
);
906 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
910 if (pointer_needs_unmarshaling
) {
911 unsigned char **current_ptr
= pPointer
;
912 if (pStubMsg
->IsClient
) {
914 /* if we aren't forcing allocation of memory then try to use the existing
915 * (source) pointer to unmarshall the data into so that [in,out]
916 * parameters behave correctly. it doesn't matter if the parameter is
917 * [out] only since in that case the pointer will be NULL. we force
918 * allocation when the source pointer is NULL here instead of in the type
919 * unmarshalling routine for the benefit of the deref code below */
922 TRACE("setting *pPointer to %p\n", pSrcPointer
);
923 *pPointer
= pSrcPointer
;
929 /* the memory in a stub is never initialised, so we have to work out here
930 * whether we have to initialise it so we can use the optimisation of
931 * setting the pointer to the buffer, if possible, or set fMustAlloc to
933 if (attr
& RPC_FC_P_DEREF
) {
940 if (attr
& RPC_FC_P_ALLOCALLNODES
)
941 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
943 if (attr
& RPC_FC_P_DEREF
) {
945 unsigned char *base_ptr_val
= NdrAllocate(pStubMsg
, sizeof(void *));
946 *pPointer
= base_ptr_val
;
947 current_ptr
= (unsigned char **)base_ptr_val
;
949 current_ptr
= *(unsigned char***)current_ptr
;
950 TRACE("deref => %p\n", current_ptr
);
951 if (!fMustAlloc
&& !*current_ptr
) fMustAlloc
= TRUE
;
953 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
954 if (m
) m(pStubMsg
, current_ptr
, desc
, fMustAlloc
);
955 else FIXME("no unmarshaller for data type=%02x\n", *desc
);
957 if (type
== RPC_FC_FP
)
958 NdrFullPointerInsertRefId(pStubMsg
->FullPtrXlatTables
, pointer_id
,
962 TRACE("pointer=%p\n", *pPointer
);
965 /***********************************************************************
966 * PointerBufferSize [internal]
968 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
969 unsigned char *Pointer
,
970 PFORMAT_STRING pFormat
)
972 unsigned type
= pFormat
[0], attr
= pFormat
[1];
975 BOOL pointer_needs_sizing
;
978 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
979 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
981 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
982 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
985 case RPC_FC_RP
: /* ref pointer (always non-null) */
988 ERR("NULL ref pointer is not allowed\n");
989 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
994 /* NULL pointer has no further representation */
999 pointer_needs_sizing
= !NdrFullPointerQueryPointer(
1000 pStubMsg
->FullPtrXlatTables
, Pointer
, 0, &pointer_id
);
1001 if (!pointer_needs_sizing
)
1005 FIXME("unhandled ptr type=%02x\n", type
);
1006 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1010 if (attr
& RPC_FC_P_DEREF
) {
1011 Pointer
= *(unsigned char**)Pointer
;
1012 TRACE("deref => %p\n", Pointer
);
1015 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
1016 if (m
) m(pStubMsg
, Pointer
, desc
);
1017 else FIXME("no buffersizer for data type=%02x\n", *desc
);
1020 /***********************************************************************
1021 * PointerMemorySize [internal]
1023 static ULONG
PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1024 unsigned char *Buffer
, PFORMAT_STRING pFormat
)
1026 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1027 PFORMAT_STRING desc
;
1029 DWORD pointer_id
= 0;
1030 BOOL pointer_needs_sizing
;
1032 TRACE("(%p,%p,%p)\n", pStubMsg
, Buffer
, pFormat
);
1033 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1035 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1036 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1039 case RPC_FC_RP
: /* ref pointer (always non-null) */
1040 pointer_needs_sizing
= TRUE
;
1042 case RPC_FC_UP
: /* unique pointer */
1043 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
1044 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1045 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1047 pointer_needs_sizing
= TRUE
;
1049 pointer_needs_sizing
= FALSE
;
1054 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1055 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1056 pointer_needs_sizing
= !NdrFullPointerQueryRefId(
1057 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, &pointer
);
1061 FIXME("unhandled ptr type=%02x\n", type
);
1062 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1066 if (attr
& RPC_FC_P_DEREF
) {
1067 align_length(&pStubMsg
->MemorySize
, sizeof(void*));
1068 pStubMsg
->MemorySize
+= sizeof(void*);
1072 if (pointer_needs_sizing
) {
1073 m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
1074 if (m
) m(pStubMsg
, desc
);
1075 else FIXME("no memorysizer for data type=%02x\n", *desc
);
1078 return pStubMsg
->MemorySize
;
1081 /***********************************************************************
1082 * PointerFree [internal]
1084 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1085 unsigned char *Pointer
,
1086 PFORMAT_STRING pFormat
)
1088 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1089 PFORMAT_STRING desc
;
1091 unsigned char *current_pointer
= Pointer
;
1093 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1094 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1095 if (attr
& RPC_FC_P_DONTFREE
) return;
1097 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1098 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1100 if (!Pointer
) return;
1102 if (type
== RPC_FC_FP
) {
1103 int pointer_needs_freeing
= NdrFullPointerFree(
1104 pStubMsg
->FullPtrXlatTables
, Pointer
);
1105 if (!pointer_needs_freeing
)
1109 if (attr
& RPC_FC_P_DEREF
) {
1110 current_pointer
= *(unsigned char**)Pointer
;
1111 TRACE("deref => %p\n", current_pointer
);
1114 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
1115 if (m
) m(pStubMsg
, current_pointer
, desc
);
1117 /* this check stops us from trying to free buffer memory. we don't have to
1118 * worry about clients, since they won't call this function.
1119 * we don't have to check for the buffer being reallocated because
1120 * BufferStart and BufferEnd won't be reset when allocating memory for
1121 * sending the response. we don't have to check for the new buffer here as
1122 * it won't be used a type memory, only for buffer memory */
1123 if (Pointer
>= pStubMsg
->BufferStart
&& Pointer
<= pStubMsg
->BufferEnd
)
1126 if (attr
& RPC_FC_P_ONSTACK
) {
1127 TRACE("not freeing stack ptr %p\n", Pointer
);
1130 TRACE("freeing %p\n", Pointer
);
1131 NdrFree(pStubMsg
, Pointer
);
1134 TRACE("not freeing %p\n", Pointer
);
1137 /***********************************************************************
1138 * EmbeddedPointerMarshall
1140 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1141 unsigned char *pMemory
,
1142 PFORMAT_STRING pFormat
)
1144 unsigned char *Mark
= pStubMsg
->BufferMark
;
1145 unsigned rep
, count
, stride
;
1147 unsigned char *saved_buffer
= NULL
;
1149 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1151 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1154 if (pStubMsg
->PointerBufferMark
)
1156 saved_buffer
= pStubMsg
->Buffer
;
1157 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1158 pStubMsg
->PointerBufferMark
= NULL
;
1161 while (pFormat
[0] != RPC_FC_END
) {
1162 switch (pFormat
[0]) {
1164 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat
[0]);
1166 case RPC_FC_NO_REPEAT
:
1172 case RPC_FC_FIXED_REPEAT
:
1173 rep
= *(const WORD
*)&pFormat
[2];
1174 stride
= *(const WORD
*)&pFormat
[4];
1175 count
= *(const WORD
*)&pFormat
[8];
1178 case RPC_FC_VARIABLE_REPEAT
:
1179 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1180 stride
= *(const WORD
*)&pFormat
[2];
1181 count
= *(const WORD
*)&pFormat
[6];
1185 for (i
= 0; i
< rep
; i
++) {
1186 PFORMAT_STRING info
= pFormat
;
1187 unsigned char *membase
= pMemory
+ (i
* stride
);
1188 unsigned char *bufbase
= Mark
+ (i
* stride
);
1191 for (u
=0; u
<count
; u
++,info
+=8) {
1192 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1193 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1194 unsigned char *saved_memory
= pStubMsg
->Memory
;
1196 pStubMsg
->Memory
= pMemory
;
1197 PointerMarshall(pStubMsg
, bufptr
, *(unsigned char**)memptr
, info
+4);
1198 pStubMsg
->Memory
= saved_memory
;
1201 pFormat
+= 8 * count
;
1206 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1207 pStubMsg
->Buffer
= saved_buffer
;
1210 STD_OVERFLOW_CHECK(pStubMsg
);
1215 /***********************************************************************
1216 * EmbeddedPointerUnmarshall
1218 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1219 unsigned char *pDstBuffer
,
1220 unsigned char *pSrcMemoryPtrs
,
1221 PFORMAT_STRING pFormat
,
1222 unsigned char fMustAlloc
)
1224 unsigned char *Mark
= pStubMsg
->BufferMark
;
1225 unsigned rep
, count
, stride
;
1227 unsigned char *saved_buffer
= NULL
;
1229 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg
, pDstBuffer
, pSrcMemoryPtrs
, pFormat
, fMustAlloc
);
1231 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1234 if (pStubMsg
->PointerBufferMark
)
1236 saved_buffer
= pStubMsg
->Buffer
;
1237 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1238 pStubMsg
->PointerBufferMark
= NULL
;
1241 while (pFormat
[0] != RPC_FC_END
) {
1242 TRACE("pFormat[0] = 0x%x\n", pFormat
[0]);
1243 switch (pFormat
[0]) {
1245 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat
[0]);
1247 case RPC_FC_NO_REPEAT
:
1253 case RPC_FC_FIXED_REPEAT
:
1254 rep
= *(const WORD
*)&pFormat
[2];
1255 stride
= *(const WORD
*)&pFormat
[4];
1256 count
= *(const WORD
*)&pFormat
[8];
1259 case RPC_FC_VARIABLE_REPEAT
:
1260 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1261 stride
= *(const WORD
*)&pFormat
[2];
1262 count
= *(const WORD
*)&pFormat
[6];
1266 for (i
= 0; i
< rep
; i
++) {
1267 PFORMAT_STRING info
= pFormat
;
1268 unsigned char *bufdstbase
= pDstBuffer
+ (i
* stride
);
1269 unsigned char *memsrcbase
= pSrcMemoryPtrs
+ (i
* stride
);
1270 unsigned char *bufbase
= Mark
+ (i
* stride
);
1273 for (u
=0; u
<count
; u
++,info
+=8) {
1274 unsigned char **bufdstptr
= (unsigned char **)(bufdstbase
+ *(const SHORT
*)&info
[2]);
1275 unsigned char **memsrcptr
= (unsigned char **)(memsrcbase
+ *(const SHORT
*)&info
[0]);
1276 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1277 PointerUnmarshall(pStubMsg
, bufptr
, bufdstptr
, *memsrcptr
, info
+4, fMustAlloc
);
1280 pFormat
+= 8 * count
;
1285 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1286 pStubMsg
->Buffer
= saved_buffer
;
1292 /***********************************************************************
1293 * EmbeddedPointerBufferSize
1295 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1296 unsigned char *pMemory
,
1297 PFORMAT_STRING pFormat
)
1299 unsigned rep
, count
, stride
;
1301 ULONG saved_buffer_length
= 0;
1303 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1305 if (pStubMsg
->IgnoreEmbeddedPointers
) return;
1307 if (*pFormat
!= RPC_FC_PP
) return;
1310 if (pStubMsg
->PointerLength
)
1312 saved_buffer_length
= pStubMsg
->BufferLength
;
1313 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
1314 pStubMsg
->PointerLength
= 0;
1317 while (pFormat
[0] != RPC_FC_END
) {
1318 switch (pFormat
[0]) {
1320 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat
[0]);
1322 case RPC_FC_NO_REPEAT
:
1328 case RPC_FC_FIXED_REPEAT
:
1329 rep
= *(const WORD
*)&pFormat
[2];
1330 stride
= *(const WORD
*)&pFormat
[4];
1331 count
= *(const WORD
*)&pFormat
[8];
1334 case RPC_FC_VARIABLE_REPEAT
:
1335 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1336 stride
= *(const WORD
*)&pFormat
[2];
1337 count
= *(const WORD
*)&pFormat
[6];
1341 for (i
= 0; i
< rep
; i
++) {
1342 PFORMAT_STRING info
= pFormat
;
1343 unsigned char *membase
= pMemory
+ (i
* stride
);
1346 for (u
=0; u
<count
; u
++,info
+=8) {
1347 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1348 unsigned char *saved_memory
= pStubMsg
->Memory
;
1350 pStubMsg
->Memory
= pMemory
;
1351 PointerBufferSize(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1352 pStubMsg
->Memory
= saved_memory
;
1355 pFormat
+= 8 * count
;
1358 if (saved_buffer_length
)
1360 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
1361 pStubMsg
->BufferLength
= saved_buffer_length
;
1365 /***********************************************************************
1366 * EmbeddedPointerMemorySize [internal]
1368 static ULONG
EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1369 PFORMAT_STRING pFormat
)
1371 unsigned char *Mark
= pStubMsg
->BufferMark
;
1372 unsigned rep
, count
, stride
;
1374 unsigned char *saved_buffer
= NULL
;
1376 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1378 if (pStubMsg
->IgnoreEmbeddedPointers
) return 0;
1380 if (pStubMsg
->PointerBufferMark
)
1382 saved_buffer
= pStubMsg
->Buffer
;
1383 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1384 pStubMsg
->PointerBufferMark
= NULL
;
1387 if (*pFormat
!= RPC_FC_PP
) return 0;
1390 while (pFormat
[0] != RPC_FC_END
) {
1391 switch (pFormat
[0]) {
1393 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat
[0]);
1395 case RPC_FC_NO_REPEAT
:
1401 case RPC_FC_FIXED_REPEAT
:
1402 rep
= *(const WORD
*)&pFormat
[2];
1403 stride
= *(const WORD
*)&pFormat
[4];
1404 count
= *(const WORD
*)&pFormat
[8];
1407 case RPC_FC_VARIABLE_REPEAT
:
1408 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1409 stride
= *(const WORD
*)&pFormat
[2];
1410 count
= *(const WORD
*)&pFormat
[6];
1414 for (i
= 0; i
< rep
; i
++) {
1415 PFORMAT_STRING info
= pFormat
;
1416 unsigned char *bufbase
= Mark
+ (i
* stride
);
1418 for (u
=0; u
<count
; u
++,info
+=8) {
1419 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1420 PointerMemorySize(pStubMsg
, bufptr
, info
+4);
1423 pFormat
+= 8 * count
;
1428 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1429 pStubMsg
->Buffer
= saved_buffer
;
1435 /***********************************************************************
1436 * EmbeddedPointerFree [internal]
1438 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1439 unsigned char *pMemory
,
1440 PFORMAT_STRING pFormat
)
1442 unsigned rep
, count
, stride
;
1445 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1446 if (*pFormat
!= RPC_FC_PP
) return;
1449 while (pFormat
[0] != RPC_FC_END
) {
1450 switch (pFormat
[0]) {
1452 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat
[0]);
1454 case RPC_FC_NO_REPEAT
:
1460 case RPC_FC_FIXED_REPEAT
:
1461 rep
= *(const WORD
*)&pFormat
[2];
1462 stride
= *(const WORD
*)&pFormat
[4];
1463 count
= *(const WORD
*)&pFormat
[8];
1466 case RPC_FC_VARIABLE_REPEAT
:
1467 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1468 stride
= *(const WORD
*)&pFormat
[2];
1469 count
= *(const WORD
*)&pFormat
[6];
1473 for (i
= 0; i
< rep
; i
++) {
1474 PFORMAT_STRING info
= pFormat
;
1475 unsigned char *membase
= pMemory
+ (i
* stride
);
1478 for (u
=0; u
<count
; u
++,info
+=8) {
1479 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1480 unsigned char *saved_memory
= pStubMsg
->Memory
;
1482 pStubMsg
->Memory
= pMemory
;
1483 PointerFree(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1484 pStubMsg
->Memory
= saved_memory
;
1487 pFormat
+= 8 * count
;
1491 /***********************************************************************
1492 * NdrPointerMarshall [RPCRT4.@]
1494 unsigned char * WINAPI
NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1495 unsigned char *pMemory
,
1496 PFORMAT_STRING pFormat
)
1498 unsigned char *Buffer
;
1500 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1502 /* Increment the buffer here instead of in PointerMarshall,
1503 * as that is used by embedded pointers which already handle the incrementing
1504 * the buffer, and shouldn't write any additional pointer data to the wire */
1505 if (*pFormat
!= RPC_FC_RP
)
1507 align_pointer_clear(&pStubMsg
->Buffer
, 4);
1508 Buffer
= pStubMsg
->Buffer
;
1509 safe_buffer_increment(pStubMsg
, 4);
1512 Buffer
= pStubMsg
->Buffer
;
1514 PointerMarshall(pStubMsg
, Buffer
, pMemory
, pFormat
);
1519 /***********************************************************************
1520 * NdrPointerUnmarshall [RPCRT4.@]
1522 unsigned char * WINAPI
NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1523 unsigned char **ppMemory
,
1524 PFORMAT_STRING pFormat
,
1525 unsigned char fMustAlloc
)
1527 unsigned char *Buffer
;
1529 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1531 if (*pFormat
== RPC_FC_RP
)
1533 Buffer
= pStubMsg
->Buffer
;
1534 /* Do the NULL ref pointer check here because embedded pointers can be
1535 * NULL if the type the pointer is embedded in was allocated rather than
1536 * being passed in by the client */
1537 if (pStubMsg
->IsClient
&& !*ppMemory
)
1539 ERR("NULL ref pointer is not allowed\n");
1540 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
1545 /* Increment the buffer here instead of in PointerUnmarshall,
1546 * as that is used by embedded pointers which already handle the incrementing
1547 * the buffer, and shouldn't read any additional pointer data from the
1549 align_pointer(&pStubMsg
->Buffer
, 4);
1550 Buffer
= pStubMsg
->Buffer
;
1551 safe_buffer_increment(pStubMsg
, 4);
1554 PointerUnmarshall(pStubMsg
, Buffer
, ppMemory
, *ppMemory
, pFormat
, fMustAlloc
);
1559 /***********************************************************************
1560 * NdrPointerBufferSize [RPCRT4.@]
1562 void WINAPI
NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1563 unsigned char *pMemory
,
1564 PFORMAT_STRING pFormat
)
1566 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1568 /* Increment the buffer length here instead of in PointerBufferSize,
1569 * as that is used by embedded pointers which already handle the buffer
1570 * length, and shouldn't write anything more to the wire */
1571 if (*pFormat
!= RPC_FC_RP
)
1573 align_length(&pStubMsg
->BufferLength
, 4);
1574 safe_buffer_length_increment(pStubMsg
, 4);
1577 PointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1580 /***********************************************************************
1581 * NdrPointerMemorySize [RPCRT4.@]
1583 ULONG WINAPI
NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1584 PFORMAT_STRING pFormat
)
1586 unsigned char *Buffer
= pStubMsg
->Buffer
;
1587 if (*pFormat
!= RPC_FC_RP
)
1589 align_pointer(&pStubMsg
->Buffer
, 4);
1590 safe_buffer_increment(pStubMsg
, 4);
1592 align_length(&pStubMsg
->MemorySize
, sizeof(void *));
1593 return PointerMemorySize(pStubMsg
, Buffer
, pFormat
);
1596 /***********************************************************************
1597 * NdrPointerFree [RPCRT4.@]
1599 void WINAPI
NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1600 unsigned char *pMemory
,
1601 PFORMAT_STRING pFormat
)
1603 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1604 PointerFree(pStubMsg
, pMemory
, pFormat
);
1607 /***********************************************************************
1608 * NdrSimpleTypeMarshall [RPCRT4.@]
1610 void WINAPI
NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1611 unsigned char FormatChar
)
1613 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &FormatChar
);
1616 /***********************************************************************
1617 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1619 * Unmarshall a base type.
1622 * Doesn't check that the buffer is long enough before copying, so the caller
1625 void WINAPI
NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1626 unsigned char FormatChar
)
1628 #define BASE_TYPE_UNMARSHALL(type) \
1629 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
1630 TRACE("pMemory: %p\n", pMemory); \
1631 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1632 pStubMsg->Buffer += sizeof(type);
1640 BASE_TYPE_UNMARSHALL(UCHAR
);
1641 TRACE("value: 0x%02x\n", *pMemory
);
1646 BASE_TYPE_UNMARSHALL(USHORT
);
1647 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
1651 case RPC_FC_ERROR_STATUS_T
:
1653 BASE_TYPE_UNMARSHALL(ULONG
);
1654 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
1657 BASE_TYPE_UNMARSHALL(float);
1658 TRACE("value: %f\n", *(float *)pMemory
);
1661 BASE_TYPE_UNMARSHALL(double);
1662 TRACE("value: %f\n", *(double *)pMemory
);
1665 BASE_TYPE_UNMARSHALL(ULONGLONG
);
1666 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
1669 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
1670 TRACE("pMemory: %p\n", pMemory
);
1671 /* 16-bits on the wire, but int in memory */
1672 *(UINT
*)pMemory
= *(USHORT
*)pStubMsg
->Buffer
;
1673 pStubMsg
->Buffer
+= sizeof(USHORT
);
1674 TRACE("value: 0x%08x\n", *(UINT
*)pMemory
);
1676 case RPC_FC_INT3264
:
1677 align_pointer(&pStubMsg
->Buffer
, sizeof(INT
));
1678 /* 32-bits on the wire, but int_ptr in memory */
1679 *(INT_PTR
*)pMemory
= *(INT
*)pStubMsg
->Buffer
;
1680 pStubMsg
->Buffer
+= sizeof(INT
);
1681 TRACE("value: 0x%08lx\n", *(INT_PTR
*)pMemory
);
1683 case RPC_FC_UINT3264
:
1684 align_pointer(&pStubMsg
->Buffer
, sizeof(UINT
));
1685 /* 32-bits on the wire, but int_ptr in memory */
1686 *(UINT_PTR
*)pMemory
= *(UINT
*)pStubMsg
->Buffer
;
1687 pStubMsg
->Buffer
+= sizeof(UINT
);
1688 TRACE("value: 0x%08lx\n", *(UINT_PTR
*)pMemory
);
1693 FIXME("Unhandled base type: 0x%02x\n", FormatChar
);
1695 #undef BASE_TYPE_UNMARSHALL
1698 /***********************************************************************
1699 * NdrSimpleStructMarshall [RPCRT4.@]
1701 unsigned char * WINAPI
NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1702 unsigned char *pMemory
,
1703 PFORMAT_STRING pFormat
)
1705 unsigned size
= *(const WORD
*)(pFormat
+2);
1706 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1708 align_pointer_clear(&pStubMsg
->Buffer
, pFormat
[1] + 1);
1710 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1711 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
1713 if (pFormat
[0] != RPC_FC_STRUCT
)
1714 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
+4);
1719 /***********************************************************************
1720 * NdrSimpleStructUnmarshall [RPCRT4.@]
1722 unsigned char * WINAPI
NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1723 unsigned char **ppMemory
,
1724 PFORMAT_STRING pFormat
,
1725 unsigned char fMustAlloc
)
1727 unsigned size
= *(const WORD
*)(pFormat
+2);
1728 unsigned char *saved_buffer
;
1729 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1731 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
1734 *ppMemory
= NdrAllocate(pStubMsg
, size
);
1737 if (!pStubMsg
->IsClient
&& !*ppMemory
)
1738 /* for servers, we just point straight into the RPC buffer */
1739 *ppMemory
= pStubMsg
->Buffer
;
1742 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1743 safe_buffer_increment(pStubMsg
, size
);
1744 if (pFormat
[0] == RPC_FC_PSTRUCT
)
1745 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
+4, fMustAlloc
);
1747 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
1748 if (*ppMemory
!= saved_buffer
)
1749 memcpy(*ppMemory
, saved_buffer
, size
);
1754 /***********************************************************************
1755 * NdrSimpleStructBufferSize [RPCRT4.@]
1757 void WINAPI
NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1758 unsigned char *pMemory
,
1759 PFORMAT_STRING pFormat
)
1761 unsigned size
= *(const WORD
*)(pFormat
+2);
1762 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1764 align_length(&pStubMsg
->BufferLength
, pFormat
[1] + 1);
1766 safe_buffer_length_increment(pStubMsg
, size
);
1767 if (pFormat
[0] != RPC_FC_STRUCT
)
1768 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
+4);
1771 /***********************************************************************
1772 * NdrSimpleStructMemorySize [RPCRT4.@]
1774 ULONG WINAPI
NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1775 PFORMAT_STRING pFormat
)
1777 unsigned short size
= *(const WORD
*)(pFormat
+2);
1779 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1781 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
1782 pStubMsg
->MemorySize
+= size
;
1783 safe_buffer_increment(pStubMsg
, size
);
1785 if (pFormat
[0] != RPC_FC_STRUCT
)
1786 EmbeddedPointerMemorySize(pStubMsg
, pFormat
+4);
1787 return pStubMsg
->MemorySize
;
1790 /***********************************************************************
1791 * NdrSimpleStructFree [RPCRT4.@]
1793 void WINAPI
NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
1794 unsigned char *pMemory
,
1795 PFORMAT_STRING pFormat
)
1797 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1798 if (pFormat
[0] != RPC_FC_STRUCT
)
1799 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
+4);
1804 static inline void array_compute_and_size_conformance(
1805 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1806 PFORMAT_STRING pFormat
)
1813 ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1814 SizeConformance(pStubMsg
);
1816 case RPC_FC_CVARRAY
:
1817 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, 0);
1818 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
1819 SizeConformance(pStubMsg
);
1821 case RPC_FC_C_CSTRING
:
1822 case RPC_FC_C_WSTRING
:
1823 if (fc
== RPC_FC_C_CSTRING
)
1825 TRACE("string=%s\n", debugstr_a((const char *)pMemory
));
1826 pStubMsg
->ActualCount
= strlen((const char *)pMemory
)+1;
1830 TRACE("string=%s\n", debugstr_w((LPCWSTR
)pMemory
));
1831 pStubMsg
->ActualCount
= strlenW((LPCWSTR
)pMemory
)+1;
1834 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
1835 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
1837 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
1839 SizeConformance(pStubMsg
);
1841 case RPC_FC_BOGUS_ARRAY
:
1842 count
= *(const WORD
*)(pFormat
+ 2);
1844 if (IsConformanceOrVariancePresent(pFormat
)) SizeConformance(pStubMsg
);
1845 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, count
);
1846 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
1849 ERR("unknown array format 0x%x\n", fc
);
1850 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1854 static inline void array_buffer_size(
1855 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1856 PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
1860 unsigned char alignment
;
1865 esize
= *(const WORD
*)(pFormat
+2);
1866 alignment
= pFormat
[1] + 1;
1868 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1870 align_length(&pStubMsg
->BufferLength
, alignment
);
1872 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
1873 /* conformance value plus array */
1874 safe_buffer_length_increment(pStubMsg
, size
);
1877 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1879 case RPC_FC_CVARRAY
:
1880 esize
= *(const WORD
*)(pFormat
+2);
1881 alignment
= pFormat
[1] + 1;
1883 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1884 pFormat
= SkipVariance(pStubMsg
, pFormat
);
1886 SizeVariance(pStubMsg
);
1888 align_length(&pStubMsg
->BufferLength
, alignment
);
1890 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1891 safe_buffer_length_increment(pStubMsg
, size
);
1894 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1896 case RPC_FC_C_CSTRING
:
1897 case RPC_FC_C_WSTRING
:
1898 if (fc
== RPC_FC_C_CSTRING
)
1903 SizeVariance(pStubMsg
);
1905 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1906 safe_buffer_length_increment(pStubMsg
, size
);
1908 case RPC_FC_BOGUS_ARRAY
:
1909 alignment
= pFormat
[1] + 1;
1910 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1911 if (IsConformanceOrVariancePresent(pFormat
)) SizeVariance(pStubMsg
);
1912 pFormat
= SkipVariance(pStubMsg
, pFormat
);
1914 align_length(&pStubMsg
->BufferLength
, alignment
);
1916 size
= pStubMsg
->ActualCount
;
1917 for (i
= 0; i
< size
; i
++)
1918 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
1921 ERR("unknown array format 0x%x\n", fc
);
1922 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1926 static inline void array_compute_and_write_conformance(
1927 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1928 PFORMAT_STRING pFormat
)
1931 BOOL conformance_present
;
1936 ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1937 WriteConformance(pStubMsg
);
1939 case RPC_FC_CVARRAY
:
1940 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, 0);
1941 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
1942 WriteConformance(pStubMsg
);
1944 case RPC_FC_C_CSTRING
:
1945 case RPC_FC_C_WSTRING
:
1946 if (fc
== RPC_FC_C_CSTRING
)
1948 TRACE("string=%s\n", debugstr_a((const char *)pMemory
));
1949 pStubMsg
->ActualCount
= strlen((const char *)pMemory
)+1;
1953 TRACE("string=%s\n", debugstr_w((LPCWSTR
)pMemory
));
1954 pStubMsg
->ActualCount
= strlenW((LPCWSTR
)pMemory
)+1;
1956 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
1957 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
1959 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
1960 pStubMsg
->Offset
= 0;
1961 WriteConformance(pStubMsg
);
1963 case RPC_FC_BOGUS_ARRAY
:
1964 def
= *(const WORD
*)(pFormat
+ 2);
1966 conformance_present
= IsConformanceOrVariancePresent(pFormat
);
1967 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
1968 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
1969 if (conformance_present
) WriteConformance(pStubMsg
);
1972 ERR("unknown array format 0x%x\n", fc
);
1973 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1977 static inline void array_write_variance_and_marshall(
1978 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1979 PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
1983 unsigned char alignment
;
1988 esize
= *(const WORD
*)(pFormat
+2);
1989 alignment
= pFormat
[1] + 1;
1991 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1993 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
1995 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
1997 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1998 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
2001 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2003 case RPC_FC_CVARRAY
:
2004 esize
= *(const WORD
*)(pFormat
+2);
2005 alignment
= pFormat
[1] + 1;
2007 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2008 pFormat
= SkipVariance(pStubMsg
, pFormat
);
2010 WriteVariance(pStubMsg
);
2012 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
2014 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2017 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2018 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, size
);
2021 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2023 case RPC_FC_C_CSTRING
:
2024 case RPC_FC_C_WSTRING
:
2025 if (fc
== RPC_FC_C_CSTRING
)
2030 WriteVariance(pStubMsg
);
2032 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2033 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
2035 case RPC_FC_BOGUS_ARRAY
:
2036 alignment
= pFormat
[1] + 1;
2037 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2038 if (IsConformanceOrVariancePresent(pFormat
)) WriteVariance(pStubMsg
);
2039 pFormat
= SkipVariance(pStubMsg
, pFormat
);
2041 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
2043 size
= pStubMsg
->ActualCount
;
2044 for (i
= 0; i
< size
; i
++)
2045 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
2048 ERR("unknown array format 0x%x\n", fc
);
2049 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2053 static inline ULONG
array_read_conformance(
2054 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
2061 esize
= *(const WORD
*)(pFormat
+2);
2062 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2063 return safe_multiply(esize
, pStubMsg
->MaxCount
);
2064 case RPC_FC_CVARRAY
:
2065 esize
= *(const WORD
*)(pFormat
+2);
2066 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2067 return safe_multiply(esize
, pStubMsg
->MaxCount
);
2068 case RPC_FC_C_CSTRING
:
2069 case RPC_FC_C_WSTRING
:
2070 if (fc
== RPC_FC_C_CSTRING
)
2075 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
2076 ReadConformance(pStubMsg
, pFormat
+ 2);
2078 ReadConformance(pStubMsg
, NULL
);
2079 return safe_multiply(esize
, pStubMsg
->MaxCount
);
2080 case RPC_FC_BOGUS_ARRAY
:
2081 def
= *(const WORD
*)(pFormat
+ 2);
2083 if (IsConformanceOrVariancePresent(pFormat
)) pFormat
= ReadConformance(pStubMsg
, pFormat
);
2086 pStubMsg
->MaxCount
= def
;
2087 pFormat
= SkipConformance( pStubMsg
, pFormat
);
2089 pFormat
= SkipVariance( pStubMsg
, pFormat
);
2091 esize
= ComplexStructSize(pStubMsg
, pFormat
);
2092 return safe_multiply(pStubMsg
->MaxCount
, esize
);
2094 ERR("unknown array format 0x%x\n", fc
);
2095 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2099 static inline ULONG
array_read_variance_and_unmarshall(
2100 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char **ppMemory
,
2101 PFORMAT_STRING pFormat
, unsigned char fMustAlloc
,
2102 unsigned char fUseBufferMemoryServer
, unsigned char fUnmarshall
)
2104 ULONG bufsize
, memsize
;
2106 unsigned char alignment
;
2107 unsigned char *saved_buffer
, *pMemory
;
2108 ULONG i
, offset
, count
;
2113 esize
= *(const WORD
*)(pFormat
+2);
2114 alignment
= pFormat
[1] + 1;
2116 bufsize
= memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2118 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2120 align_pointer(&pStubMsg
->Buffer
, alignment
);
2125 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2128 if (fUseBufferMemoryServer
&& !pStubMsg
->IsClient
&& !*ppMemory
)
2129 /* for servers, we just point straight into the RPC buffer */
2130 *ppMemory
= pStubMsg
->Buffer
;
2133 saved_buffer
= pStubMsg
->Buffer
;
2134 safe_buffer_increment(pStubMsg
, bufsize
);
2136 pStubMsg
->BufferMark
= saved_buffer
;
2137 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
2139 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
2140 if (*ppMemory
!= saved_buffer
)
2141 memcpy(*ppMemory
, saved_buffer
, bufsize
);
2144 case RPC_FC_CVARRAY
:
2145 esize
= *(const WORD
*)(pFormat
+2);
2146 alignment
= pFormat
[1] + 1;
2148 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2150 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2152 align_pointer(&pStubMsg
->Buffer
, alignment
);
2154 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2155 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2159 offset
= pStubMsg
->Offset
;
2161 if (!fMustAlloc
&& !*ppMemory
)
2164 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2165 saved_buffer
= pStubMsg
->Buffer
;
2166 safe_buffer_increment(pStubMsg
, bufsize
);
2168 pStubMsg
->BufferMark
= saved_buffer
;
2169 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
,
2172 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
2175 case RPC_FC_C_CSTRING
:
2176 case RPC_FC_C_WSTRING
:
2177 if (fc
== RPC_FC_C_CSTRING
)
2182 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
2184 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
2186 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2187 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
2188 RpcRaiseException(RPC_S_INVALID_BOUND
);
2190 if (pStubMsg
->Offset
)
2192 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2193 RpcRaiseException(RPC_S_INVALID_BOUND
);
2196 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2197 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2199 validate_string_data(pStubMsg
, bufsize
, esize
);
2204 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2207 if (fUseBufferMemoryServer
&& !pStubMsg
->IsClient
&&
2208 !*ppMemory
&& (pStubMsg
->MaxCount
== pStubMsg
->ActualCount
))
2209 /* if the data in the RPC buffer is big enough, we just point
2210 * straight into it */
2211 *ppMemory
= pStubMsg
->Buffer
;
2212 else if (!*ppMemory
)
2213 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2216 if (*ppMemory
== pStubMsg
->Buffer
)
2217 safe_buffer_increment(pStubMsg
, bufsize
);
2219 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
2221 if (*pFormat
== RPC_FC_C_CSTRING
)
2222 TRACE("string=%s\n", debugstr_a((char*)*ppMemory
));
2224 TRACE("string=%s\n", debugstr_w((LPWSTR
)*ppMemory
));
2228 case RPC_FC_BOGUS_ARRAY
:
2229 alignment
= pFormat
[1] + 1;
2230 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2231 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2233 esize
= ComplexStructSize(pStubMsg
, pFormat
);
2234 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2236 assert( fUnmarshall
);
2238 if (!fMustAlloc
&& !*ppMemory
)
2241 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2243 align_pointer(&pStubMsg
->Buffer
, alignment
);
2244 saved_buffer
= pStubMsg
->Buffer
;
2246 pMemory
= *ppMemory
;
2247 count
= pStubMsg
->ActualCount
;
2248 for (i
= 0; i
< count
; i
++)
2249 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
, fMustAlloc
);
2250 return pStubMsg
->Buffer
- saved_buffer
;
2253 ERR("unknown array format 0x%x\n", fc
);
2254 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2258 static inline void array_memory_size(
2259 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
,
2260 unsigned char fHasPointers
)
2262 ULONG i
, count
, SavedMemorySize
;
2263 ULONG bufsize
, memsize
;
2265 unsigned char alignment
;
2270 esize
= *(const WORD
*)(pFormat
+2);
2271 alignment
= pFormat
[1] + 1;
2273 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2275 bufsize
= memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2276 pStubMsg
->MemorySize
+= memsize
;
2278 align_pointer(&pStubMsg
->Buffer
, alignment
);
2280 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2281 safe_buffer_increment(pStubMsg
, bufsize
);
2284 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2286 case RPC_FC_CVARRAY
:
2287 esize
= *(const WORD
*)(pFormat
+2);
2288 alignment
= pFormat
[1] + 1;
2290 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2292 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2294 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2295 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2296 pStubMsg
->MemorySize
+= memsize
;
2298 align_pointer(&pStubMsg
->Buffer
, alignment
);
2300 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2301 safe_buffer_increment(pStubMsg
, bufsize
);
2304 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2306 case RPC_FC_C_CSTRING
:
2307 case RPC_FC_C_WSTRING
:
2308 if (fc
== RPC_FC_C_CSTRING
)
2313 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
2315 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
2317 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2318 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
2319 RpcRaiseException(RPC_S_INVALID_BOUND
);
2321 if (pStubMsg
->Offset
)
2323 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2324 RpcRaiseException(RPC_S_INVALID_BOUND
);
2327 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2328 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2330 validate_string_data(pStubMsg
, bufsize
, esize
);
2332 safe_buffer_increment(pStubMsg
, bufsize
);
2333 pStubMsg
->MemorySize
+= memsize
;
2335 case RPC_FC_BOGUS_ARRAY
:
2336 alignment
= pFormat
[1] + 1;
2337 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2338 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2340 align_pointer(&pStubMsg
->Buffer
, alignment
);
2342 SavedMemorySize
= pStubMsg
->MemorySize
;
2344 esize
= ComplexStructSize(pStubMsg
, pFormat
);
2345 memsize
= safe_multiply(pStubMsg
->MaxCount
, esize
);
2347 count
= pStubMsg
->ActualCount
;
2348 for (i
= 0; i
< count
; i
++)
2349 ComplexStructMemorySize(pStubMsg
, pFormat
, NULL
);
2351 pStubMsg
->MemorySize
= SavedMemorySize
+ memsize
;
2354 ERR("unknown array format 0x%x\n", fc
);
2355 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2359 static inline void array_free(
2360 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
,
2361 unsigned char *pMemory
, PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
2368 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2370 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2372 case RPC_FC_CVARRAY
:
2373 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2374 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2376 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2378 case RPC_FC_C_CSTRING
:
2379 case RPC_FC_C_WSTRING
:
2380 /* No embedded pointers so nothing to do */
2382 case RPC_FC_BOGUS_ARRAY
:
2383 count
= *(const WORD
*)(pFormat
+ 2);
2384 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, count
);
2385 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
2387 count
= pStubMsg
->ActualCount
;
2388 for (i
= 0; i
< count
; i
++)
2389 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
2392 ERR("unknown array format 0x%x\n", fc
);
2393 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2398 * NdrConformantString:
2400 * What MS calls a ConformantString is, in DCE terminology,
2401 * a Varying-Conformant String.
2403 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2404 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2405 * into unmarshalled string)
2406 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2408 * data: CHARTYPE[maxlen]
2410 * ], where CHARTYPE is the appropriate character type (specified externally)
2414 /***********************************************************************
2415 * NdrConformantStringMarshall [RPCRT4.@]
2417 unsigned char *WINAPI
NdrConformantStringMarshall(MIDL_STUB_MESSAGE
*pStubMsg
,
2418 unsigned char *pszMessage
, PFORMAT_STRING pFormat
)
2420 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg
, pszMessage
, pFormat
);
2422 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2423 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2424 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2427 /* allow compiler to optimise inline function by passing constant into
2428 * these functions */
2429 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2430 array_compute_and_write_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pszMessage
,
2432 array_write_variance_and_marshall(RPC_FC_C_CSTRING
, pStubMsg
, pszMessage
,
2433 pFormat
, TRUE
/* fHasPointers */);
2435 array_compute_and_write_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pszMessage
,
2437 array_write_variance_and_marshall(RPC_FC_C_WSTRING
, pStubMsg
, pszMessage
,
2438 pFormat
, TRUE
/* fHasPointers */);
2444 /***********************************************************************
2445 * NdrConformantStringBufferSize [RPCRT4.@]
2447 void WINAPI
NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2448 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
2450 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2452 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2453 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2454 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2457 /* allow compiler to optimise inline function by passing constant into
2458 * these functions */
2459 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2460 array_compute_and_size_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pMemory
,
2462 array_buffer_size(RPC_FC_C_CSTRING
, pStubMsg
, pMemory
, pFormat
,
2463 TRUE
/* fHasPointers */);
2465 array_compute_and_size_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pMemory
,
2467 array_buffer_size(RPC_FC_C_WSTRING
, pStubMsg
, pMemory
, pFormat
,
2468 TRUE
/* fHasPointers */);
2472 /************************************************************************
2473 * NdrConformantStringMemorySize [RPCRT4.@]
2475 ULONG WINAPI
NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
2476 PFORMAT_STRING pFormat
)
2478 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
2480 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2481 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2482 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2485 /* allow compiler to optimise inline function by passing constant into
2486 * these functions */
2487 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2488 array_read_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
);
2489 array_memory_size(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
,
2490 TRUE
/* fHasPointers */);
2492 array_read_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
);
2493 array_memory_size(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
,
2494 TRUE
/* fHasPointers */);
2497 return pStubMsg
->MemorySize
;
2500 /************************************************************************
2501 * NdrConformantStringUnmarshall [RPCRT4.@]
2503 unsigned char *WINAPI
NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2504 unsigned char** ppMemory
, PFORMAT_STRING pFormat
, unsigned char fMustAlloc
)
2506 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2507 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
2509 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2510 ERR("Unhandled string type: %#x\n", *pFormat
);
2511 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2514 /* allow compiler to optimise inline function by passing constant into
2515 * these functions */
2516 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2517 array_read_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
);
2518 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING
, pStubMsg
, ppMemory
,
2519 pFormat
, fMustAlloc
,
2520 TRUE
/* fUseBufferMemoryServer */,
2521 TRUE
/* fUnmarshall */);
2523 array_read_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
);
2524 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING
, pStubMsg
, ppMemory
,
2525 pFormat
, fMustAlloc
,
2526 TRUE
/* fUseBufferMemoryServer */,
2527 TRUE
/* fUnmarshall */);
2533 /***********************************************************************
2534 * NdrNonConformantStringMarshall [RPCRT4.@]
2536 unsigned char * WINAPI
NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2537 unsigned char *pMemory
,
2538 PFORMAT_STRING pFormat
)
2540 ULONG esize
, size
, maxsize
;
2542 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2544 maxsize
= *(const USHORT
*)&pFormat
[2];
2546 if (*pFormat
== RPC_FC_CSTRING
)
2549 const char *str
= (const char *)pMemory
;
2550 while (i
< maxsize
&& str
[i
]) i
++;
2551 TRACE("string=%s\n", debugstr_an(str
, i
));
2552 pStubMsg
->ActualCount
= i
+ 1;
2555 else if (*pFormat
== RPC_FC_WSTRING
)
2558 const WCHAR
*str
= (const WCHAR
*)pMemory
;
2559 while (i
< maxsize
&& str
[i
]) i
++;
2560 TRACE("string=%s\n", debugstr_wn(str
, i
));
2561 pStubMsg
->ActualCount
= i
+ 1;
2566 ERR("Unhandled string type: %#x\n", *pFormat
);
2567 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2570 pStubMsg
->Offset
= 0;
2571 WriteVariance(pStubMsg
);
2573 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2574 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
2579 /***********************************************************************
2580 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2582 unsigned char * WINAPI
NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2583 unsigned char **ppMemory
,
2584 PFORMAT_STRING pFormat
,
2585 unsigned char fMustAlloc
)
2587 ULONG bufsize
, memsize
, esize
, maxsize
;
2589 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2590 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
2592 maxsize
= *(const USHORT
*)&pFormat
[2];
2594 ReadVariance(pStubMsg
, NULL
, maxsize
);
2595 if (pStubMsg
->Offset
)
2597 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2598 RpcRaiseException(RPC_S_INVALID_BOUND
);
2601 if (*pFormat
== RPC_FC_CSTRING
) esize
= 1;
2602 else if (*pFormat
== RPC_FC_WSTRING
) esize
= 2;
2605 ERR("Unhandled string type: %#x\n", *pFormat
);
2606 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2609 memsize
= esize
* maxsize
;
2610 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2612 validate_string_data(pStubMsg
, bufsize
, esize
);
2614 if (!fMustAlloc
&& !*ppMemory
)
2617 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2619 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
2621 if (*pFormat
== RPC_FC_CSTRING
) {
2622 TRACE("string=%s\n", debugstr_an((char*)*ppMemory
, pStubMsg
->ActualCount
));
2624 else if (*pFormat
== RPC_FC_WSTRING
) {
2625 TRACE("string=%s\n", debugstr_wn((LPWSTR
)*ppMemory
, pStubMsg
->ActualCount
));
2631 /***********************************************************************
2632 * NdrNonConformantStringBufferSize [RPCRT4.@]
2634 void WINAPI
NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2635 unsigned char *pMemory
,
2636 PFORMAT_STRING pFormat
)
2638 ULONG esize
, maxsize
;
2640 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2642 maxsize
= *(const USHORT
*)&pFormat
[2];
2644 SizeVariance(pStubMsg
);
2646 if (*pFormat
== RPC_FC_CSTRING
)
2649 const char *str
= (const char *)pMemory
;
2650 while (i
< maxsize
&& str
[i
]) i
++;
2651 TRACE("string=%s\n", debugstr_an(str
, i
));
2652 pStubMsg
->ActualCount
= i
+ 1;
2655 else if (*pFormat
== RPC_FC_WSTRING
)
2658 const WCHAR
*str
= (const WCHAR
*)pMemory
;
2659 while (i
< maxsize
&& str
[i
]) i
++;
2660 TRACE("string=%s\n", debugstr_wn(str
, i
));
2661 pStubMsg
->ActualCount
= i
+ 1;
2666 ERR("Unhandled string type: %#x\n", *pFormat
);
2667 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2670 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
2673 /***********************************************************************
2674 * NdrNonConformantStringMemorySize [RPCRT4.@]
2676 ULONG WINAPI
NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2677 PFORMAT_STRING pFormat
)
2679 ULONG bufsize
, memsize
, esize
, maxsize
;
2681 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
2683 maxsize
= *(const USHORT
*)&pFormat
[2];
2685 ReadVariance(pStubMsg
, NULL
, maxsize
);
2687 if (pStubMsg
->Offset
)
2689 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2690 RpcRaiseException(RPC_S_INVALID_BOUND
);
2693 if (*pFormat
== RPC_FC_CSTRING
) esize
= 1;
2694 else if (*pFormat
== RPC_FC_WSTRING
) esize
= 2;
2697 ERR("Unhandled string type: %#x\n", *pFormat
);
2698 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2701 memsize
= esize
* maxsize
;
2702 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2704 validate_string_data(pStubMsg
, bufsize
, esize
);
2706 safe_buffer_increment(pStubMsg
, bufsize
);
2707 pStubMsg
->MemorySize
+= memsize
;
2709 return pStubMsg
->MemorySize
;
2714 #include "pshpack1.h"
2718 unsigned char flags_type
; /* flags in upper nibble, type in lower nibble */
2722 #include "poppack.h"
2724 static ULONG
EmbeddedComplexSize(MIDL_STUB_MESSAGE
*pStubMsg
,
2725 PFORMAT_STRING pFormat
)
2729 case RPC_FC_PSTRUCT
:
2730 case RPC_FC_CSTRUCT
:
2731 case RPC_FC_BOGUS_STRUCT
:
2732 case RPC_FC_SMFARRAY
:
2733 case RPC_FC_SMVARRAY
:
2734 case RPC_FC_CSTRING
:
2735 return *(const WORD
*)&pFormat
[2];
2736 case RPC_FC_USER_MARSHAL
:
2737 return *(const WORD
*)&pFormat
[4];
2738 case RPC_FC_RANGE
: {
2739 switch (((const NDR_RANGE
*)pFormat
)->flags_type
& 0xf) {
2744 return sizeof(UCHAR
);
2748 return sizeof(USHORT
);
2752 case RPC_FC_INT3264
:
2753 case RPC_FC_UINT3264
:
2754 return sizeof(ULONG
);
2756 return sizeof(float);
2758 return sizeof(double);
2760 return sizeof(ULONGLONG
);
2762 return sizeof(UINT
);
2764 ERR("unknown type 0x%x\n", ((const NDR_RANGE
*)pFormat
)->flags_type
& 0xf);
2765 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2768 case RPC_FC_NON_ENCAPSULATED_UNION
:
2770 if (pStubMsg
->fHasNewCorrDesc
)
2775 pFormat
+= *(const SHORT
*)pFormat
;
2776 return *(const SHORT
*)pFormat
;
2778 return sizeof(void *);
2779 case RPC_FC_WSTRING
:
2780 return *(const WORD
*)&pFormat
[2] * 2;
2782 FIXME("unhandled embedded type %02x\n", *pFormat
);
2788 static ULONG
EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2789 PFORMAT_STRING pFormat
)
2791 NDR_MEMORYSIZE m
= NdrMemorySizer
[*pFormat
& NDR_TABLE_MASK
];
2795 FIXME("no memorysizer for data type=%02x\n", *pFormat
);
2799 return m(pStubMsg
, pFormat
);
2803 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2804 unsigned char *pMemory
,
2805 PFORMAT_STRING pFormat
,
2806 PFORMAT_STRING pPointer
)
2808 PFORMAT_STRING desc
;
2812 while (*pFormat
!= RPC_FC_END
) {
2818 TRACE("byte=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2819 safe_copy_to_buffer(pStubMsg
, pMemory
, 1);
2825 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2826 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
2831 USHORT val
= *(DWORD
*)pMemory
;
2832 TRACE("enum16=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2833 if (32767 < *(DWORD
*)pMemory
)
2834 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
2835 safe_copy_to_buffer(pStubMsg
, &val
, 2);
2842 TRACE("long=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2843 safe_copy_to_buffer(pStubMsg
, pMemory
, 4);
2846 case RPC_FC_INT3264
:
2847 case RPC_FC_UINT3264
:
2849 UINT val
= *(UINT_PTR
*)pMemory
;
2850 TRACE("int3264=%ld <= %p\n", *(UINT_PTR
*)pMemory
, pMemory
);
2851 safe_copy_to_buffer(pStubMsg
, &val
, sizeof(UINT
));
2852 pMemory
+= sizeof(UINT_PTR
);
2856 TRACE("float=%f <= %p\n", *(float*)pMemory
, pMemory
);
2857 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
2858 pMemory
+= sizeof(float);
2861 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2862 safe_copy_to_buffer(pStubMsg
, pMemory
, 8);
2866 TRACE("double=%f <= %p\n", *(double*)pMemory
, pMemory
);
2867 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
2868 pMemory
+= sizeof(double);
2874 case RPC_FC_POINTER
:
2876 unsigned char *saved_buffer
;
2877 BOOL pointer_buffer_mark_set
= FALSE
;
2878 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
2879 TRACE("pStubMsg->Buffer before %p\n", pStubMsg
->Buffer
);
2880 if (*pFormat
!= RPC_FC_POINTER
)
2882 if (*pPointer
!= RPC_FC_RP
)
2883 align_pointer_clear(&pStubMsg
->Buffer
, 4);
2884 saved_buffer
= pStubMsg
->Buffer
;
2885 if (pStubMsg
->PointerBufferMark
)
2887 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2888 pStubMsg
->PointerBufferMark
= NULL
;
2889 pointer_buffer_mark_set
= TRUE
;
2891 else if (*pPointer
!= RPC_FC_RP
)
2892 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2893 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char**)pMemory
, pPointer
);
2894 if (pointer_buffer_mark_set
)
2896 STD_OVERFLOW_CHECK(pStubMsg
);
2897 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2898 pStubMsg
->Buffer
= saved_buffer
;
2899 if (*pPointer
!= RPC_FC_RP
)
2900 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2902 TRACE("pStubMsg->Buffer after %p\n", pStubMsg
->Buffer
);
2903 if (*pFormat
== RPC_FC_POINTER
)
2907 pMemory
+= sizeof(void *);
2910 case RPC_FC_ALIGNM2
:
2911 align_pointer(&pMemory
, 2);
2913 case RPC_FC_ALIGNM4
:
2914 align_pointer(&pMemory
, 4);
2916 case RPC_FC_ALIGNM8
:
2917 align_pointer(&pMemory
, 8);
2919 case RPC_FC_STRUCTPAD1
:
2920 case RPC_FC_STRUCTPAD2
:
2921 case RPC_FC_STRUCTPAD3
:
2922 case RPC_FC_STRUCTPAD4
:
2923 case RPC_FC_STRUCTPAD5
:
2924 case RPC_FC_STRUCTPAD6
:
2925 case RPC_FC_STRUCTPAD7
:
2926 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2928 case RPC_FC_EMBEDDED_COMPLEX
:
2929 pMemory
+= pFormat
[1];
2931 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2932 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2933 TRACE("embedded complex (size=%d) <= %p\n", size
, pMemory
);
2934 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
2937 /* for some reason interface pointers aren't generated as
2938 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2939 * they still need the derefencing treatment that pointers are
2941 if (*desc
== RPC_FC_IP
)
2942 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2944 m(pStubMsg
, pMemory
, desc
);
2946 else FIXME("no marshaller for embedded type %02x\n", *desc
);
2953 FIXME("unhandled format 0x%02x\n", *pFormat
);
2961 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2962 unsigned char *pMemory
,
2963 PFORMAT_STRING pFormat
,
2964 PFORMAT_STRING pPointer
,
2965 unsigned char fMustAlloc
)
2967 PFORMAT_STRING desc
;
2971 while (*pFormat
!= RPC_FC_END
) {
2977 safe_copy_from_buffer(pStubMsg
, pMemory
, 1);
2978 TRACE("byte=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2984 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
2985 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2991 safe_copy_from_buffer(pStubMsg
, &val
, 2);
2992 *(DWORD
*)pMemory
= val
;
2993 TRACE("enum16=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
2994 if (32767 < *(DWORD
*)pMemory
)
2995 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
3002 safe_copy_from_buffer(pStubMsg
, pMemory
, 4);
3003 TRACE("long=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
3006 case RPC_FC_INT3264
:
3009 safe_copy_from_buffer(pStubMsg
, &val
, 4);
3010 *(INT_PTR
*)pMemory
= val
;
3011 TRACE("int3264=%ld => %p\n", *(INT_PTR
*)pMemory
, pMemory
);
3012 pMemory
+= sizeof(INT_PTR
);
3015 case RPC_FC_UINT3264
:
3018 safe_copy_from_buffer(pStubMsg
, &val
, 4);
3019 *(UINT_PTR
*)pMemory
= val
;
3020 TRACE("uint3264=%ld => %p\n", *(UINT_PTR
*)pMemory
, pMemory
);
3021 pMemory
+= sizeof(UINT_PTR
);
3025 safe_copy_from_buffer(pStubMsg
, pMemory
, sizeof(float));
3026 TRACE("float=%f => %p\n", *(float*)pMemory
, pMemory
);
3027 pMemory
+= sizeof(float);
3030 safe_copy_from_buffer(pStubMsg
, pMemory
, 8);
3031 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
3035 safe_copy_from_buffer(pStubMsg
, pMemory
, sizeof(double));
3036 TRACE("double=%f => %p\n", *(double*)pMemory
, pMemory
);
3037 pMemory
+= sizeof(double);
3043 case RPC_FC_POINTER
:
3045 unsigned char *saved_buffer
;
3046 BOOL pointer_buffer_mark_set
= FALSE
;
3047 TRACE("pointer => %p\n", pMemory
);
3048 if (*pFormat
!= RPC_FC_POINTER
)
3050 if (*pPointer
!= RPC_FC_RP
)
3051 align_pointer(&pStubMsg
->Buffer
, 4);
3052 saved_buffer
= pStubMsg
->Buffer
;
3053 if (pStubMsg
->PointerBufferMark
)
3055 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3056 pStubMsg
->PointerBufferMark
= NULL
;
3057 pointer_buffer_mark_set
= TRUE
;
3059 else if (*pPointer
!= RPC_FC_RP
)
3060 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3062 PointerUnmarshall(pStubMsg
, saved_buffer
, (unsigned char**)pMemory
, *(unsigned char**)pMemory
, pPointer
, fMustAlloc
);
3063 if (pointer_buffer_mark_set
)
3065 STD_OVERFLOW_CHECK(pStubMsg
);
3066 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3067 pStubMsg
->Buffer
= saved_buffer
;
3068 if (*pPointer
!= RPC_FC_RP
)
3069 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3071 if (*pFormat
== RPC_FC_POINTER
)
3075 pMemory
+= sizeof(void *);
3078 case RPC_FC_ALIGNM2
:
3079 align_pointer_clear(&pMemory
, 2);
3081 case RPC_FC_ALIGNM4
:
3082 align_pointer_clear(&pMemory
, 4);
3084 case RPC_FC_ALIGNM8
:
3085 align_pointer_clear(&pMemory
, 8);
3087 case RPC_FC_STRUCTPAD1
:
3088 case RPC_FC_STRUCTPAD2
:
3089 case RPC_FC_STRUCTPAD3
:
3090 case RPC_FC_STRUCTPAD4
:
3091 case RPC_FC_STRUCTPAD5
:
3092 case RPC_FC_STRUCTPAD6
:
3093 case RPC_FC_STRUCTPAD7
:
3094 memset(pMemory
, 0, *pFormat
- RPC_FC_STRUCTPAD1
+ 1);
3095 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3097 case RPC_FC_EMBEDDED_COMPLEX
:
3098 pMemory
+= pFormat
[1];
3100 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3101 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3102 TRACE("embedded complex (size=%d) => %p\n", size
, pMemory
);
3104 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
3105 * since the type is part of the memory block that is encompassed by
3106 * the whole complex type. Memory is forced to allocate when pointers
3107 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
3108 * clearing the memory we pass in to the unmarshaller */
3109 memset(pMemory
, 0, size
);
3110 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
3113 /* for some reason interface pointers aren't generated as
3114 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3115 * they still need the derefencing treatment that pointers are
3117 if (*desc
== RPC_FC_IP
)
3118 m(pStubMsg
, (unsigned char **)pMemory
, desc
, FALSE
);
3120 m(pStubMsg
, &pMemory
, desc
, FALSE
);
3122 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
3129 FIXME("unhandled format %d\n", *pFormat
);
3137 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3138 unsigned char *pMemory
,
3139 PFORMAT_STRING pFormat
,
3140 PFORMAT_STRING pPointer
)
3142 PFORMAT_STRING desc
;
3146 while (*pFormat
!= RPC_FC_END
) {
3152 safe_buffer_length_increment(pStubMsg
, 1);
3158 safe_buffer_length_increment(pStubMsg
, 2);
3162 safe_buffer_length_increment(pStubMsg
, 2);
3169 safe_buffer_length_increment(pStubMsg
, 4);
3172 case RPC_FC_INT3264
:
3173 case RPC_FC_UINT3264
:
3174 safe_buffer_length_increment(pStubMsg
, 4);
3175 pMemory
+= sizeof(INT_PTR
);
3179 safe_buffer_length_increment(pStubMsg
, 8);
3186 case RPC_FC_POINTER
:
3187 if (*pFormat
!= RPC_FC_POINTER
)
3189 if (!pStubMsg
->IgnoreEmbeddedPointers
)
3191 int saved_buffer_length
= pStubMsg
->BufferLength
;
3192 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3193 pStubMsg
->PointerLength
= 0;
3194 if(!pStubMsg
->BufferLength
)
3195 ERR("BufferLength == 0??\n");
3196 PointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
3197 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3198 pStubMsg
->BufferLength
= saved_buffer_length
;
3200 if (*pPointer
!= RPC_FC_RP
)
3202 align_length(&pStubMsg
->BufferLength
, 4);
3203 safe_buffer_length_increment(pStubMsg
, 4);
3205 if (*pFormat
== RPC_FC_POINTER
)
3209 pMemory
+= sizeof(void*);
3211 case RPC_FC_ALIGNM2
:
3212 align_pointer(&pMemory
, 2);
3214 case RPC_FC_ALIGNM4
:
3215 align_pointer(&pMemory
, 4);
3217 case RPC_FC_ALIGNM8
:
3218 align_pointer(&pMemory
, 8);
3220 case RPC_FC_STRUCTPAD1
:
3221 case RPC_FC_STRUCTPAD2
:
3222 case RPC_FC_STRUCTPAD3
:
3223 case RPC_FC_STRUCTPAD4
:
3224 case RPC_FC_STRUCTPAD5
:
3225 case RPC_FC_STRUCTPAD6
:
3226 case RPC_FC_STRUCTPAD7
:
3227 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3229 case RPC_FC_EMBEDDED_COMPLEX
:
3230 pMemory
+= pFormat
[1];
3232 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3233 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3234 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
3237 /* for some reason interface pointers aren't generated as
3238 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3239 * they still need the derefencing treatment that pointers are
3241 if (*desc
== RPC_FC_IP
)
3242 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
3244 m(pStubMsg
, pMemory
, desc
);
3246 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
3253 FIXME("unhandled format 0x%02x\n", *pFormat
);
3261 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
3262 unsigned char *pMemory
,
3263 PFORMAT_STRING pFormat
,
3264 PFORMAT_STRING pPointer
)
3266 PFORMAT_STRING desc
;
3270 while (*pFormat
!= RPC_FC_END
) {
3290 case RPC_FC_INT3264
:
3291 case RPC_FC_UINT3264
:
3292 pMemory
+= sizeof(INT_PTR
);
3302 case RPC_FC_POINTER
:
3303 if (*pFormat
!= RPC_FC_POINTER
)
3305 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
3306 if (*pFormat
== RPC_FC_POINTER
)
3310 pMemory
+= sizeof(void *);
3312 case RPC_FC_ALIGNM2
:
3313 align_pointer(&pMemory
, 2);
3315 case RPC_FC_ALIGNM4
:
3316 align_pointer(&pMemory
, 4);
3318 case RPC_FC_ALIGNM8
:
3319 align_pointer(&pMemory
, 8);
3321 case RPC_FC_STRUCTPAD1
:
3322 case RPC_FC_STRUCTPAD2
:
3323 case RPC_FC_STRUCTPAD3
:
3324 case RPC_FC_STRUCTPAD4
:
3325 case RPC_FC_STRUCTPAD5
:
3326 case RPC_FC_STRUCTPAD6
:
3327 case RPC_FC_STRUCTPAD7
:
3328 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3330 case RPC_FC_EMBEDDED_COMPLEX
:
3331 pMemory
+= pFormat
[1];
3333 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3334 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3335 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
3338 /* for some reason interface pointers aren't generated as
3339 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3340 * they still need the derefencing treatment that pointers are
3342 if (*desc
== RPC_FC_IP
)
3343 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
3345 m(pStubMsg
, pMemory
, desc
);
3353 FIXME("unhandled format 0x%02x\n", *pFormat
);
3361 static ULONG
ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3362 PFORMAT_STRING pFormat
,
3363 PFORMAT_STRING pPointer
)
3365 PFORMAT_STRING desc
;
3368 while (*pFormat
!= RPC_FC_END
) {
3375 safe_buffer_increment(pStubMsg
, 1);
3381 safe_buffer_increment(pStubMsg
, 2);
3385 safe_buffer_increment(pStubMsg
, 2);
3392 safe_buffer_increment(pStubMsg
, 4);
3394 case RPC_FC_INT3264
:
3395 case RPC_FC_UINT3264
:
3396 size
+= sizeof(INT_PTR
);
3397 safe_buffer_increment(pStubMsg
, 4);
3402 safe_buffer_increment(pStubMsg
, 8);
3408 case RPC_FC_POINTER
:
3410 unsigned char *saved_buffer
;
3411 BOOL pointer_buffer_mark_set
= FALSE
;
3412 if (*pFormat
!= RPC_FC_POINTER
)
3414 if (*pPointer
!= RPC_FC_RP
)
3415 align_pointer(&pStubMsg
->Buffer
, 4);
3416 saved_buffer
= pStubMsg
->Buffer
;
3417 if (pStubMsg
->PointerBufferMark
)
3419 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3420 pStubMsg
->PointerBufferMark
= NULL
;
3421 pointer_buffer_mark_set
= TRUE
;
3423 else if (*pPointer
!= RPC_FC_RP
)
3424 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3426 if (!pStubMsg
->IgnoreEmbeddedPointers
)
3427 PointerMemorySize(pStubMsg
, saved_buffer
, pPointer
);
3428 if (pointer_buffer_mark_set
)
3430 STD_OVERFLOW_CHECK(pStubMsg
);
3431 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3432 pStubMsg
->Buffer
= saved_buffer
;
3433 if (*pPointer
!= RPC_FC_RP
)
3434 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3436 if (*pFormat
== RPC_FC_POINTER
)
3440 size
+= sizeof(void *);
3443 case RPC_FC_ALIGNM2
:
3444 align_length(&size
, 2);
3446 case RPC_FC_ALIGNM4
:
3447 align_length(&size
, 4);
3449 case RPC_FC_ALIGNM8
:
3450 align_length(&size
, 8);
3452 case RPC_FC_STRUCTPAD1
:
3453 case RPC_FC_STRUCTPAD2
:
3454 case RPC_FC_STRUCTPAD3
:
3455 case RPC_FC_STRUCTPAD4
:
3456 case RPC_FC_STRUCTPAD5
:
3457 case RPC_FC_STRUCTPAD6
:
3458 case RPC_FC_STRUCTPAD7
:
3459 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3461 case RPC_FC_EMBEDDED_COMPLEX
:
3464 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3465 size
+= EmbeddedComplexMemorySize(pStubMsg
, desc
);
3471 FIXME("unhandled format 0x%02x\n", *pFormat
);
3479 ULONG
ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
3481 PFORMAT_STRING desc
;
3484 while (*pFormat
!= RPC_FC_END
) {
3504 case RPC_FC_INT3264
:
3505 case RPC_FC_UINT3264
:
3506 size
+= sizeof(INT_PTR
);
3516 case RPC_FC_POINTER
:
3517 size
+= sizeof(void *);
3518 if (*pFormat
!= RPC_FC_POINTER
)
3521 case RPC_FC_ALIGNM2
:
3522 align_length(&size
, 2);
3524 case RPC_FC_ALIGNM4
:
3525 align_length(&size
, 4);
3527 case RPC_FC_ALIGNM8
:
3528 align_length(&size
, 8);
3530 case RPC_FC_STRUCTPAD1
:
3531 case RPC_FC_STRUCTPAD2
:
3532 case RPC_FC_STRUCTPAD3
:
3533 case RPC_FC_STRUCTPAD4
:
3534 case RPC_FC_STRUCTPAD5
:
3535 case RPC_FC_STRUCTPAD6
:
3536 case RPC_FC_STRUCTPAD7
:
3537 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3539 case RPC_FC_EMBEDDED_COMPLEX
:
3542 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3543 size
+= EmbeddedComplexSize(pStubMsg
, desc
);
3549 FIXME("unhandled format 0x%02x\n", *pFormat
);
3557 /***********************************************************************
3558 * NdrComplexStructMarshall [RPCRT4.@]
3560 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3561 unsigned char *pMemory
,
3562 PFORMAT_STRING pFormat
)
3564 PFORMAT_STRING conf_array
= NULL
;
3565 PFORMAT_STRING pointer_desc
= NULL
;
3566 unsigned char *OldMemory
= pStubMsg
->Memory
;
3567 BOOL pointer_buffer_mark_set
= FALSE
;
3569 ULONG max_count
= 0;
3572 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3574 if (!pStubMsg
->PointerBufferMark
)
3576 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3577 /* save buffer length */
3578 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
3580 /* get the buffer pointer after complex array data, but before
3582 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
;
3583 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3584 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
3585 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3587 /* save it for use by embedded pointer code later */
3588 pStubMsg
->PointerBufferMark
= (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
;
3589 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->PointerBufferMark
- pStubMsg
->Buffer
));
3590 pointer_buffer_mark_set
= TRUE
;
3592 /* restore the original buffer length */
3593 pStubMsg
->BufferLength
= saved_buffer_length
;
3596 align_pointer_clear(&pStubMsg
->Buffer
, pFormat
[1] + 1);
3599 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3601 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3604 pStubMsg
->Memory
= pMemory
;
3608 ULONG struct_size
= ComplexStructSize(pStubMsg
, pFormat
);
3609 array_compute_and_write_conformance(conf_array
[0], pStubMsg
,
3610 pMemory
+ struct_size
, conf_array
);
3611 /* these could be changed in ComplexMarshall so save them for later */
3612 max_count
= pStubMsg
->MaxCount
;
3613 count
= pStubMsg
->ActualCount
;
3614 offset
= pStubMsg
->Offset
;
3617 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3621 pStubMsg
->MaxCount
= max_count
;
3622 pStubMsg
->ActualCount
= count
;
3623 pStubMsg
->Offset
= offset
;
3624 array_write_variance_and_marshall(conf_array
[0], pStubMsg
, pMemory
,
3625 conf_array
, TRUE
/* fHasPointers */);
3628 pStubMsg
->Memory
= OldMemory
;
3630 if (pointer_buffer_mark_set
)
3632 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3633 pStubMsg
->PointerBufferMark
= NULL
;
3636 STD_OVERFLOW_CHECK(pStubMsg
);
3641 /***********************************************************************
3642 * NdrComplexStructUnmarshall [RPCRT4.@]
3644 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3645 unsigned char **ppMemory
,
3646 PFORMAT_STRING pFormat
,
3647 unsigned char fMustAlloc
)
3649 unsigned size
= *(const WORD
*)(pFormat
+2);
3650 PFORMAT_STRING conf_array
= NULL
;
3651 PFORMAT_STRING pointer_desc
= NULL
;
3652 unsigned char *pMemory
;
3653 BOOL pointer_buffer_mark_set
= FALSE
;
3655 ULONG max_count
= 0;
3657 ULONG array_size
= 0;
3659 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3661 if (!pStubMsg
->PointerBufferMark
)
3663 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3664 /* save buffer pointer */
3665 unsigned char *saved_buffer
= pStubMsg
->Buffer
;
3667 /* get the buffer pointer after complex array data, but before
3669 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3670 NdrComplexStructMemorySize(pStubMsg
, pFormat
);
3671 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3673 /* save it for use by embedded pointer code later */
3674 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3675 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->PointerBufferMark
- saved_buffer
));
3676 pointer_buffer_mark_set
= TRUE
;
3678 /* restore the original buffer */
3679 pStubMsg
->Buffer
= saved_buffer
;
3682 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
3685 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3687 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3692 array_size
= array_read_conformance(conf_array
[0], pStubMsg
, conf_array
);
3695 /* these could be changed in ComplexMarshall so save them for later */
3696 max_count
= pStubMsg
->MaxCount
;
3697 count
= pStubMsg
->ActualCount
;
3698 offset
= pStubMsg
->Offset
;
3701 if (!fMustAlloc
&& !*ppMemory
)
3704 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3706 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
, fMustAlloc
);
3710 pStubMsg
->MaxCount
= max_count
;
3711 pStubMsg
->ActualCount
= count
;
3712 pStubMsg
->Offset
= offset
;
3714 memset(pMemory
, 0, array_size
);
3715 array_read_variance_and_unmarshall(conf_array
[0], pStubMsg
, &pMemory
,
3717 FALSE
/* fUseBufferMemoryServer */,
3718 TRUE
/* fUnmarshall */);
3721 if (pointer_buffer_mark_set
)
3723 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3724 pStubMsg
->PointerBufferMark
= NULL
;
3730 /***********************************************************************
3731 * NdrComplexStructBufferSize [RPCRT4.@]
3733 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3734 unsigned char *pMemory
,
3735 PFORMAT_STRING pFormat
)
3737 PFORMAT_STRING conf_array
= NULL
;
3738 PFORMAT_STRING pointer_desc
= NULL
;
3739 unsigned char *OldMemory
= pStubMsg
->Memory
;
3740 int pointer_length_set
= 0;
3742 ULONG max_count
= 0;
3745 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3747 align_length(&pStubMsg
->BufferLength
, pFormat
[1] + 1);
3749 if(!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
3751 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3752 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
3754 /* get the buffer length after complex struct data, but before
3756 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3757 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
3758 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3760 /* save it for use by embedded pointer code later */
3761 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3762 pointer_length_set
= 1;
3763 TRACE("difference = 0x%x\n", pStubMsg
->PointerLength
- saved_buffer_length
);
3765 /* restore the original buffer length */
3766 pStubMsg
->BufferLength
= saved_buffer_length
;
3770 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3772 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3775 pStubMsg
->Memory
= pMemory
;
3779 ULONG struct_size
= ComplexStructSize(pStubMsg
, pFormat
);
3780 array_compute_and_size_conformance(conf_array
[0], pStubMsg
, pMemory
+ struct_size
,
3783 /* these could be changed in ComplexMarshall so save them for later */
3784 max_count
= pStubMsg
->MaxCount
;
3785 count
= pStubMsg
->ActualCount
;
3786 offset
= pStubMsg
->Offset
;
3789 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3793 pStubMsg
->MaxCount
= max_count
;
3794 pStubMsg
->ActualCount
= count
;
3795 pStubMsg
->Offset
= offset
;
3796 array_buffer_size(conf_array
[0], pStubMsg
, pMemory
, conf_array
,
3797 TRUE
/* fHasPointers */);
3800 pStubMsg
->Memory
= OldMemory
;
3802 if(pointer_length_set
)
3804 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3805 pStubMsg
->PointerLength
= 0;
3810 /***********************************************************************
3811 * NdrComplexStructMemorySize [RPCRT4.@]
3813 ULONG WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3814 PFORMAT_STRING pFormat
)
3816 unsigned size
= *(const WORD
*)(pFormat
+2);
3817 PFORMAT_STRING conf_array
= NULL
;
3818 PFORMAT_STRING pointer_desc
= NULL
;
3820 ULONG max_count
= 0;
3823 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3825 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
3828 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3830 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3835 array_read_conformance(conf_array
[0], pStubMsg
, conf_array
);
3837 /* these could be changed in ComplexStructMemorySize so save them for
3839 max_count
= pStubMsg
->MaxCount
;
3840 count
= pStubMsg
->ActualCount
;
3841 offset
= pStubMsg
->Offset
;
3844 ComplexStructMemorySize(pStubMsg
, pFormat
, pointer_desc
);
3848 pStubMsg
->MaxCount
= max_count
;
3849 pStubMsg
->ActualCount
= count
;
3850 pStubMsg
->Offset
= offset
;
3851 array_memory_size(conf_array
[0], pStubMsg
, conf_array
,
3852 TRUE
/* fHasPointers */);
3858 /***********************************************************************
3859 * NdrComplexStructFree [RPCRT4.@]
3861 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3862 unsigned char *pMemory
,
3863 PFORMAT_STRING pFormat
)
3865 PFORMAT_STRING conf_array
= NULL
;
3866 PFORMAT_STRING pointer_desc
= NULL
;
3867 unsigned char *OldMemory
= pStubMsg
->Memory
;
3869 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3872 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3874 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3877 pStubMsg
->Memory
= pMemory
;
3879 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3882 array_free(conf_array
[0], pStubMsg
, pMemory
, conf_array
,
3883 TRUE
/* fHasPointers */);
3885 pStubMsg
->Memory
= OldMemory
;
3888 /***********************************************************************
3889 * NdrConformantArrayMarshall [RPCRT4.@]
3891 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3892 unsigned char *pMemory
,
3893 PFORMAT_STRING pFormat
)
3895 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3896 if (pFormat
[0] != RPC_FC_CARRAY
)
3898 ERR("invalid format = 0x%x\n", pFormat
[0]);
3899 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3902 array_compute_and_write_conformance(RPC_FC_CARRAY
, pStubMsg
, pMemory
,
3904 array_write_variance_and_marshall(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3905 TRUE
/* fHasPointers */);
3910 /***********************************************************************
3911 * NdrConformantArrayUnmarshall [RPCRT4.@]
3913 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3914 unsigned char **ppMemory
,
3915 PFORMAT_STRING pFormat
,
3916 unsigned char fMustAlloc
)
3918 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3919 if (pFormat
[0] != RPC_FC_CARRAY
)
3921 ERR("invalid format = 0x%x\n", pFormat
[0]);
3922 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3925 array_read_conformance(RPC_FC_CARRAY
, pStubMsg
, pFormat
);
3926 array_read_variance_and_unmarshall(RPC_FC_CARRAY
, pStubMsg
, ppMemory
, pFormat
,
3928 TRUE
/* fUseBufferMemoryServer */,
3929 TRUE
/* fUnmarshall */);
3934 /***********************************************************************
3935 * NdrConformantArrayBufferSize [RPCRT4.@]
3937 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3938 unsigned char *pMemory
,
3939 PFORMAT_STRING pFormat
)
3941 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3942 if (pFormat
[0] != RPC_FC_CARRAY
)
3944 ERR("invalid format = 0x%x\n", pFormat
[0]);
3945 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3948 array_compute_and_size_conformance(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
);
3949 array_buffer_size(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3950 TRUE
/* fHasPointers */);
3953 /***********************************************************************
3954 * NdrConformantArrayMemorySize [RPCRT4.@]
3956 ULONG WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3957 PFORMAT_STRING pFormat
)
3959 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3960 if (pFormat
[0] != RPC_FC_CARRAY
)
3962 ERR("invalid format = 0x%x\n", pFormat
[0]);
3963 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3966 array_read_conformance(RPC_FC_CARRAY
, pStubMsg
, pFormat
);
3967 array_memory_size(RPC_FC_CARRAY
, pStubMsg
, pFormat
, TRUE
/* fHasPointers */);
3969 return pStubMsg
->MemorySize
;
3972 /***********************************************************************
3973 * NdrConformantArrayFree [RPCRT4.@]
3975 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3976 unsigned char *pMemory
,
3977 PFORMAT_STRING pFormat
)
3979 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3980 if (pFormat
[0] != RPC_FC_CARRAY
)
3982 ERR("invalid format = 0x%x\n", pFormat
[0]);
3983 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3986 array_free(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3987 TRUE
/* fHasPointers */);
3991 /***********************************************************************
3992 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3994 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
3995 unsigned char* pMemory
,
3996 PFORMAT_STRING pFormat
)
3998 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4000 if (pFormat
[0] != RPC_FC_CVARRAY
)
4002 ERR("invalid format type %x\n", pFormat
[0]);
4003 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4007 array_compute_and_write_conformance(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
4009 array_write_variance_and_marshall(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
4010 pFormat
, TRUE
/* fHasPointers */);
4016 /***********************************************************************
4017 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
4019 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
4020 unsigned char** ppMemory
,
4021 PFORMAT_STRING pFormat
,
4022 unsigned char fMustAlloc
)
4024 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4026 if (pFormat
[0] != RPC_FC_CVARRAY
)
4028 ERR("invalid format type %x\n", pFormat
[0]);
4029 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4033 array_read_conformance(RPC_FC_CVARRAY
, pStubMsg
, pFormat
);
4034 array_read_variance_and_unmarshall(RPC_FC_CVARRAY
, pStubMsg
, ppMemory
,
4035 pFormat
, fMustAlloc
,
4036 TRUE
/* fUseBufferMemoryServer */,
4037 TRUE
/* fUnmarshall */);
4043 /***********************************************************************
4044 * NdrConformantVaryingArrayFree [RPCRT4.@]
4046 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
4047 unsigned char* pMemory
,
4048 PFORMAT_STRING pFormat
)
4050 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4052 if (pFormat
[0] != RPC_FC_CVARRAY
)
4054 ERR("invalid format type %x\n", pFormat
[0]);
4055 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4059 array_free(RPC_FC_CVARRAY
, pStubMsg
, pMemory
, pFormat
,
4060 TRUE
/* fHasPointers */);
4064 /***********************************************************************
4065 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
4067 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
4068 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
4070 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4072 if (pFormat
[0] != RPC_FC_CVARRAY
)
4074 ERR("invalid format type %x\n", pFormat
[0]);
4075 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4079 array_compute_and_size_conformance(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
4081 array_buffer_size(RPC_FC_CVARRAY
, pStubMsg
, pMemory
, pFormat
,
4082 TRUE
/* fHasPointers */);
4086 /***********************************************************************
4087 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
4089 ULONG WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
4090 PFORMAT_STRING pFormat
)
4092 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4094 if (pFormat
[0] != RPC_FC_CVARRAY
)
4096 ERR("invalid format type %x\n", pFormat
[0]);
4097 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4098 return pStubMsg
->MemorySize
;
4101 array_read_conformance(RPC_FC_CVARRAY
, pStubMsg
, pFormat
);
4102 array_memory_size(RPC_FC_CVARRAY
, pStubMsg
, pFormat
,
4103 TRUE
/* fHasPointers */);
4105 return pStubMsg
->MemorySize
;
4109 /***********************************************************************
4110 * NdrComplexArrayMarshall [RPCRT4.@]
4112 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4113 unsigned char *pMemory
,
4114 PFORMAT_STRING pFormat
)
4116 BOOL pointer_buffer_mark_set
= FALSE
;
4118 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4120 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4122 ERR("invalid format type %x\n", pFormat
[0]);
4123 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4127 if (!pStubMsg
->PointerBufferMark
)
4129 /* save buffer fields that may be changed by buffer sizer functions
4130 * and that may be needed later on */
4131 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
4132 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
4133 ULONG_PTR saved_max_count
= pStubMsg
->MaxCount
;
4134 ULONG saved_offset
= pStubMsg
->Offset
;
4135 ULONG saved_actual_count
= pStubMsg
->ActualCount
;
4137 /* get the buffer pointer after complex array data, but before
4139 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
;
4140 pStubMsg
->IgnoreEmbeddedPointers
= 1;
4141 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
4142 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
4144 /* save it for use by embedded pointer code later */
4145 pStubMsg
->PointerBufferMark
= (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
;
4146 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
));
4147 pointer_buffer_mark_set
= TRUE
;
4149 /* restore fields */
4150 pStubMsg
->ActualCount
= saved_actual_count
;
4151 pStubMsg
->Offset
= saved_offset
;
4152 pStubMsg
->MaxCount
= saved_max_count
;
4153 pStubMsg
->BufferLength
= saved_buffer_length
;
4156 array_compute_and_write_conformance(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pMemory
, pFormat
);
4157 array_write_variance_and_marshall(RPC_FC_BOGUS_ARRAY
, pStubMsg
,
4158 pMemory
, pFormat
, TRUE
/* fHasPointers */);
4160 STD_OVERFLOW_CHECK(pStubMsg
);
4162 if (pointer_buffer_mark_set
)
4164 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4165 pStubMsg
->PointerBufferMark
= NULL
;
4171 /***********************************************************************
4172 * NdrComplexArrayUnmarshall [RPCRT4.@]
4174 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4175 unsigned char **ppMemory
,
4176 PFORMAT_STRING pFormat
,
4177 unsigned char fMustAlloc
)
4179 unsigned char *saved_buffer
;
4180 BOOL pointer_buffer_mark_set
= FALSE
;
4181 int saved_ignore_embedded
;
4183 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4185 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4187 ERR("invalid format type %x\n", pFormat
[0]);
4188 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4192 saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
4193 /* save buffer pointer */
4194 saved_buffer
= pStubMsg
->Buffer
;
4195 /* get the buffer pointer after complex array data, but before
4197 pStubMsg
->IgnoreEmbeddedPointers
= 1;
4198 pStubMsg
->MemorySize
= 0;
4199 NdrComplexArrayMemorySize(pStubMsg
, pFormat
);
4200 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
4202 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->Buffer
- saved_buffer
));
4203 if (!pStubMsg
->PointerBufferMark
)
4205 /* save it for use by embedded pointer code later */
4206 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4207 pointer_buffer_mark_set
= TRUE
;
4209 /* restore the original buffer */
4210 pStubMsg
->Buffer
= saved_buffer
;
4212 array_read_conformance(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pFormat
);
4213 array_read_variance_and_unmarshall(RPC_FC_BOGUS_ARRAY
, pStubMsg
, ppMemory
, pFormat
, fMustAlloc
,
4214 TRUE
/* fUseBufferMemoryServer */, TRUE
/* fUnmarshall */);
4216 if (pointer_buffer_mark_set
)
4218 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4219 pStubMsg
->PointerBufferMark
= NULL
;
4225 /***********************************************************************
4226 * NdrComplexArrayBufferSize [RPCRT4.@]
4228 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4229 unsigned char *pMemory
,
4230 PFORMAT_STRING pFormat
)
4232 int pointer_length_set
= 0;
4234 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4236 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4238 ERR("invalid format type %x\n", pFormat
[0]);
4239 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4243 if (!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
4245 /* save buffer fields that may be changed by buffer sizer functions
4246 * and that may be needed later on */
4247 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
4248 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
4249 ULONG_PTR saved_max_count
= pStubMsg
->MaxCount
;
4250 ULONG saved_offset
= pStubMsg
->Offset
;
4251 ULONG saved_actual_count
= pStubMsg
->ActualCount
;
4253 /* get the buffer pointer after complex array data, but before
4255 pStubMsg
->IgnoreEmbeddedPointers
= 1;
4256 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
4257 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
4259 /* save it for use by embedded pointer code later */
4260 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4261 pointer_length_set
= 1;
4263 /* restore fields */
4264 pStubMsg
->ActualCount
= saved_actual_count
;
4265 pStubMsg
->Offset
= saved_offset
;
4266 pStubMsg
->MaxCount
= saved_max_count
;
4267 pStubMsg
->BufferLength
= saved_buffer_length
;
4270 array_compute_and_size_conformance(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pMemory
, pFormat
);
4271 array_buffer_size(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pMemory
, pFormat
, TRUE
/* fHasPointers */);
4273 if(pointer_length_set
)
4275 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4276 pStubMsg
->PointerLength
= 0;
4280 /***********************************************************************
4281 * NdrComplexArrayMemorySize [RPCRT4.@]
4283 ULONG WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4284 PFORMAT_STRING pFormat
)
4286 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
4288 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4290 ERR("invalid format type %x\n", pFormat
[0]);
4291 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4295 array_read_conformance(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pFormat
);
4296 array_memory_size(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pFormat
, TRUE
/* fHasPointers */);
4297 return pStubMsg
->MemorySize
;
4300 /***********************************************************************
4301 * NdrComplexArrayFree [RPCRT4.@]
4303 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4304 unsigned char *pMemory
,
4305 PFORMAT_STRING pFormat
)
4307 ULONG i
, count
, def
;
4309 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4311 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4313 ERR("invalid format type %x\n", pFormat
[0]);
4314 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4318 def
= *(const WORD
*)&pFormat
[2];
4321 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
4322 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
4324 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
4325 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
4327 count
= pStubMsg
->ActualCount
;
4328 for (i
= 0; i
< count
; i
++)
4329 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
4332 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg
,
4333 USER_MARSHAL_CB_TYPE cbtype
, PFORMAT_STRING pFormat
,
4334 USER_MARSHAL_CB
*umcb
)
4336 umcb
->Flags
= MAKELONG(pStubMsg
->dwDestContext
,
4337 pStubMsg
->RpcMsg
->DataRepresentation
);
4338 umcb
->pStubMsg
= pStubMsg
;
4339 umcb
->pReserve
= NULL
;
4340 umcb
->Signature
= USER_MARSHAL_CB_SIGNATURE
;
4341 umcb
->CBType
= cbtype
;
4342 umcb
->pFormat
= pFormat
;
4343 umcb
->pTypeFormat
= NULL
/* FIXME */;
4346 #define USER_MARSHAL_PTR_PREFIX \
4347 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4348 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4350 /***********************************************************************
4351 * NdrUserMarshalMarshall [RPCRT4.@]
4353 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4354 unsigned char *pMemory
,
4355 PFORMAT_STRING pFormat
)
4357 unsigned flags
= pFormat
[1];
4358 unsigned index
= *(const WORD
*)&pFormat
[2];
4359 unsigned char *saved_buffer
= NULL
;
4360 USER_MARSHAL_CB umcb
;
4362 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4363 TRACE("index=%d\n", index
);
4365 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_MARSHALL
, pFormat
, &umcb
);
4367 if (flags
& USER_MARSHAL_POINTER
)
4369 align_pointer_clear(&pStubMsg
->Buffer
, 4);
4370 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, USER_MARSHAL_PTR_PREFIX
);
4371 pStubMsg
->Buffer
+= 4;
4372 if (pStubMsg
->PointerBufferMark
)
4374 saved_buffer
= pStubMsg
->Buffer
;
4375 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4376 pStubMsg
->PointerBufferMark
= NULL
;
4378 align_pointer_clear(&pStubMsg
->Buffer
, 8);
4381 align_pointer_clear(&pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4384 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
4385 &umcb
.Flags
, pStubMsg
->Buffer
, pMemory
);
4389 STD_OVERFLOW_CHECK(pStubMsg
);
4390 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4391 pStubMsg
->Buffer
= saved_buffer
;
4394 STD_OVERFLOW_CHECK(pStubMsg
);
4399 /***********************************************************************
4400 * NdrUserMarshalUnmarshall [RPCRT4.@]
4402 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4403 unsigned char **ppMemory
,
4404 PFORMAT_STRING pFormat
,
4405 unsigned char fMustAlloc
)
4407 unsigned flags
= pFormat
[1];
4408 unsigned index
= *(const WORD
*)&pFormat
[2];
4409 DWORD memsize
= *(const WORD
*)&pFormat
[4];
4410 unsigned char *saved_buffer
= NULL
;
4411 USER_MARSHAL_CB umcb
;
4413 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4414 TRACE("index=%d\n", index
);
4416 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_UNMARSHALL
, pFormat
, &umcb
);
4418 if (flags
& USER_MARSHAL_POINTER
)
4420 align_pointer(&pStubMsg
->Buffer
, 4);
4421 /* skip pointer prefix */
4422 pStubMsg
->Buffer
+= 4;
4423 if (pStubMsg
->PointerBufferMark
)
4425 saved_buffer
= pStubMsg
->Buffer
;
4426 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4427 pStubMsg
->PointerBufferMark
= NULL
;
4429 align_pointer(&pStubMsg
->Buffer
, 8);
4432 align_pointer(&pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4434 if (!fMustAlloc
&& !*ppMemory
)
4438 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
4439 memset(*ppMemory
, 0, memsize
);
4443 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
4444 &umcb
.Flags
, pStubMsg
->Buffer
, *ppMemory
);
4448 STD_OVERFLOW_CHECK(pStubMsg
);
4449 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4450 pStubMsg
->Buffer
= saved_buffer
;
4456 /***********************************************************************
4457 * NdrUserMarshalBufferSize [RPCRT4.@]
4459 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4460 unsigned char *pMemory
,
4461 PFORMAT_STRING pFormat
)
4463 unsigned flags
= pFormat
[1];
4464 unsigned index
= *(const WORD
*)&pFormat
[2];
4465 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
4466 USER_MARSHAL_CB umcb
;
4467 ULONG saved_buffer_length
= 0;
4469 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4470 TRACE("index=%d\n", index
);
4472 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_BUFFER_SIZE
, pFormat
, &umcb
);
4474 if (flags
& USER_MARSHAL_POINTER
)
4476 align_length(&pStubMsg
->BufferLength
, 4);
4477 /* skip pointer prefix */
4478 safe_buffer_length_increment(pStubMsg
, 4);
4479 if (pStubMsg
->IgnoreEmbeddedPointers
)
4481 if (pStubMsg
->PointerLength
)
4483 saved_buffer_length
= pStubMsg
->BufferLength
;
4484 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4485 pStubMsg
->PointerLength
= 0;
4487 align_length(&pStubMsg
->BufferLength
, 8);
4490 align_length(&pStubMsg
->BufferLength
, (flags
& 0xf) + 1);
4493 TRACE("size=%d\n", bufsize
);
4494 safe_buffer_length_increment(pStubMsg
, bufsize
);
4497 pStubMsg
->BufferLength
=
4498 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
4499 &umcb
.Flags
, pStubMsg
->BufferLength
, pMemory
);
4501 if (saved_buffer_length
)
4503 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4504 pStubMsg
->BufferLength
= saved_buffer_length
;
4509 /***********************************************************************
4510 * NdrUserMarshalMemorySize [RPCRT4.@]
4512 ULONG WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4513 PFORMAT_STRING pFormat
)
4515 unsigned flags
= pFormat
[1];
4516 unsigned index
= *(const WORD
*)&pFormat
[2];
4517 DWORD memsize
= *(const WORD
*)&pFormat
[4];
4518 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
4520 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
4521 TRACE("index=%d\n", index
);
4523 pStubMsg
->MemorySize
+= memsize
;
4525 if (flags
& USER_MARSHAL_POINTER
)
4527 align_pointer(&pStubMsg
->Buffer
, 4);
4528 /* skip pointer prefix */
4529 pStubMsg
->Buffer
+= 4;
4530 if (pStubMsg
->IgnoreEmbeddedPointers
)
4531 return pStubMsg
->MemorySize
;
4532 align_pointer(&pStubMsg
->Buffer
, 8);
4535 align_pointer(&pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4538 FIXME("not implemented for varying buffer size\n");
4540 pStubMsg
->Buffer
+= bufsize
;
4542 return pStubMsg
->MemorySize
;
4545 /***********************************************************************
4546 * NdrUserMarshalFree [RPCRT4.@]
4548 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
4549 unsigned char *pMemory
,
4550 PFORMAT_STRING pFormat
)
4552 /* unsigned flags = pFormat[1]; */
4553 unsigned index
= *(const WORD
*)&pFormat
[2];
4554 USER_MARSHAL_CB umcb
;
4556 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4557 TRACE("index=%d\n", index
);
4559 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_FREE
, pFormat
, &umcb
);
4561 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
4562 &umcb
.Flags
, pMemory
);
4565 /***********************************************************************
4566 * NdrGetUserMarshalInfo [RPCRT4.@]
4568 RPC_STATUS RPC_ENTRY
NdrGetUserMarshalInfo(ULONG
*flags
, ULONG level
, NDR_USER_MARSHAL_INFO
*umi
)
4570 USER_MARSHAL_CB
*umcb
= CONTAINING_RECORD(flags
, USER_MARSHAL_CB
, Flags
);
4572 TRACE("(%p,%u,%p)\n", flags
, level
, umi
);
4575 return RPC_S_INVALID_ARG
;
4577 memset(&umi
->u1
.Level1
, 0, sizeof(umi
->u1
.Level1
));
4578 umi
->InformationLevel
= level
;
4580 if (umcb
->Signature
!= USER_MARSHAL_CB_SIGNATURE
)
4581 return RPC_S_INVALID_ARG
;
4583 umi
->u1
.Level1
.pfnAllocate
= umcb
->pStubMsg
->pfnAllocate
;
4584 umi
->u1
.Level1
.pfnFree
= umcb
->pStubMsg
->pfnFree
;
4585 umi
->u1
.Level1
.pRpcChannelBuffer
= umcb
->pStubMsg
->pRpcChannelBuffer
;
4587 switch (umcb
->CBType
)
4589 case USER_MARSHAL_CB_MARSHALL
:
4590 case USER_MARSHAL_CB_UNMARSHALL
:
4592 RPC_MESSAGE
*msg
= umcb
->pStubMsg
->RpcMsg
;
4593 unsigned char *buffer_start
= msg
->Buffer
;
4594 unsigned char *buffer_end
=
4595 (unsigned char *)msg
->Buffer
+ msg
->BufferLength
;
4597 if (umcb
->pStubMsg
->Buffer
< buffer_start
||
4598 umcb
->pStubMsg
->Buffer
> buffer_end
)
4599 return ERROR_INVALID_USER_BUFFER
;
4601 umi
->u1
.Level1
.Buffer
= umcb
->pStubMsg
->Buffer
;
4602 umi
->u1
.Level1
.BufferSize
= buffer_end
- umcb
->pStubMsg
->Buffer
;
4605 case USER_MARSHAL_CB_BUFFER_SIZE
:
4606 case USER_MARSHAL_CB_FREE
:
4609 WARN("unrecognised CBType %d\n", umcb
->CBType
);
4615 /***********************************************************************
4616 * NdrClearOutParameters [RPCRT4.@]
4618 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
4619 PFORMAT_STRING pFormat
,
4622 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
4625 /***********************************************************************
4626 * NdrConvert [RPCRT4.@]
4628 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
4630 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
4631 /* FIXME: since this stub doesn't do any converting, the proper behavior
4632 is to raise an exception */
4635 /***********************************************************************
4636 * NdrConvert2 [RPCRT4.@]
4638 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, LONG NumberParams
)
4640 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4641 pStubMsg
, pFormat
, NumberParams
);
4642 /* FIXME: since this stub doesn't do any converting, the proper behavior
4643 is to raise an exception */
4646 #include "pshpack1.h"
4647 typedef struct _NDR_CSTRUCT_FORMAT
4650 unsigned char alignment
;
4651 unsigned short memory_size
;
4652 short offset_to_array_description
;
4653 } NDR_CSTRUCT_FORMAT
, NDR_CVSTRUCT_FORMAT
;
4654 #include "poppack.h"
4656 /***********************************************************************
4657 * NdrConformantStructMarshall [RPCRT4.@]
4659 unsigned char * WINAPI
NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4660 unsigned char *pMemory
,
4661 PFORMAT_STRING pFormat
)
4663 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4664 PFORMAT_STRING pCArrayFormat
;
4665 ULONG esize
, bufsize
;
4667 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4669 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4670 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4672 ERR("invalid format type %x\n", pCStructFormat
->type
);
4673 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4677 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4678 pCStructFormat
->offset_to_array_description
;
4679 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4681 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4682 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4685 esize
= *(const WORD
*)(pCArrayFormat
+2);
4687 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4688 pCArrayFormat
+ 4, 0);
4690 WriteConformance(pStubMsg
);
4692 align_pointer_clear(&pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4694 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4696 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4697 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4699 ERR("integer overflow of memory_size %u with bufsize %u\n",
4700 pCStructFormat
->memory_size
, bufsize
);
4701 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4703 /* copy constant sized part of struct */
4704 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4705 safe_copy_to_buffer(pStubMsg
, pMemory
, pCStructFormat
->memory_size
+ bufsize
);
4707 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4708 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4713 /***********************************************************************
4714 * NdrConformantStructUnmarshall [RPCRT4.@]
4716 unsigned char * WINAPI
NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4717 unsigned char **ppMemory
,
4718 PFORMAT_STRING pFormat
,
4719 unsigned char fMustAlloc
)
4721 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4722 PFORMAT_STRING pCArrayFormat
;
4723 ULONG esize
, bufsize
;
4724 unsigned char *saved_buffer
;
4726 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4728 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4729 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4731 ERR("invalid format type %x\n", pCStructFormat
->type
);
4732 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4735 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4736 pCStructFormat
->offset_to_array_description
;
4737 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4739 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4740 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4743 esize
= *(const WORD
*)(pCArrayFormat
+2);
4745 pCArrayFormat
= ReadConformance(pStubMsg
, pCArrayFormat
+ 4);
4747 align_pointer(&pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4749 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4751 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4752 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4754 ERR("integer overflow of memory_size %u with bufsize %u\n",
4755 pCStructFormat
->memory_size
, bufsize
);
4756 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4761 SIZE_T size
= pCStructFormat
->memory_size
+ bufsize
;
4762 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4766 if (!pStubMsg
->IsClient
&& !*ppMemory
)
4767 /* for servers, we just point straight into the RPC buffer */
4768 *ppMemory
= pStubMsg
->Buffer
;
4771 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4772 safe_buffer_increment(pStubMsg
, pCStructFormat
->memory_size
+ bufsize
);
4773 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4774 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4776 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
4777 if (*ppMemory
!= saved_buffer
)
4778 memcpy(*ppMemory
, saved_buffer
, pCStructFormat
->memory_size
+ bufsize
);
4783 /***********************************************************************
4784 * NdrConformantStructBufferSize [RPCRT4.@]
4786 void WINAPI
NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4787 unsigned char *pMemory
,
4788 PFORMAT_STRING pFormat
)
4790 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4791 PFORMAT_STRING pCArrayFormat
;
4794 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4796 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4797 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4799 ERR("invalid format type %x\n", pCStructFormat
->type
);
4800 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4803 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4804 pCStructFormat
->offset_to_array_description
;
4805 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4807 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4808 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4811 esize
= *(const WORD
*)(pCArrayFormat
+2);
4813 pCArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
, pCArrayFormat
+4, 0);
4814 SizeConformance(pStubMsg
);
4816 align_length(&pStubMsg
->BufferLength
, pCStructFormat
->alignment
+ 1);
4818 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4820 safe_buffer_length_increment(pStubMsg
, pCStructFormat
->memory_size
);
4821 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
4823 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4824 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4827 /***********************************************************************
4828 * NdrConformantStructMemorySize [RPCRT4.@]
4830 ULONG WINAPI
NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4831 PFORMAT_STRING pFormat
)
4837 /***********************************************************************
4838 * NdrConformantStructFree [RPCRT4.@]
4840 void WINAPI
NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
4841 unsigned char *pMemory
,
4842 PFORMAT_STRING pFormat
)
4844 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4845 PFORMAT_STRING pCArrayFormat
;
4847 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4849 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4850 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4852 ERR("invalid format type %x\n", pCStructFormat
->type
);
4853 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4857 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4858 pCStructFormat
->offset_to_array_description
;
4859 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4861 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4862 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4866 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4867 pCArrayFormat
+ 4, 0);
4869 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4871 /* copy constant sized part of struct */
4872 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4874 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4875 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4878 /***********************************************************************
4879 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4881 unsigned char * WINAPI
NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4882 unsigned char *pMemory
,
4883 PFORMAT_STRING pFormat
)
4885 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4886 PFORMAT_STRING pCVArrayFormat
;
4888 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4890 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4891 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4893 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4894 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4898 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4899 pCVStructFormat
->offset_to_array_description
;
4901 array_compute_and_write_conformance(*pCVArrayFormat
, pStubMsg
,
4902 pMemory
+ pCVStructFormat
->memory_size
,
4905 align_pointer_clear(&pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4907 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4909 /* write constant sized part */
4910 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4911 safe_copy_to_buffer(pStubMsg
, pMemory
, pCVStructFormat
->memory_size
);
4913 array_write_variance_and_marshall(*pCVArrayFormat
, pStubMsg
,
4914 pMemory
+ pCVStructFormat
->memory_size
,
4915 pCVArrayFormat
, FALSE
/* fHasPointers */);
4917 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4922 /***********************************************************************
4923 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4925 unsigned char * WINAPI
NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4926 unsigned char **ppMemory
,
4927 PFORMAT_STRING pFormat
,
4928 unsigned char fMustAlloc
)
4930 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4931 PFORMAT_STRING pCVArrayFormat
;
4932 ULONG memsize
, bufsize
;
4933 unsigned char *saved_buffer
, *saved_array_buffer
;
4935 unsigned char *array_memory
;
4937 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4939 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4940 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4942 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4943 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4947 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4948 pCVStructFormat
->offset_to_array_description
;
4950 memsize
= array_read_conformance(*pCVArrayFormat
, pStubMsg
,
4953 align_pointer(&pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4955 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4957 /* work out how much memory to allocate if we need to do so */
4958 if (!fMustAlloc
&& !*ppMemory
)
4962 SIZE_T size
= pCVStructFormat
->memory_size
+ memsize
;
4963 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4966 /* mark the start of the constant data */
4967 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4968 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4970 array_memory
= *ppMemory
+ pCVStructFormat
->memory_size
;
4971 bufsize
= array_read_variance_and_unmarshall(*pCVArrayFormat
, pStubMsg
,
4972 &array_memory
, pCVArrayFormat
,
4973 FALSE
/* fMustAlloc */,
4974 FALSE
/* fUseServerBufferMemory */,
4975 FALSE
/* fUnmarshall */);
4977 /* save offset in case unmarshalling pointers changes it */
4978 offset
= pStubMsg
->Offset
;
4980 /* mark the start of the array data */
4981 saved_array_buffer
= pStubMsg
->Buffer
;
4982 safe_buffer_increment(pStubMsg
, bufsize
);
4984 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4986 /* copy the constant data */
4987 memcpy(*ppMemory
, saved_buffer
, pCVStructFormat
->memory_size
);
4988 /* copy the array data */
4989 TRACE("copying %p to %p\n", saved_array_buffer
, *ppMemory
+ pCVStructFormat
->memory_size
);
4990 memcpy(*ppMemory
+ pCVStructFormat
->memory_size
+ offset
,
4991 saved_array_buffer
, bufsize
);
4993 if (*pCVArrayFormat
== RPC_FC_C_CSTRING
)
4994 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory
+ pCVStructFormat
->memory_size
)));
4995 else if (*pCVArrayFormat
== RPC_FC_C_WSTRING
)
4996 TRACE("string=%s\n", debugstr_w((WCHAR
*)(*ppMemory
+ pCVStructFormat
->memory_size
)));
5001 /***********************************************************************
5002 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
5004 void WINAPI
NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5005 unsigned char *pMemory
,
5006 PFORMAT_STRING pFormat
)
5008 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
5009 PFORMAT_STRING pCVArrayFormat
;
5011 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5013 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
5014 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
5016 ERR("invalid format type %x\n", pCVStructFormat
->type
);
5017 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5021 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
5022 pCVStructFormat
->offset_to_array_description
;
5023 array_compute_and_size_conformance(*pCVArrayFormat
, pStubMsg
,
5024 pMemory
+ pCVStructFormat
->memory_size
,
5027 align_length(&pStubMsg
->BufferLength
, pCVStructFormat
->alignment
+ 1);
5029 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
5031 safe_buffer_length_increment(pStubMsg
, pCVStructFormat
->memory_size
);
5033 array_buffer_size(*pCVArrayFormat
, pStubMsg
,
5034 pMemory
+ pCVStructFormat
->memory_size
, pCVArrayFormat
,
5035 FALSE
/* fHasPointers */);
5037 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5040 /***********************************************************************
5041 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
5043 ULONG WINAPI
NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5044 PFORMAT_STRING pFormat
)
5046 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
5047 PFORMAT_STRING pCVArrayFormat
;
5049 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5051 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
5052 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
5054 ERR("invalid format type %x\n", pCVStructFormat
->type
);
5055 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5059 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
5060 pCVStructFormat
->offset_to_array_description
;
5061 array_read_conformance(*pCVArrayFormat
, pStubMsg
, pCVArrayFormat
);
5063 align_pointer(&pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
5065 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
5067 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
5068 array_memory_size(*pCVArrayFormat
, pStubMsg
, pCVArrayFormat
,
5069 FALSE
/* fHasPointers */);
5071 pStubMsg
->MemorySize
+= pCVStructFormat
->memory_size
;
5073 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5075 return pStubMsg
->MemorySize
;
5078 /***********************************************************************
5079 * NdrConformantVaryingStructFree [RPCRT4.@]
5081 void WINAPI
NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
5082 unsigned char *pMemory
,
5083 PFORMAT_STRING pFormat
)
5085 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
5086 PFORMAT_STRING pCVArrayFormat
;
5088 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5090 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
5091 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
5093 ERR("invalid format type %x\n", pCVStructFormat
->type
);
5094 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5098 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
5099 pCVStructFormat
->offset_to_array_description
;
5100 array_free(*pCVArrayFormat
, pStubMsg
,
5101 pMemory
+ pCVStructFormat
->memory_size
, pCVArrayFormat
,
5102 FALSE
/* fHasPointers */);
5104 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
5106 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5109 #include "pshpack1.h"
5113 unsigned char alignment
;
5114 unsigned short total_size
;
5115 } NDR_SMFARRAY_FORMAT
;
5120 unsigned char alignment
;
5122 } NDR_LGFARRAY_FORMAT
;
5123 #include "poppack.h"
5125 /***********************************************************************
5126 * NdrFixedArrayMarshall [RPCRT4.@]
5128 unsigned char * WINAPI
NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5129 unsigned char *pMemory
,
5130 PFORMAT_STRING pFormat
)
5132 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5135 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5137 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5138 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5140 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5141 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5145 align_pointer_clear(&pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
5147 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5149 total_size
= pSmFArrayFormat
->total_size
;
5150 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5154 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5155 total_size
= pLgFArrayFormat
->total_size
;
5156 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5159 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5160 safe_copy_to_buffer(pStubMsg
, pMemory
, total_size
);
5162 pFormat
= EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
5167 /***********************************************************************
5168 * NdrFixedArrayUnmarshall [RPCRT4.@]
5170 unsigned char * WINAPI
NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5171 unsigned char **ppMemory
,
5172 PFORMAT_STRING pFormat
,
5173 unsigned char fMustAlloc
)
5175 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5177 unsigned char *saved_buffer
;
5179 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5181 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5182 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5184 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5185 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5189 align_pointer(&pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
5191 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5193 total_size
= pSmFArrayFormat
->total_size
;
5194 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5198 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5199 total_size
= pLgFArrayFormat
->total_size
;
5200 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5204 *ppMemory
= NdrAllocate(pStubMsg
, total_size
);
5207 if (!pStubMsg
->IsClient
&& !*ppMemory
)
5208 /* for servers, we just point straight into the RPC buffer */
5209 *ppMemory
= pStubMsg
->Buffer
;
5212 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5213 safe_buffer_increment(pStubMsg
, total_size
);
5214 pFormat
= EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
5216 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
5217 if (*ppMemory
!= saved_buffer
)
5218 memcpy(*ppMemory
, saved_buffer
, total_size
);
5223 /***********************************************************************
5224 * NdrFixedArrayBufferSize [RPCRT4.@]
5226 void WINAPI
NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5227 unsigned char *pMemory
,
5228 PFORMAT_STRING pFormat
)
5230 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5233 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5235 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5236 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5238 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5239 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5243 align_length(&pStubMsg
->BufferLength
, pSmFArrayFormat
->alignment
+ 1);
5245 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5247 total_size
= pSmFArrayFormat
->total_size
;
5248 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5252 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5253 total_size
= pLgFArrayFormat
->total_size
;
5254 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5256 safe_buffer_length_increment(pStubMsg
, total_size
);
5258 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5261 /***********************************************************************
5262 * NdrFixedArrayMemorySize [RPCRT4.@]
5264 ULONG WINAPI
NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5265 PFORMAT_STRING pFormat
)
5267 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5270 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5272 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5273 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5275 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5276 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5280 align_pointer(&pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
5282 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5284 total_size
= pSmFArrayFormat
->total_size
;
5285 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5289 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5290 total_size
= pLgFArrayFormat
->total_size
;
5291 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5293 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5294 safe_buffer_increment(pStubMsg
, total_size
);
5295 pStubMsg
->MemorySize
+= total_size
;
5297 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5302 /***********************************************************************
5303 * NdrFixedArrayFree [RPCRT4.@]
5305 void WINAPI
NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
5306 unsigned char *pMemory
,
5307 PFORMAT_STRING pFormat
)
5309 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5311 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5313 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5314 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5316 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5317 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5321 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5322 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5325 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5326 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5329 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5332 /***********************************************************************
5333 * NdrVaryingArrayMarshall [RPCRT4.@]
5335 unsigned char * WINAPI
NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5336 unsigned char *pMemory
,
5337 PFORMAT_STRING pFormat
)
5339 unsigned char alignment
;
5340 DWORD elements
, esize
;
5343 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5345 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5346 (pFormat
[0] != RPC_FC_LGVARRAY
))
5348 ERR("invalid format type %x\n", pFormat
[0]);
5349 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5353 alignment
= pFormat
[1] + 1;
5355 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5358 pFormat
+= sizeof(WORD
);
5359 elements
= *(const WORD
*)pFormat
;
5360 pFormat
+= sizeof(WORD
);
5365 pFormat
+= sizeof(DWORD
);
5366 elements
= *(const DWORD
*)pFormat
;
5367 pFormat
+= sizeof(DWORD
);
5370 esize
= *(const WORD
*)pFormat
;
5371 pFormat
+= sizeof(WORD
);
5373 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5374 if ((pStubMsg
->ActualCount
> elements
) ||
5375 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5377 RpcRaiseException(RPC_S_INVALID_BOUND
);
5381 WriteVariance(pStubMsg
);
5383 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
5385 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
5386 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5387 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
5389 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
5394 /***********************************************************************
5395 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5397 unsigned char * WINAPI
NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5398 unsigned char **ppMemory
,
5399 PFORMAT_STRING pFormat
,
5400 unsigned char fMustAlloc
)
5402 unsigned char alignment
;
5403 DWORD size
, elements
, esize
;
5405 unsigned char *saved_buffer
;
5408 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5410 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5411 (pFormat
[0] != RPC_FC_LGVARRAY
))
5413 ERR("invalid format type %x\n", pFormat
[0]);
5414 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5418 alignment
= pFormat
[1] + 1;
5420 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5423 size
= *(const WORD
*)pFormat
;
5424 pFormat
+= sizeof(WORD
);
5425 elements
= *(const WORD
*)pFormat
;
5426 pFormat
+= sizeof(WORD
);
5431 size
= *(const DWORD
*)pFormat
;
5432 pFormat
+= sizeof(DWORD
);
5433 elements
= *(const DWORD
*)pFormat
;
5434 pFormat
+= sizeof(DWORD
);
5437 esize
= *(const WORD
*)pFormat
;
5438 pFormat
+= sizeof(WORD
);
5440 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
5442 align_pointer(&pStubMsg
->Buffer
, alignment
);
5444 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
5445 offset
= pStubMsg
->Offset
;
5447 if (!fMustAlloc
&& !*ppMemory
)
5450 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5451 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5452 safe_buffer_increment(pStubMsg
, bufsize
);
5454 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
5456 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
5461 /***********************************************************************
5462 * NdrVaryingArrayBufferSize [RPCRT4.@]
5464 void WINAPI
NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5465 unsigned char *pMemory
,
5466 PFORMAT_STRING pFormat
)
5468 unsigned char alignment
;
5469 DWORD elements
, esize
;
5471 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5473 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5474 (pFormat
[0] != RPC_FC_LGVARRAY
))
5476 ERR("invalid format type %x\n", pFormat
[0]);
5477 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5481 alignment
= pFormat
[1] + 1;
5483 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5486 pFormat
+= sizeof(WORD
);
5487 elements
= *(const WORD
*)pFormat
;
5488 pFormat
+= sizeof(WORD
);
5493 pFormat
+= sizeof(DWORD
);
5494 elements
= *(const DWORD
*)pFormat
;
5495 pFormat
+= sizeof(DWORD
);
5498 esize
= *(const WORD
*)pFormat
;
5499 pFormat
+= sizeof(WORD
);
5501 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5502 if ((pStubMsg
->ActualCount
> elements
) ||
5503 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5505 RpcRaiseException(RPC_S_INVALID_BOUND
);
5509 SizeVariance(pStubMsg
);
5511 align_length(&pStubMsg
->BufferLength
, alignment
);
5513 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
5515 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5518 /***********************************************************************
5519 * NdrVaryingArrayMemorySize [RPCRT4.@]
5521 ULONG WINAPI
NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5522 PFORMAT_STRING pFormat
)
5524 unsigned char alignment
;
5525 DWORD size
, elements
, esize
;
5527 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5529 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5530 (pFormat
[0] != RPC_FC_LGVARRAY
))
5532 ERR("invalid format type %x\n", pFormat
[0]);
5533 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5537 alignment
= pFormat
[1] + 1;
5539 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5542 size
= *(const WORD
*)pFormat
;
5543 pFormat
+= sizeof(WORD
);
5544 elements
= *(const WORD
*)pFormat
;
5545 pFormat
+= sizeof(WORD
);
5550 size
= *(const DWORD
*)pFormat
;
5551 pFormat
+= sizeof(DWORD
);
5552 elements
= *(const DWORD
*)pFormat
;
5553 pFormat
+= sizeof(DWORD
);
5556 esize
= *(const WORD
*)pFormat
;
5557 pFormat
+= sizeof(WORD
);
5559 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
5561 align_pointer(&pStubMsg
->Buffer
, alignment
);
5563 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
5564 pStubMsg
->MemorySize
+= size
;
5566 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5568 return pStubMsg
->MemorySize
;
5571 /***********************************************************************
5572 * NdrVaryingArrayFree [RPCRT4.@]
5574 void WINAPI
NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
5575 unsigned char *pMemory
,
5576 PFORMAT_STRING pFormat
)
5580 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5582 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5583 (pFormat
[0] != RPC_FC_LGVARRAY
))
5585 ERR("invalid format type %x\n", pFormat
[0]);
5586 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5590 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5593 pFormat
+= sizeof(WORD
);
5594 elements
= *(const WORD
*)pFormat
;
5595 pFormat
+= sizeof(WORD
);
5600 pFormat
+= sizeof(DWORD
);
5601 elements
= *(const DWORD
*)pFormat
;
5602 pFormat
+= sizeof(DWORD
);
5605 pFormat
+= sizeof(WORD
);
5607 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5608 if ((pStubMsg
->ActualCount
> elements
) ||
5609 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5611 RpcRaiseException(RPC_S_INVALID_BOUND
);
5615 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5618 static ULONG
get_discriminant(unsigned char fc
, const unsigned char *pMemory
)
5631 return *(const USHORT
*)pMemory
;
5635 return *(const ULONG
*)pMemory
;
5636 case RPC_FC_INT3264
:
5637 case RPC_FC_UINT3264
:
5638 return *(const ULONG_PTR
*)pMemory
;
5640 FIXME("Unhandled base type: 0x%02x\n", fc
);
5645 static PFORMAT_STRING
get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg
,
5647 PFORMAT_STRING pFormat
)
5649 unsigned short num_arms
, arm
, type
;
5651 num_arms
= *(const SHORT
*)pFormat
& 0x0fff;
5653 for(arm
= 0; arm
< num_arms
; arm
++)
5655 if(discriminant
== *(const ULONG
*)pFormat
)
5663 type
= *(const unsigned short*)pFormat
;
5664 TRACE("type %04x\n", type
);
5665 if(arm
== num_arms
) /* default arm extras */
5669 ERR("no arm for 0x%x and no default case\n", discriminant
);
5670 RpcRaiseException(RPC_S_INVALID_TAG
);
5675 TRACE("falling back to empty default case for 0x%x\n", discriminant
);
5682 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
, ULONG discriminant
, PFORMAT_STRING pFormat
)
5684 unsigned short type
;
5688 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5692 type
= *(const unsigned short*)pFormat
;
5693 if((type
& 0xff00) == 0x8000)
5695 unsigned char basetype
= LOBYTE(type
);
5696 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &basetype
);
5700 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5701 NDR_MARSHALL m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
5704 unsigned char *saved_buffer
= NULL
;
5705 BOOL pointer_buffer_mark_set
= FALSE
;
5712 align_pointer_clear(&pStubMsg
->Buffer
, 4);
5713 saved_buffer
= pStubMsg
->Buffer
;
5714 if (pStubMsg
->PointerBufferMark
)
5716 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5717 pStubMsg
->PointerBufferMark
= NULL
;
5718 pointer_buffer_mark_set
= TRUE
;
5721 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
5723 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char **)pMemory
, desc
);
5724 if (pointer_buffer_mark_set
)
5726 STD_OVERFLOW_CHECK(pStubMsg
);
5727 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5728 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5730 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5731 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
5732 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5734 pStubMsg
->Buffer
= saved_buffer
+ 4;
5738 m(pStubMsg
, pMemory
, desc
);
5741 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5746 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5747 unsigned char **ppMemory
,
5749 PFORMAT_STRING pFormat
,
5750 unsigned char fMustAlloc
)
5752 unsigned short type
;
5756 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5760 type
= *(const unsigned short*)pFormat
;
5761 if((type
& 0xff00) == 0x8000)
5763 unsigned char basetype
= LOBYTE(type
);
5764 return NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &basetype
, FALSE
);
5768 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5769 NDR_UNMARSHALL m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
5772 unsigned char *saved_buffer
= NULL
;
5773 BOOL pointer_buffer_mark_set
= FALSE
;
5780 align_pointer(&pStubMsg
->Buffer
, 4);
5781 saved_buffer
= pStubMsg
->Buffer
;
5782 if (pStubMsg
->PointerBufferMark
)
5784 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5785 pStubMsg
->PointerBufferMark
= NULL
;
5786 pointer_buffer_mark_set
= TRUE
;
5789 pStubMsg
->Buffer
+= 4; /* for pointer ID */
5791 if (saved_buffer
+ 4 > pStubMsg
->BufferEnd
)
5793 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5794 saved_buffer
, pStubMsg
->BufferEnd
);
5795 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5798 PointerUnmarshall(pStubMsg
, saved_buffer
, *(unsigned char ***)ppMemory
, **(unsigned char ***)ppMemory
, desc
, fMustAlloc
);
5799 if (pointer_buffer_mark_set
)
5801 STD_OVERFLOW_CHECK(pStubMsg
);
5802 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5803 pStubMsg
->Buffer
= saved_buffer
+ 4;
5807 m(pStubMsg
, ppMemory
, desc
, fMustAlloc
);
5810 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5815 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg
,
5816 unsigned char *pMemory
,
5818 PFORMAT_STRING pFormat
)
5820 unsigned short type
;
5824 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5828 type
= *(const unsigned short*)pFormat
;
5829 if((type
& 0xff00) == 0x8000)
5831 unsigned char basetype
= LOBYTE(type
);
5832 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &basetype
);
5836 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5837 NDR_BUFFERSIZE m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
5846 align_length(&pStubMsg
->BufferLength
, 4);
5847 safe_buffer_length_increment(pStubMsg
, 4); /* for pointer ID */
5848 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5850 int saved_buffer_length
= pStubMsg
->BufferLength
;
5851 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
5852 pStubMsg
->PointerLength
= 0;
5853 if(!pStubMsg
->BufferLength
)
5854 ERR("BufferLength == 0??\n");
5855 PointerBufferSize(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5856 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
5857 pStubMsg
->BufferLength
= saved_buffer_length
;
5861 m(pStubMsg
, pMemory
, desc
);
5864 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
5868 static ULONG
union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg
,
5870 PFORMAT_STRING pFormat
)
5872 unsigned short type
, size
;
5874 size
= *(const unsigned short*)pFormat
;
5875 pStubMsg
->Memory
+= size
;
5878 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5882 type
= *(const unsigned short*)pFormat
;
5883 if((type
& 0xff00) == 0x8000)
5885 return NdrBaseTypeMemorySize(pStubMsg
, pFormat
);
5889 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5890 NDR_MEMORYSIZE m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
5891 unsigned char *saved_buffer
;
5900 align_pointer(&pStubMsg
->Buffer
, 4);
5901 saved_buffer
= pStubMsg
->Buffer
;
5902 safe_buffer_increment(pStubMsg
, 4);
5903 align_length(&pStubMsg
->MemorySize
, sizeof(void *));
5904 pStubMsg
->MemorySize
+= sizeof(void *);
5905 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5906 PointerMemorySize(pStubMsg
, saved_buffer
, pFormat
);
5909 return m(pStubMsg
, desc
);
5912 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5915 TRACE("size %d\n", size
);
5919 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg
,
5920 unsigned char *pMemory
,
5922 PFORMAT_STRING pFormat
)
5924 unsigned short type
;
5928 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5932 type
= *(const unsigned short*)pFormat
;
5933 if((type
& 0xff00) != 0x8000)
5935 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5936 NDR_FREE m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
5945 PointerFree(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5948 m(pStubMsg
, pMemory
, desc
);
5954 /***********************************************************************
5955 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5957 unsigned char * WINAPI
NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5958 unsigned char *pMemory
,
5959 PFORMAT_STRING pFormat
)
5961 unsigned char switch_type
;
5962 unsigned char increment
;
5965 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5968 switch_type
= *pFormat
& 0xf;
5969 increment
= (*pFormat
& 0xf0) >> 4;
5972 align_pointer_clear(&pStubMsg
->Buffer
, increment
);
5974 switch_value
= get_discriminant(switch_type
, pMemory
);
5975 TRACE("got switch value 0x%x\n", switch_value
);
5977 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &switch_type
);
5978 pMemory
+= increment
;
5980 return union_arm_marshall(pStubMsg
, pMemory
, switch_value
, pFormat
);
5983 /***********************************************************************
5984 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5986 unsigned char * WINAPI
NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5987 unsigned char **ppMemory
,
5988 PFORMAT_STRING pFormat
,
5989 unsigned char fMustAlloc
)
5991 unsigned char switch_type
;
5992 unsigned char increment
;
5994 unsigned short size
;
5995 unsigned char *pMemoryArm
;
5997 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
6000 switch_type
= *pFormat
& 0xf;
6001 increment
= (*pFormat
& 0xf0) >> 4;
6004 align_pointer(&pStubMsg
->Buffer
, increment
);
6005 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
6006 TRACE("got switch value 0x%x\n", switch_value
);
6008 size
= *(const unsigned short*)pFormat
+ increment
;
6009 if (!fMustAlloc
&& !*ppMemory
)
6012 *ppMemory
= NdrAllocate(pStubMsg
, size
);
6014 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6015 * since the arm is part of the memory block that is encompassed by
6016 * the whole union. Memory is forced to allocate when pointers
6017 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6018 * clearing the memory we pass in to the unmarshaller */
6020 memset(*ppMemory
, 0, size
);
6022 NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &switch_type
, FALSE
);
6023 pMemoryArm
= *ppMemory
+ increment
;
6025 return union_arm_unmarshall(pStubMsg
, &pMemoryArm
, switch_value
, pFormat
, FALSE
);
6028 /***********************************************************************
6029 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
6031 void WINAPI
NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6032 unsigned char *pMemory
,
6033 PFORMAT_STRING pFormat
)
6035 unsigned char switch_type
;
6036 unsigned char increment
;
6039 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6042 switch_type
= *pFormat
& 0xf;
6043 increment
= (*pFormat
& 0xf0) >> 4;
6046 align_length(&pStubMsg
->BufferLength
, increment
);
6047 switch_value
= get_discriminant(switch_type
, pMemory
);
6048 TRACE("got switch value 0x%x\n", switch_value
);
6050 /* Add discriminant size */
6051 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&switch_value
, &switch_type
);
6052 pMemory
+= increment
;
6054 union_arm_buffer_size(pStubMsg
, pMemory
, switch_value
, pFormat
);
6057 /***********************************************************************
6058 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
6060 ULONG WINAPI
NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6061 PFORMAT_STRING pFormat
)
6063 unsigned char switch_type
;
6064 unsigned char increment
;
6067 switch_type
= *pFormat
& 0xf;
6068 increment
= (*pFormat
& 0xf0) >> 4;
6071 align_pointer(&pStubMsg
->Buffer
, increment
);
6072 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
6073 TRACE("got switch value 0x%x\n", switch_value
);
6075 pStubMsg
->Memory
+= increment
;
6077 return increment
+ union_arm_memory_size(pStubMsg
, switch_value
, pFormat
+ *(const SHORT
*)pFormat
);
6080 /***********************************************************************
6081 * NdrEncapsulatedUnionFree [RPCRT4.@]
6083 void WINAPI
NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
6084 unsigned char *pMemory
,
6085 PFORMAT_STRING pFormat
)
6087 unsigned char switch_type
;
6088 unsigned char increment
;
6091 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6094 switch_type
= *pFormat
& 0xf;
6095 increment
= (*pFormat
& 0xf0) >> 4;
6098 switch_value
= get_discriminant(switch_type
, pMemory
);
6099 TRACE("got switch value 0x%x\n", switch_value
);
6101 pMemory
+= increment
;
6103 union_arm_free(pStubMsg
, pMemory
, switch_value
, pFormat
);
6106 /***********************************************************************
6107 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
6109 unsigned char * WINAPI
NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6110 unsigned char *pMemory
,
6111 PFORMAT_STRING pFormat
)
6113 unsigned char switch_type
;
6115 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6118 switch_type
= *pFormat
;
6121 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6122 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6123 /* Marshall discriminant */
6124 NdrBaseTypeMarshall(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
6126 return union_arm_marshall(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6129 static LONG
unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg
,
6130 PFORMAT_STRING
*ppFormat
)
6132 LONG discriminant
= 0;
6142 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
6152 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6153 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
6161 align_pointer(&pStubMsg
->Buffer
, sizeof(ULONG
));
6162 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
6167 FIXME("Unhandled base type: 0x%02x\n", **ppFormat
);
6171 if (pStubMsg
->fHasNewCorrDesc
)
6175 return discriminant
;
6178 /**********************************************************************
6179 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
6181 unsigned char * WINAPI
NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6182 unsigned char **ppMemory
,
6183 PFORMAT_STRING pFormat
,
6184 unsigned char fMustAlloc
)
6187 unsigned short size
;
6189 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
6192 /* Unmarshall discriminant */
6193 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
6194 TRACE("unmarshalled discriminant %x\n", discriminant
);
6196 pFormat
+= *(const SHORT
*)pFormat
;
6198 size
= *(const unsigned short*)pFormat
;
6200 if (!fMustAlloc
&& !*ppMemory
)
6203 *ppMemory
= NdrAllocate(pStubMsg
, size
);
6205 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6206 * since the arm is part of the memory block that is encompassed by
6207 * the whole union. Memory is forced to allocate when pointers
6208 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6209 * clearing the memory we pass in to the unmarshaller */
6211 memset(*ppMemory
, 0, size
);
6213 return union_arm_unmarshall(pStubMsg
, ppMemory
, discriminant
, pFormat
, FALSE
);
6216 /***********************************************************************
6217 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
6219 void WINAPI
NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6220 unsigned char *pMemory
,
6221 PFORMAT_STRING pFormat
)
6223 unsigned char switch_type
;
6225 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6228 switch_type
= *pFormat
;
6231 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6232 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6233 /* Add discriminant size */
6234 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
6236 union_arm_buffer_size(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6239 /***********************************************************************
6240 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
6242 ULONG WINAPI
NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6243 PFORMAT_STRING pFormat
)
6248 /* Unmarshall discriminant */
6249 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
6250 TRACE("unmarshalled discriminant 0x%x\n", discriminant
);
6252 return union_arm_memory_size(pStubMsg
, discriminant
, pFormat
+ *(const SHORT
*)pFormat
);
6255 /***********************************************************************
6256 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6258 void WINAPI
NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
6259 unsigned char *pMemory
,
6260 PFORMAT_STRING pFormat
)
6262 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6266 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6267 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6269 union_arm_free(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6272 /***********************************************************************
6273 * NdrByteCountPointerMarshall [RPCRT4.@]
6275 unsigned char * WINAPI
NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6276 unsigned char *pMemory
,
6277 PFORMAT_STRING pFormat
)
6283 /***********************************************************************
6284 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6286 unsigned char * WINAPI
NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6287 unsigned char **ppMemory
,
6288 PFORMAT_STRING pFormat
,
6289 unsigned char fMustAlloc
)
6295 /***********************************************************************
6296 * NdrByteCountPointerBufferSize [RPCRT4.@]
6298 void WINAPI
NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6299 unsigned char *pMemory
,
6300 PFORMAT_STRING pFormat
)
6305 /***********************************************************************
6306 * NdrByteCountPointerMemorySize [internal]
6308 static ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6309 PFORMAT_STRING pFormat
)
6315 /***********************************************************************
6316 * NdrByteCountPointerFree [RPCRT4.@]
6318 void WINAPI
NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
6319 unsigned char *pMemory
,
6320 PFORMAT_STRING pFormat
)
6325 /***********************************************************************
6326 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6328 unsigned char * WINAPI
NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6329 unsigned char *pMemory
,
6330 PFORMAT_STRING pFormat
)
6336 /***********************************************************************
6337 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6339 unsigned char * WINAPI
NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6340 unsigned char **ppMemory
,
6341 PFORMAT_STRING pFormat
,
6342 unsigned char fMustAlloc
)
6348 /***********************************************************************
6349 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6351 void WINAPI
NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6352 unsigned char *pMemory
,
6353 PFORMAT_STRING pFormat
)
6358 /***********************************************************************
6359 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6361 ULONG WINAPI
NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6362 PFORMAT_STRING pFormat
)
6368 /***********************************************************************
6369 * NdrXmitOrRepAsFree [RPCRT4.@]
6371 void WINAPI
NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg
,
6372 unsigned char *pMemory
,
6373 PFORMAT_STRING pFormat
)
6378 /***********************************************************************
6379 * NdrRangeMarshall [internal]
6381 static unsigned char *WINAPI
NdrRangeMarshall(
6382 PMIDL_STUB_MESSAGE pStubMsg
,
6383 unsigned char *pMemory
,
6384 PFORMAT_STRING pFormat
)
6386 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6387 unsigned char base_type
;
6389 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6391 if (pRange
->type
!= RPC_FC_RANGE
)
6393 ERR("invalid format type %x\n", pRange
->type
);
6394 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6398 base_type
= pRange
->flags_type
& 0xf;
6400 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &base_type
);
6403 /***********************************************************************
6404 * NdrRangeUnmarshall [RPCRT4.@]
6406 unsigned char *WINAPI
NdrRangeUnmarshall(
6407 PMIDL_STUB_MESSAGE pStubMsg
,
6408 unsigned char **ppMemory
,
6409 PFORMAT_STRING pFormat
,
6410 unsigned char fMustAlloc
)
6412 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6413 unsigned char base_type
;
6415 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6417 if (pRange
->type
!= RPC_FC_RANGE
)
6419 ERR("invalid format type %x\n", pRange
->type
);
6420 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6423 base_type
= pRange
->flags_type
& 0xf;
6425 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6426 base_type
, pRange
->low_value
, pRange
->high_value
);
6428 #define RANGE_UNMARSHALL(mem_type, wire_type, format_spec) \
6431 align_pointer(&pStubMsg->Buffer, sizeof(wire_type)); \
6432 if (!fMustAlloc && !*ppMemory) \
6433 fMustAlloc = TRUE; \
6435 *ppMemory = NdrAllocate(pStubMsg, sizeof(mem_type)); \
6436 if (pStubMsg->Buffer + sizeof(wire_type) > pStubMsg->BufferEnd) \
6438 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6439 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6440 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6442 if ((*(wire_type *)pStubMsg->Buffer < (mem_type)pRange->low_value) || \
6443 (*(wire_type *)pStubMsg->Buffer > (mem_type)pRange->high_value)) \
6445 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6446 *(wire_type *)pStubMsg->Buffer, (mem_type)pRange->low_value, \
6447 (mem_type)pRange->high_value); \
6448 RpcRaiseException(RPC_S_INVALID_BOUND); \
6451 TRACE("*ppMemory: %p\n", *ppMemory); \
6452 **(mem_type **)ppMemory = *(wire_type *)pStubMsg->Buffer; \
6453 pStubMsg->Buffer += sizeof(wire_type); \
6460 RANGE_UNMARSHALL(UCHAR
, UCHAR
, "%d");
6461 TRACE("value: 0x%02x\n", **ppMemory
);
6465 RANGE_UNMARSHALL(CHAR
, CHAR
, "%u");
6466 TRACE("value: 0x%02x\n", **ppMemory
);
6468 case RPC_FC_WCHAR
: /* FIXME: valid? */
6470 RANGE_UNMARSHALL(USHORT
, USHORT
, "%u");
6471 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6474 RANGE_UNMARSHALL(SHORT
, SHORT
, "%d");
6475 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6479 RANGE_UNMARSHALL(LONG
, LONG
, "%d");
6480 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6483 RANGE_UNMARSHALL(ULONG
, ULONG
, "%u");
6484 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6487 RANGE_UNMARSHALL(UINT
, USHORT
, "%u");
6488 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
6494 ERR("invalid range base type: 0x%02x\n", base_type
);
6495 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6501 /***********************************************************************
6502 * NdrRangeBufferSize [internal]
6504 static void WINAPI
NdrRangeBufferSize(
6505 PMIDL_STUB_MESSAGE pStubMsg
,
6506 unsigned char *pMemory
,
6507 PFORMAT_STRING pFormat
)
6509 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6510 unsigned char base_type
;
6512 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6514 if (pRange
->type
!= RPC_FC_RANGE
)
6516 ERR("invalid format type %x\n", pRange
->type
);
6517 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6519 base_type
= pRange
->flags_type
& 0xf;
6521 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &base_type
);
6524 /***********************************************************************
6525 * NdrRangeMemorySize [internal]
6527 static ULONG WINAPI
NdrRangeMemorySize(
6528 PMIDL_STUB_MESSAGE pStubMsg
,
6529 PFORMAT_STRING pFormat
)
6531 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6532 unsigned char base_type
;
6534 if (pRange
->type
!= RPC_FC_RANGE
)
6536 ERR("invalid format type %x\n", pRange
->type
);
6537 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6540 base_type
= pRange
->flags_type
& 0xf;
6542 return NdrBaseTypeMemorySize(pStubMsg
, &base_type
);
6545 /***********************************************************************
6546 * NdrRangeFree [internal]
6548 static void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6549 unsigned char *pMemory
,
6550 PFORMAT_STRING pFormat
)
6552 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6557 /***********************************************************************
6558 * NdrBaseTypeMarshall [internal]
6560 static unsigned char *WINAPI
NdrBaseTypeMarshall(
6561 PMIDL_STUB_MESSAGE pStubMsg
,
6562 unsigned char *pMemory
,
6563 PFORMAT_STRING pFormat
)
6565 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6573 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(UCHAR
));
6574 TRACE("value: 0x%02x\n", *pMemory
);
6579 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(USHORT
));
6580 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(USHORT
));
6581 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
6585 case RPC_FC_ERROR_STATUS_T
:
6587 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(ULONG
));
6588 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONG
));
6589 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
6592 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(float));
6593 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
6596 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(double));
6597 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
6600 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(ULONGLONG
));
6601 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONGLONG
));
6602 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
6606 USHORT val
= *(UINT
*)pMemory
;
6607 /* only 16-bits on the wire, so do a sanity check */
6608 if (*(UINT
*)pMemory
> SHRT_MAX
)
6609 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
6610 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(USHORT
));
6611 safe_copy_to_buffer(pStubMsg
, &val
, sizeof(val
));
6612 TRACE("value: 0x%04x\n", *(UINT
*)pMemory
);
6615 case RPC_FC_INT3264
:
6616 case RPC_FC_UINT3264
:
6618 UINT val
= *(UINT_PTR
*)pMemory
;
6619 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(UINT
));
6620 safe_copy_to_buffer(pStubMsg
, &val
, sizeof(val
));
6626 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6629 /* FIXME: what is the correct return value? */
6633 /***********************************************************************
6634 * NdrBaseTypeUnmarshall [internal]
6636 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(
6637 PMIDL_STUB_MESSAGE pStubMsg
,
6638 unsigned char **ppMemory
,
6639 PFORMAT_STRING pFormat
,
6640 unsigned char fMustAlloc
)
6642 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6644 #define BASE_TYPE_UNMARSHALL(type) do { \
6645 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
6646 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6648 *ppMemory = pStubMsg->Buffer; \
6649 TRACE("*ppMemory: %p\n", *ppMemory); \
6650 safe_buffer_increment(pStubMsg, sizeof(type)); \
6655 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6656 TRACE("*ppMemory: %p\n", *ppMemory); \
6657 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6667 BASE_TYPE_UNMARSHALL(UCHAR
);
6668 TRACE("value: 0x%02x\n", **ppMemory
);
6673 BASE_TYPE_UNMARSHALL(USHORT
);
6674 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6678 case RPC_FC_ERROR_STATUS_T
:
6680 BASE_TYPE_UNMARSHALL(ULONG
);
6681 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6684 BASE_TYPE_UNMARSHALL(float);
6685 TRACE("value: %f\n", **(float **)ppMemory
);
6688 BASE_TYPE_UNMARSHALL(double);
6689 TRACE("value: %f\n", **(double **)ppMemory
);
6692 BASE_TYPE_UNMARSHALL(ULONGLONG
);
6693 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG
**)ppMemory
));
6698 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6699 if (!fMustAlloc
&& !*ppMemory
)
6702 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT
));
6703 safe_copy_from_buffer(pStubMsg
, &val
, sizeof(USHORT
));
6704 /* 16-bits on the wire, but int in memory */
6705 **(UINT
**)ppMemory
= val
;
6706 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
6709 case RPC_FC_INT3264
:
6710 if (sizeof(INT_PTR
) == sizeof(INT
)) BASE_TYPE_UNMARSHALL(INT
);
6714 align_pointer(&pStubMsg
->Buffer
, sizeof(INT
));
6715 if (!fMustAlloc
&& !*ppMemory
)
6718 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(INT_PTR
));
6719 safe_copy_from_buffer(pStubMsg
, &val
, sizeof(INT
));
6720 **(INT_PTR
**)ppMemory
= val
;
6721 TRACE("value: 0x%08lx\n", **(INT_PTR
**)ppMemory
);
6724 case RPC_FC_UINT3264
:
6725 if (sizeof(UINT_PTR
) == sizeof(UINT
)) BASE_TYPE_UNMARSHALL(UINT
);
6729 align_pointer(&pStubMsg
->Buffer
, sizeof(UINT
));
6730 if (!fMustAlloc
&& !*ppMemory
)
6733 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT_PTR
));
6734 safe_copy_from_buffer(pStubMsg
, &val
, sizeof(UINT
));
6735 **(UINT_PTR
**)ppMemory
= val
;
6736 TRACE("value: 0x%08lx\n", **(UINT_PTR
**)ppMemory
);
6742 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6744 #undef BASE_TYPE_UNMARSHALL
6746 /* FIXME: what is the correct return value? */
6751 /***********************************************************************
6752 * NdrBaseTypeBufferSize [internal]
6754 static void WINAPI
NdrBaseTypeBufferSize(
6755 PMIDL_STUB_MESSAGE pStubMsg
,
6756 unsigned char *pMemory
,
6757 PFORMAT_STRING pFormat
)
6759 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6767 safe_buffer_length_increment(pStubMsg
, sizeof(UCHAR
));
6773 align_length(&pStubMsg
->BufferLength
, sizeof(USHORT
));
6774 safe_buffer_length_increment(pStubMsg
, sizeof(USHORT
));
6779 case RPC_FC_INT3264
:
6780 case RPC_FC_UINT3264
:
6781 align_length(&pStubMsg
->BufferLength
, sizeof(ULONG
));
6782 safe_buffer_length_increment(pStubMsg
, sizeof(ULONG
));
6785 align_length(&pStubMsg
->BufferLength
, sizeof(float));
6786 safe_buffer_length_increment(pStubMsg
, sizeof(float));
6789 align_length(&pStubMsg
->BufferLength
, sizeof(double));
6790 safe_buffer_length_increment(pStubMsg
, sizeof(double));
6793 align_length(&pStubMsg
->BufferLength
, sizeof(ULONGLONG
));
6794 safe_buffer_length_increment(pStubMsg
, sizeof(ULONGLONG
));
6796 case RPC_FC_ERROR_STATUS_T
:
6797 align_length(&pStubMsg
->BufferLength
, sizeof(error_status_t
));
6798 safe_buffer_length_increment(pStubMsg
, sizeof(error_status_t
));
6803 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6807 /***********************************************************************
6808 * NdrBaseTypeMemorySize [internal]
6810 static ULONG WINAPI
NdrBaseTypeMemorySize(
6811 PMIDL_STUB_MESSAGE pStubMsg
,
6812 PFORMAT_STRING pFormat
)
6814 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg
, *pFormat
);
6822 safe_buffer_increment(pStubMsg
, sizeof(UCHAR
));
6823 pStubMsg
->MemorySize
+= sizeof(UCHAR
);
6824 return sizeof(UCHAR
);
6828 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6829 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6830 align_length(&pStubMsg
->MemorySize
, sizeof(USHORT
));
6831 pStubMsg
->MemorySize
+= sizeof(USHORT
);
6832 return sizeof(USHORT
);
6836 align_pointer(&pStubMsg
->Buffer
, sizeof(ULONG
));
6837 safe_buffer_increment(pStubMsg
, sizeof(ULONG
));
6838 align_length(&pStubMsg
->MemorySize
, sizeof(ULONG
));
6839 pStubMsg
->MemorySize
+= sizeof(ULONG
);
6840 return sizeof(ULONG
);
6842 align_pointer(&pStubMsg
->Buffer
, sizeof(float));
6843 safe_buffer_increment(pStubMsg
, sizeof(float));
6844 align_length(&pStubMsg
->MemorySize
, sizeof(float));
6845 pStubMsg
->MemorySize
+= sizeof(float);
6846 return sizeof(float);
6848 align_pointer(&pStubMsg
->Buffer
, sizeof(double));
6849 safe_buffer_increment(pStubMsg
, sizeof(double));
6850 align_length(&pStubMsg
->MemorySize
, sizeof(double));
6851 pStubMsg
->MemorySize
+= sizeof(double);
6852 return sizeof(double);
6854 align_pointer(&pStubMsg
->Buffer
, sizeof(ULONGLONG
));
6855 safe_buffer_increment(pStubMsg
, sizeof(ULONGLONG
));
6856 align_length(&pStubMsg
->MemorySize
, sizeof(ULONGLONG
));
6857 pStubMsg
->MemorySize
+= sizeof(ULONGLONG
);
6858 return sizeof(ULONGLONG
);
6859 case RPC_FC_ERROR_STATUS_T
:
6860 align_pointer(&pStubMsg
->Buffer
, sizeof(error_status_t
));
6861 safe_buffer_increment(pStubMsg
, sizeof(error_status_t
));
6862 align_length(&pStubMsg
->MemorySize
, sizeof(error_status_t
));
6863 pStubMsg
->MemorySize
+= sizeof(error_status_t
);
6864 return sizeof(error_status_t
);
6866 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6867 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6868 align_length(&pStubMsg
->MemorySize
, sizeof(UINT
));
6869 pStubMsg
->MemorySize
+= sizeof(UINT
);
6870 return sizeof(UINT
);
6871 case RPC_FC_INT3264
:
6872 case RPC_FC_UINT3264
:
6873 align_pointer(&pStubMsg
->Buffer
, sizeof(UINT
));
6874 safe_buffer_increment(pStubMsg
, sizeof(UINT
));
6875 align_length(&pStubMsg
->MemorySize
, sizeof(UINT_PTR
));
6876 pStubMsg
->MemorySize
+= sizeof(UINT_PTR
);
6877 return sizeof(UINT_PTR
);
6879 align_length(&pStubMsg
->MemorySize
, sizeof(void *));
6880 pStubMsg
->MemorySize
+= sizeof(void *);
6881 return sizeof(void *);
6883 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6888 /***********************************************************************
6889 * NdrBaseTypeFree [internal]
6891 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6892 unsigned char *pMemory
,
6893 PFORMAT_STRING pFormat
)
6895 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6900 /***********************************************************************
6901 * NdrContextHandleBufferSize [internal]
6903 static void WINAPI
NdrContextHandleBufferSize(
6904 PMIDL_STUB_MESSAGE pStubMsg
,
6905 unsigned char *pMemory
,
6906 PFORMAT_STRING pFormat
)
6908 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6910 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6912 ERR("invalid format type %x\n", *pFormat
);
6913 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6915 align_length(&pStubMsg
->BufferLength
, 4);
6916 safe_buffer_length_increment(pStubMsg
, cbNDRContext
);
6919 /***********************************************************************
6920 * NdrContextHandleMarshall [internal]
6922 static unsigned char *WINAPI
NdrContextHandleMarshall(
6923 PMIDL_STUB_MESSAGE pStubMsg
,
6924 unsigned char *pMemory
,
6925 PFORMAT_STRING pFormat
)
6927 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6929 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6931 ERR("invalid format type %x\n", *pFormat
);
6932 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6934 TRACE("flags: 0x%02x\n", pFormat
[1]);
6936 if (pStubMsg
->IsClient
)
6938 if (pFormat
[1] & HANDLE_PARAM_IS_VIA_PTR
)
6939 NdrClientContextMarshall(pStubMsg
, *(NDR_CCONTEXT
**)pMemory
, FALSE
);
6941 NdrClientContextMarshall(pStubMsg
, pMemory
, FALSE
);
6945 NDR_SCONTEXT ctxt
= NDRSContextFromValue(pMemory
);
6946 NDR_RUNDOWN rundown
= pStubMsg
->StubDesc
->apfnNdrRundownRoutines
[pFormat
[2]];
6947 NdrServerContextNewMarshall(pStubMsg
, ctxt
, rundown
, pFormat
);
6953 /***********************************************************************
6954 * NdrContextHandleUnmarshall [internal]
6956 static unsigned char *WINAPI
NdrContextHandleUnmarshall(
6957 PMIDL_STUB_MESSAGE pStubMsg
,
6958 unsigned char **ppMemory
,
6959 PFORMAT_STRING pFormat
,
6960 unsigned char fMustAlloc
)
6962 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg
,
6963 ppMemory
, pFormat
, fMustAlloc
? "TRUE": "FALSE");
6965 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6967 ERR("invalid format type %x\n", *pFormat
);
6968 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6970 TRACE("flags: 0x%02x\n", pFormat
[1]);
6972 if (pStubMsg
->IsClient
)
6974 /* [out]-only or [ret] param */
6975 if ((pFormat
[1] & (HANDLE_PARAM_IS_IN
|HANDLE_PARAM_IS_OUT
)) == HANDLE_PARAM_IS_OUT
)
6976 **(NDR_CCONTEXT
**)ppMemory
= NULL
;
6977 NdrClientContextUnmarshall(pStubMsg
, *(NDR_CCONTEXT
**)ppMemory
, pStubMsg
->RpcMsg
->Handle
);
6982 ctxt
= NdrServerContextNewUnmarshall(pStubMsg
, pFormat
);
6983 if (pFormat
[1] & HANDLE_PARAM_IS_VIA_PTR
)
6984 *(void **)ppMemory
= NDRSContextValue(ctxt
);
6986 *(void **)ppMemory
= *NDRSContextValue(ctxt
);
6992 /***********************************************************************
6993 * NdrClientContextMarshall [RPCRT4.@]
6995 void WINAPI
NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6996 NDR_CCONTEXT ContextHandle
,
6999 TRACE("(%p, %p, %d)\n", pStubMsg
, ContextHandle
, fCheck
);
7001 align_pointer_clear(&pStubMsg
->Buffer
, 4);
7003 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7005 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7006 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7007 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7010 /* FIXME: what does fCheck do? */
7011 NDRCContextMarshall(ContextHandle
,
7014 pStubMsg
->Buffer
+= cbNDRContext
;
7017 /***********************************************************************
7018 * NdrClientContextUnmarshall [RPCRT4.@]
7020 void WINAPI
NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7021 NDR_CCONTEXT
* pContextHandle
,
7022 RPC_BINDING_HANDLE BindHandle
)
7024 TRACE("(%p, %p, %p)\n", pStubMsg
, pContextHandle
, BindHandle
);
7026 align_pointer(&pStubMsg
->Buffer
, 4);
7028 if (pStubMsg
->Buffer
+ cbNDRContext
> pStubMsg
->BufferEnd
)
7029 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7031 NDRCContextUnmarshall(pContextHandle
,
7034 pStubMsg
->RpcMsg
->DataRepresentation
);
7036 pStubMsg
->Buffer
+= cbNDRContext
;
7039 void WINAPI
NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7040 NDR_SCONTEXT ContextHandle
,
7041 NDR_RUNDOWN RundownRoutine
)
7043 TRACE("(%p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
);
7045 align_pointer(&pStubMsg
->Buffer
, 4);
7047 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7049 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7050 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7051 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7054 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
7055 pStubMsg
->Buffer
, RundownRoutine
, NULL
,
7056 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
7057 pStubMsg
->Buffer
+= cbNDRContext
;
7060 NDR_SCONTEXT WINAPI
NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
)
7062 NDR_SCONTEXT ContextHandle
;
7064 TRACE("(%p)\n", pStubMsg
);
7066 align_pointer(&pStubMsg
->Buffer
, 4);
7068 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7070 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7071 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7072 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7075 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
7077 pStubMsg
->RpcMsg
->DataRepresentation
,
7078 NULL
, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
7079 pStubMsg
->Buffer
+= cbNDRContext
;
7081 return ContextHandle
;
7084 void WINAPI
NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg
,
7085 unsigned char* pMemory
,
7086 PFORMAT_STRING pFormat
)
7088 FIXME("(%p, %p, %p): stub\n", pStubMsg
, pMemory
, pFormat
);
7091 NDR_SCONTEXT WINAPI
NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg
,
7092 PFORMAT_STRING pFormat
)
7094 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
7095 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
7097 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
7099 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
7100 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
7101 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
7102 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
7103 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
7105 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
7106 if_id
= &sif
->InterfaceId
;
7109 return NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
, NULL
,
7110 pStubMsg
->RpcMsg
->DataRepresentation
, if_id
,
7114 void WINAPI
NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7115 NDR_SCONTEXT ContextHandle
,
7116 NDR_RUNDOWN RundownRoutine
,
7117 PFORMAT_STRING pFormat
)
7119 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
7120 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
7122 TRACE("(%p, %p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
, pFormat
);
7124 align_pointer(&pStubMsg
->Buffer
, 4);
7126 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7128 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7129 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7130 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7133 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
7134 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
7135 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
7136 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
7137 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
7139 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
7140 if_id
= &sif
->InterfaceId
;
7143 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
7144 pStubMsg
->Buffer
, RundownRoutine
, if_id
, flags
);
7145 pStubMsg
->Buffer
+= cbNDRContext
;
7148 NDR_SCONTEXT WINAPI
NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7149 PFORMAT_STRING pFormat
)
7151 NDR_SCONTEXT ContextHandle
;
7152 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
7153 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
7155 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
7157 align_pointer(&pStubMsg
->Buffer
, 4);
7159 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7161 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7162 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7163 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7166 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
7167 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
7168 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
7169 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
7170 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
7172 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
7173 if_id
= &sif
->InterfaceId
;
7176 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
7178 pStubMsg
->RpcMsg
->DataRepresentation
,
7180 pStubMsg
->Buffer
+= cbNDRContext
;
7182 return ContextHandle
;
7185 /***********************************************************************
7186 * NdrCorrelationInitialize [RPCRT4.@]
7188 * Initializes correlation validity checking.
7191 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7192 * pMemory [I] Pointer to memory to use as a cache.
7193 * CacheSize [I] Size of the memory pointed to by pMemory.
7194 * Flags [I] Reserved. Set to zero.
7199 void WINAPI
NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg
, void *pMemory
, ULONG CacheSize
, ULONG Flags
)
7201 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg
, pMemory
, CacheSize
, Flags
);
7202 pStubMsg
->fHasNewCorrDesc
= TRUE
;
7205 /***********************************************************************
7206 * NdrCorrelationPass [RPCRT4.@]
7208 * Performs correlation validity checking.
7211 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7216 void WINAPI
NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg
)
7218 FIXME("(%p): stub\n", pStubMsg
);
7221 /***********************************************************************
7222 * NdrCorrelationFree [RPCRT4.@]
7224 * Frees any resources used while unmarshalling parameters that need
7225 * correlation validity checking.
7228 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7233 void WINAPI
NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg
)
7235 FIXME("(%p): stub\n", pStubMsg
);