4 * Copyright 2002 Greg Turner
5 * Copyright 2003-2006 CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 * - Byte count pointers
24 * - transmit_as/represent as
25 * - Multi-dimensional arrays
26 * - Conversion functions (NdrConvert)
27 * - Checks for integer addition overflow in user marshall functions
36 #define NONAMELESSUNION
45 #include "wine/unicode.h"
46 #include "wine/rpcfc.h"
48 #include "wine/debug.h"
50 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
53 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
54 (*((UINT32 *)(pchar)) = (uint32))
56 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
57 (*((UINT32 *)(pchar)))
59 /* these would work for i386 too, but less efficient */
60 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
61 (*(pchar) = LOBYTE(LOWORD(uint32)), \
62 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
63 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
64 *((pchar)+3) = HIBYTE(HIWORD(uint32)))
66 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
68 MAKEWORD(*(pchar), *((pchar)+1)), \
69 MAKEWORD(*((pchar)+2), *((pchar)+3))))
72 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
73 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
74 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
75 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
76 *(pchar) = HIBYTE(HIWORD(uint32)))
78 #define BIG_ENDIAN_UINT32_READ(pchar) \
80 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
81 MAKEWORD(*((pchar)+1), *(pchar))))
83 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
84 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
85 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
86 # define NDR_LOCAL_UINT32_READ(pchar) \
87 BIG_ENDIAN_UINT32_READ(pchar)
89 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
90 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
91 # define NDR_LOCAL_UINT32_READ(pchar) \
92 LITTLE_ENDIAN_UINT32_READ(pchar)
95 static inline void align_length( ULONG
*len
, unsigned int align
)
97 *len
= (*len
+ align
- 1) & ~(align
- 1);
100 static inline void align_pointer( unsigned char **ptr
, unsigned int align
)
102 ULONG_PTR mask
= align
- 1;
103 *ptr
= (unsigned char *)(((ULONG_PTR
)*ptr
+ mask
) & ~mask
);
106 static inline void align_pointer_clear( unsigned char **ptr
, unsigned int align
)
108 ULONG_PTR mask
= align
- 1;
109 memset( *ptr
, 0, (align
- (ULONG_PTR
)*ptr
) & mask
);
110 *ptr
= (unsigned char *)(((ULONG_PTR
)*ptr
+ mask
) & ~mask
);
113 #define STD_OVERFLOW_CHECK(_Msg) do { \
114 TRACE("buffer=%d/%d\n", (ULONG)(_Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer), _Msg->BufferLength); \
115 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
116 ERR("buffer overflow %d bytes\n", (ULONG)(_Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength))); \
119 #define NDR_POINTER_ID_BASE 0x20000
120 #define NDR_POINTER_ID(pStubMsg) (NDR_POINTER_ID_BASE + ((pStubMsg)->UniquePtrCount++) * 4)
121 #define NDR_TABLE_SIZE 128
122 #define NDR_TABLE_MASK 127
124 #define NDRSContextFromValue(user_context) (NDR_SCONTEXT)((char *)(user_context) - (char *)NDRSContextValue((NDR_SCONTEXT)NULL))
126 static unsigned char *WINAPI
NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
127 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
128 static void WINAPI
NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
129 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
130 static ULONG WINAPI
NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
132 static unsigned char *WINAPI
NdrContextHandleMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
133 static void WINAPI
NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
134 static unsigned char *WINAPI
NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
136 static unsigned char *WINAPI
NdrRangeMarshall(PMIDL_STUB_MESSAGE
,unsigned char *, PFORMAT_STRING
);
137 static void WINAPI
NdrRangeBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
138 static ULONG WINAPI
NdrRangeMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
139 static void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
141 static ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
143 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
144 unsigned char *pMemory
,
145 PFORMAT_STRING pFormat
,
146 PFORMAT_STRING pPointer
);
147 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
148 unsigned char *pMemory
,
149 PFORMAT_STRING pFormat
,
150 PFORMAT_STRING pPointer
);
151 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
152 unsigned char *pMemory
,
153 PFORMAT_STRING pFormat
,
154 PFORMAT_STRING pPointer
,
155 unsigned char fMustAlloc
);
156 static ULONG
ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
157 PFORMAT_STRING pFormat
,
158 PFORMAT_STRING pPointer
);
159 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
160 unsigned char *pMemory
,
161 PFORMAT_STRING pFormat
,
162 PFORMAT_STRING pPointer
);
164 const NDR_MARSHALL NdrMarshaller
[NDR_TABLE_SIZE
] = {
166 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
167 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
168 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
169 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
173 NdrPointerMarshall
, NdrPointerMarshall
,
174 NdrPointerMarshall
, NdrPointerMarshall
,
176 NdrSimpleStructMarshall
, NdrSimpleStructMarshall
,
177 NdrConformantStructMarshall
, NdrConformantStructMarshall
,
178 NdrConformantVaryingStructMarshall
,
179 NdrComplexStructMarshall
,
181 NdrConformantArrayMarshall
,
182 NdrConformantVaryingArrayMarshall
,
183 NdrFixedArrayMarshall
, NdrFixedArrayMarshall
,
184 NdrVaryingArrayMarshall
, NdrVaryingArrayMarshall
,
185 NdrComplexArrayMarshall
,
187 NdrConformantStringMarshall
, 0, 0,
188 NdrConformantStringMarshall
,
189 NdrNonConformantStringMarshall
, 0, 0, 0,
191 NdrEncapsulatedUnionMarshall
,
192 NdrNonEncapsulatedUnionMarshall
,
193 NdrByteCountPointerMarshall
,
194 NdrXmitOrRepAsMarshall
, NdrXmitOrRepAsMarshall
,
196 NdrInterfacePointerMarshall
,
198 NdrContextHandleMarshall
,
201 NdrUserMarshalMarshall
,
208 const NDR_UNMARSHALL NdrUnmarshaller
[NDR_TABLE_SIZE
] = {
210 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
211 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
212 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
213 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
215 NdrBaseTypeUnmarshall
,
217 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
218 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
220 NdrSimpleStructUnmarshall
, NdrSimpleStructUnmarshall
,
221 NdrConformantStructUnmarshall
, NdrConformantStructUnmarshall
,
222 NdrConformantVaryingStructUnmarshall
,
223 NdrComplexStructUnmarshall
,
225 NdrConformantArrayUnmarshall
,
226 NdrConformantVaryingArrayUnmarshall
,
227 NdrFixedArrayUnmarshall
, NdrFixedArrayUnmarshall
,
228 NdrVaryingArrayUnmarshall
, NdrVaryingArrayUnmarshall
,
229 NdrComplexArrayUnmarshall
,
231 NdrConformantStringUnmarshall
, 0, 0,
232 NdrConformantStringUnmarshall
,
233 NdrNonConformantStringUnmarshall
, 0, 0, 0,
235 NdrEncapsulatedUnionUnmarshall
,
236 NdrNonEncapsulatedUnionUnmarshall
,
237 NdrByteCountPointerUnmarshall
,
238 NdrXmitOrRepAsUnmarshall
, NdrXmitOrRepAsUnmarshall
,
240 NdrInterfacePointerUnmarshall
,
242 NdrContextHandleUnmarshall
,
245 NdrUserMarshalUnmarshall
,
249 NdrBaseTypeUnmarshall
,
250 NdrBaseTypeUnmarshall
252 const NDR_BUFFERSIZE NdrBufferSizer
[NDR_TABLE_SIZE
] = {
254 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
255 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
256 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
257 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
259 NdrBaseTypeBufferSize
,
261 NdrPointerBufferSize
, NdrPointerBufferSize
,
262 NdrPointerBufferSize
, NdrPointerBufferSize
,
264 NdrSimpleStructBufferSize
, NdrSimpleStructBufferSize
,
265 NdrConformantStructBufferSize
, NdrConformantStructBufferSize
,
266 NdrConformantVaryingStructBufferSize
,
267 NdrComplexStructBufferSize
,
269 NdrConformantArrayBufferSize
,
270 NdrConformantVaryingArrayBufferSize
,
271 NdrFixedArrayBufferSize
, NdrFixedArrayBufferSize
,
272 NdrVaryingArrayBufferSize
, NdrVaryingArrayBufferSize
,
273 NdrComplexArrayBufferSize
,
275 NdrConformantStringBufferSize
, 0, 0,
276 NdrConformantStringBufferSize
,
277 NdrNonConformantStringBufferSize
, 0, 0, 0,
279 NdrEncapsulatedUnionBufferSize
,
280 NdrNonEncapsulatedUnionBufferSize
,
281 NdrByteCountPointerBufferSize
,
282 NdrXmitOrRepAsBufferSize
, NdrXmitOrRepAsBufferSize
,
284 NdrInterfacePointerBufferSize
,
286 NdrContextHandleBufferSize
,
289 NdrUserMarshalBufferSize
,
293 NdrBaseTypeBufferSize
,
294 NdrBaseTypeBufferSize
296 const NDR_MEMORYSIZE NdrMemorySizer
[NDR_TABLE_SIZE
] = {
298 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
299 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
300 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
301 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
303 NdrBaseTypeMemorySize
,
305 NdrPointerMemorySize
, NdrPointerMemorySize
,
306 NdrPointerMemorySize
, NdrPointerMemorySize
,
308 NdrSimpleStructMemorySize
, NdrSimpleStructMemorySize
,
309 NdrConformantStructMemorySize
, NdrConformantStructMemorySize
,
310 NdrConformantVaryingStructMemorySize
,
311 NdrComplexStructMemorySize
,
313 NdrConformantArrayMemorySize
,
314 NdrConformantVaryingArrayMemorySize
,
315 NdrFixedArrayMemorySize
, NdrFixedArrayMemorySize
,
316 NdrVaryingArrayMemorySize
, NdrVaryingArrayMemorySize
,
317 NdrComplexArrayMemorySize
,
319 NdrConformantStringMemorySize
, 0, 0,
320 NdrConformantStringMemorySize
,
321 NdrNonConformantStringMemorySize
, 0, 0, 0,
323 NdrEncapsulatedUnionMemorySize
,
324 NdrNonEncapsulatedUnionMemorySize
,
325 NdrByteCountPointerMemorySize
,
326 NdrXmitOrRepAsMemorySize
, NdrXmitOrRepAsMemorySize
,
328 NdrInterfacePointerMemorySize
,
333 NdrUserMarshalMemorySize
,
337 NdrBaseTypeMemorySize
,
338 NdrBaseTypeMemorySize
340 const NDR_FREE NdrFreer
[NDR_TABLE_SIZE
] = {
342 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
343 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
344 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
345 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
349 NdrPointerFree
, NdrPointerFree
,
350 NdrPointerFree
, NdrPointerFree
,
352 NdrSimpleStructFree
, NdrSimpleStructFree
,
353 NdrConformantStructFree
, NdrConformantStructFree
,
354 NdrConformantVaryingStructFree
,
355 NdrComplexStructFree
,
357 NdrConformantArrayFree
,
358 NdrConformantVaryingArrayFree
,
359 NdrFixedArrayFree
, NdrFixedArrayFree
,
360 NdrVaryingArrayFree
, NdrVaryingArrayFree
,
366 NdrEncapsulatedUnionFree
,
367 NdrNonEncapsulatedUnionFree
,
369 NdrXmitOrRepAsFree
, NdrXmitOrRepAsFree
,
371 NdrInterfacePointerFree
,
384 typedef struct _NDR_MEMORY_LIST
389 struct _NDR_MEMORY_LIST
*next
;
392 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
394 /***********************************************************************
395 * NdrAllocate [RPCRT4.@]
397 * Allocates a block of memory using pStubMsg->pfnAllocate.
400 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
401 * len [I] Size of memory block to allocate.
404 * The memory block of size len that was allocated.
407 * The memory block is always 8-byte aligned.
408 * If the function is unable to allocate memory an RPC_X_NO_MEMORY
409 * exception is raised.
411 void * WINAPI
NdrAllocate(MIDL_STUB_MESSAGE
*pStubMsg
, SIZE_T len
)
416 NDR_MEMORY_LIST
*mem_list
;
418 aligned_len
= (len
+ 7) & ~7;
419 adjusted_len
= aligned_len
+ sizeof(NDR_MEMORY_LIST
);
420 /* check for overflow */
421 if (adjusted_len
< len
)
423 ERR("overflow of adjusted_len %ld, len %ld\n", adjusted_len
, len
);
424 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
427 p
= pStubMsg
->pfnAllocate(adjusted_len
);
428 if (!p
) RpcRaiseException(RPC_X_NO_MEMORY
);
430 mem_list
= (NDR_MEMORY_LIST
*)((char *)p
+ aligned_len
);
431 mem_list
->magic
= MEML_MAGIC
;
432 mem_list
->size
= aligned_len
;
433 mem_list
->reserved
= 0;
434 mem_list
->next
= pStubMsg
->pMemoryList
;
435 pStubMsg
->pMemoryList
= mem_list
;
441 static void NdrFree(MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *Pointer
)
443 TRACE("(%p, %p)\n", pStubMsg
, Pointer
);
445 pStubMsg
->pfnFree(Pointer
);
448 static inline BOOL
IsConformanceOrVariancePresent(PFORMAT_STRING pFormat
)
450 return (*(const ULONG
*)pFormat
!= -1);
453 static inline PFORMAT_STRING
SkipConformance(const PMIDL_STUB_MESSAGE pStubMsg
, const PFORMAT_STRING pFormat
)
455 return pFormat
+ 4 + pStubMsg
->CorrDespIncrement
;
458 static PFORMAT_STRING
ReadConformance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
)
460 align_pointer(&pStubMsg
->Buffer
, 4);
461 if (pStubMsg
->Buffer
+ 4 > pStubMsg
->BufferEnd
)
462 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
463 pStubMsg
->MaxCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
464 pStubMsg
->Buffer
+= 4;
465 TRACE("unmarshalled conformance is %ld\n", pStubMsg
->MaxCount
);
466 return SkipConformance(pStubMsg
, pFormat
);
469 static inline PFORMAT_STRING
ReadVariance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
, ULONG MaxValue
)
471 if (pFormat
&& !IsConformanceOrVariancePresent(pFormat
))
473 pStubMsg
->Offset
= 0;
474 pStubMsg
->ActualCount
= pStubMsg
->MaxCount
;
478 align_pointer(&pStubMsg
->Buffer
, 4);
479 if (pStubMsg
->Buffer
+ 8 > pStubMsg
->BufferEnd
)
480 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
481 pStubMsg
->Offset
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
482 pStubMsg
->Buffer
+= 4;
483 TRACE("offset is %d\n", pStubMsg
->Offset
);
484 pStubMsg
->ActualCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
485 pStubMsg
->Buffer
+= 4;
486 TRACE("variance is %d\n", pStubMsg
->ActualCount
);
488 if ((pStubMsg
->ActualCount
> MaxValue
) ||
489 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> MaxValue
))
491 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
492 pStubMsg
->ActualCount
, pStubMsg
->Offset
, MaxValue
);
493 RpcRaiseException(RPC_S_INVALID_BOUND
);
498 return SkipConformance(pStubMsg
, pFormat
);
501 /* writes the conformance value to the buffer */
502 static inline void WriteConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
504 align_pointer_clear(&pStubMsg
->Buffer
, 4);
505 if (pStubMsg
->Buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
506 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
507 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->MaxCount
);
508 pStubMsg
->Buffer
+= 4;
511 /* writes the variance values to the buffer */
512 static inline void WriteVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
514 align_pointer_clear(&pStubMsg
->Buffer
, 4);
515 if (pStubMsg
->Buffer
+ 8 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
516 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
517 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->Offset
);
518 pStubMsg
->Buffer
+= 4;
519 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->ActualCount
);
520 pStubMsg
->Buffer
+= 4;
523 /* requests buffer space for the conformance value */
524 static inline void SizeConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
526 align_length(&pStubMsg
->BufferLength
, 4);
527 if (pStubMsg
->BufferLength
+ 4 < pStubMsg
->BufferLength
)
528 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
529 pStubMsg
->BufferLength
+= 4;
532 /* requests buffer space for the variance values */
533 static inline void SizeVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
535 align_length(&pStubMsg
->BufferLength
, 4);
536 if (pStubMsg
->BufferLength
+ 8 < pStubMsg
->BufferLength
)
537 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
538 pStubMsg
->BufferLength
+= 8;
541 PFORMAT_STRING
ComputeConformanceOrVariance(
542 MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *pMemory
,
543 PFORMAT_STRING pFormat
, ULONG_PTR def
, ULONG_PTR
*pCount
)
545 BYTE dtype
= pFormat
[0] & 0xf;
546 short ofs
= *(const short *)&pFormat
[2];
550 if (!IsConformanceOrVariancePresent(pFormat
)) {
551 /* null descriptor */
556 switch (pFormat
[0] & 0xf0) {
557 case RPC_FC_NORMAL_CONFORMANCE
:
558 TRACE("normal conformance, ofs=%d\n", ofs
);
561 case RPC_FC_POINTER_CONFORMANCE
:
562 TRACE("pointer conformance, ofs=%d\n", ofs
);
563 ptr
= pStubMsg
->Memory
;
565 case RPC_FC_TOP_LEVEL_CONFORMANCE
:
566 TRACE("toplevel conformance, ofs=%d\n", ofs
);
567 if (pStubMsg
->StackTop
) {
568 ptr
= pStubMsg
->StackTop
;
571 /* -Os mode, *pCount is already set */
575 case RPC_FC_CONSTANT_CONFORMANCE
:
576 data
= ofs
| ((DWORD
)pFormat
[1] << 16);
577 TRACE("constant conformance, val=%ld\n", data
);
580 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE
:
581 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs
);
582 if (pStubMsg
->StackTop
) {
583 ptr
= pStubMsg
->StackTop
;
591 FIXME("unknown conformance type %x, expect crash.\n", pFormat
[0] & 0xf0);
595 switch (pFormat
[1]) {
596 case RPC_FC_DEREFERENCE
:
597 ptr
= *(LPVOID
*)((char *)ptr
+ ofs
);
599 case RPC_FC_CALLBACK
:
601 unsigned char *old_stack_top
= pStubMsg
->StackTop
;
602 ULONG_PTR max_count
, old_max_count
= pStubMsg
->MaxCount
;
604 pStubMsg
->StackTop
= ptr
;
606 /* ofs is index into StubDesc->apfnExprEval */
607 TRACE("callback conformance into apfnExprEval[%d]\n", ofs
);
608 pStubMsg
->StubDesc
->apfnExprEval
[ofs
](pStubMsg
);
610 pStubMsg
->StackTop
= old_stack_top
;
612 /* the callback function always stores the computed value in MaxCount */
613 max_count
= pStubMsg
->MaxCount
;
614 pStubMsg
->MaxCount
= old_max_count
;
619 ptr
= (char *)ptr
+ ofs
;
632 data
= *(USHORT
*)ptr
;
643 data
= *(ULONGLONG
*)ptr
;
646 FIXME("unknown conformance data type %x\n", dtype
);
649 TRACE("dereferenced data type %x at %p, got %ld\n", dtype
, ptr
, data
);
652 switch (pFormat
[1]) {
653 case RPC_FC_DEREFERENCE
: /* already handled */
670 FIXME("unknown conformance op %d\n", pFormat
[1]);
675 TRACE("resulting conformance is %ld\n", *pCount
);
677 return SkipConformance(pStubMsg
, pFormat
);
680 static inline PFORMAT_STRING
SkipVariance(PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
682 return SkipConformance( pStubMsg
, pFormat
);
685 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
686 * the result overflows 32-bits */
687 static inline ULONG
safe_multiply(ULONG a
, ULONG b
)
689 ULONGLONG ret
= (ULONGLONG
)a
* b
;
690 if (ret
> 0xffffffff)
692 RpcRaiseException(RPC_S_INVALID_BOUND
);
698 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
700 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
701 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
702 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
703 pStubMsg
->Buffer
+= size
;
706 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
708 if (pStubMsg
->BufferLength
+ size
< pStubMsg
->BufferLength
) /* integer overflow of pStubMsg->BufferSize */
710 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
711 pStubMsg
->BufferLength
, size
);
712 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
714 pStubMsg
->BufferLength
+= size
;
717 /* copies data from the buffer, checking that there is enough data in the buffer
719 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, void *p
, ULONG size
)
721 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
722 (pStubMsg
->Buffer
+ size
> pStubMsg
->BufferEnd
))
724 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
725 pStubMsg
->Buffer
, pStubMsg
->BufferEnd
, size
);
726 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
728 if (p
== pStubMsg
->Buffer
)
729 ERR("pointer is the same as the buffer\n");
730 memcpy(p
, pStubMsg
->Buffer
, size
);
731 pStubMsg
->Buffer
+= size
;
734 /* copies data to the buffer, checking that there is enough space to do so */
735 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, const void *p
, ULONG size
)
737 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
738 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
740 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
741 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
,
743 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
745 memcpy(pStubMsg
->Buffer
, p
, size
);
746 pStubMsg
->Buffer
+= size
;
749 /* verify that string data sitting in the buffer is valid and safe to
751 static void validate_string_data(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG bufsize
, ULONG esize
)
755 /* verify the buffer is safe to access */
756 if ((pStubMsg
->Buffer
+ bufsize
< pStubMsg
->Buffer
) ||
757 (pStubMsg
->Buffer
+ bufsize
> pStubMsg
->BufferEnd
))
759 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize
,
760 pStubMsg
->BufferEnd
, pStubMsg
->Buffer
);
761 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
764 /* strings must always have null terminating bytes */
767 ERR("invalid string length of %d\n", bufsize
/ esize
);
768 RpcRaiseException(RPC_S_INVALID_BOUND
);
771 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
772 if (pStubMsg
->Buffer
[i
] != 0)
774 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
775 i
, pStubMsg
->Buffer
[i
]);
776 RpcRaiseException(RPC_S_INVALID_BOUND
);
780 static inline void dump_pointer_attr(unsigned char attr
)
782 if (attr
& RPC_FC_P_ALLOCALLNODES
)
783 TRACE(" RPC_FC_P_ALLOCALLNODES");
784 if (attr
& RPC_FC_P_DONTFREE
)
785 TRACE(" RPC_FC_P_DONTFREE");
786 if (attr
& RPC_FC_P_ONSTACK
)
787 TRACE(" RPC_FC_P_ONSTACK");
788 if (attr
& RPC_FC_P_SIMPLEPOINTER
)
789 TRACE(" RPC_FC_P_SIMPLEPOINTER");
790 if (attr
& RPC_FC_P_DEREF
)
791 TRACE(" RPC_FC_P_DEREF");
795 /***********************************************************************
796 * PointerMarshall [internal]
798 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
799 unsigned char *Buffer
,
800 unsigned char *Pointer
,
801 PFORMAT_STRING pFormat
)
803 unsigned type
= pFormat
[0], attr
= pFormat
[1];
807 BOOL pointer_needs_marshaling
;
809 TRACE("(%p,%p,%p,%p)\n", pStubMsg
, Buffer
, Pointer
, pFormat
);
810 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
812 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
813 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
816 case RPC_FC_RP
: /* ref pointer (always non-null) */
819 ERR("NULL ref pointer is not allowed\n");
820 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
822 pointer_needs_marshaling
= TRUE
;
824 case RPC_FC_UP
: /* unique pointer */
825 case RPC_FC_OP
: /* object pointer - same as unique here */
827 pointer_needs_marshaling
= TRUE
;
829 pointer_needs_marshaling
= FALSE
;
830 pointer_id
= Pointer
? NDR_POINTER_ID(pStubMsg
) : 0;
831 TRACE("writing 0x%08x to buffer\n", pointer_id
);
832 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
835 pointer_needs_marshaling
= !NdrFullPointerQueryPointer(
836 pStubMsg
->FullPtrXlatTables
, Pointer
, 1, &pointer_id
);
837 TRACE("writing 0x%08x to buffer\n", pointer_id
);
838 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
841 FIXME("unhandled ptr type=%02x\n", type
);
842 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
846 TRACE("calling marshaller for type 0x%x\n", (int)*desc
);
848 if (pointer_needs_marshaling
) {
849 if (attr
& RPC_FC_P_DEREF
) {
850 Pointer
= *(unsigned char**)Pointer
;
851 TRACE("deref => %p\n", Pointer
);
853 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
854 if (m
) m(pStubMsg
, Pointer
, desc
);
855 else FIXME("no marshaller for data type=%02x\n", *desc
);
858 STD_OVERFLOW_CHECK(pStubMsg
);
861 /***********************************************************************
862 * PointerUnmarshall [internal]
864 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
865 unsigned char *Buffer
,
866 unsigned char **pPointer
,
867 unsigned char *pSrcPointer
,
868 PFORMAT_STRING pFormat
,
869 unsigned char fMustAlloc
)
871 unsigned type
= pFormat
[0], attr
= pFormat
[1];
874 DWORD pointer_id
= 0;
875 BOOL pointer_needs_unmarshaling
;
877 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg
, Buffer
, pPointer
, pSrcPointer
, pFormat
, fMustAlloc
);
878 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
880 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
881 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
884 case RPC_FC_RP
: /* ref pointer (always non-null) */
885 pointer_needs_unmarshaling
= TRUE
;
887 case RPC_FC_UP
: /* unique pointer */
888 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
889 TRACE("pointer_id is 0x%08x\n", pointer_id
);
891 pointer_needs_unmarshaling
= TRUE
;
894 pointer_needs_unmarshaling
= FALSE
;
897 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
898 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
899 TRACE("pointer_id is 0x%08x\n", pointer_id
);
900 if (!fMustAlloc
&& pSrcPointer
)
902 FIXME("free object pointer %p\n", pSrcPointer
);
906 pointer_needs_unmarshaling
= TRUE
;
910 pointer_needs_unmarshaling
= FALSE
;
914 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
915 TRACE("pointer_id is 0x%08x\n", pointer_id
);
916 pointer_needs_unmarshaling
= !NdrFullPointerQueryRefId(
917 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, (void **)pPointer
);
920 FIXME("unhandled ptr type=%02x\n", type
);
921 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
925 if (pointer_needs_unmarshaling
) {
926 unsigned char **current_ptr
= pPointer
;
927 if (pStubMsg
->IsClient
) {
929 /* if we aren't forcing allocation of memory then try to use the existing
930 * (source) pointer to unmarshall the data into so that [in,out]
931 * parameters behave correctly. it doesn't matter if the parameter is
932 * [out] only since in that case the pointer will be NULL. we force
933 * allocation when the source pointer is NULL here instead of in the type
934 * unmarshalling routine for the benefit of the deref code below */
937 TRACE("setting *pPointer to %p\n", pSrcPointer
);
938 *pPointer
= pSrcPointer
;
944 /* the memory in a stub is never initialised, so we have to work out here
945 * whether we have to initialise it so we can use the optimisation of
946 * setting the pointer to the buffer, if possible, or set fMustAlloc to
948 if (attr
& RPC_FC_P_DEREF
) {
955 if (attr
& RPC_FC_P_ALLOCALLNODES
)
956 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
958 if (attr
& RPC_FC_P_DEREF
) {
960 unsigned char *base_ptr_val
= NdrAllocate(pStubMsg
, sizeof(void *));
961 *pPointer
= base_ptr_val
;
962 current_ptr
= (unsigned char **)base_ptr_val
;
964 current_ptr
= *(unsigned char***)current_ptr
;
965 TRACE("deref => %p\n", current_ptr
);
966 if (!fMustAlloc
&& !*current_ptr
) fMustAlloc
= TRUE
;
968 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
969 if (m
) m(pStubMsg
, current_ptr
, desc
, fMustAlloc
);
970 else FIXME("no unmarshaller for data type=%02x\n", *desc
);
972 if (type
== RPC_FC_FP
)
973 NdrFullPointerInsertRefId(pStubMsg
->FullPtrXlatTables
, pointer_id
,
977 TRACE("pointer=%p\n", *pPointer
);
980 /***********************************************************************
981 * PointerBufferSize [internal]
983 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
984 unsigned char *Pointer
,
985 PFORMAT_STRING pFormat
)
987 unsigned type
= pFormat
[0], attr
= pFormat
[1];
990 BOOL pointer_needs_sizing
;
993 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
994 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
996 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
997 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1000 case RPC_FC_RP
: /* ref pointer (always non-null) */
1003 ERR("NULL ref pointer is not allowed\n");
1004 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
1009 /* NULL pointer has no further representation */
1014 pointer_needs_sizing
= !NdrFullPointerQueryPointer(
1015 pStubMsg
->FullPtrXlatTables
, Pointer
, 0, &pointer_id
);
1016 if (!pointer_needs_sizing
)
1020 FIXME("unhandled ptr type=%02x\n", type
);
1021 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1025 if (attr
& RPC_FC_P_DEREF
) {
1026 Pointer
= *(unsigned char**)Pointer
;
1027 TRACE("deref => %p\n", Pointer
);
1030 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
1031 if (m
) m(pStubMsg
, Pointer
, desc
);
1032 else FIXME("no buffersizer for data type=%02x\n", *desc
);
1035 /***********************************************************************
1036 * PointerMemorySize [internal]
1038 static ULONG
PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1039 unsigned char *Buffer
, PFORMAT_STRING pFormat
)
1041 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1042 PFORMAT_STRING desc
;
1044 DWORD pointer_id
= 0;
1045 BOOL pointer_needs_sizing
;
1047 TRACE("(%p,%p,%p)\n", pStubMsg
, Buffer
, pFormat
);
1048 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1050 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1051 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1054 case RPC_FC_RP
: /* ref pointer (always non-null) */
1055 pointer_needs_sizing
= TRUE
;
1057 case RPC_FC_UP
: /* unique pointer */
1058 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
1059 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1060 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1062 pointer_needs_sizing
= TRUE
;
1064 pointer_needs_sizing
= FALSE
;
1069 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1070 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1071 pointer_needs_sizing
= !NdrFullPointerQueryRefId(
1072 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, &pointer
);
1076 FIXME("unhandled ptr type=%02x\n", type
);
1077 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1081 if (attr
& RPC_FC_P_DEREF
) {
1082 align_length(&pStubMsg
->MemorySize
, sizeof(void*));
1083 pStubMsg
->MemorySize
+= sizeof(void*);
1087 if (pointer_needs_sizing
) {
1088 m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
1089 if (m
) m(pStubMsg
, desc
);
1090 else FIXME("no memorysizer for data type=%02x\n", *desc
);
1093 return pStubMsg
->MemorySize
;
1096 /***********************************************************************
1097 * PointerFree [internal]
1099 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1100 unsigned char *Pointer
,
1101 PFORMAT_STRING pFormat
)
1103 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1104 PFORMAT_STRING desc
;
1106 unsigned char *current_pointer
= Pointer
;
1108 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1109 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1110 if (attr
& RPC_FC_P_DONTFREE
) return;
1112 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1113 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1115 if (!Pointer
) return;
1117 if (type
== RPC_FC_FP
) {
1118 int pointer_needs_freeing
= NdrFullPointerFree(
1119 pStubMsg
->FullPtrXlatTables
, Pointer
);
1120 if (!pointer_needs_freeing
)
1124 if (attr
& RPC_FC_P_DEREF
) {
1125 current_pointer
= *(unsigned char**)Pointer
;
1126 TRACE("deref => %p\n", current_pointer
);
1129 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
1130 if (m
) m(pStubMsg
, current_pointer
, desc
);
1132 /* this check stops us from trying to free buffer memory. we don't have to
1133 * worry about clients, since they won't call this function.
1134 * we don't have to check for the buffer being reallocated because
1135 * BufferStart and BufferEnd won't be reset when allocating memory for
1136 * sending the response. we don't have to check for the new buffer here as
1137 * it won't be used a type memory, only for buffer memory */
1138 if (Pointer
>= pStubMsg
->BufferStart
&& Pointer
<= pStubMsg
->BufferEnd
)
1141 if (attr
& RPC_FC_P_ONSTACK
) {
1142 TRACE("not freeing stack ptr %p\n", Pointer
);
1145 TRACE("freeing %p\n", Pointer
);
1146 NdrFree(pStubMsg
, Pointer
);
1149 TRACE("not freeing %p\n", Pointer
);
1152 /***********************************************************************
1153 * EmbeddedPointerMarshall
1155 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1156 unsigned char *pMemory
,
1157 PFORMAT_STRING pFormat
)
1159 unsigned char *Mark
= pStubMsg
->BufferMark
;
1160 unsigned rep
, count
, stride
;
1162 unsigned char *saved_buffer
= NULL
;
1164 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1166 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1169 if (pStubMsg
->PointerBufferMark
)
1171 saved_buffer
= pStubMsg
->Buffer
;
1172 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1173 pStubMsg
->PointerBufferMark
= NULL
;
1176 while (pFormat
[0] != RPC_FC_END
) {
1177 switch (pFormat
[0]) {
1179 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat
[0]);
1181 case RPC_FC_NO_REPEAT
:
1187 case RPC_FC_FIXED_REPEAT
:
1188 rep
= *(const WORD
*)&pFormat
[2];
1189 stride
= *(const WORD
*)&pFormat
[4];
1190 count
= *(const WORD
*)&pFormat
[8];
1193 case RPC_FC_VARIABLE_REPEAT
:
1194 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1195 stride
= *(const WORD
*)&pFormat
[2];
1196 count
= *(const WORD
*)&pFormat
[6];
1200 for (i
= 0; i
< rep
; i
++) {
1201 PFORMAT_STRING info
= pFormat
;
1202 unsigned char *membase
= pMemory
+ (i
* stride
);
1203 unsigned char *bufbase
= Mark
+ (i
* stride
);
1206 for (u
=0; u
<count
; u
++,info
+=8) {
1207 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1208 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1209 unsigned char *saved_memory
= pStubMsg
->Memory
;
1211 pStubMsg
->Memory
= membase
;
1212 PointerMarshall(pStubMsg
, bufptr
, *(unsigned char**)memptr
, info
+4);
1213 pStubMsg
->Memory
= saved_memory
;
1216 pFormat
+= 8 * count
;
1221 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1222 pStubMsg
->Buffer
= saved_buffer
;
1225 STD_OVERFLOW_CHECK(pStubMsg
);
1230 /***********************************************************************
1231 * EmbeddedPointerUnmarshall
1233 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1234 unsigned char *pDstBuffer
,
1235 unsigned char *pSrcMemoryPtrs
,
1236 PFORMAT_STRING pFormat
,
1237 unsigned char fMustAlloc
)
1239 unsigned char *Mark
= pStubMsg
->BufferMark
;
1240 unsigned rep
, count
, stride
;
1242 unsigned char *saved_buffer
= NULL
;
1244 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg
, pDstBuffer
, pSrcMemoryPtrs
, pFormat
, fMustAlloc
);
1246 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1249 if (pStubMsg
->PointerBufferMark
)
1251 saved_buffer
= pStubMsg
->Buffer
;
1252 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1253 pStubMsg
->PointerBufferMark
= NULL
;
1256 while (pFormat
[0] != RPC_FC_END
) {
1257 TRACE("pFormat[0] = 0x%x\n", pFormat
[0]);
1258 switch (pFormat
[0]) {
1260 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat
[0]);
1262 case RPC_FC_NO_REPEAT
:
1268 case RPC_FC_FIXED_REPEAT
:
1269 rep
= *(const WORD
*)&pFormat
[2];
1270 stride
= *(const WORD
*)&pFormat
[4];
1271 count
= *(const WORD
*)&pFormat
[8];
1274 case RPC_FC_VARIABLE_REPEAT
:
1275 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1276 stride
= *(const WORD
*)&pFormat
[2];
1277 count
= *(const WORD
*)&pFormat
[6];
1281 for (i
= 0; i
< rep
; i
++) {
1282 PFORMAT_STRING info
= pFormat
;
1283 unsigned char *bufdstbase
= pDstBuffer
+ (i
* stride
);
1284 unsigned char *memsrcbase
= pSrcMemoryPtrs
+ (i
* stride
);
1285 unsigned char *bufbase
= Mark
+ (i
* stride
);
1288 for (u
=0; u
<count
; u
++,info
+=8) {
1289 unsigned char **bufdstptr
= (unsigned char **)(bufdstbase
+ *(const SHORT
*)&info
[2]);
1290 unsigned char **memsrcptr
= (unsigned char **)(memsrcbase
+ *(const SHORT
*)&info
[0]);
1291 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1292 PointerUnmarshall(pStubMsg
, bufptr
, bufdstptr
, *memsrcptr
, info
+4, fMustAlloc
);
1295 pFormat
+= 8 * count
;
1300 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1301 pStubMsg
->Buffer
= saved_buffer
;
1307 /***********************************************************************
1308 * EmbeddedPointerBufferSize
1310 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1311 unsigned char *pMemory
,
1312 PFORMAT_STRING pFormat
)
1314 unsigned rep
, count
, stride
;
1316 ULONG saved_buffer_length
= 0;
1318 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1320 if (pStubMsg
->IgnoreEmbeddedPointers
) return;
1322 if (*pFormat
!= RPC_FC_PP
) return;
1325 if (pStubMsg
->PointerLength
)
1327 saved_buffer_length
= pStubMsg
->BufferLength
;
1328 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
1329 pStubMsg
->PointerLength
= 0;
1332 while (pFormat
[0] != RPC_FC_END
) {
1333 switch (pFormat
[0]) {
1335 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat
[0]);
1337 case RPC_FC_NO_REPEAT
:
1343 case RPC_FC_FIXED_REPEAT
:
1344 rep
= *(const WORD
*)&pFormat
[2];
1345 stride
= *(const WORD
*)&pFormat
[4];
1346 count
= *(const WORD
*)&pFormat
[8];
1349 case RPC_FC_VARIABLE_REPEAT
:
1350 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1351 stride
= *(const WORD
*)&pFormat
[2];
1352 count
= *(const WORD
*)&pFormat
[6];
1356 for (i
= 0; i
< rep
; i
++) {
1357 PFORMAT_STRING info
= pFormat
;
1358 unsigned char *membase
= pMemory
+ (i
* stride
);
1361 for (u
=0; u
<count
; u
++,info
+=8) {
1362 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1363 unsigned char *saved_memory
= pStubMsg
->Memory
;
1365 pStubMsg
->Memory
= membase
;
1366 PointerBufferSize(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1367 pStubMsg
->Memory
= saved_memory
;
1370 pFormat
+= 8 * count
;
1373 if (saved_buffer_length
)
1375 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
1376 pStubMsg
->BufferLength
= saved_buffer_length
;
1380 /***********************************************************************
1381 * EmbeddedPointerMemorySize [internal]
1383 static ULONG
EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1384 PFORMAT_STRING pFormat
)
1386 unsigned char *Mark
= pStubMsg
->BufferMark
;
1387 unsigned rep
, count
, stride
;
1389 unsigned char *saved_buffer
= NULL
;
1391 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1393 if (pStubMsg
->IgnoreEmbeddedPointers
) return 0;
1395 if (pStubMsg
->PointerBufferMark
)
1397 saved_buffer
= pStubMsg
->Buffer
;
1398 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1399 pStubMsg
->PointerBufferMark
= NULL
;
1402 if (*pFormat
!= RPC_FC_PP
) return 0;
1405 while (pFormat
[0] != RPC_FC_END
) {
1406 switch (pFormat
[0]) {
1408 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat
[0]);
1410 case RPC_FC_NO_REPEAT
:
1416 case RPC_FC_FIXED_REPEAT
:
1417 rep
= *(const WORD
*)&pFormat
[2];
1418 stride
= *(const WORD
*)&pFormat
[4];
1419 count
= *(const WORD
*)&pFormat
[8];
1422 case RPC_FC_VARIABLE_REPEAT
:
1423 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1424 stride
= *(const WORD
*)&pFormat
[2];
1425 count
= *(const WORD
*)&pFormat
[6];
1429 for (i
= 0; i
< rep
; i
++) {
1430 PFORMAT_STRING info
= pFormat
;
1431 unsigned char *bufbase
= Mark
+ (i
* stride
);
1433 for (u
=0; u
<count
; u
++,info
+=8) {
1434 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1435 PointerMemorySize(pStubMsg
, bufptr
, info
+4);
1438 pFormat
+= 8 * count
;
1443 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1444 pStubMsg
->Buffer
= saved_buffer
;
1450 /***********************************************************************
1451 * EmbeddedPointerFree [internal]
1453 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1454 unsigned char *pMemory
,
1455 PFORMAT_STRING pFormat
)
1457 unsigned rep
, count
, stride
;
1460 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1461 if (*pFormat
!= RPC_FC_PP
) return;
1464 while (pFormat
[0] != RPC_FC_END
) {
1465 switch (pFormat
[0]) {
1467 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat
[0]);
1469 case RPC_FC_NO_REPEAT
:
1475 case RPC_FC_FIXED_REPEAT
:
1476 rep
= *(const WORD
*)&pFormat
[2];
1477 stride
= *(const WORD
*)&pFormat
[4];
1478 count
= *(const WORD
*)&pFormat
[8];
1481 case RPC_FC_VARIABLE_REPEAT
:
1482 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1483 stride
= *(const WORD
*)&pFormat
[2];
1484 count
= *(const WORD
*)&pFormat
[6];
1488 for (i
= 0; i
< rep
; i
++) {
1489 PFORMAT_STRING info
= pFormat
;
1490 unsigned char *membase
= pMemory
+ (i
* stride
);
1493 for (u
=0; u
<count
; u
++,info
+=8) {
1494 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1495 unsigned char *saved_memory
= pStubMsg
->Memory
;
1497 pStubMsg
->Memory
= membase
;
1498 PointerFree(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1499 pStubMsg
->Memory
= saved_memory
;
1502 pFormat
+= 8 * count
;
1506 /***********************************************************************
1507 * NdrPointerMarshall [RPCRT4.@]
1509 unsigned char * WINAPI
NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1510 unsigned char *pMemory
,
1511 PFORMAT_STRING pFormat
)
1513 unsigned char *Buffer
;
1515 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1517 /* Increment the buffer here instead of in PointerMarshall,
1518 * as that is used by embedded pointers which already handle the incrementing
1519 * the buffer, and shouldn't write any additional pointer data to the wire */
1520 if (*pFormat
!= RPC_FC_RP
)
1522 align_pointer_clear(&pStubMsg
->Buffer
, 4);
1523 Buffer
= pStubMsg
->Buffer
;
1524 safe_buffer_increment(pStubMsg
, 4);
1527 Buffer
= pStubMsg
->Buffer
;
1529 PointerMarshall(pStubMsg
, Buffer
, pMemory
, pFormat
);
1534 /***********************************************************************
1535 * NdrPointerUnmarshall [RPCRT4.@]
1537 unsigned char * WINAPI
NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1538 unsigned char **ppMemory
,
1539 PFORMAT_STRING pFormat
,
1540 unsigned char fMustAlloc
)
1542 unsigned char *Buffer
;
1544 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1546 if (*pFormat
== RPC_FC_RP
)
1548 Buffer
= pStubMsg
->Buffer
;
1549 /* Do the NULL ref pointer check here because embedded pointers can be
1550 * NULL if the type the pointer is embedded in was allocated rather than
1551 * being passed in by the client */
1552 if (pStubMsg
->IsClient
&& !*ppMemory
)
1554 ERR("NULL ref pointer is not allowed\n");
1555 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
1560 /* Increment the buffer here instead of in PointerUnmarshall,
1561 * as that is used by embedded pointers which already handle the incrementing
1562 * the buffer, and shouldn't read any additional pointer data from the
1564 align_pointer(&pStubMsg
->Buffer
, 4);
1565 Buffer
= pStubMsg
->Buffer
;
1566 safe_buffer_increment(pStubMsg
, 4);
1569 PointerUnmarshall(pStubMsg
, Buffer
, ppMemory
, *ppMemory
, pFormat
, fMustAlloc
);
1574 /***********************************************************************
1575 * NdrPointerBufferSize [RPCRT4.@]
1577 void WINAPI
NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1578 unsigned char *pMemory
,
1579 PFORMAT_STRING pFormat
)
1581 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1583 /* Increment the buffer length here instead of in PointerBufferSize,
1584 * as that is used by embedded pointers which already handle the buffer
1585 * length, and shouldn't write anything more to the wire */
1586 if (*pFormat
!= RPC_FC_RP
)
1588 align_length(&pStubMsg
->BufferLength
, 4);
1589 safe_buffer_length_increment(pStubMsg
, 4);
1592 PointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1595 /***********************************************************************
1596 * NdrPointerMemorySize [RPCRT4.@]
1598 ULONG WINAPI
NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1599 PFORMAT_STRING pFormat
)
1601 unsigned char *Buffer
= pStubMsg
->Buffer
;
1602 if (*pFormat
!= RPC_FC_RP
)
1604 align_pointer(&pStubMsg
->Buffer
, 4);
1605 safe_buffer_increment(pStubMsg
, 4);
1607 align_length(&pStubMsg
->MemorySize
, sizeof(void *));
1608 return PointerMemorySize(pStubMsg
, Buffer
, pFormat
);
1611 /***********************************************************************
1612 * NdrPointerFree [RPCRT4.@]
1614 void WINAPI
NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1615 unsigned char *pMemory
,
1616 PFORMAT_STRING pFormat
)
1618 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1619 PointerFree(pStubMsg
, pMemory
, pFormat
);
1622 /***********************************************************************
1623 * NdrSimpleTypeMarshall [RPCRT4.@]
1625 void WINAPI
NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1626 unsigned char FormatChar
)
1628 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &FormatChar
);
1631 /***********************************************************************
1632 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1634 * Unmarshall a base type.
1637 * Doesn't check that the buffer is long enough before copying, so the caller
1640 void WINAPI
NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1641 unsigned char FormatChar
)
1643 #define BASE_TYPE_UNMARSHALL(type) \
1644 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
1645 TRACE("pMemory: %p\n", pMemory); \
1646 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1647 pStubMsg->Buffer += sizeof(type);
1655 BASE_TYPE_UNMARSHALL(UCHAR
);
1656 TRACE("value: 0x%02x\n", *pMemory
);
1661 BASE_TYPE_UNMARSHALL(USHORT
);
1662 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
1666 case RPC_FC_ERROR_STATUS_T
:
1668 BASE_TYPE_UNMARSHALL(ULONG
);
1669 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
1672 BASE_TYPE_UNMARSHALL(float);
1673 TRACE("value: %f\n", *(float *)pMemory
);
1676 BASE_TYPE_UNMARSHALL(double);
1677 TRACE("value: %f\n", *(double *)pMemory
);
1680 BASE_TYPE_UNMARSHALL(ULONGLONG
);
1681 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
1684 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
1685 TRACE("pMemory: %p\n", pMemory
);
1686 /* 16-bits on the wire, but int in memory */
1687 *(UINT
*)pMemory
= *(USHORT
*)pStubMsg
->Buffer
;
1688 pStubMsg
->Buffer
+= sizeof(USHORT
);
1689 TRACE("value: 0x%08x\n", *(UINT
*)pMemory
);
1691 case RPC_FC_INT3264
:
1692 align_pointer(&pStubMsg
->Buffer
, sizeof(INT
));
1693 /* 32-bits on the wire, but int_ptr in memory */
1694 *(INT_PTR
*)pMemory
= *(INT
*)pStubMsg
->Buffer
;
1695 pStubMsg
->Buffer
+= sizeof(INT
);
1696 TRACE("value: 0x%08lx\n", *(INT_PTR
*)pMemory
);
1698 case RPC_FC_UINT3264
:
1699 align_pointer(&pStubMsg
->Buffer
, sizeof(UINT
));
1700 /* 32-bits on the wire, but int_ptr in memory */
1701 *(UINT_PTR
*)pMemory
= *(UINT
*)pStubMsg
->Buffer
;
1702 pStubMsg
->Buffer
+= sizeof(UINT
);
1703 TRACE("value: 0x%08lx\n", *(UINT_PTR
*)pMemory
);
1708 FIXME("Unhandled base type: 0x%02x\n", FormatChar
);
1710 #undef BASE_TYPE_UNMARSHALL
1713 /***********************************************************************
1714 * NdrSimpleStructMarshall [RPCRT4.@]
1716 unsigned char * WINAPI
NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1717 unsigned char *pMemory
,
1718 PFORMAT_STRING pFormat
)
1720 unsigned size
= *(const WORD
*)(pFormat
+2);
1721 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1723 align_pointer_clear(&pStubMsg
->Buffer
, pFormat
[1] + 1);
1725 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1726 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
1728 if (pFormat
[0] != RPC_FC_STRUCT
)
1729 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
+4);
1734 /***********************************************************************
1735 * NdrSimpleStructUnmarshall [RPCRT4.@]
1737 unsigned char * WINAPI
NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1738 unsigned char **ppMemory
,
1739 PFORMAT_STRING pFormat
,
1740 unsigned char fMustAlloc
)
1742 unsigned size
= *(const WORD
*)(pFormat
+2);
1743 unsigned char *saved_buffer
;
1744 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1746 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
1749 *ppMemory
= NdrAllocate(pStubMsg
, size
);
1752 if (!pStubMsg
->IsClient
&& !*ppMemory
)
1753 /* for servers, we just point straight into the RPC buffer */
1754 *ppMemory
= pStubMsg
->Buffer
;
1757 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1758 safe_buffer_increment(pStubMsg
, size
);
1759 if (pFormat
[0] == RPC_FC_PSTRUCT
)
1760 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
+4, fMustAlloc
);
1762 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
1763 if (*ppMemory
!= saved_buffer
)
1764 memcpy(*ppMemory
, saved_buffer
, size
);
1769 /***********************************************************************
1770 * NdrSimpleStructBufferSize [RPCRT4.@]
1772 void WINAPI
NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1773 unsigned char *pMemory
,
1774 PFORMAT_STRING pFormat
)
1776 unsigned size
= *(const WORD
*)(pFormat
+2);
1777 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1779 align_length(&pStubMsg
->BufferLength
, pFormat
[1] + 1);
1781 safe_buffer_length_increment(pStubMsg
, size
);
1782 if (pFormat
[0] != RPC_FC_STRUCT
)
1783 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
+4);
1786 /***********************************************************************
1787 * NdrSimpleStructMemorySize [RPCRT4.@]
1789 ULONG WINAPI
NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1790 PFORMAT_STRING pFormat
)
1792 unsigned short size
= *(const WORD
*)(pFormat
+2);
1794 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1796 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
1797 pStubMsg
->MemorySize
+= size
;
1798 safe_buffer_increment(pStubMsg
, size
);
1800 if (pFormat
[0] != RPC_FC_STRUCT
)
1801 EmbeddedPointerMemorySize(pStubMsg
, pFormat
+4);
1802 return pStubMsg
->MemorySize
;
1805 /***********************************************************************
1806 * NdrSimpleStructFree [RPCRT4.@]
1808 void WINAPI
NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
1809 unsigned char *pMemory
,
1810 PFORMAT_STRING pFormat
)
1812 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1813 if (pFormat
[0] != RPC_FC_STRUCT
)
1814 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
+4);
1819 static inline void array_compute_and_size_conformance(
1820 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1821 PFORMAT_STRING pFormat
)
1828 ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1829 SizeConformance(pStubMsg
);
1831 case RPC_FC_CVARRAY
:
1832 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, 0);
1833 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
1834 SizeConformance(pStubMsg
);
1836 case RPC_FC_C_CSTRING
:
1837 case RPC_FC_C_WSTRING
:
1838 if (fc
== RPC_FC_C_CSTRING
)
1840 TRACE("string=%s\n", debugstr_a((const char *)pMemory
));
1841 pStubMsg
->ActualCount
= strlen((const char *)pMemory
)+1;
1845 TRACE("string=%s\n", debugstr_w((LPCWSTR
)pMemory
));
1846 pStubMsg
->ActualCount
= strlenW((LPCWSTR
)pMemory
)+1;
1849 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
1850 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
1852 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
1854 SizeConformance(pStubMsg
);
1856 case RPC_FC_BOGUS_ARRAY
:
1857 count
= *(const WORD
*)(pFormat
+ 2);
1859 if (IsConformanceOrVariancePresent(pFormat
)) SizeConformance(pStubMsg
);
1860 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, count
);
1861 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
1864 ERR("unknown array format 0x%x\n", fc
);
1865 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1869 static inline void array_buffer_size(
1870 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1871 PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
1875 unsigned char alignment
;
1880 esize
= *(const WORD
*)(pFormat
+2);
1881 alignment
= pFormat
[1] + 1;
1883 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1885 align_length(&pStubMsg
->BufferLength
, alignment
);
1887 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
1888 /* conformance value plus array */
1889 safe_buffer_length_increment(pStubMsg
, size
);
1892 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1894 case RPC_FC_CVARRAY
:
1895 esize
= *(const WORD
*)(pFormat
+2);
1896 alignment
= pFormat
[1] + 1;
1898 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1899 pFormat
= SkipVariance(pStubMsg
, pFormat
);
1901 SizeVariance(pStubMsg
);
1903 align_length(&pStubMsg
->BufferLength
, alignment
);
1905 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1906 safe_buffer_length_increment(pStubMsg
, size
);
1909 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1911 case RPC_FC_C_CSTRING
:
1912 case RPC_FC_C_WSTRING
:
1913 if (fc
== RPC_FC_C_CSTRING
)
1918 SizeVariance(pStubMsg
);
1920 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1921 safe_buffer_length_increment(pStubMsg
, size
);
1923 case RPC_FC_BOGUS_ARRAY
:
1924 alignment
= pFormat
[1] + 1;
1925 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1926 if (IsConformanceOrVariancePresent(pFormat
)) SizeVariance(pStubMsg
);
1927 pFormat
= SkipVariance(pStubMsg
, pFormat
);
1929 align_length(&pStubMsg
->BufferLength
, alignment
);
1931 size
= pStubMsg
->ActualCount
;
1932 for (i
= 0; i
< size
; i
++)
1933 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
1936 ERR("unknown array format 0x%x\n", fc
);
1937 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1941 static inline void array_compute_and_write_conformance(
1942 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1943 PFORMAT_STRING pFormat
)
1946 BOOL conformance_present
;
1951 ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1952 WriteConformance(pStubMsg
);
1954 case RPC_FC_CVARRAY
:
1955 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, 0);
1956 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
1957 WriteConformance(pStubMsg
);
1959 case RPC_FC_C_CSTRING
:
1960 case RPC_FC_C_WSTRING
:
1961 if (fc
== RPC_FC_C_CSTRING
)
1963 TRACE("string=%s\n", debugstr_a((const char *)pMemory
));
1964 pStubMsg
->ActualCount
= strlen((const char *)pMemory
)+1;
1968 TRACE("string=%s\n", debugstr_w((LPCWSTR
)pMemory
));
1969 pStubMsg
->ActualCount
= strlenW((LPCWSTR
)pMemory
)+1;
1971 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
1972 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
1974 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
1975 pStubMsg
->Offset
= 0;
1976 WriteConformance(pStubMsg
);
1978 case RPC_FC_BOGUS_ARRAY
:
1979 def
= *(const WORD
*)(pFormat
+ 2);
1981 conformance_present
= IsConformanceOrVariancePresent(pFormat
);
1982 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
1983 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
1984 if (conformance_present
) WriteConformance(pStubMsg
);
1987 ERR("unknown array format 0x%x\n", fc
);
1988 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1992 static inline void array_write_variance_and_marshall(
1993 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1994 PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
1998 unsigned char alignment
;
2003 esize
= *(const WORD
*)(pFormat
+2);
2004 alignment
= pFormat
[1] + 1;
2006 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2008 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
2010 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2012 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2013 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
2016 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2018 case RPC_FC_CVARRAY
:
2019 esize
= *(const WORD
*)(pFormat
+2);
2020 alignment
= pFormat
[1] + 1;
2022 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2023 pFormat
= SkipVariance(pStubMsg
, pFormat
);
2025 WriteVariance(pStubMsg
);
2027 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
2029 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2032 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2033 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, size
);
2036 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2038 case RPC_FC_C_CSTRING
:
2039 case RPC_FC_C_WSTRING
:
2040 if (fc
== RPC_FC_C_CSTRING
)
2045 WriteVariance(pStubMsg
);
2047 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2048 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
2050 case RPC_FC_BOGUS_ARRAY
:
2051 alignment
= pFormat
[1] + 1;
2052 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2053 if (IsConformanceOrVariancePresent(pFormat
)) WriteVariance(pStubMsg
);
2054 pFormat
= SkipVariance(pStubMsg
, pFormat
);
2056 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
2058 size
= pStubMsg
->ActualCount
;
2059 for (i
= 0; i
< size
; i
++)
2060 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
2063 ERR("unknown array format 0x%x\n", fc
);
2064 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2068 static inline ULONG
array_read_conformance(
2069 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
2076 esize
= *(const WORD
*)(pFormat
+2);
2077 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2078 return safe_multiply(esize
, pStubMsg
->MaxCount
);
2079 case RPC_FC_CVARRAY
:
2080 esize
= *(const WORD
*)(pFormat
+2);
2081 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2082 return safe_multiply(esize
, pStubMsg
->MaxCount
);
2083 case RPC_FC_C_CSTRING
:
2084 case RPC_FC_C_WSTRING
:
2085 if (fc
== RPC_FC_C_CSTRING
)
2090 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
2091 ReadConformance(pStubMsg
, pFormat
+ 2);
2093 ReadConformance(pStubMsg
, NULL
);
2094 return safe_multiply(esize
, pStubMsg
->MaxCount
);
2095 case RPC_FC_BOGUS_ARRAY
:
2096 def
= *(const WORD
*)(pFormat
+ 2);
2098 if (IsConformanceOrVariancePresent(pFormat
)) pFormat
= ReadConformance(pStubMsg
, pFormat
);
2101 pStubMsg
->MaxCount
= def
;
2102 pFormat
= SkipConformance( pStubMsg
, pFormat
);
2104 pFormat
= SkipVariance( pStubMsg
, pFormat
);
2106 esize
= ComplexStructSize(pStubMsg
, pFormat
);
2107 return safe_multiply(pStubMsg
->MaxCount
, esize
);
2109 ERR("unknown array format 0x%x\n", fc
);
2110 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2114 static inline ULONG
array_read_variance_and_unmarshall(
2115 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char **ppMemory
,
2116 PFORMAT_STRING pFormat
, unsigned char fMustAlloc
,
2117 unsigned char fUseBufferMemoryServer
, unsigned char fUnmarshall
)
2119 ULONG bufsize
, memsize
;
2121 unsigned char alignment
;
2122 unsigned char *saved_buffer
, *pMemory
;
2123 ULONG i
, offset
, count
;
2128 esize
= *(const WORD
*)(pFormat
+2);
2129 alignment
= pFormat
[1] + 1;
2131 bufsize
= memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2133 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2135 align_pointer(&pStubMsg
->Buffer
, alignment
);
2140 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2143 if (fUseBufferMemoryServer
&& !pStubMsg
->IsClient
&& !*ppMemory
)
2144 /* for servers, we just point straight into the RPC buffer */
2145 *ppMemory
= pStubMsg
->Buffer
;
2148 saved_buffer
= pStubMsg
->Buffer
;
2149 safe_buffer_increment(pStubMsg
, bufsize
);
2151 pStubMsg
->BufferMark
= saved_buffer
;
2152 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
2154 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
2155 if (*ppMemory
!= saved_buffer
)
2156 memcpy(*ppMemory
, saved_buffer
, bufsize
);
2159 case RPC_FC_CVARRAY
:
2160 esize
= *(const WORD
*)(pFormat
+2);
2161 alignment
= pFormat
[1] + 1;
2163 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2165 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2167 align_pointer(&pStubMsg
->Buffer
, alignment
);
2169 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2170 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2174 offset
= pStubMsg
->Offset
;
2176 if (!fMustAlloc
&& !*ppMemory
)
2179 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2180 saved_buffer
= pStubMsg
->Buffer
;
2181 safe_buffer_increment(pStubMsg
, bufsize
);
2183 pStubMsg
->BufferMark
= saved_buffer
;
2184 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
,
2187 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
2190 case RPC_FC_C_CSTRING
:
2191 case RPC_FC_C_WSTRING
:
2192 if (fc
== RPC_FC_C_CSTRING
)
2197 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
2199 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
2201 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2202 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
2203 RpcRaiseException(RPC_S_INVALID_BOUND
);
2205 if (pStubMsg
->Offset
)
2207 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2208 RpcRaiseException(RPC_S_INVALID_BOUND
);
2211 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2212 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2214 validate_string_data(pStubMsg
, bufsize
, esize
);
2219 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2222 if (fUseBufferMemoryServer
&& !pStubMsg
->IsClient
&&
2223 !*ppMemory
&& (pStubMsg
->MaxCount
== pStubMsg
->ActualCount
))
2224 /* if the data in the RPC buffer is big enough, we just point
2225 * straight into it */
2226 *ppMemory
= pStubMsg
->Buffer
;
2227 else if (!*ppMemory
)
2228 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2231 if (*ppMemory
== pStubMsg
->Buffer
)
2232 safe_buffer_increment(pStubMsg
, bufsize
);
2234 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
2236 if (*pFormat
== RPC_FC_C_CSTRING
)
2237 TRACE("string=%s\n", debugstr_a((char*)*ppMemory
));
2239 TRACE("string=%s\n", debugstr_w((LPWSTR
)*ppMemory
));
2243 case RPC_FC_BOGUS_ARRAY
:
2244 alignment
= pFormat
[1] + 1;
2245 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2246 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2248 esize
= ComplexStructSize(pStubMsg
, pFormat
);
2249 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2251 assert( fUnmarshall
);
2253 if (!fMustAlloc
&& !*ppMemory
)
2256 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2258 align_pointer(&pStubMsg
->Buffer
, alignment
);
2259 saved_buffer
= pStubMsg
->Buffer
;
2261 pMemory
= *ppMemory
;
2262 count
= pStubMsg
->ActualCount
;
2263 for (i
= 0; i
< count
; i
++)
2264 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
, fMustAlloc
);
2265 return pStubMsg
->Buffer
- saved_buffer
;
2268 ERR("unknown array format 0x%x\n", fc
);
2269 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2273 static inline void array_memory_size(
2274 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
,
2275 unsigned char fHasPointers
)
2277 ULONG i
, count
, SavedMemorySize
;
2278 ULONG bufsize
, memsize
;
2280 unsigned char alignment
;
2285 esize
= *(const WORD
*)(pFormat
+2);
2286 alignment
= pFormat
[1] + 1;
2288 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2290 bufsize
= memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2291 pStubMsg
->MemorySize
+= memsize
;
2293 align_pointer(&pStubMsg
->Buffer
, alignment
);
2295 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2296 safe_buffer_increment(pStubMsg
, bufsize
);
2299 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2301 case RPC_FC_CVARRAY
:
2302 esize
= *(const WORD
*)(pFormat
+2);
2303 alignment
= pFormat
[1] + 1;
2305 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2307 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2309 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2310 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2311 pStubMsg
->MemorySize
+= memsize
;
2313 align_pointer(&pStubMsg
->Buffer
, alignment
);
2315 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2316 safe_buffer_increment(pStubMsg
, bufsize
);
2319 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2321 case RPC_FC_C_CSTRING
:
2322 case RPC_FC_C_WSTRING
:
2323 if (fc
== RPC_FC_C_CSTRING
)
2328 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
2330 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
2332 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2333 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
2334 RpcRaiseException(RPC_S_INVALID_BOUND
);
2336 if (pStubMsg
->Offset
)
2338 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2339 RpcRaiseException(RPC_S_INVALID_BOUND
);
2342 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2343 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2345 validate_string_data(pStubMsg
, bufsize
, esize
);
2347 safe_buffer_increment(pStubMsg
, bufsize
);
2348 pStubMsg
->MemorySize
+= memsize
;
2350 case RPC_FC_BOGUS_ARRAY
:
2351 alignment
= pFormat
[1] + 1;
2352 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2353 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2355 align_pointer(&pStubMsg
->Buffer
, alignment
);
2357 SavedMemorySize
= pStubMsg
->MemorySize
;
2359 esize
= ComplexStructSize(pStubMsg
, pFormat
);
2360 memsize
= safe_multiply(pStubMsg
->MaxCount
, esize
);
2362 count
= pStubMsg
->ActualCount
;
2363 for (i
= 0; i
< count
; i
++)
2364 ComplexStructMemorySize(pStubMsg
, pFormat
, NULL
);
2366 pStubMsg
->MemorySize
= SavedMemorySize
+ memsize
;
2369 ERR("unknown array format 0x%x\n", fc
);
2370 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2374 static inline void array_free(
2375 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
,
2376 unsigned char *pMemory
, PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
2383 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2385 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2387 case RPC_FC_CVARRAY
:
2388 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2389 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2391 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2393 case RPC_FC_C_CSTRING
:
2394 case RPC_FC_C_WSTRING
:
2395 /* No embedded pointers so nothing to do */
2397 case RPC_FC_BOGUS_ARRAY
:
2398 count
= *(const WORD
*)(pFormat
+ 2);
2399 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, count
);
2400 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
2402 count
= pStubMsg
->ActualCount
;
2403 for (i
= 0; i
< count
; i
++)
2404 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
2407 ERR("unknown array format 0x%x\n", fc
);
2408 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2413 * NdrConformantString:
2415 * What MS calls a ConformantString is, in DCE terminology,
2416 * a Varying-Conformant String.
2418 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2419 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2420 * into unmarshalled string)
2421 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2423 * data: CHARTYPE[maxlen]
2425 * ], where CHARTYPE is the appropriate character type (specified externally)
2429 /***********************************************************************
2430 * NdrConformantStringMarshall [RPCRT4.@]
2432 unsigned char *WINAPI
NdrConformantStringMarshall(MIDL_STUB_MESSAGE
*pStubMsg
,
2433 unsigned char *pszMessage
, PFORMAT_STRING pFormat
)
2435 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg
, pszMessage
, pFormat
);
2437 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2438 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2439 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2442 /* allow compiler to optimise inline function by passing constant into
2443 * these functions */
2444 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2445 array_compute_and_write_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pszMessage
,
2447 array_write_variance_and_marshall(RPC_FC_C_CSTRING
, pStubMsg
, pszMessage
,
2448 pFormat
, TRUE
/* fHasPointers */);
2450 array_compute_and_write_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pszMessage
,
2452 array_write_variance_and_marshall(RPC_FC_C_WSTRING
, pStubMsg
, pszMessage
,
2453 pFormat
, TRUE
/* fHasPointers */);
2459 /***********************************************************************
2460 * NdrConformantStringBufferSize [RPCRT4.@]
2462 void WINAPI
NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2463 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
2465 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2467 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2468 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2469 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2472 /* allow compiler to optimise inline function by passing constant into
2473 * these functions */
2474 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2475 array_compute_and_size_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pMemory
,
2477 array_buffer_size(RPC_FC_C_CSTRING
, pStubMsg
, pMemory
, pFormat
,
2478 TRUE
/* fHasPointers */);
2480 array_compute_and_size_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pMemory
,
2482 array_buffer_size(RPC_FC_C_WSTRING
, pStubMsg
, pMemory
, pFormat
,
2483 TRUE
/* fHasPointers */);
2487 /************************************************************************
2488 * NdrConformantStringMemorySize [RPCRT4.@]
2490 ULONG WINAPI
NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
2491 PFORMAT_STRING pFormat
)
2493 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
2495 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2496 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2497 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2500 /* allow compiler to optimise inline function by passing constant into
2501 * these functions */
2502 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2503 array_read_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
);
2504 array_memory_size(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
,
2505 TRUE
/* fHasPointers */);
2507 array_read_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
);
2508 array_memory_size(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
,
2509 TRUE
/* fHasPointers */);
2512 return pStubMsg
->MemorySize
;
2515 /************************************************************************
2516 * NdrConformantStringUnmarshall [RPCRT4.@]
2518 unsigned char *WINAPI
NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2519 unsigned char** ppMemory
, PFORMAT_STRING pFormat
, unsigned char fMustAlloc
)
2521 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2522 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
2524 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2525 ERR("Unhandled string type: %#x\n", *pFormat
);
2526 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2529 /* allow compiler to optimise inline function by passing constant into
2530 * these functions */
2531 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2532 array_read_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
);
2533 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING
, pStubMsg
, ppMemory
,
2534 pFormat
, fMustAlloc
,
2535 TRUE
/* fUseBufferMemoryServer */,
2536 TRUE
/* fUnmarshall */);
2538 array_read_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
);
2539 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING
, pStubMsg
, ppMemory
,
2540 pFormat
, fMustAlloc
,
2541 TRUE
/* fUseBufferMemoryServer */,
2542 TRUE
/* fUnmarshall */);
2548 /***********************************************************************
2549 * NdrNonConformantStringMarshall [RPCRT4.@]
2551 unsigned char * WINAPI
NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2552 unsigned char *pMemory
,
2553 PFORMAT_STRING pFormat
)
2555 ULONG esize
, size
, maxsize
;
2557 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2559 maxsize
= *(const USHORT
*)&pFormat
[2];
2561 if (*pFormat
== RPC_FC_CSTRING
)
2564 const char *str
= (const char *)pMemory
;
2565 while (i
< maxsize
&& str
[i
]) i
++;
2566 TRACE("string=%s\n", debugstr_an(str
, i
));
2567 pStubMsg
->ActualCount
= i
+ 1;
2570 else if (*pFormat
== RPC_FC_WSTRING
)
2573 const WCHAR
*str
= (const WCHAR
*)pMemory
;
2574 while (i
< maxsize
&& str
[i
]) i
++;
2575 TRACE("string=%s\n", debugstr_wn(str
, i
));
2576 pStubMsg
->ActualCount
= i
+ 1;
2581 ERR("Unhandled string type: %#x\n", *pFormat
);
2582 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2585 pStubMsg
->Offset
= 0;
2586 WriteVariance(pStubMsg
);
2588 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2589 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
2594 /***********************************************************************
2595 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2597 unsigned char * WINAPI
NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2598 unsigned char **ppMemory
,
2599 PFORMAT_STRING pFormat
,
2600 unsigned char fMustAlloc
)
2602 ULONG bufsize
, memsize
, esize
, maxsize
;
2604 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2605 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
2607 maxsize
= *(const USHORT
*)&pFormat
[2];
2609 ReadVariance(pStubMsg
, NULL
, maxsize
);
2610 if (pStubMsg
->Offset
)
2612 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2613 RpcRaiseException(RPC_S_INVALID_BOUND
);
2616 if (*pFormat
== RPC_FC_CSTRING
) esize
= 1;
2617 else if (*pFormat
== RPC_FC_WSTRING
) esize
= 2;
2620 ERR("Unhandled string type: %#x\n", *pFormat
);
2621 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2624 memsize
= esize
* maxsize
;
2625 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2627 validate_string_data(pStubMsg
, bufsize
, esize
);
2629 if (!fMustAlloc
&& !*ppMemory
)
2632 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2634 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
2636 if (*pFormat
== RPC_FC_CSTRING
) {
2637 TRACE("string=%s\n", debugstr_an((char*)*ppMemory
, pStubMsg
->ActualCount
));
2639 else if (*pFormat
== RPC_FC_WSTRING
) {
2640 TRACE("string=%s\n", debugstr_wn((LPWSTR
)*ppMemory
, pStubMsg
->ActualCount
));
2646 /***********************************************************************
2647 * NdrNonConformantStringBufferSize [RPCRT4.@]
2649 void WINAPI
NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2650 unsigned char *pMemory
,
2651 PFORMAT_STRING pFormat
)
2653 ULONG esize
, maxsize
;
2655 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2657 maxsize
= *(const USHORT
*)&pFormat
[2];
2659 SizeVariance(pStubMsg
);
2661 if (*pFormat
== RPC_FC_CSTRING
)
2664 const char *str
= (const char *)pMemory
;
2665 while (i
< maxsize
&& str
[i
]) i
++;
2666 TRACE("string=%s\n", debugstr_an(str
, i
));
2667 pStubMsg
->ActualCount
= i
+ 1;
2670 else if (*pFormat
== RPC_FC_WSTRING
)
2673 const WCHAR
*str
= (const WCHAR
*)pMemory
;
2674 while (i
< maxsize
&& str
[i
]) i
++;
2675 TRACE("string=%s\n", debugstr_wn(str
, i
));
2676 pStubMsg
->ActualCount
= i
+ 1;
2681 ERR("Unhandled string type: %#x\n", *pFormat
);
2682 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2685 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
2688 /***********************************************************************
2689 * NdrNonConformantStringMemorySize [RPCRT4.@]
2691 ULONG WINAPI
NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2692 PFORMAT_STRING pFormat
)
2694 ULONG bufsize
, memsize
, esize
, maxsize
;
2696 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
2698 maxsize
= *(const USHORT
*)&pFormat
[2];
2700 ReadVariance(pStubMsg
, NULL
, maxsize
);
2702 if (pStubMsg
->Offset
)
2704 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2705 RpcRaiseException(RPC_S_INVALID_BOUND
);
2708 if (*pFormat
== RPC_FC_CSTRING
) esize
= 1;
2709 else if (*pFormat
== RPC_FC_WSTRING
) esize
= 2;
2712 ERR("Unhandled string type: %#x\n", *pFormat
);
2713 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2716 memsize
= esize
* maxsize
;
2717 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2719 validate_string_data(pStubMsg
, bufsize
, esize
);
2721 safe_buffer_increment(pStubMsg
, bufsize
);
2722 pStubMsg
->MemorySize
+= memsize
;
2724 return pStubMsg
->MemorySize
;
2729 #include "pshpack1.h"
2733 unsigned char flags_type
; /* flags in upper nibble, type in lower nibble */
2737 #include "poppack.h"
2739 static ULONG
EmbeddedComplexSize(MIDL_STUB_MESSAGE
*pStubMsg
,
2740 PFORMAT_STRING pFormat
)
2744 case RPC_FC_PSTRUCT
:
2745 case RPC_FC_CSTRUCT
:
2746 case RPC_FC_BOGUS_STRUCT
:
2747 case RPC_FC_SMFARRAY
:
2748 case RPC_FC_SMVARRAY
:
2749 case RPC_FC_CSTRING
:
2750 return *(const WORD
*)&pFormat
[2];
2751 case RPC_FC_USER_MARSHAL
:
2752 return *(const WORD
*)&pFormat
[4];
2753 case RPC_FC_RANGE
: {
2754 switch (((const NDR_RANGE
*)pFormat
)->flags_type
& 0xf) {
2759 return sizeof(UCHAR
);
2763 return sizeof(USHORT
);
2767 case RPC_FC_INT3264
:
2768 case RPC_FC_UINT3264
:
2769 return sizeof(ULONG
);
2771 return sizeof(float);
2773 return sizeof(double);
2775 return sizeof(ULONGLONG
);
2777 return sizeof(UINT
);
2779 ERR("unknown type 0x%x\n", ((const NDR_RANGE
*)pFormat
)->flags_type
& 0xf);
2780 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2783 case RPC_FC_NON_ENCAPSULATED_UNION
:
2785 pFormat
= SkipConformance(pStubMsg
, pFormat
);
2786 pFormat
+= *(const SHORT
*)pFormat
;
2787 return *(const SHORT
*)pFormat
;
2789 return sizeof(void *);
2790 case RPC_FC_WSTRING
:
2791 return *(const WORD
*)&pFormat
[2] * 2;
2793 FIXME("unhandled embedded type %02x\n", *pFormat
);
2799 static ULONG
EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2800 PFORMAT_STRING pFormat
)
2802 NDR_MEMORYSIZE m
= NdrMemorySizer
[*pFormat
& NDR_TABLE_MASK
];
2806 FIXME("no memorysizer for data type=%02x\n", *pFormat
);
2810 return m(pStubMsg
, pFormat
);
2814 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2815 unsigned char *pMemory
,
2816 PFORMAT_STRING pFormat
,
2817 PFORMAT_STRING pPointer
)
2819 PFORMAT_STRING desc
;
2823 while (*pFormat
!= RPC_FC_END
) {
2829 TRACE("byte=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2830 safe_copy_to_buffer(pStubMsg
, pMemory
, 1);
2836 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2837 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
2842 USHORT val
= *(DWORD
*)pMemory
;
2843 TRACE("enum16=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2844 if (32767 < *(DWORD
*)pMemory
)
2845 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
2846 safe_copy_to_buffer(pStubMsg
, &val
, 2);
2853 TRACE("long=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2854 safe_copy_to_buffer(pStubMsg
, pMemory
, 4);
2857 case RPC_FC_INT3264
:
2858 case RPC_FC_UINT3264
:
2860 UINT val
= *(UINT_PTR
*)pMemory
;
2861 TRACE("int3264=%ld <= %p\n", *(UINT_PTR
*)pMemory
, pMemory
);
2862 safe_copy_to_buffer(pStubMsg
, &val
, sizeof(UINT
));
2863 pMemory
+= sizeof(UINT_PTR
);
2867 TRACE("float=%f <= %p\n", *(float*)pMemory
, pMemory
);
2868 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
2869 pMemory
+= sizeof(float);
2872 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2873 safe_copy_to_buffer(pStubMsg
, pMemory
, 8);
2877 TRACE("double=%f <= %p\n", *(double*)pMemory
, pMemory
);
2878 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
2879 pMemory
+= sizeof(double);
2885 case RPC_FC_POINTER
:
2887 unsigned char *saved_buffer
;
2888 BOOL pointer_buffer_mark_set
= FALSE
;
2889 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
2890 TRACE("pStubMsg->Buffer before %p\n", pStubMsg
->Buffer
);
2891 if (*pFormat
!= RPC_FC_POINTER
)
2893 if (*pPointer
!= RPC_FC_RP
)
2894 align_pointer_clear(&pStubMsg
->Buffer
, 4);
2895 saved_buffer
= pStubMsg
->Buffer
;
2896 if (pStubMsg
->PointerBufferMark
)
2898 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2899 pStubMsg
->PointerBufferMark
= NULL
;
2900 pointer_buffer_mark_set
= TRUE
;
2902 else if (*pPointer
!= RPC_FC_RP
)
2903 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2904 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char**)pMemory
, pPointer
);
2905 if (pointer_buffer_mark_set
)
2907 STD_OVERFLOW_CHECK(pStubMsg
);
2908 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2909 pStubMsg
->Buffer
= saved_buffer
;
2910 if (*pPointer
!= RPC_FC_RP
)
2911 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2913 TRACE("pStubMsg->Buffer after %p\n", pStubMsg
->Buffer
);
2914 if (*pFormat
== RPC_FC_POINTER
)
2918 pMemory
+= sizeof(void *);
2921 case RPC_FC_ALIGNM2
:
2922 align_pointer(&pMemory
, 2);
2924 case RPC_FC_ALIGNM4
:
2925 align_pointer(&pMemory
, 4);
2927 case RPC_FC_ALIGNM8
:
2928 align_pointer(&pMemory
, 8);
2930 case RPC_FC_STRUCTPAD1
:
2931 case RPC_FC_STRUCTPAD2
:
2932 case RPC_FC_STRUCTPAD3
:
2933 case RPC_FC_STRUCTPAD4
:
2934 case RPC_FC_STRUCTPAD5
:
2935 case RPC_FC_STRUCTPAD6
:
2936 case RPC_FC_STRUCTPAD7
:
2937 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2939 case RPC_FC_EMBEDDED_COMPLEX
:
2940 pMemory
+= pFormat
[1];
2942 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2943 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2944 TRACE("embedded complex (size=%d) <= %p\n", size
, pMemory
);
2945 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
2948 /* for some reason interface pointers aren't generated as
2949 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2950 * they still need the derefencing treatment that pointers are
2952 if (*desc
== RPC_FC_IP
)
2953 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2955 m(pStubMsg
, pMemory
, desc
);
2957 else FIXME("no marshaller for embedded type %02x\n", *desc
);
2964 FIXME("unhandled format 0x%02x\n", *pFormat
);
2972 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2973 unsigned char *pMemory
,
2974 PFORMAT_STRING pFormat
,
2975 PFORMAT_STRING pPointer
,
2976 unsigned char fMustAlloc
)
2978 PFORMAT_STRING desc
;
2982 while (*pFormat
!= RPC_FC_END
) {
2988 safe_copy_from_buffer(pStubMsg
, pMemory
, 1);
2989 TRACE("byte=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2995 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
2996 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
3002 safe_copy_from_buffer(pStubMsg
, &val
, 2);
3003 *(DWORD
*)pMemory
= val
;
3004 TRACE("enum16=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
3005 if (32767 < *(DWORD
*)pMemory
)
3006 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
3013 safe_copy_from_buffer(pStubMsg
, pMemory
, 4);
3014 TRACE("long=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
3017 case RPC_FC_INT3264
:
3020 safe_copy_from_buffer(pStubMsg
, &val
, 4);
3021 *(INT_PTR
*)pMemory
= val
;
3022 TRACE("int3264=%ld => %p\n", *(INT_PTR
*)pMemory
, pMemory
);
3023 pMemory
+= sizeof(INT_PTR
);
3026 case RPC_FC_UINT3264
:
3029 safe_copy_from_buffer(pStubMsg
, &val
, 4);
3030 *(UINT_PTR
*)pMemory
= val
;
3031 TRACE("uint3264=%ld => %p\n", *(UINT_PTR
*)pMemory
, pMemory
);
3032 pMemory
+= sizeof(UINT_PTR
);
3036 safe_copy_from_buffer(pStubMsg
, pMemory
, sizeof(float));
3037 TRACE("float=%f => %p\n", *(float*)pMemory
, pMemory
);
3038 pMemory
+= sizeof(float);
3041 safe_copy_from_buffer(pStubMsg
, pMemory
, 8);
3042 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
3046 safe_copy_from_buffer(pStubMsg
, pMemory
, sizeof(double));
3047 TRACE("double=%f => %p\n", *(double*)pMemory
, pMemory
);
3048 pMemory
+= sizeof(double);
3054 case RPC_FC_POINTER
:
3056 unsigned char *saved_buffer
;
3057 BOOL pointer_buffer_mark_set
= FALSE
;
3058 TRACE("pointer => %p\n", pMemory
);
3059 if (*pFormat
!= RPC_FC_POINTER
)
3061 if (*pPointer
!= RPC_FC_RP
)
3062 align_pointer(&pStubMsg
->Buffer
, 4);
3063 saved_buffer
= pStubMsg
->Buffer
;
3064 if (pStubMsg
->PointerBufferMark
)
3066 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3067 pStubMsg
->PointerBufferMark
= NULL
;
3068 pointer_buffer_mark_set
= TRUE
;
3070 else if (*pPointer
!= RPC_FC_RP
)
3071 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3073 PointerUnmarshall(pStubMsg
, saved_buffer
, (unsigned char**)pMemory
, *(unsigned char**)pMemory
, pPointer
, fMustAlloc
);
3074 if (pointer_buffer_mark_set
)
3076 STD_OVERFLOW_CHECK(pStubMsg
);
3077 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3078 pStubMsg
->Buffer
= saved_buffer
;
3079 if (*pPointer
!= RPC_FC_RP
)
3080 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3082 if (*pFormat
== RPC_FC_POINTER
)
3086 pMemory
+= sizeof(void *);
3089 case RPC_FC_ALIGNM2
:
3090 align_pointer_clear(&pMemory
, 2);
3092 case RPC_FC_ALIGNM4
:
3093 align_pointer_clear(&pMemory
, 4);
3095 case RPC_FC_ALIGNM8
:
3096 align_pointer_clear(&pMemory
, 8);
3098 case RPC_FC_STRUCTPAD1
:
3099 case RPC_FC_STRUCTPAD2
:
3100 case RPC_FC_STRUCTPAD3
:
3101 case RPC_FC_STRUCTPAD4
:
3102 case RPC_FC_STRUCTPAD5
:
3103 case RPC_FC_STRUCTPAD6
:
3104 case RPC_FC_STRUCTPAD7
:
3105 memset(pMemory
, 0, *pFormat
- RPC_FC_STRUCTPAD1
+ 1);
3106 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3108 case RPC_FC_EMBEDDED_COMPLEX
:
3109 pMemory
+= pFormat
[1];
3111 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3112 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3113 TRACE("embedded complex (size=%d) => %p\n", size
, pMemory
);
3115 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
3116 * since the type is part of the memory block that is encompassed by
3117 * the whole complex type. Memory is forced to allocate when pointers
3118 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
3119 * clearing the memory we pass in to the unmarshaller */
3120 memset(pMemory
, 0, size
);
3121 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
3124 /* for some reason interface pointers aren't generated as
3125 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3126 * they still need the derefencing treatment that pointers are
3128 if (*desc
== RPC_FC_IP
)
3129 m(pStubMsg
, (unsigned char **)pMemory
, desc
, FALSE
);
3131 m(pStubMsg
, &pMemory
, desc
, FALSE
);
3133 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
3140 FIXME("unhandled format %d\n", *pFormat
);
3148 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3149 unsigned char *pMemory
,
3150 PFORMAT_STRING pFormat
,
3151 PFORMAT_STRING pPointer
)
3153 PFORMAT_STRING desc
;
3157 while (*pFormat
!= RPC_FC_END
) {
3163 safe_buffer_length_increment(pStubMsg
, 1);
3169 safe_buffer_length_increment(pStubMsg
, 2);
3173 safe_buffer_length_increment(pStubMsg
, 2);
3180 safe_buffer_length_increment(pStubMsg
, 4);
3183 case RPC_FC_INT3264
:
3184 case RPC_FC_UINT3264
:
3185 safe_buffer_length_increment(pStubMsg
, 4);
3186 pMemory
+= sizeof(INT_PTR
);
3190 safe_buffer_length_increment(pStubMsg
, 8);
3197 case RPC_FC_POINTER
:
3198 if (*pFormat
!= RPC_FC_POINTER
)
3200 if (!pStubMsg
->IgnoreEmbeddedPointers
)
3202 int saved_buffer_length
= pStubMsg
->BufferLength
;
3203 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3204 pStubMsg
->PointerLength
= 0;
3205 if(!pStubMsg
->BufferLength
)
3206 ERR("BufferLength == 0??\n");
3207 PointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
3208 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3209 pStubMsg
->BufferLength
= saved_buffer_length
;
3211 if (*pPointer
!= RPC_FC_RP
)
3213 align_length(&pStubMsg
->BufferLength
, 4);
3214 safe_buffer_length_increment(pStubMsg
, 4);
3216 if (*pFormat
== RPC_FC_POINTER
)
3220 pMemory
+= sizeof(void*);
3222 case RPC_FC_ALIGNM2
:
3223 align_pointer(&pMemory
, 2);
3225 case RPC_FC_ALIGNM4
:
3226 align_pointer(&pMemory
, 4);
3228 case RPC_FC_ALIGNM8
:
3229 align_pointer(&pMemory
, 8);
3231 case RPC_FC_STRUCTPAD1
:
3232 case RPC_FC_STRUCTPAD2
:
3233 case RPC_FC_STRUCTPAD3
:
3234 case RPC_FC_STRUCTPAD4
:
3235 case RPC_FC_STRUCTPAD5
:
3236 case RPC_FC_STRUCTPAD6
:
3237 case RPC_FC_STRUCTPAD7
:
3238 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3240 case RPC_FC_EMBEDDED_COMPLEX
:
3241 pMemory
+= pFormat
[1];
3243 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3244 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3245 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
3248 /* for some reason interface pointers aren't generated as
3249 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3250 * they still need the derefencing treatment that pointers are
3252 if (*desc
== RPC_FC_IP
)
3253 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
3255 m(pStubMsg
, pMemory
, desc
);
3257 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
3264 FIXME("unhandled format 0x%02x\n", *pFormat
);
3272 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
3273 unsigned char *pMemory
,
3274 PFORMAT_STRING pFormat
,
3275 PFORMAT_STRING pPointer
)
3277 PFORMAT_STRING desc
;
3281 while (*pFormat
!= RPC_FC_END
) {
3301 case RPC_FC_INT3264
:
3302 case RPC_FC_UINT3264
:
3303 pMemory
+= sizeof(INT_PTR
);
3313 case RPC_FC_POINTER
:
3314 if (*pFormat
!= RPC_FC_POINTER
)
3316 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
3317 if (*pFormat
== RPC_FC_POINTER
)
3321 pMemory
+= sizeof(void *);
3323 case RPC_FC_ALIGNM2
:
3324 align_pointer(&pMemory
, 2);
3326 case RPC_FC_ALIGNM4
:
3327 align_pointer(&pMemory
, 4);
3329 case RPC_FC_ALIGNM8
:
3330 align_pointer(&pMemory
, 8);
3332 case RPC_FC_STRUCTPAD1
:
3333 case RPC_FC_STRUCTPAD2
:
3334 case RPC_FC_STRUCTPAD3
:
3335 case RPC_FC_STRUCTPAD4
:
3336 case RPC_FC_STRUCTPAD5
:
3337 case RPC_FC_STRUCTPAD6
:
3338 case RPC_FC_STRUCTPAD7
:
3339 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3341 case RPC_FC_EMBEDDED_COMPLEX
:
3342 pMemory
+= pFormat
[1];
3344 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3345 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3346 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
3349 /* for some reason interface pointers aren't generated as
3350 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3351 * they still need the derefencing treatment that pointers are
3353 if (*desc
== RPC_FC_IP
)
3354 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
3356 m(pStubMsg
, pMemory
, desc
);
3364 FIXME("unhandled format 0x%02x\n", *pFormat
);
3372 static ULONG
ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3373 PFORMAT_STRING pFormat
,
3374 PFORMAT_STRING pPointer
)
3376 PFORMAT_STRING desc
;
3379 while (*pFormat
!= RPC_FC_END
) {
3386 safe_buffer_increment(pStubMsg
, 1);
3392 safe_buffer_increment(pStubMsg
, 2);
3396 safe_buffer_increment(pStubMsg
, 2);
3403 safe_buffer_increment(pStubMsg
, 4);
3405 case RPC_FC_INT3264
:
3406 case RPC_FC_UINT3264
:
3407 size
+= sizeof(INT_PTR
);
3408 safe_buffer_increment(pStubMsg
, 4);
3413 safe_buffer_increment(pStubMsg
, 8);
3419 case RPC_FC_POINTER
:
3421 unsigned char *saved_buffer
;
3422 BOOL pointer_buffer_mark_set
= FALSE
;
3423 if (*pFormat
!= RPC_FC_POINTER
)
3425 if (*pPointer
!= RPC_FC_RP
)
3426 align_pointer(&pStubMsg
->Buffer
, 4);
3427 saved_buffer
= pStubMsg
->Buffer
;
3428 if (pStubMsg
->PointerBufferMark
)
3430 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3431 pStubMsg
->PointerBufferMark
= NULL
;
3432 pointer_buffer_mark_set
= TRUE
;
3434 else if (*pPointer
!= RPC_FC_RP
)
3435 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3437 if (!pStubMsg
->IgnoreEmbeddedPointers
)
3438 PointerMemorySize(pStubMsg
, saved_buffer
, pPointer
);
3439 if (pointer_buffer_mark_set
)
3441 STD_OVERFLOW_CHECK(pStubMsg
);
3442 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3443 pStubMsg
->Buffer
= saved_buffer
;
3444 if (*pPointer
!= RPC_FC_RP
)
3445 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3447 if (*pFormat
== RPC_FC_POINTER
)
3451 size
+= sizeof(void *);
3454 case RPC_FC_ALIGNM2
:
3455 align_length(&size
, 2);
3457 case RPC_FC_ALIGNM4
:
3458 align_length(&size
, 4);
3460 case RPC_FC_ALIGNM8
:
3461 align_length(&size
, 8);
3463 case RPC_FC_STRUCTPAD1
:
3464 case RPC_FC_STRUCTPAD2
:
3465 case RPC_FC_STRUCTPAD3
:
3466 case RPC_FC_STRUCTPAD4
:
3467 case RPC_FC_STRUCTPAD5
:
3468 case RPC_FC_STRUCTPAD6
:
3469 case RPC_FC_STRUCTPAD7
:
3470 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3472 case RPC_FC_EMBEDDED_COMPLEX
:
3475 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3476 size
+= EmbeddedComplexMemorySize(pStubMsg
, desc
);
3482 FIXME("unhandled format 0x%02x\n", *pFormat
);
3490 ULONG
ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
3492 PFORMAT_STRING desc
;
3495 while (*pFormat
!= RPC_FC_END
) {
3515 case RPC_FC_INT3264
:
3516 case RPC_FC_UINT3264
:
3517 size
+= sizeof(INT_PTR
);
3527 case RPC_FC_POINTER
:
3528 size
+= sizeof(void *);
3529 if (*pFormat
!= RPC_FC_POINTER
)
3532 case RPC_FC_ALIGNM2
:
3533 align_length(&size
, 2);
3535 case RPC_FC_ALIGNM4
:
3536 align_length(&size
, 4);
3538 case RPC_FC_ALIGNM8
:
3539 align_length(&size
, 8);
3541 case RPC_FC_STRUCTPAD1
:
3542 case RPC_FC_STRUCTPAD2
:
3543 case RPC_FC_STRUCTPAD3
:
3544 case RPC_FC_STRUCTPAD4
:
3545 case RPC_FC_STRUCTPAD5
:
3546 case RPC_FC_STRUCTPAD6
:
3547 case RPC_FC_STRUCTPAD7
:
3548 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3550 case RPC_FC_EMBEDDED_COMPLEX
:
3553 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3554 size
+= EmbeddedComplexSize(pStubMsg
, desc
);
3560 FIXME("unhandled format 0x%02x\n", *pFormat
);
3568 /***********************************************************************
3569 * NdrComplexStructMarshall [RPCRT4.@]
3571 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3572 unsigned char *pMemory
,
3573 PFORMAT_STRING pFormat
)
3575 PFORMAT_STRING conf_array
= NULL
;
3576 PFORMAT_STRING pointer_desc
= NULL
;
3577 unsigned char *OldMemory
= pStubMsg
->Memory
;
3578 BOOL pointer_buffer_mark_set
= FALSE
;
3580 ULONG max_count
= 0;
3583 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3585 if (!pStubMsg
->PointerBufferMark
)
3587 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3588 /* save buffer length */
3589 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
3591 /* get the buffer pointer after complex array data, but before
3593 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
;
3594 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3595 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
3596 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3598 /* save it for use by embedded pointer code later */
3599 pStubMsg
->PointerBufferMark
= (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
;
3600 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->PointerBufferMark
- pStubMsg
->Buffer
));
3601 pointer_buffer_mark_set
= TRUE
;
3603 /* restore the original buffer length */
3604 pStubMsg
->BufferLength
= saved_buffer_length
;
3607 align_pointer_clear(&pStubMsg
->Buffer
, pFormat
[1] + 1);
3610 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3612 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3615 pStubMsg
->Memory
= pMemory
;
3619 ULONG struct_size
= ComplexStructSize(pStubMsg
, pFormat
);
3620 array_compute_and_write_conformance(conf_array
[0], pStubMsg
,
3621 pMemory
+ struct_size
, conf_array
);
3622 /* these could be changed in ComplexMarshall so save them for later */
3623 max_count
= pStubMsg
->MaxCount
;
3624 count
= pStubMsg
->ActualCount
;
3625 offset
= pStubMsg
->Offset
;
3628 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3632 pStubMsg
->MaxCount
= max_count
;
3633 pStubMsg
->ActualCount
= count
;
3634 pStubMsg
->Offset
= offset
;
3635 array_write_variance_and_marshall(conf_array
[0], pStubMsg
, pMemory
,
3636 conf_array
, TRUE
/* fHasPointers */);
3639 pStubMsg
->Memory
= OldMemory
;
3641 if (pointer_buffer_mark_set
)
3643 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3644 pStubMsg
->PointerBufferMark
= NULL
;
3647 STD_OVERFLOW_CHECK(pStubMsg
);
3652 /***********************************************************************
3653 * NdrComplexStructUnmarshall [RPCRT4.@]
3655 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3656 unsigned char **ppMemory
,
3657 PFORMAT_STRING pFormat
,
3658 unsigned char fMustAlloc
)
3660 unsigned size
= *(const WORD
*)(pFormat
+2);
3661 PFORMAT_STRING conf_array
= NULL
;
3662 PFORMAT_STRING pointer_desc
= NULL
;
3663 unsigned char *pMemory
;
3664 BOOL pointer_buffer_mark_set
= FALSE
;
3666 ULONG max_count
= 0;
3668 ULONG array_size
= 0;
3670 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3672 if (!pStubMsg
->PointerBufferMark
)
3674 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3675 /* save buffer pointer */
3676 unsigned char *saved_buffer
= pStubMsg
->Buffer
;
3678 /* get the buffer pointer after complex array data, but before
3680 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3681 NdrComplexStructMemorySize(pStubMsg
, pFormat
);
3682 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3684 /* save it for use by embedded pointer code later */
3685 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3686 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->PointerBufferMark
- saved_buffer
));
3687 pointer_buffer_mark_set
= TRUE
;
3689 /* restore the original buffer */
3690 pStubMsg
->Buffer
= saved_buffer
;
3693 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
3696 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3698 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3703 array_size
= array_read_conformance(conf_array
[0], pStubMsg
, conf_array
);
3706 /* these could be changed in ComplexMarshall so save them for later */
3707 max_count
= pStubMsg
->MaxCount
;
3708 count
= pStubMsg
->ActualCount
;
3709 offset
= pStubMsg
->Offset
;
3712 if (!fMustAlloc
&& !*ppMemory
)
3715 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3717 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
, fMustAlloc
);
3721 pStubMsg
->MaxCount
= max_count
;
3722 pStubMsg
->ActualCount
= count
;
3723 pStubMsg
->Offset
= offset
;
3725 memset(pMemory
, 0, array_size
);
3726 array_read_variance_and_unmarshall(conf_array
[0], pStubMsg
, &pMemory
,
3728 FALSE
/* fUseBufferMemoryServer */,
3729 TRUE
/* fUnmarshall */);
3732 if (pointer_buffer_mark_set
)
3734 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3735 pStubMsg
->PointerBufferMark
= NULL
;
3741 /***********************************************************************
3742 * NdrComplexStructBufferSize [RPCRT4.@]
3744 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3745 unsigned char *pMemory
,
3746 PFORMAT_STRING pFormat
)
3748 PFORMAT_STRING conf_array
= NULL
;
3749 PFORMAT_STRING pointer_desc
= NULL
;
3750 unsigned char *OldMemory
= pStubMsg
->Memory
;
3751 int pointer_length_set
= 0;
3753 ULONG max_count
= 0;
3756 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3758 align_length(&pStubMsg
->BufferLength
, pFormat
[1] + 1);
3760 if(!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
3762 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3763 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
3765 /* get the buffer length after complex struct data, but before
3767 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3768 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
3769 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3771 /* save it for use by embedded pointer code later */
3772 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3773 pointer_length_set
= 1;
3774 TRACE("difference = 0x%x\n", pStubMsg
->PointerLength
- saved_buffer_length
);
3776 /* restore the original buffer length */
3777 pStubMsg
->BufferLength
= saved_buffer_length
;
3781 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3783 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3786 pStubMsg
->Memory
= pMemory
;
3790 ULONG struct_size
= ComplexStructSize(pStubMsg
, pFormat
);
3791 array_compute_and_size_conformance(conf_array
[0], pStubMsg
, pMemory
+ struct_size
,
3794 /* these could be changed in ComplexMarshall so save them for later */
3795 max_count
= pStubMsg
->MaxCount
;
3796 count
= pStubMsg
->ActualCount
;
3797 offset
= pStubMsg
->Offset
;
3800 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3804 pStubMsg
->MaxCount
= max_count
;
3805 pStubMsg
->ActualCount
= count
;
3806 pStubMsg
->Offset
= offset
;
3807 array_buffer_size(conf_array
[0], pStubMsg
, pMemory
, conf_array
,
3808 TRUE
/* fHasPointers */);
3811 pStubMsg
->Memory
= OldMemory
;
3813 if(pointer_length_set
)
3815 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3816 pStubMsg
->PointerLength
= 0;
3821 /***********************************************************************
3822 * NdrComplexStructMemorySize [RPCRT4.@]
3824 ULONG WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3825 PFORMAT_STRING pFormat
)
3827 unsigned size
= *(const WORD
*)(pFormat
+2);
3828 PFORMAT_STRING conf_array
= NULL
;
3829 PFORMAT_STRING pointer_desc
= NULL
;
3831 ULONG max_count
= 0;
3834 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3836 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
3839 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3841 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3846 array_read_conformance(conf_array
[0], pStubMsg
, conf_array
);
3848 /* these could be changed in ComplexStructMemorySize so save them for
3850 max_count
= pStubMsg
->MaxCount
;
3851 count
= pStubMsg
->ActualCount
;
3852 offset
= pStubMsg
->Offset
;
3855 ComplexStructMemorySize(pStubMsg
, pFormat
, pointer_desc
);
3859 pStubMsg
->MaxCount
= max_count
;
3860 pStubMsg
->ActualCount
= count
;
3861 pStubMsg
->Offset
= offset
;
3862 array_memory_size(conf_array
[0], pStubMsg
, conf_array
,
3863 TRUE
/* fHasPointers */);
3869 /***********************************************************************
3870 * NdrComplexStructFree [RPCRT4.@]
3872 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3873 unsigned char *pMemory
,
3874 PFORMAT_STRING pFormat
)
3876 PFORMAT_STRING conf_array
= NULL
;
3877 PFORMAT_STRING pointer_desc
= NULL
;
3878 unsigned char *OldMemory
= pStubMsg
->Memory
;
3880 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3883 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3885 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3888 pStubMsg
->Memory
= pMemory
;
3890 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3893 array_free(conf_array
[0], pStubMsg
, pMemory
, conf_array
,
3894 TRUE
/* fHasPointers */);
3896 pStubMsg
->Memory
= OldMemory
;
3899 /***********************************************************************
3900 * NdrConformantArrayMarshall [RPCRT4.@]
3902 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3903 unsigned char *pMemory
,
3904 PFORMAT_STRING pFormat
)
3906 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3907 if (pFormat
[0] != RPC_FC_CARRAY
)
3909 ERR("invalid format = 0x%x\n", pFormat
[0]);
3910 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3913 array_compute_and_write_conformance(RPC_FC_CARRAY
, pStubMsg
, pMemory
,
3915 array_write_variance_and_marshall(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3916 TRUE
/* fHasPointers */);
3921 /***********************************************************************
3922 * NdrConformantArrayUnmarshall [RPCRT4.@]
3924 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3925 unsigned char **ppMemory
,
3926 PFORMAT_STRING pFormat
,
3927 unsigned char fMustAlloc
)
3929 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3930 if (pFormat
[0] != RPC_FC_CARRAY
)
3932 ERR("invalid format = 0x%x\n", pFormat
[0]);
3933 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3936 array_read_conformance(RPC_FC_CARRAY
, pStubMsg
, pFormat
);
3937 array_read_variance_and_unmarshall(RPC_FC_CARRAY
, pStubMsg
, ppMemory
, pFormat
,
3939 TRUE
/* fUseBufferMemoryServer */,
3940 TRUE
/* fUnmarshall */);
3945 /***********************************************************************
3946 * NdrConformantArrayBufferSize [RPCRT4.@]
3948 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3949 unsigned char *pMemory
,
3950 PFORMAT_STRING pFormat
)
3952 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3953 if (pFormat
[0] != RPC_FC_CARRAY
)
3955 ERR("invalid format = 0x%x\n", pFormat
[0]);
3956 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3959 array_compute_and_size_conformance(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
);
3960 array_buffer_size(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3961 TRUE
/* fHasPointers */);
3964 /***********************************************************************
3965 * NdrConformantArrayMemorySize [RPCRT4.@]
3967 ULONG WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3968 PFORMAT_STRING pFormat
)
3970 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3971 if (pFormat
[0] != RPC_FC_CARRAY
)
3973 ERR("invalid format = 0x%x\n", pFormat
[0]);
3974 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3977 array_read_conformance(RPC_FC_CARRAY
, pStubMsg
, pFormat
);
3978 array_memory_size(RPC_FC_CARRAY
, pStubMsg
, pFormat
, TRUE
/* fHasPointers */);
3980 return pStubMsg
->MemorySize
;
3983 /***********************************************************************
3984 * NdrConformantArrayFree [RPCRT4.@]
3986 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3987 unsigned char *pMemory
,
3988 PFORMAT_STRING pFormat
)
3990 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3991 if (pFormat
[0] != RPC_FC_CARRAY
)
3993 ERR("invalid format = 0x%x\n", pFormat
[0]);
3994 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3997 array_free(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3998 TRUE
/* fHasPointers */);
4002 /***********************************************************************
4003 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
4005 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
4006 unsigned char* pMemory
,
4007 PFORMAT_STRING pFormat
)
4009 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4011 if (pFormat
[0] != RPC_FC_CVARRAY
)
4013 ERR("invalid format type %x\n", pFormat
[0]);
4014 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4018 array_compute_and_write_conformance(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
4020 array_write_variance_and_marshall(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
4021 pFormat
, TRUE
/* fHasPointers */);
4027 /***********************************************************************
4028 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
4030 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
4031 unsigned char** ppMemory
,
4032 PFORMAT_STRING pFormat
,
4033 unsigned char fMustAlloc
)
4035 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4037 if (pFormat
[0] != RPC_FC_CVARRAY
)
4039 ERR("invalid format type %x\n", pFormat
[0]);
4040 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4044 array_read_conformance(RPC_FC_CVARRAY
, pStubMsg
, pFormat
);
4045 array_read_variance_and_unmarshall(RPC_FC_CVARRAY
, pStubMsg
, ppMemory
,
4046 pFormat
, fMustAlloc
,
4047 TRUE
/* fUseBufferMemoryServer */,
4048 TRUE
/* fUnmarshall */);
4054 /***********************************************************************
4055 * NdrConformantVaryingArrayFree [RPCRT4.@]
4057 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
4058 unsigned char* pMemory
,
4059 PFORMAT_STRING pFormat
)
4061 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4063 if (pFormat
[0] != RPC_FC_CVARRAY
)
4065 ERR("invalid format type %x\n", pFormat
[0]);
4066 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4070 array_free(RPC_FC_CVARRAY
, pStubMsg
, pMemory
, pFormat
,
4071 TRUE
/* fHasPointers */);
4075 /***********************************************************************
4076 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
4078 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
4079 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
4081 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4083 if (pFormat
[0] != RPC_FC_CVARRAY
)
4085 ERR("invalid format type %x\n", pFormat
[0]);
4086 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4090 array_compute_and_size_conformance(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
4092 array_buffer_size(RPC_FC_CVARRAY
, pStubMsg
, pMemory
, pFormat
,
4093 TRUE
/* fHasPointers */);
4097 /***********************************************************************
4098 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
4100 ULONG WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
4101 PFORMAT_STRING pFormat
)
4103 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4105 if (pFormat
[0] != RPC_FC_CVARRAY
)
4107 ERR("invalid format type %x\n", pFormat
[0]);
4108 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4109 return pStubMsg
->MemorySize
;
4112 array_read_conformance(RPC_FC_CVARRAY
, pStubMsg
, pFormat
);
4113 array_memory_size(RPC_FC_CVARRAY
, pStubMsg
, pFormat
,
4114 TRUE
/* fHasPointers */);
4116 return pStubMsg
->MemorySize
;
4120 /***********************************************************************
4121 * NdrComplexArrayMarshall [RPCRT4.@]
4123 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4124 unsigned char *pMemory
,
4125 PFORMAT_STRING pFormat
)
4127 BOOL pointer_buffer_mark_set
= FALSE
;
4129 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4131 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4133 ERR("invalid format type %x\n", pFormat
[0]);
4134 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4138 if (!pStubMsg
->PointerBufferMark
)
4140 /* save buffer fields that may be changed by buffer sizer functions
4141 * and that may be needed later on */
4142 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
4143 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
4144 ULONG_PTR saved_max_count
= pStubMsg
->MaxCount
;
4145 ULONG saved_offset
= pStubMsg
->Offset
;
4146 ULONG saved_actual_count
= pStubMsg
->ActualCount
;
4148 /* get the buffer pointer after complex array data, but before
4150 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
;
4151 pStubMsg
->IgnoreEmbeddedPointers
= 1;
4152 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
4153 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
4155 /* save it for use by embedded pointer code later */
4156 pStubMsg
->PointerBufferMark
= (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
;
4157 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
));
4158 pointer_buffer_mark_set
= TRUE
;
4160 /* restore fields */
4161 pStubMsg
->ActualCount
= saved_actual_count
;
4162 pStubMsg
->Offset
= saved_offset
;
4163 pStubMsg
->MaxCount
= saved_max_count
;
4164 pStubMsg
->BufferLength
= saved_buffer_length
;
4167 array_compute_and_write_conformance(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pMemory
, pFormat
);
4168 array_write_variance_and_marshall(RPC_FC_BOGUS_ARRAY
, pStubMsg
,
4169 pMemory
, pFormat
, TRUE
/* fHasPointers */);
4171 STD_OVERFLOW_CHECK(pStubMsg
);
4173 if (pointer_buffer_mark_set
)
4175 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4176 pStubMsg
->PointerBufferMark
= NULL
;
4182 /***********************************************************************
4183 * NdrComplexArrayUnmarshall [RPCRT4.@]
4185 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4186 unsigned char **ppMemory
,
4187 PFORMAT_STRING pFormat
,
4188 unsigned char fMustAlloc
)
4190 unsigned char *saved_buffer
;
4191 BOOL pointer_buffer_mark_set
= FALSE
;
4192 int saved_ignore_embedded
;
4194 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4196 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4198 ERR("invalid format type %x\n", pFormat
[0]);
4199 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4203 saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
4204 /* save buffer pointer */
4205 saved_buffer
= pStubMsg
->Buffer
;
4206 /* get the buffer pointer after complex array data, but before
4208 pStubMsg
->IgnoreEmbeddedPointers
= 1;
4209 pStubMsg
->MemorySize
= 0;
4210 NdrComplexArrayMemorySize(pStubMsg
, pFormat
);
4211 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
4213 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->Buffer
- saved_buffer
));
4214 if (!pStubMsg
->PointerBufferMark
)
4216 /* save it for use by embedded pointer code later */
4217 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4218 pointer_buffer_mark_set
= TRUE
;
4220 /* restore the original buffer */
4221 pStubMsg
->Buffer
= saved_buffer
;
4223 array_read_conformance(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pFormat
);
4224 array_read_variance_and_unmarshall(RPC_FC_BOGUS_ARRAY
, pStubMsg
, ppMemory
, pFormat
, fMustAlloc
,
4225 TRUE
/* fUseBufferMemoryServer */, TRUE
/* fUnmarshall */);
4227 if (pointer_buffer_mark_set
)
4229 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4230 pStubMsg
->PointerBufferMark
= NULL
;
4236 /***********************************************************************
4237 * NdrComplexArrayBufferSize [RPCRT4.@]
4239 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4240 unsigned char *pMemory
,
4241 PFORMAT_STRING pFormat
)
4243 int pointer_length_set
= 0;
4245 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4247 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4249 ERR("invalid format type %x\n", pFormat
[0]);
4250 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4254 if (!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
4256 /* save buffer fields that may be changed by buffer sizer functions
4257 * and that may be needed later on */
4258 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
4259 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
4260 ULONG_PTR saved_max_count
= pStubMsg
->MaxCount
;
4261 ULONG saved_offset
= pStubMsg
->Offset
;
4262 ULONG saved_actual_count
= pStubMsg
->ActualCount
;
4264 /* get the buffer pointer after complex array data, but before
4266 pStubMsg
->IgnoreEmbeddedPointers
= 1;
4267 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
4268 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
4270 /* save it for use by embedded pointer code later */
4271 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4272 pointer_length_set
= 1;
4274 /* restore fields */
4275 pStubMsg
->ActualCount
= saved_actual_count
;
4276 pStubMsg
->Offset
= saved_offset
;
4277 pStubMsg
->MaxCount
= saved_max_count
;
4278 pStubMsg
->BufferLength
= saved_buffer_length
;
4281 array_compute_and_size_conformance(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pMemory
, pFormat
);
4282 array_buffer_size(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pMemory
, pFormat
, TRUE
/* fHasPointers */);
4284 if(pointer_length_set
)
4286 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4287 pStubMsg
->PointerLength
= 0;
4291 /***********************************************************************
4292 * NdrComplexArrayMemorySize [RPCRT4.@]
4294 ULONG WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4295 PFORMAT_STRING pFormat
)
4297 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
4299 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4301 ERR("invalid format type %x\n", pFormat
[0]);
4302 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4306 array_read_conformance(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pFormat
);
4307 array_memory_size(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pFormat
, TRUE
/* fHasPointers */);
4308 return pStubMsg
->MemorySize
;
4311 /***********************************************************************
4312 * NdrComplexArrayFree [RPCRT4.@]
4314 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4315 unsigned char *pMemory
,
4316 PFORMAT_STRING pFormat
)
4318 ULONG i
, count
, def
;
4320 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4322 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4324 ERR("invalid format type %x\n", pFormat
[0]);
4325 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4329 def
= *(const WORD
*)&pFormat
[2];
4332 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
4333 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
4335 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
4336 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
4338 count
= pStubMsg
->ActualCount
;
4339 for (i
= 0; i
< count
; i
++)
4340 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
4343 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg
,
4344 USER_MARSHAL_CB_TYPE cbtype
, PFORMAT_STRING pFormat
,
4345 USER_MARSHAL_CB
*umcb
)
4347 umcb
->Flags
= MAKELONG(pStubMsg
->dwDestContext
,
4348 pStubMsg
->RpcMsg
->DataRepresentation
);
4349 umcb
->pStubMsg
= pStubMsg
;
4350 umcb
->pReserve
= NULL
;
4351 umcb
->Signature
= USER_MARSHAL_CB_SIGNATURE
;
4352 umcb
->CBType
= cbtype
;
4353 umcb
->pFormat
= pFormat
;
4354 umcb
->pTypeFormat
= NULL
/* FIXME */;
4357 #define USER_MARSHAL_PTR_PREFIX \
4358 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4359 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4361 /***********************************************************************
4362 * NdrUserMarshalMarshall [RPCRT4.@]
4364 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4365 unsigned char *pMemory
,
4366 PFORMAT_STRING pFormat
)
4368 unsigned flags
= pFormat
[1];
4369 unsigned index
= *(const WORD
*)&pFormat
[2];
4370 unsigned char *saved_buffer
= NULL
;
4371 USER_MARSHAL_CB umcb
;
4373 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4374 TRACE("index=%d\n", index
);
4376 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_MARSHALL
, pFormat
, &umcb
);
4378 if (flags
& USER_MARSHAL_POINTER
)
4380 align_pointer_clear(&pStubMsg
->Buffer
, 4);
4381 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, USER_MARSHAL_PTR_PREFIX
);
4382 pStubMsg
->Buffer
+= 4;
4383 if (pStubMsg
->PointerBufferMark
)
4385 saved_buffer
= pStubMsg
->Buffer
;
4386 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4387 pStubMsg
->PointerBufferMark
= NULL
;
4389 align_pointer_clear(&pStubMsg
->Buffer
, 8);
4392 align_pointer_clear(&pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4395 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
4396 &umcb
.Flags
, pStubMsg
->Buffer
, pMemory
);
4400 STD_OVERFLOW_CHECK(pStubMsg
);
4401 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4402 pStubMsg
->Buffer
= saved_buffer
;
4405 STD_OVERFLOW_CHECK(pStubMsg
);
4410 /***********************************************************************
4411 * NdrUserMarshalUnmarshall [RPCRT4.@]
4413 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4414 unsigned char **ppMemory
,
4415 PFORMAT_STRING pFormat
,
4416 unsigned char fMustAlloc
)
4418 unsigned flags
= pFormat
[1];
4419 unsigned index
= *(const WORD
*)&pFormat
[2];
4420 DWORD memsize
= *(const WORD
*)&pFormat
[4];
4421 unsigned char *saved_buffer
= NULL
;
4422 USER_MARSHAL_CB umcb
;
4424 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4425 TRACE("index=%d\n", index
);
4427 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_UNMARSHALL
, pFormat
, &umcb
);
4429 if (flags
& USER_MARSHAL_POINTER
)
4431 align_pointer(&pStubMsg
->Buffer
, 4);
4432 /* skip pointer prefix */
4433 pStubMsg
->Buffer
+= 4;
4434 if (pStubMsg
->PointerBufferMark
)
4436 saved_buffer
= pStubMsg
->Buffer
;
4437 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4438 pStubMsg
->PointerBufferMark
= NULL
;
4440 align_pointer(&pStubMsg
->Buffer
, 8);
4443 align_pointer(&pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4445 if (!fMustAlloc
&& !*ppMemory
)
4449 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
4450 memset(*ppMemory
, 0, memsize
);
4454 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
4455 &umcb
.Flags
, pStubMsg
->Buffer
, *ppMemory
);
4459 STD_OVERFLOW_CHECK(pStubMsg
);
4460 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4461 pStubMsg
->Buffer
= saved_buffer
;
4467 /***********************************************************************
4468 * NdrUserMarshalBufferSize [RPCRT4.@]
4470 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4471 unsigned char *pMemory
,
4472 PFORMAT_STRING pFormat
)
4474 unsigned flags
= pFormat
[1];
4475 unsigned index
= *(const WORD
*)&pFormat
[2];
4476 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
4477 USER_MARSHAL_CB umcb
;
4478 ULONG saved_buffer_length
= 0;
4480 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4481 TRACE("index=%d\n", index
);
4483 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_BUFFER_SIZE
, pFormat
, &umcb
);
4485 if (flags
& USER_MARSHAL_POINTER
)
4487 align_length(&pStubMsg
->BufferLength
, 4);
4488 /* skip pointer prefix */
4489 safe_buffer_length_increment(pStubMsg
, 4);
4490 if (pStubMsg
->IgnoreEmbeddedPointers
)
4492 if (pStubMsg
->PointerLength
)
4494 saved_buffer_length
= pStubMsg
->BufferLength
;
4495 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4496 pStubMsg
->PointerLength
= 0;
4498 align_length(&pStubMsg
->BufferLength
, 8);
4501 align_length(&pStubMsg
->BufferLength
, (flags
& 0xf) + 1);
4504 TRACE("size=%d\n", bufsize
);
4505 safe_buffer_length_increment(pStubMsg
, bufsize
);
4508 pStubMsg
->BufferLength
=
4509 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
4510 &umcb
.Flags
, pStubMsg
->BufferLength
, pMemory
);
4512 if (saved_buffer_length
)
4514 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4515 pStubMsg
->BufferLength
= saved_buffer_length
;
4520 /***********************************************************************
4521 * NdrUserMarshalMemorySize [RPCRT4.@]
4523 ULONG WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4524 PFORMAT_STRING pFormat
)
4526 unsigned flags
= pFormat
[1];
4527 unsigned index
= *(const WORD
*)&pFormat
[2];
4528 DWORD memsize
= *(const WORD
*)&pFormat
[4];
4529 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
4531 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
4532 TRACE("index=%d\n", index
);
4534 pStubMsg
->MemorySize
+= memsize
;
4536 if (flags
& USER_MARSHAL_POINTER
)
4538 align_pointer(&pStubMsg
->Buffer
, 4);
4539 /* skip pointer prefix */
4540 pStubMsg
->Buffer
+= 4;
4541 if (pStubMsg
->IgnoreEmbeddedPointers
)
4542 return pStubMsg
->MemorySize
;
4543 align_pointer(&pStubMsg
->Buffer
, 8);
4546 align_pointer(&pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4549 FIXME("not implemented for varying buffer size\n");
4551 pStubMsg
->Buffer
+= bufsize
;
4553 return pStubMsg
->MemorySize
;
4556 /***********************************************************************
4557 * NdrUserMarshalFree [RPCRT4.@]
4559 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
4560 unsigned char *pMemory
,
4561 PFORMAT_STRING pFormat
)
4563 /* unsigned flags = pFormat[1]; */
4564 unsigned index
= *(const WORD
*)&pFormat
[2];
4565 USER_MARSHAL_CB umcb
;
4567 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4568 TRACE("index=%d\n", index
);
4570 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_FREE
, pFormat
, &umcb
);
4572 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
4573 &umcb
.Flags
, pMemory
);
4576 /***********************************************************************
4577 * NdrGetUserMarshalInfo [RPCRT4.@]
4579 RPC_STATUS RPC_ENTRY
NdrGetUserMarshalInfo(ULONG
*flags
, ULONG level
, NDR_USER_MARSHAL_INFO
*umi
)
4581 USER_MARSHAL_CB
*umcb
= CONTAINING_RECORD(flags
, USER_MARSHAL_CB
, Flags
);
4583 TRACE("(%p,%u,%p)\n", flags
, level
, umi
);
4586 return RPC_S_INVALID_ARG
;
4588 memset(&umi
->u1
.Level1
, 0, sizeof(umi
->u1
.Level1
));
4589 umi
->InformationLevel
= level
;
4591 if (umcb
->Signature
!= USER_MARSHAL_CB_SIGNATURE
)
4592 return RPC_S_INVALID_ARG
;
4594 umi
->u1
.Level1
.pfnAllocate
= umcb
->pStubMsg
->pfnAllocate
;
4595 umi
->u1
.Level1
.pfnFree
= umcb
->pStubMsg
->pfnFree
;
4596 umi
->u1
.Level1
.pRpcChannelBuffer
= umcb
->pStubMsg
->pRpcChannelBuffer
;
4598 switch (umcb
->CBType
)
4600 case USER_MARSHAL_CB_MARSHALL
:
4601 case USER_MARSHAL_CB_UNMARSHALL
:
4603 RPC_MESSAGE
*msg
= umcb
->pStubMsg
->RpcMsg
;
4604 unsigned char *buffer_start
= msg
->Buffer
;
4605 unsigned char *buffer_end
=
4606 (unsigned char *)msg
->Buffer
+ msg
->BufferLength
;
4608 if (umcb
->pStubMsg
->Buffer
< buffer_start
||
4609 umcb
->pStubMsg
->Buffer
> buffer_end
)
4610 return RPC_X_INVALID_BUFFER
;
4612 umi
->u1
.Level1
.Buffer
= umcb
->pStubMsg
->Buffer
;
4613 umi
->u1
.Level1
.BufferSize
= buffer_end
- umcb
->pStubMsg
->Buffer
;
4616 case USER_MARSHAL_CB_BUFFER_SIZE
:
4617 case USER_MARSHAL_CB_FREE
:
4620 WARN("unrecognised CBType %d\n", umcb
->CBType
);
4626 /***********************************************************************
4627 * NdrClearOutParameters [RPCRT4.@]
4629 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
4630 PFORMAT_STRING pFormat
,
4633 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
4636 /***********************************************************************
4637 * NdrConvert [RPCRT4.@]
4639 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
4641 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
4642 /* FIXME: since this stub doesn't do any converting, the proper behavior
4643 is to raise an exception */
4646 /***********************************************************************
4647 * NdrConvert2 [RPCRT4.@]
4649 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, LONG NumberParams
)
4651 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4652 pStubMsg
, pFormat
, NumberParams
);
4653 /* FIXME: since this stub doesn't do any converting, the proper behavior
4654 is to raise an exception */
4657 #include "pshpack1.h"
4658 typedef struct _NDR_CSTRUCT_FORMAT
4661 unsigned char alignment
;
4662 unsigned short memory_size
;
4663 short offset_to_array_description
;
4664 } NDR_CSTRUCT_FORMAT
, NDR_CVSTRUCT_FORMAT
;
4665 #include "poppack.h"
4667 /***********************************************************************
4668 * NdrConformantStructMarshall [RPCRT4.@]
4670 unsigned char * WINAPI
NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4671 unsigned char *pMemory
,
4672 PFORMAT_STRING pFormat
)
4674 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4675 PFORMAT_STRING pCArrayFormat
;
4676 ULONG esize
, bufsize
;
4678 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4680 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4681 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4683 ERR("invalid format type %x\n", pCStructFormat
->type
);
4684 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4688 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4689 pCStructFormat
->offset_to_array_description
;
4690 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4692 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4693 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4696 esize
= *(const WORD
*)(pCArrayFormat
+2);
4698 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4699 pCArrayFormat
+ 4, 0);
4701 WriteConformance(pStubMsg
);
4703 align_pointer_clear(&pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4705 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4707 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4708 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4710 ERR("integer overflow of memory_size %u with bufsize %u\n",
4711 pCStructFormat
->memory_size
, bufsize
);
4712 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4714 /* copy constant sized part of struct */
4715 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4716 safe_copy_to_buffer(pStubMsg
, pMemory
, pCStructFormat
->memory_size
+ bufsize
);
4718 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4719 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4724 /***********************************************************************
4725 * NdrConformantStructUnmarshall [RPCRT4.@]
4727 unsigned char * WINAPI
NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4728 unsigned char **ppMemory
,
4729 PFORMAT_STRING pFormat
,
4730 unsigned char fMustAlloc
)
4732 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4733 PFORMAT_STRING pCArrayFormat
;
4734 ULONG esize
, bufsize
;
4735 unsigned char *saved_buffer
;
4737 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4739 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4740 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4742 ERR("invalid format type %x\n", pCStructFormat
->type
);
4743 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4746 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4747 pCStructFormat
->offset_to_array_description
;
4748 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4750 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4751 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4754 esize
= *(const WORD
*)(pCArrayFormat
+2);
4756 pCArrayFormat
= ReadConformance(pStubMsg
, pCArrayFormat
+ 4);
4758 align_pointer(&pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4760 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4762 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4763 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4765 ERR("integer overflow of memory_size %u with bufsize %u\n",
4766 pCStructFormat
->memory_size
, bufsize
);
4767 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4772 SIZE_T size
= pCStructFormat
->memory_size
+ bufsize
;
4773 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4777 if (!pStubMsg
->IsClient
&& !*ppMemory
)
4778 /* for servers, we just point straight into the RPC buffer */
4779 *ppMemory
= pStubMsg
->Buffer
;
4782 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4783 safe_buffer_increment(pStubMsg
, pCStructFormat
->memory_size
+ bufsize
);
4784 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4785 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4787 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
4788 if (*ppMemory
!= saved_buffer
)
4789 memcpy(*ppMemory
, saved_buffer
, pCStructFormat
->memory_size
+ bufsize
);
4794 /***********************************************************************
4795 * NdrConformantStructBufferSize [RPCRT4.@]
4797 void WINAPI
NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4798 unsigned char *pMemory
,
4799 PFORMAT_STRING pFormat
)
4801 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4802 PFORMAT_STRING pCArrayFormat
;
4805 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4807 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4808 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4810 ERR("invalid format type %x\n", pCStructFormat
->type
);
4811 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4814 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4815 pCStructFormat
->offset_to_array_description
;
4816 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4818 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4819 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4822 esize
= *(const WORD
*)(pCArrayFormat
+2);
4824 pCArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
, pCArrayFormat
+4, 0);
4825 SizeConformance(pStubMsg
);
4827 align_length(&pStubMsg
->BufferLength
, pCStructFormat
->alignment
+ 1);
4829 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4831 safe_buffer_length_increment(pStubMsg
, pCStructFormat
->memory_size
);
4832 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
4834 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4835 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4838 /***********************************************************************
4839 * NdrConformantStructMemorySize [RPCRT4.@]
4841 ULONG WINAPI
NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4842 PFORMAT_STRING pFormat
)
4848 /***********************************************************************
4849 * NdrConformantStructFree [RPCRT4.@]
4851 void WINAPI
NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
4852 unsigned char *pMemory
,
4853 PFORMAT_STRING pFormat
)
4855 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4856 PFORMAT_STRING pCArrayFormat
;
4858 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4860 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4861 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4863 ERR("invalid format type %x\n", pCStructFormat
->type
);
4864 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4868 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4869 pCStructFormat
->offset_to_array_description
;
4870 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4872 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4873 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4877 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4878 pCArrayFormat
+ 4, 0);
4880 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4882 /* copy constant sized part of struct */
4883 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4885 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4886 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4889 /***********************************************************************
4890 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4892 unsigned char * WINAPI
NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4893 unsigned char *pMemory
,
4894 PFORMAT_STRING pFormat
)
4896 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4897 PFORMAT_STRING pCVArrayFormat
;
4899 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4901 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4902 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4904 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4905 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4909 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4910 pCVStructFormat
->offset_to_array_description
;
4912 array_compute_and_write_conformance(*pCVArrayFormat
, pStubMsg
,
4913 pMemory
+ pCVStructFormat
->memory_size
,
4916 align_pointer_clear(&pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4918 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4920 /* write constant sized part */
4921 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4922 safe_copy_to_buffer(pStubMsg
, pMemory
, pCVStructFormat
->memory_size
);
4924 array_write_variance_and_marshall(*pCVArrayFormat
, pStubMsg
,
4925 pMemory
+ pCVStructFormat
->memory_size
,
4926 pCVArrayFormat
, FALSE
/* fHasPointers */);
4928 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4933 /***********************************************************************
4934 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4936 unsigned char * WINAPI
NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4937 unsigned char **ppMemory
,
4938 PFORMAT_STRING pFormat
,
4939 unsigned char fMustAlloc
)
4941 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4942 PFORMAT_STRING pCVArrayFormat
;
4943 ULONG memsize
, bufsize
;
4944 unsigned char *saved_buffer
, *saved_array_buffer
;
4946 unsigned char *array_memory
;
4948 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4950 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4951 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4953 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4954 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4958 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4959 pCVStructFormat
->offset_to_array_description
;
4961 memsize
= array_read_conformance(*pCVArrayFormat
, pStubMsg
,
4964 align_pointer(&pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4966 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4968 /* work out how much memory to allocate if we need to do so */
4969 if (!fMustAlloc
&& !*ppMemory
)
4973 SIZE_T size
= pCVStructFormat
->memory_size
+ memsize
;
4974 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4977 /* mark the start of the constant data */
4978 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4979 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4981 array_memory
= *ppMemory
+ pCVStructFormat
->memory_size
;
4982 bufsize
= array_read_variance_and_unmarshall(*pCVArrayFormat
, pStubMsg
,
4983 &array_memory
, pCVArrayFormat
,
4984 FALSE
/* fMustAlloc */,
4985 FALSE
/* fUseServerBufferMemory */,
4986 FALSE
/* fUnmarshall */);
4988 /* save offset in case unmarshalling pointers changes it */
4989 offset
= pStubMsg
->Offset
;
4991 /* mark the start of the array data */
4992 saved_array_buffer
= pStubMsg
->Buffer
;
4993 safe_buffer_increment(pStubMsg
, bufsize
);
4995 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4997 /* copy the constant data */
4998 memcpy(*ppMemory
, saved_buffer
, pCVStructFormat
->memory_size
);
4999 /* copy the array data */
5000 TRACE("copying %p to %p\n", saved_array_buffer
, *ppMemory
+ pCVStructFormat
->memory_size
);
5001 memcpy(*ppMemory
+ pCVStructFormat
->memory_size
+ offset
,
5002 saved_array_buffer
, bufsize
);
5004 if (*pCVArrayFormat
== RPC_FC_C_CSTRING
)
5005 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory
+ pCVStructFormat
->memory_size
)));
5006 else if (*pCVArrayFormat
== RPC_FC_C_WSTRING
)
5007 TRACE("string=%s\n", debugstr_w((WCHAR
*)(*ppMemory
+ pCVStructFormat
->memory_size
)));
5012 /***********************************************************************
5013 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
5015 void WINAPI
NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5016 unsigned char *pMemory
,
5017 PFORMAT_STRING pFormat
)
5019 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
5020 PFORMAT_STRING pCVArrayFormat
;
5022 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5024 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
5025 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
5027 ERR("invalid format type %x\n", pCVStructFormat
->type
);
5028 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5032 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
5033 pCVStructFormat
->offset_to_array_description
;
5034 array_compute_and_size_conformance(*pCVArrayFormat
, pStubMsg
,
5035 pMemory
+ pCVStructFormat
->memory_size
,
5038 align_length(&pStubMsg
->BufferLength
, pCVStructFormat
->alignment
+ 1);
5040 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
5042 safe_buffer_length_increment(pStubMsg
, pCVStructFormat
->memory_size
);
5044 array_buffer_size(*pCVArrayFormat
, pStubMsg
,
5045 pMemory
+ pCVStructFormat
->memory_size
, pCVArrayFormat
,
5046 FALSE
/* fHasPointers */);
5048 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5051 /***********************************************************************
5052 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
5054 ULONG WINAPI
NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5055 PFORMAT_STRING pFormat
)
5057 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
5058 PFORMAT_STRING pCVArrayFormat
;
5060 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5062 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
5063 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
5065 ERR("invalid format type %x\n", pCVStructFormat
->type
);
5066 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5070 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
5071 pCVStructFormat
->offset_to_array_description
;
5072 array_read_conformance(*pCVArrayFormat
, pStubMsg
, pCVArrayFormat
);
5074 align_pointer(&pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
5076 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
5078 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
5079 array_memory_size(*pCVArrayFormat
, pStubMsg
, pCVArrayFormat
,
5080 FALSE
/* fHasPointers */);
5082 pStubMsg
->MemorySize
+= pCVStructFormat
->memory_size
;
5084 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5086 return pStubMsg
->MemorySize
;
5089 /***********************************************************************
5090 * NdrConformantVaryingStructFree [RPCRT4.@]
5092 void WINAPI
NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
5093 unsigned char *pMemory
,
5094 PFORMAT_STRING pFormat
)
5096 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
5097 PFORMAT_STRING pCVArrayFormat
;
5099 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5101 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
5102 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
5104 ERR("invalid format type %x\n", pCVStructFormat
->type
);
5105 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5109 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
5110 pCVStructFormat
->offset_to_array_description
;
5111 array_free(*pCVArrayFormat
, pStubMsg
,
5112 pMemory
+ pCVStructFormat
->memory_size
, pCVArrayFormat
,
5113 FALSE
/* fHasPointers */);
5115 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
5117 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5120 #include "pshpack1.h"
5124 unsigned char alignment
;
5125 unsigned short total_size
;
5126 } NDR_SMFARRAY_FORMAT
;
5131 unsigned char alignment
;
5133 } NDR_LGFARRAY_FORMAT
;
5134 #include "poppack.h"
5136 /***********************************************************************
5137 * NdrFixedArrayMarshall [RPCRT4.@]
5139 unsigned char * WINAPI
NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5140 unsigned char *pMemory
,
5141 PFORMAT_STRING pFormat
)
5143 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5146 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5148 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5149 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5151 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5152 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5156 align_pointer_clear(&pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
5158 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5160 total_size
= pSmFArrayFormat
->total_size
;
5161 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5165 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5166 total_size
= pLgFArrayFormat
->total_size
;
5167 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5170 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5171 safe_copy_to_buffer(pStubMsg
, pMemory
, total_size
);
5173 pFormat
= EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
5178 /***********************************************************************
5179 * NdrFixedArrayUnmarshall [RPCRT4.@]
5181 unsigned char * WINAPI
NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5182 unsigned char **ppMemory
,
5183 PFORMAT_STRING pFormat
,
5184 unsigned char fMustAlloc
)
5186 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5188 unsigned char *saved_buffer
;
5190 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5192 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5193 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5195 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5196 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5200 align_pointer(&pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
5202 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5204 total_size
= pSmFArrayFormat
->total_size
;
5205 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5209 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5210 total_size
= pLgFArrayFormat
->total_size
;
5211 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5215 *ppMemory
= NdrAllocate(pStubMsg
, total_size
);
5218 if (!pStubMsg
->IsClient
&& !*ppMemory
)
5219 /* for servers, we just point straight into the RPC buffer */
5220 *ppMemory
= pStubMsg
->Buffer
;
5223 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5224 safe_buffer_increment(pStubMsg
, total_size
);
5225 pFormat
= EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
5227 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
5228 if (*ppMemory
!= saved_buffer
)
5229 memcpy(*ppMemory
, saved_buffer
, total_size
);
5234 /***********************************************************************
5235 * NdrFixedArrayBufferSize [RPCRT4.@]
5237 void WINAPI
NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5238 unsigned char *pMemory
,
5239 PFORMAT_STRING pFormat
)
5241 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5244 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5246 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5247 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5249 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5250 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5254 align_length(&pStubMsg
->BufferLength
, pSmFArrayFormat
->alignment
+ 1);
5256 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5258 total_size
= pSmFArrayFormat
->total_size
;
5259 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5263 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5264 total_size
= pLgFArrayFormat
->total_size
;
5265 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5267 safe_buffer_length_increment(pStubMsg
, total_size
);
5269 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5272 /***********************************************************************
5273 * NdrFixedArrayMemorySize [RPCRT4.@]
5275 ULONG WINAPI
NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5276 PFORMAT_STRING pFormat
)
5278 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5281 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5283 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5284 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5286 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5287 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5291 align_pointer(&pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
5293 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5295 total_size
= pSmFArrayFormat
->total_size
;
5296 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5300 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5301 total_size
= pLgFArrayFormat
->total_size
;
5302 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5304 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5305 safe_buffer_increment(pStubMsg
, total_size
);
5306 pStubMsg
->MemorySize
+= total_size
;
5308 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5313 /***********************************************************************
5314 * NdrFixedArrayFree [RPCRT4.@]
5316 void WINAPI
NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
5317 unsigned char *pMemory
,
5318 PFORMAT_STRING pFormat
)
5320 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5322 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5324 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5325 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5327 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5328 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5332 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5333 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5336 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5337 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5340 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5343 /***********************************************************************
5344 * NdrVaryingArrayMarshall [RPCRT4.@]
5346 unsigned char * WINAPI
NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5347 unsigned char *pMemory
,
5348 PFORMAT_STRING pFormat
)
5350 unsigned char alignment
;
5351 DWORD elements
, esize
;
5354 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5356 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5357 (pFormat
[0] != RPC_FC_LGVARRAY
))
5359 ERR("invalid format type %x\n", pFormat
[0]);
5360 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5364 alignment
= pFormat
[1] + 1;
5366 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5369 pFormat
+= sizeof(WORD
);
5370 elements
= *(const WORD
*)pFormat
;
5371 pFormat
+= sizeof(WORD
);
5376 pFormat
+= sizeof(DWORD
);
5377 elements
= *(const DWORD
*)pFormat
;
5378 pFormat
+= sizeof(DWORD
);
5381 esize
= *(const WORD
*)pFormat
;
5382 pFormat
+= sizeof(WORD
);
5384 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5385 if ((pStubMsg
->ActualCount
> elements
) ||
5386 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5388 RpcRaiseException(RPC_S_INVALID_BOUND
);
5392 WriteVariance(pStubMsg
);
5394 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
5396 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
5397 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5398 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
5400 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
5405 /***********************************************************************
5406 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5408 unsigned char * WINAPI
NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5409 unsigned char **ppMemory
,
5410 PFORMAT_STRING pFormat
,
5411 unsigned char fMustAlloc
)
5413 unsigned char alignment
;
5414 DWORD size
, elements
, esize
;
5416 unsigned char *saved_buffer
;
5419 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5421 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5422 (pFormat
[0] != RPC_FC_LGVARRAY
))
5424 ERR("invalid format type %x\n", pFormat
[0]);
5425 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5429 alignment
= pFormat
[1] + 1;
5431 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5434 size
= *(const WORD
*)pFormat
;
5435 pFormat
+= sizeof(WORD
);
5436 elements
= *(const WORD
*)pFormat
;
5437 pFormat
+= sizeof(WORD
);
5442 size
= *(const DWORD
*)pFormat
;
5443 pFormat
+= sizeof(DWORD
);
5444 elements
= *(const DWORD
*)pFormat
;
5445 pFormat
+= sizeof(DWORD
);
5448 esize
= *(const WORD
*)pFormat
;
5449 pFormat
+= sizeof(WORD
);
5451 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
5453 align_pointer(&pStubMsg
->Buffer
, alignment
);
5455 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
5456 offset
= pStubMsg
->Offset
;
5458 if (!fMustAlloc
&& !*ppMemory
)
5461 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5462 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5463 safe_buffer_increment(pStubMsg
, bufsize
);
5465 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
5467 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
5472 /***********************************************************************
5473 * NdrVaryingArrayBufferSize [RPCRT4.@]
5475 void WINAPI
NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5476 unsigned char *pMemory
,
5477 PFORMAT_STRING pFormat
)
5479 unsigned char alignment
;
5480 DWORD elements
, esize
;
5482 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5484 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5485 (pFormat
[0] != RPC_FC_LGVARRAY
))
5487 ERR("invalid format type %x\n", pFormat
[0]);
5488 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5492 alignment
= pFormat
[1] + 1;
5494 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5497 pFormat
+= sizeof(WORD
);
5498 elements
= *(const WORD
*)pFormat
;
5499 pFormat
+= sizeof(WORD
);
5504 pFormat
+= sizeof(DWORD
);
5505 elements
= *(const DWORD
*)pFormat
;
5506 pFormat
+= sizeof(DWORD
);
5509 esize
= *(const WORD
*)pFormat
;
5510 pFormat
+= sizeof(WORD
);
5512 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5513 if ((pStubMsg
->ActualCount
> elements
) ||
5514 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5516 RpcRaiseException(RPC_S_INVALID_BOUND
);
5520 SizeVariance(pStubMsg
);
5522 align_length(&pStubMsg
->BufferLength
, alignment
);
5524 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
5526 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5529 /***********************************************************************
5530 * NdrVaryingArrayMemorySize [RPCRT4.@]
5532 ULONG WINAPI
NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5533 PFORMAT_STRING pFormat
)
5535 unsigned char alignment
;
5536 DWORD size
, elements
, esize
;
5538 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5540 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5541 (pFormat
[0] != RPC_FC_LGVARRAY
))
5543 ERR("invalid format type %x\n", pFormat
[0]);
5544 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5548 alignment
= pFormat
[1] + 1;
5550 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5553 size
= *(const WORD
*)pFormat
;
5554 pFormat
+= sizeof(WORD
);
5555 elements
= *(const WORD
*)pFormat
;
5556 pFormat
+= sizeof(WORD
);
5561 size
= *(const DWORD
*)pFormat
;
5562 pFormat
+= sizeof(DWORD
);
5563 elements
= *(const DWORD
*)pFormat
;
5564 pFormat
+= sizeof(DWORD
);
5567 esize
= *(const WORD
*)pFormat
;
5568 pFormat
+= sizeof(WORD
);
5570 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
5572 align_pointer(&pStubMsg
->Buffer
, alignment
);
5574 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
5575 pStubMsg
->MemorySize
+= size
;
5577 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5579 return pStubMsg
->MemorySize
;
5582 /***********************************************************************
5583 * NdrVaryingArrayFree [RPCRT4.@]
5585 void WINAPI
NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
5586 unsigned char *pMemory
,
5587 PFORMAT_STRING pFormat
)
5591 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5593 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5594 (pFormat
[0] != RPC_FC_LGVARRAY
))
5596 ERR("invalid format type %x\n", pFormat
[0]);
5597 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5601 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5604 pFormat
+= sizeof(WORD
);
5605 elements
= *(const WORD
*)pFormat
;
5606 pFormat
+= sizeof(WORD
);
5611 pFormat
+= sizeof(DWORD
);
5612 elements
= *(const DWORD
*)pFormat
;
5613 pFormat
+= sizeof(DWORD
);
5616 pFormat
+= sizeof(WORD
);
5618 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5619 if ((pStubMsg
->ActualCount
> elements
) ||
5620 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5622 RpcRaiseException(RPC_S_INVALID_BOUND
);
5626 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5629 static ULONG
get_discriminant(unsigned char fc
, const unsigned char *pMemory
)
5642 return *(const USHORT
*)pMemory
;
5646 return *(const ULONG
*)pMemory
;
5647 case RPC_FC_INT3264
:
5648 case RPC_FC_UINT3264
:
5649 return *(const ULONG_PTR
*)pMemory
;
5651 FIXME("Unhandled base type: 0x%02x\n", fc
);
5656 static PFORMAT_STRING
get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg
,
5658 PFORMAT_STRING pFormat
)
5660 unsigned short num_arms
, arm
, type
;
5662 num_arms
= *(const SHORT
*)pFormat
& 0x0fff;
5664 for(arm
= 0; arm
< num_arms
; arm
++)
5666 if(discriminant
== *(const ULONG
*)pFormat
)
5674 type
= *(const unsigned short*)pFormat
;
5675 TRACE("type %04x\n", type
);
5676 if(arm
== num_arms
) /* default arm extras */
5680 ERR("no arm for 0x%x and no default case\n", discriminant
);
5681 RpcRaiseException(RPC_S_INVALID_TAG
);
5686 TRACE("falling back to empty default case for 0x%x\n", discriminant
);
5693 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
, ULONG discriminant
, PFORMAT_STRING pFormat
)
5695 unsigned short type
;
5699 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5703 type
= *(const unsigned short*)pFormat
;
5704 if((type
& 0xff00) == 0x8000)
5706 unsigned char basetype
= LOBYTE(type
);
5707 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &basetype
);
5711 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5712 NDR_MARSHALL m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
5715 unsigned char *saved_buffer
= NULL
;
5716 BOOL pointer_buffer_mark_set
= FALSE
;
5723 align_pointer_clear(&pStubMsg
->Buffer
, 4);
5724 saved_buffer
= pStubMsg
->Buffer
;
5725 if (pStubMsg
->PointerBufferMark
)
5727 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5728 pStubMsg
->PointerBufferMark
= NULL
;
5729 pointer_buffer_mark_set
= TRUE
;
5732 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
5734 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char **)pMemory
, desc
);
5735 if (pointer_buffer_mark_set
)
5737 STD_OVERFLOW_CHECK(pStubMsg
);
5738 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5739 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5741 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5742 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
5743 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5745 pStubMsg
->Buffer
= saved_buffer
+ 4;
5749 m(pStubMsg
, pMemory
, desc
);
5752 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5757 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5758 unsigned char **ppMemory
,
5760 PFORMAT_STRING pFormat
,
5761 unsigned char fMustAlloc
)
5763 unsigned short type
;
5767 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5771 type
= *(const unsigned short*)pFormat
;
5772 if((type
& 0xff00) == 0x8000)
5774 unsigned char basetype
= LOBYTE(type
);
5775 return NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &basetype
, FALSE
);
5779 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5780 NDR_UNMARSHALL m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
5783 unsigned char *saved_buffer
= NULL
;
5784 BOOL pointer_buffer_mark_set
= FALSE
;
5791 align_pointer(&pStubMsg
->Buffer
, 4);
5792 saved_buffer
= pStubMsg
->Buffer
;
5793 if (pStubMsg
->PointerBufferMark
)
5795 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5796 pStubMsg
->PointerBufferMark
= NULL
;
5797 pointer_buffer_mark_set
= TRUE
;
5800 pStubMsg
->Buffer
+= 4; /* for pointer ID */
5802 if (saved_buffer
+ 4 > pStubMsg
->BufferEnd
)
5804 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5805 saved_buffer
, pStubMsg
->BufferEnd
);
5806 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5809 PointerUnmarshall(pStubMsg
, saved_buffer
, *(unsigned char ***)ppMemory
, **(unsigned char ***)ppMemory
, desc
, fMustAlloc
);
5810 if (pointer_buffer_mark_set
)
5812 STD_OVERFLOW_CHECK(pStubMsg
);
5813 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5814 pStubMsg
->Buffer
= saved_buffer
+ 4;
5818 m(pStubMsg
, ppMemory
, desc
, fMustAlloc
);
5821 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5826 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg
,
5827 unsigned char *pMemory
,
5829 PFORMAT_STRING pFormat
)
5831 unsigned short type
;
5835 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5839 type
= *(const unsigned short*)pFormat
;
5840 if((type
& 0xff00) == 0x8000)
5842 unsigned char basetype
= LOBYTE(type
);
5843 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &basetype
);
5847 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5848 NDR_BUFFERSIZE m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
5857 align_length(&pStubMsg
->BufferLength
, 4);
5858 safe_buffer_length_increment(pStubMsg
, 4); /* for pointer ID */
5859 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5861 int saved_buffer_length
= pStubMsg
->BufferLength
;
5862 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
5863 pStubMsg
->PointerLength
= 0;
5864 if(!pStubMsg
->BufferLength
)
5865 ERR("BufferLength == 0??\n");
5866 PointerBufferSize(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5867 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
5868 pStubMsg
->BufferLength
= saved_buffer_length
;
5872 m(pStubMsg
, pMemory
, desc
);
5875 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
5879 static ULONG
union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg
,
5881 PFORMAT_STRING pFormat
)
5883 unsigned short type
, size
;
5885 size
= *(const unsigned short*)pFormat
;
5886 pStubMsg
->Memory
+= size
;
5889 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5893 type
= *(const unsigned short*)pFormat
;
5894 if((type
& 0xff00) == 0x8000)
5896 return NdrBaseTypeMemorySize(pStubMsg
, pFormat
);
5900 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5901 NDR_MEMORYSIZE m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
5902 unsigned char *saved_buffer
;
5911 align_pointer(&pStubMsg
->Buffer
, 4);
5912 saved_buffer
= pStubMsg
->Buffer
;
5913 safe_buffer_increment(pStubMsg
, 4);
5914 align_length(&pStubMsg
->MemorySize
, sizeof(void *));
5915 pStubMsg
->MemorySize
+= sizeof(void *);
5916 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5917 PointerMemorySize(pStubMsg
, saved_buffer
, pFormat
);
5920 return m(pStubMsg
, desc
);
5923 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5926 TRACE("size %d\n", size
);
5930 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg
,
5931 unsigned char *pMemory
,
5933 PFORMAT_STRING pFormat
)
5935 unsigned short type
;
5939 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5943 type
= *(const unsigned short*)pFormat
;
5944 if((type
& 0xff00) != 0x8000)
5946 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5947 NDR_FREE m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
5956 PointerFree(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5959 m(pStubMsg
, pMemory
, desc
);
5965 /***********************************************************************
5966 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5968 unsigned char * WINAPI
NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5969 unsigned char *pMemory
,
5970 PFORMAT_STRING pFormat
)
5972 unsigned char switch_type
;
5973 unsigned char increment
;
5976 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5979 switch_type
= *pFormat
& 0xf;
5980 increment
= (*pFormat
& 0xf0) >> 4;
5983 align_pointer_clear(&pStubMsg
->Buffer
, increment
);
5985 switch_value
= get_discriminant(switch_type
, pMemory
);
5986 TRACE("got switch value 0x%x\n", switch_value
);
5988 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &switch_type
);
5989 pMemory
+= increment
;
5991 return union_arm_marshall(pStubMsg
, pMemory
, switch_value
, pFormat
);
5994 /***********************************************************************
5995 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5997 unsigned char * WINAPI
NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5998 unsigned char **ppMemory
,
5999 PFORMAT_STRING pFormat
,
6000 unsigned char fMustAlloc
)
6002 unsigned char switch_type
;
6003 unsigned char increment
;
6005 unsigned short size
;
6006 unsigned char *pMemoryArm
;
6008 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
6011 switch_type
= *pFormat
& 0xf;
6012 increment
= (*pFormat
& 0xf0) >> 4;
6015 align_pointer(&pStubMsg
->Buffer
, increment
);
6016 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
6017 TRACE("got switch value 0x%x\n", switch_value
);
6019 size
= *(const unsigned short*)pFormat
+ increment
;
6020 if (!fMustAlloc
&& !*ppMemory
)
6023 *ppMemory
= NdrAllocate(pStubMsg
, size
);
6025 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6026 * since the arm is part of the memory block that is encompassed by
6027 * the whole union. Memory is forced to allocate when pointers
6028 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6029 * clearing the memory we pass in to the unmarshaller */
6031 memset(*ppMemory
, 0, size
);
6033 NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &switch_type
, FALSE
);
6034 pMemoryArm
= *ppMemory
+ increment
;
6036 return union_arm_unmarshall(pStubMsg
, &pMemoryArm
, switch_value
, pFormat
, FALSE
);
6039 /***********************************************************************
6040 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
6042 void WINAPI
NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6043 unsigned char *pMemory
,
6044 PFORMAT_STRING pFormat
)
6046 unsigned char switch_type
;
6047 unsigned char increment
;
6050 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6053 switch_type
= *pFormat
& 0xf;
6054 increment
= (*pFormat
& 0xf0) >> 4;
6057 align_length(&pStubMsg
->BufferLength
, increment
);
6058 switch_value
= get_discriminant(switch_type
, pMemory
);
6059 TRACE("got switch value 0x%x\n", switch_value
);
6061 /* Add discriminant size */
6062 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&switch_value
, &switch_type
);
6063 pMemory
+= increment
;
6065 union_arm_buffer_size(pStubMsg
, pMemory
, switch_value
, pFormat
);
6068 /***********************************************************************
6069 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
6071 ULONG WINAPI
NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6072 PFORMAT_STRING pFormat
)
6074 unsigned char switch_type
;
6075 unsigned char increment
;
6078 switch_type
= *pFormat
& 0xf;
6079 increment
= (*pFormat
& 0xf0) >> 4;
6082 align_pointer(&pStubMsg
->Buffer
, increment
);
6083 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
6084 TRACE("got switch value 0x%x\n", switch_value
);
6086 pStubMsg
->Memory
+= increment
;
6088 return increment
+ union_arm_memory_size(pStubMsg
, switch_value
, pFormat
+ *(const SHORT
*)pFormat
);
6091 /***********************************************************************
6092 * NdrEncapsulatedUnionFree [RPCRT4.@]
6094 void WINAPI
NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
6095 unsigned char *pMemory
,
6096 PFORMAT_STRING pFormat
)
6098 unsigned char switch_type
;
6099 unsigned char increment
;
6102 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6105 switch_type
= *pFormat
& 0xf;
6106 increment
= (*pFormat
& 0xf0) >> 4;
6109 switch_value
= get_discriminant(switch_type
, pMemory
);
6110 TRACE("got switch value 0x%x\n", switch_value
);
6112 pMemory
+= increment
;
6114 union_arm_free(pStubMsg
, pMemory
, switch_value
, pFormat
);
6117 /***********************************************************************
6118 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
6120 unsigned char * WINAPI
NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6121 unsigned char *pMemory
,
6122 PFORMAT_STRING pFormat
)
6124 unsigned char switch_type
;
6126 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6129 switch_type
= *pFormat
;
6132 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6133 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6134 /* Marshall discriminant */
6135 NdrBaseTypeMarshall(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
6137 return union_arm_marshall(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6140 static LONG
unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg
,
6141 PFORMAT_STRING
*ppFormat
)
6143 LONG discriminant
= 0;
6153 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
6163 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6164 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
6172 align_pointer(&pStubMsg
->Buffer
, sizeof(ULONG
));
6173 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
6178 FIXME("Unhandled base type: 0x%02x\n", **ppFormat
);
6182 *ppFormat
= SkipConformance(pStubMsg
, *ppFormat
);
6183 return discriminant
;
6186 /**********************************************************************
6187 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
6189 unsigned char * WINAPI
NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6190 unsigned char **ppMemory
,
6191 PFORMAT_STRING pFormat
,
6192 unsigned char fMustAlloc
)
6195 unsigned short size
;
6197 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
6200 /* Unmarshall discriminant */
6201 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
6202 TRACE("unmarshalled discriminant %x\n", discriminant
);
6204 pFormat
+= *(const SHORT
*)pFormat
;
6206 size
= *(const unsigned short*)pFormat
;
6208 if (!fMustAlloc
&& !*ppMemory
)
6211 *ppMemory
= NdrAllocate(pStubMsg
, size
);
6213 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6214 * since the arm is part of the memory block that is encompassed by
6215 * the whole union. Memory is forced to allocate when pointers
6216 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6217 * clearing the memory we pass in to the unmarshaller */
6219 memset(*ppMemory
, 0, size
);
6221 return union_arm_unmarshall(pStubMsg
, ppMemory
, discriminant
, pFormat
, FALSE
);
6224 /***********************************************************************
6225 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
6227 void WINAPI
NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6228 unsigned char *pMemory
,
6229 PFORMAT_STRING pFormat
)
6231 unsigned char switch_type
;
6233 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6236 switch_type
= *pFormat
;
6239 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6240 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6241 /* Add discriminant size */
6242 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
6244 union_arm_buffer_size(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6247 /***********************************************************************
6248 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
6250 ULONG WINAPI
NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6251 PFORMAT_STRING pFormat
)
6256 /* Unmarshall discriminant */
6257 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
6258 TRACE("unmarshalled discriminant 0x%x\n", discriminant
);
6260 return union_arm_memory_size(pStubMsg
, discriminant
, pFormat
+ *(const SHORT
*)pFormat
);
6263 /***********************************************************************
6264 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6266 void WINAPI
NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
6267 unsigned char *pMemory
,
6268 PFORMAT_STRING pFormat
)
6270 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6274 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6275 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6277 union_arm_free(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6280 /***********************************************************************
6281 * NdrByteCountPointerMarshall [RPCRT4.@]
6283 unsigned char * WINAPI
NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6284 unsigned char *pMemory
,
6285 PFORMAT_STRING pFormat
)
6291 /***********************************************************************
6292 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6294 unsigned char * WINAPI
NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6295 unsigned char **ppMemory
,
6296 PFORMAT_STRING pFormat
,
6297 unsigned char fMustAlloc
)
6303 /***********************************************************************
6304 * NdrByteCountPointerBufferSize [RPCRT4.@]
6306 void WINAPI
NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6307 unsigned char *pMemory
,
6308 PFORMAT_STRING pFormat
)
6313 /***********************************************************************
6314 * NdrByteCountPointerMemorySize [internal]
6316 static ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6317 PFORMAT_STRING pFormat
)
6323 /***********************************************************************
6324 * NdrByteCountPointerFree [RPCRT4.@]
6326 void WINAPI
NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
6327 unsigned char *pMemory
,
6328 PFORMAT_STRING pFormat
)
6333 /***********************************************************************
6334 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6336 unsigned char * WINAPI
NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6337 unsigned char *pMemory
,
6338 PFORMAT_STRING pFormat
)
6344 /***********************************************************************
6345 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6347 unsigned char * WINAPI
NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6348 unsigned char **ppMemory
,
6349 PFORMAT_STRING pFormat
,
6350 unsigned char fMustAlloc
)
6356 /***********************************************************************
6357 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6359 void WINAPI
NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6360 unsigned char *pMemory
,
6361 PFORMAT_STRING pFormat
)
6366 /***********************************************************************
6367 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6369 ULONG WINAPI
NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6370 PFORMAT_STRING pFormat
)
6376 /***********************************************************************
6377 * NdrXmitOrRepAsFree [RPCRT4.@]
6379 void WINAPI
NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg
,
6380 unsigned char *pMemory
,
6381 PFORMAT_STRING pFormat
)
6386 /***********************************************************************
6387 * NdrRangeMarshall [internal]
6389 static unsigned char *WINAPI
NdrRangeMarshall(
6390 PMIDL_STUB_MESSAGE pStubMsg
,
6391 unsigned char *pMemory
,
6392 PFORMAT_STRING pFormat
)
6394 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6395 unsigned char base_type
;
6397 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6399 if (pRange
->type
!= RPC_FC_RANGE
)
6401 ERR("invalid format type %x\n", pRange
->type
);
6402 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6406 base_type
= pRange
->flags_type
& 0xf;
6408 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &base_type
);
6411 /***********************************************************************
6412 * NdrRangeUnmarshall [RPCRT4.@]
6414 unsigned char *WINAPI
NdrRangeUnmarshall(
6415 PMIDL_STUB_MESSAGE pStubMsg
,
6416 unsigned char **ppMemory
,
6417 PFORMAT_STRING pFormat
,
6418 unsigned char fMustAlloc
)
6420 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6421 unsigned char base_type
;
6423 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6425 if (pRange
->type
!= RPC_FC_RANGE
)
6427 ERR("invalid format type %x\n", pRange
->type
);
6428 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6431 base_type
= pRange
->flags_type
& 0xf;
6433 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6434 base_type
, pRange
->low_value
, pRange
->high_value
);
6436 #define RANGE_UNMARSHALL(mem_type, wire_type, format_spec) \
6439 align_pointer(&pStubMsg->Buffer, sizeof(wire_type)); \
6440 if (!fMustAlloc && !*ppMemory) \
6441 fMustAlloc = TRUE; \
6443 *ppMemory = NdrAllocate(pStubMsg, sizeof(mem_type)); \
6444 if (pStubMsg->Buffer + sizeof(wire_type) > pStubMsg->BufferEnd) \
6446 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6447 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6448 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6450 if ((*(wire_type *)pStubMsg->Buffer < (mem_type)pRange->low_value) || \
6451 (*(wire_type *)pStubMsg->Buffer > (mem_type)pRange->high_value)) \
6453 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6454 *(wire_type *)pStubMsg->Buffer, (mem_type)pRange->low_value, \
6455 (mem_type)pRange->high_value); \
6456 RpcRaiseException(RPC_S_INVALID_BOUND); \
6459 TRACE("*ppMemory: %p\n", *ppMemory); \
6460 **(mem_type **)ppMemory = *(wire_type *)pStubMsg->Buffer; \
6461 pStubMsg->Buffer += sizeof(wire_type); \
6468 RANGE_UNMARSHALL(UCHAR
, UCHAR
, "%d");
6469 TRACE("value: 0x%02x\n", **ppMemory
);
6473 RANGE_UNMARSHALL(CHAR
, CHAR
, "%u");
6474 TRACE("value: 0x%02x\n", **ppMemory
);
6476 case RPC_FC_WCHAR
: /* FIXME: valid? */
6478 RANGE_UNMARSHALL(USHORT
, USHORT
, "%u");
6479 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6482 RANGE_UNMARSHALL(SHORT
, SHORT
, "%d");
6483 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6487 RANGE_UNMARSHALL(LONG
, LONG
, "%d");
6488 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6491 RANGE_UNMARSHALL(ULONG
, ULONG
, "%u");
6492 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6495 RANGE_UNMARSHALL(UINT
, USHORT
, "%u");
6496 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
6502 ERR("invalid range base type: 0x%02x\n", base_type
);
6503 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6509 /***********************************************************************
6510 * NdrRangeBufferSize [internal]
6512 static void WINAPI
NdrRangeBufferSize(
6513 PMIDL_STUB_MESSAGE pStubMsg
,
6514 unsigned char *pMemory
,
6515 PFORMAT_STRING pFormat
)
6517 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6518 unsigned char base_type
;
6520 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6522 if (pRange
->type
!= RPC_FC_RANGE
)
6524 ERR("invalid format type %x\n", pRange
->type
);
6525 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6527 base_type
= pRange
->flags_type
& 0xf;
6529 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &base_type
);
6532 /***********************************************************************
6533 * NdrRangeMemorySize [internal]
6535 static ULONG WINAPI
NdrRangeMemorySize(
6536 PMIDL_STUB_MESSAGE pStubMsg
,
6537 PFORMAT_STRING pFormat
)
6539 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6540 unsigned char base_type
;
6542 if (pRange
->type
!= RPC_FC_RANGE
)
6544 ERR("invalid format type %x\n", pRange
->type
);
6545 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6548 base_type
= pRange
->flags_type
& 0xf;
6550 return NdrBaseTypeMemorySize(pStubMsg
, &base_type
);
6553 /***********************************************************************
6554 * NdrRangeFree [internal]
6556 static void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6557 unsigned char *pMemory
,
6558 PFORMAT_STRING pFormat
)
6560 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6565 /***********************************************************************
6566 * NdrBaseTypeMarshall [internal]
6568 static unsigned char *WINAPI
NdrBaseTypeMarshall(
6569 PMIDL_STUB_MESSAGE pStubMsg
,
6570 unsigned char *pMemory
,
6571 PFORMAT_STRING pFormat
)
6573 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6581 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(UCHAR
));
6582 TRACE("value: 0x%02x\n", *pMemory
);
6587 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(USHORT
));
6588 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(USHORT
));
6589 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
6593 case RPC_FC_ERROR_STATUS_T
:
6595 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(ULONG
));
6596 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONG
));
6597 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
6600 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(float));
6601 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
6604 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(double));
6605 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
6608 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(ULONGLONG
));
6609 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONGLONG
));
6610 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
6614 USHORT val
= *(UINT
*)pMemory
;
6615 /* only 16-bits on the wire, so do a sanity check */
6616 if (*(UINT
*)pMemory
> SHRT_MAX
)
6617 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
6618 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(USHORT
));
6619 safe_copy_to_buffer(pStubMsg
, &val
, sizeof(val
));
6620 TRACE("value: 0x%04x\n", *(UINT
*)pMemory
);
6623 case RPC_FC_INT3264
:
6624 case RPC_FC_UINT3264
:
6626 UINT val
= *(UINT_PTR
*)pMemory
;
6627 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(UINT
));
6628 safe_copy_to_buffer(pStubMsg
, &val
, sizeof(val
));
6634 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6637 /* FIXME: what is the correct return value? */
6641 /***********************************************************************
6642 * NdrBaseTypeUnmarshall [internal]
6644 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(
6645 PMIDL_STUB_MESSAGE pStubMsg
,
6646 unsigned char **ppMemory
,
6647 PFORMAT_STRING pFormat
,
6648 unsigned char fMustAlloc
)
6650 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6652 #define BASE_TYPE_UNMARSHALL(type) do { \
6653 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
6654 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6656 *ppMemory = pStubMsg->Buffer; \
6657 TRACE("*ppMemory: %p\n", *ppMemory); \
6658 safe_buffer_increment(pStubMsg, sizeof(type)); \
6663 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6664 TRACE("*ppMemory: %p\n", *ppMemory); \
6665 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6675 BASE_TYPE_UNMARSHALL(UCHAR
);
6676 TRACE("value: 0x%02x\n", **ppMemory
);
6681 BASE_TYPE_UNMARSHALL(USHORT
);
6682 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6686 case RPC_FC_ERROR_STATUS_T
:
6688 BASE_TYPE_UNMARSHALL(ULONG
);
6689 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6692 BASE_TYPE_UNMARSHALL(float);
6693 TRACE("value: %f\n", **(float **)ppMemory
);
6696 BASE_TYPE_UNMARSHALL(double);
6697 TRACE("value: %f\n", **(double **)ppMemory
);
6700 BASE_TYPE_UNMARSHALL(ULONGLONG
);
6701 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG
**)ppMemory
));
6706 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6707 if (!fMustAlloc
&& !*ppMemory
)
6710 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT
));
6711 safe_copy_from_buffer(pStubMsg
, &val
, sizeof(USHORT
));
6712 /* 16-bits on the wire, but int in memory */
6713 **(UINT
**)ppMemory
= val
;
6714 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
6717 case RPC_FC_INT3264
:
6718 if (sizeof(INT_PTR
) == sizeof(INT
)) BASE_TYPE_UNMARSHALL(INT
);
6722 align_pointer(&pStubMsg
->Buffer
, sizeof(INT
));
6723 if (!fMustAlloc
&& !*ppMemory
)
6726 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(INT_PTR
));
6727 safe_copy_from_buffer(pStubMsg
, &val
, sizeof(INT
));
6728 **(INT_PTR
**)ppMemory
= val
;
6729 TRACE("value: 0x%08lx\n", **(INT_PTR
**)ppMemory
);
6732 case RPC_FC_UINT3264
:
6733 if (sizeof(UINT_PTR
) == sizeof(UINT
)) BASE_TYPE_UNMARSHALL(UINT
);
6737 align_pointer(&pStubMsg
->Buffer
, sizeof(UINT
));
6738 if (!fMustAlloc
&& !*ppMemory
)
6741 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT_PTR
));
6742 safe_copy_from_buffer(pStubMsg
, &val
, sizeof(UINT
));
6743 **(UINT_PTR
**)ppMemory
= val
;
6744 TRACE("value: 0x%08lx\n", **(UINT_PTR
**)ppMemory
);
6750 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6752 #undef BASE_TYPE_UNMARSHALL
6754 /* FIXME: what is the correct return value? */
6759 /***********************************************************************
6760 * NdrBaseTypeBufferSize [internal]
6762 static void WINAPI
NdrBaseTypeBufferSize(
6763 PMIDL_STUB_MESSAGE pStubMsg
,
6764 unsigned char *pMemory
,
6765 PFORMAT_STRING pFormat
)
6767 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6775 safe_buffer_length_increment(pStubMsg
, sizeof(UCHAR
));
6781 align_length(&pStubMsg
->BufferLength
, sizeof(USHORT
));
6782 safe_buffer_length_increment(pStubMsg
, sizeof(USHORT
));
6787 case RPC_FC_INT3264
:
6788 case RPC_FC_UINT3264
:
6789 align_length(&pStubMsg
->BufferLength
, sizeof(ULONG
));
6790 safe_buffer_length_increment(pStubMsg
, sizeof(ULONG
));
6793 align_length(&pStubMsg
->BufferLength
, sizeof(float));
6794 safe_buffer_length_increment(pStubMsg
, sizeof(float));
6797 align_length(&pStubMsg
->BufferLength
, sizeof(double));
6798 safe_buffer_length_increment(pStubMsg
, sizeof(double));
6801 align_length(&pStubMsg
->BufferLength
, sizeof(ULONGLONG
));
6802 safe_buffer_length_increment(pStubMsg
, sizeof(ULONGLONG
));
6804 case RPC_FC_ERROR_STATUS_T
:
6805 align_length(&pStubMsg
->BufferLength
, sizeof(error_status_t
));
6806 safe_buffer_length_increment(pStubMsg
, sizeof(error_status_t
));
6811 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6815 /***********************************************************************
6816 * NdrBaseTypeMemorySize [internal]
6818 static ULONG WINAPI
NdrBaseTypeMemorySize(
6819 PMIDL_STUB_MESSAGE pStubMsg
,
6820 PFORMAT_STRING pFormat
)
6822 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg
, *pFormat
);
6830 safe_buffer_increment(pStubMsg
, sizeof(UCHAR
));
6831 pStubMsg
->MemorySize
+= sizeof(UCHAR
);
6832 return sizeof(UCHAR
);
6836 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6837 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6838 align_length(&pStubMsg
->MemorySize
, sizeof(USHORT
));
6839 pStubMsg
->MemorySize
+= sizeof(USHORT
);
6840 return sizeof(USHORT
);
6844 align_pointer(&pStubMsg
->Buffer
, sizeof(ULONG
));
6845 safe_buffer_increment(pStubMsg
, sizeof(ULONG
));
6846 align_length(&pStubMsg
->MemorySize
, sizeof(ULONG
));
6847 pStubMsg
->MemorySize
+= sizeof(ULONG
);
6848 return sizeof(ULONG
);
6850 align_pointer(&pStubMsg
->Buffer
, sizeof(float));
6851 safe_buffer_increment(pStubMsg
, sizeof(float));
6852 align_length(&pStubMsg
->MemorySize
, sizeof(float));
6853 pStubMsg
->MemorySize
+= sizeof(float);
6854 return sizeof(float);
6856 align_pointer(&pStubMsg
->Buffer
, sizeof(double));
6857 safe_buffer_increment(pStubMsg
, sizeof(double));
6858 align_length(&pStubMsg
->MemorySize
, sizeof(double));
6859 pStubMsg
->MemorySize
+= sizeof(double);
6860 return sizeof(double);
6862 align_pointer(&pStubMsg
->Buffer
, sizeof(ULONGLONG
));
6863 safe_buffer_increment(pStubMsg
, sizeof(ULONGLONG
));
6864 align_length(&pStubMsg
->MemorySize
, sizeof(ULONGLONG
));
6865 pStubMsg
->MemorySize
+= sizeof(ULONGLONG
);
6866 return sizeof(ULONGLONG
);
6867 case RPC_FC_ERROR_STATUS_T
:
6868 align_pointer(&pStubMsg
->Buffer
, sizeof(error_status_t
));
6869 safe_buffer_increment(pStubMsg
, sizeof(error_status_t
));
6870 align_length(&pStubMsg
->MemorySize
, sizeof(error_status_t
));
6871 pStubMsg
->MemorySize
+= sizeof(error_status_t
);
6872 return sizeof(error_status_t
);
6874 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6875 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6876 align_length(&pStubMsg
->MemorySize
, sizeof(UINT
));
6877 pStubMsg
->MemorySize
+= sizeof(UINT
);
6878 return sizeof(UINT
);
6879 case RPC_FC_INT3264
:
6880 case RPC_FC_UINT3264
:
6881 align_pointer(&pStubMsg
->Buffer
, sizeof(UINT
));
6882 safe_buffer_increment(pStubMsg
, sizeof(UINT
));
6883 align_length(&pStubMsg
->MemorySize
, sizeof(UINT_PTR
));
6884 pStubMsg
->MemorySize
+= sizeof(UINT_PTR
);
6885 return sizeof(UINT_PTR
);
6887 align_length(&pStubMsg
->MemorySize
, sizeof(void *));
6888 pStubMsg
->MemorySize
+= sizeof(void *);
6889 return sizeof(void *);
6891 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6896 /***********************************************************************
6897 * NdrBaseTypeFree [internal]
6899 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6900 unsigned char *pMemory
,
6901 PFORMAT_STRING pFormat
)
6903 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6908 /***********************************************************************
6909 * NdrContextHandleBufferSize [internal]
6911 static void WINAPI
NdrContextHandleBufferSize(
6912 PMIDL_STUB_MESSAGE pStubMsg
,
6913 unsigned char *pMemory
,
6914 PFORMAT_STRING pFormat
)
6916 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6918 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6920 ERR("invalid format type %x\n", *pFormat
);
6921 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6923 align_length(&pStubMsg
->BufferLength
, 4);
6924 safe_buffer_length_increment(pStubMsg
, cbNDRContext
);
6927 /***********************************************************************
6928 * NdrContextHandleMarshall [internal]
6930 static unsigned char *WINAPI
NdrContextHandleMarshall(
6931 PMIDL_STUB_MESSAGE pStubMsg
,
6932 unsigned char *pMemory
,
6933 PFORMAT_STRING pFormat
)
6935 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6937 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6939 ERR("invalid format type %x\n", *pFormat
);
6940 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6942 TRACE("flags: 0x%02x\n", pFormat
[1]);
6944 if (pStubMsg
->IsClient
)
6946 if (pFormat
[1] & HANDLE_PARAM_IS_VIA_PTR
)
6947 NdrClientContextMarshall(pStubMsg
, *(NDR_CCONTEXT
**)pMemory
, FALSE
);
6949 NdrClientContextMarshall(pStubMsg
, pMemory
, FALSE
);
6953 NDR_SCONTEXT ctxt
= NDRSContextFromValue(pMemory
);
6954 NDR_RUNDOWN rundown
= pStubMsg
->StubDesc
->apfnNdrRundownRoutines
[pFormat
[2]];
6955 NdrServerContextNewMarshall(pStubMsg
, ctxt
, rundown
, pFormat
);
6961 /***********************************************************************
6962 * NdrContextHandleUnmarshall [internal]
6964 static unsigned char *WINAPI
NdrContextHandleUnmarshall(
6965 PMIDL_STUB_MESSAGE pStubMsg
,
6966 unsigned char **ppMemory
,
6967 PFORMAT_STRING pFormat
,
6968 unsigned char fMustAlloc
)
6970 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg
,
6971 ppMemory
, pFormat
, fMustAlloc
? "TRUE": "FALSE");
6973 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6975 ERR("invalid format type %x\n", *pFormat
);
6976 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6978 TRACE("flags: 0x%02x\n", pFormat
[1]);
6980 if (pStubMsg
->IsClient
)
6982 /* [out]-only or [ret] param */
6983 if ((pFormat
[1] & (HANDLE_PARAM_IS_IN
|HANDLE_PARAM_IS_OUT
)) == HANDLE_PARAM_IS_OUT
)
6984 **(NDR_CCONTEXT
**)ppMemory
= NULL
;
6985 NdrClientContextUnmarshall(pStubMsg
, *(NDR_CCONTEXT
**)ppMemory
, pStubMsg
->RpcMsg
->Handle
);
6990 ctxt
= NdrServerContextNewUnmarshall(pStubMsg
, pFormat
);
6991 if (pFormat
[1] & HANDLE_PARAM_IS_VIA_PTR
)
6992 *(void **)ppMemory
= NDRSContextValue(ctxt
);
6994 *(void **)ppMemory
= *NDRSContextValue(ctxt
);
7000 /***********************************************************************
7001 * NdrClientContextMarshall [RPCRT4.@]
7003 void WINAPI
NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7004 NDR_CCONTEXT ContextHandle
,
7007 TRACE("(%p, %p, %d)\n", pStubMsg
, ContextHandle
, fCheck
);
7009 align_pointer_clear(&pStubMsg
->Buffer
, 4);
7011 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7013 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7014 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7015 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7018 /* FIXME: what does fCheck do? */
7019 NDRCContextMarshall(ContextHandle
,
7022 pStubMsg
->Buffer
+= cbNDRContext
;
7025 /***********************************************************************
7026 * NdrClientContextUnmarshall [RPCRT4.@]
7028 void WINAPI
NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7029 NDR_CCONTEXT
* pContextHandle
,
7030 RPC_BINDING_HANDLE BindHandle
)
7032 TRACE("(%p, %p, %p)\n", pStubMsg
, pContextHandle
, BindHandle
);
7034 align_pointer(&pStubMsg
->Buffer
, 4);
7036 if (pStubMsg
->Buffer
+ cbNDRContext
> pStubMsg
->BufferEnd
)
7037 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7039 NDRCContextUnmarshall(pContextHandle
,
7042 pStubMsg
->RpcMsg
->DataRepresentation
);
7044 pStubMsg
->Buffer
+= cbNDRContext
;
7047 void WINAPI
NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7048 NDR_SCONTEXT ContextHandle
,
7049 NDR_RUNDOWN RundownRoutine
)
7051 TRACE("(%p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
);
7053 align_pointer(&pStubMsg
->Buffer
, 4);
7055 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7057 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7058 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7059 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7062 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
7063 pStubMsg
->Buffer
, RundownRoutine
, NULL
,
7064 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
7065 pStubMsg
->Buffer
+= cbNDRContext
;
7068 NDR_SCONTEXT WINAPI
NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
)
7070 NDR_SCONTEXT ContextHandle
;
7072 TRACE("(%p)\n", pStubMsg
);
7074 align_pointer(&pStubMsg
->Buffer
, 4);
7076 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7078 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7079 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7080 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7083 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
7085 pStubMsg
->RpcMsg
->DataRepresentation
,
7086 NULL
, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
7087 pStubMsg
->Buffer
+= cbNDRContext
;
7089 return ContextHandle
;
7092 void WINAPI
NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg
,
7093 unsigned char* pMemory
,
7094 PFORMAT_STRING pFormat
)
7096 FIXME("(%p, %p, %p): stub\n", pStubMsg
, pMemory
, pFormat
);
7099 NDR_SCONTEXT WINAPI
NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg
,
7100 PFORMAT_STRING pFormat
)
7102 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
7103 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
7105 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
7107 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
7108 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
7109 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
7110 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
7111 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
7113 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
7114 if_id
= &sif
->InterfaceId
;
7117 return NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
, NULL
,
7118 pStubMsg
->RpcMsg
->DataRepresentation
, if_id
,
7122 void WINAPI
NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7123 NDR_SCONTEXT ContextHandle
,
7124 NDR_RUNDOWN RundownRoutine
,
7125 PFORMAT_STRING pFormat
)
7127 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
7128 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
7130 TRACE("(%p, %p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
, pFormat
);
7132 align_pointer(&pStubMsg
->Buffer
, 4);
7134 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7136 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7137 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7138 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7141 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
7142 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
7143 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
7144 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
7145 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
7147 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
7148 if_id
= &sif
->InterfaceId
;
7151 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
7152 pStubMsg
->Buffer
, RundownRoutine
, if_id
, flags
);
7153 pStubMsg
->Buffer
+= cbNDRContext
;
7156 NDR_SCONTEXT WINAPI
NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7157 PFORMAT_STRING pFormat
)
7159 NDR_SCONTEXT ContextHandle
;
7160 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
7161 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
7163 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
7165 align_pointer(&pStubMsg
->Buffer
, 4);
7167 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7169 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7170 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7171 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7174 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
7175 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
7176 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
7177 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
7178 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
7180 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
7181 if_id
= &sif
->InterfaceId
;
7184 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
7186 pStubMsg
->RpcMsg
->DataRepresentation
,
7188 pStubMsg
->Buffer
+= cbNDRContext
;
7190 return ContextHandle
;
7193 /***********************************************************************
7194 * NdrCorrelationInitialize [RPCRT4.@]
7196 * Initializes correlation validity checking.
7199 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7200 * pMemory [I] Pointer to memory to use as a cache.
7201 * CacheSize [I] Size of the memory pointed to by pMemory.
7202 * Flags [I] Reserved. Set to zero.
7207 void WINAPI
NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg
, void *pMemory
, ULONG CacheSize
, ULONG Flags
)
7209 FIXME("(%p, %p, %d, 0x%x): semi-stub\n", pStubMsg
, pMemory
, CacheSize
, Flags
);
7211 if (pStubMsg
->CorrDespIncrement
== 0)
7212 pStubMsg
->CorrDespIncrement
= 2; /* size of the normal (non-range) /robust payload */
7214 pStubMsg
->fHasNewCorrDesc
= TRUE
;
7217 /***********************************************************************
7218 * NdrCorrelationPass [RPCRT4.@]
7220 * Performs correlation validity checking.
7223 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7228 void WINAPI
NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg
)
7230 FIXME("(%p): stub\n", pStubMsg
);
7233 /***********************************************************************
7234 * NdrCorrelationFree [RPCRT4.@]
7236 * Frees any resources used while unmarshalling parameters that need
7237 * correlation validity checking.
7240 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7245 void WINAPI
NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg
)
7247 FIXME("(%p): stub\n", pStubMsg
);