4 * Copyright 2002 Greg Turner
5 * Copyright 2003-2006 CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 * - Byte count pointers
24 * - transmit_as/represent as
25 * - Multi-dimensional arrays
26 * - Conversion functions (NdrConvert)
27 * - Checks for integer addition overflow in user marshall functions
32 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
35 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
36 (*((UINT32 *)(pchar)) = (uint32))
38 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
39 (*((UINT32 *)(pchar)))
41 /* these would work for i386 too, but less efficient */
42 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
43 (*(pchar) = LOBYTE(LOWORD(uint32)), \
44 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
45 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
46 *((pchar)+3) = HIBYTE(HIWORD(uint32)))
48 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
50 MAKEWORD(*(pchar), *((pchar)+1)), \
51 MAKEWORD(*((pchar)+2), *((pchar)+3))))
54 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
55 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
56 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
57 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
58 *(pchar) = HIBYTE(HIWORD(uint32)))
60 #define BIG_ENDIAN_UINT32_READ(pchar) \
62 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
63 MAKEWORD(*((pchar)+1), *(pchar))))
65 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
66 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
67 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
68 # define NDR_LOCAL_UINT32_READ(pchar) \
69 BIG_ENDIAN_UINT32_READ(pchar)
71 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
72 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
73 # define NDR_LOCAL_UINT32_READ(pchar) \
74 LITTLE_ENDIAN_UINT32_READ(pchar)
77 static inline void align_length( ULONG
*len
, unsigned int align
)
79 *len
= (*len
+ align
- 1) & ~(align
- 1);
82 static inline void align_pointer( unsigned char **ptr
, unsigned int align
)
84 ULONG_PTR mask
= align
- 1;
85 *ptr
= (unsigned char *)(((ULONG_PTR
)*ptr
+ mask
) & ~mask
);
88 static inline void align_pointer_clear( unsigned char **ptr
, unsigned int align
)
90 ULONG_PTR mask
= align
- 1;
91 memset( *ptr
, 0, (align
- (ULONG_PTR
)*ptr
) & mask
);
92 *ptr
= (unsigned char *)(((ULONG_PTR
)*ptr
+ mask
) & ~mask
);
95 #define STD_OVERFLOW_CHECK(_Msg) do { \
96 TRACE("buffer=%d/%d\n", (ULONG)(_Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer), _Msg->BufferLength); \
97 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
98 ERR("buffer overflow %d bytes\n", (ULONG)(_Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength))); \
101 #define NDR_POINTER_ID_BASE 0x20000
102 #define NDR_POINTER_ID(pStubMsg) (NDR_POINTER_ID_BASE + ((pStubMsg)->UniquePtrCount++) * 4)
103 #define NDR_TABLE_SIZE 128
104 #define NDR_TABLE_MASK 127
106 #define NDRSContextFromValue(user_context) (NDR_SCONTEXT)((char *)(user_context) - (char *)NDRSContextValue((NDR_SCONTEXT)NULL))
108 static unsigned char *WINAPI
NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
109 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
110 static void WINAPI
NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
111 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
112 static ULONG WINAPI
NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
114 static unsigned char *WINAPI
NdrContextHandleMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
115 static void WINAPI
NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
116 static unsigned char *WINAPI
NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
118 static unsigned char *WINAPI
NdrRangeMarshall(PMIDL_STUB_MESSAGE
,unsigned char *, PFORMAT_STRING
);
119 static void WINAPI
NdrRangeBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
120 static ULONG WINAPI
NdrRangeMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
121 static void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
123 static ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
125 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
126 unsigned char *pMemory
,
127 PFORMAT_STRING pFormat
,
128 PFORMAT_STRING pPointer
);
129 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
130 unsigned char *pMemory
,
131 PFORMAT_STRING pFormat
,
132 PFORMAT_STRING pPointer
);
133 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
134 unsigned char *pMemory
,
135 PFORMAT_STRING pFormat
,
136 PFORMAT_STRING pPointer
,
137 unsigned char fMustAlloc
);
138 static ULONG
ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
139 PFORMAT_STRING pFormat
,
140 PFORMAT_STRING pPointer
);
141 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
142 unsigned char *pMemory
,
143 PFORMAT_STRING pFormat
,
144 PFORMAT_STRING pPointer
);
146 const NDR_MARSHALL NdrMarshaller
[NDR_TABLE_SIZE
] = {
148 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
149 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
150 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
151 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
155 NdrPointerMarshall
, NdrPointerMarshall
,
156 NdrPointerMarshall
, NdrPointerMarshall
,
158 NdrSimpleStructMarshall
, NdrSimpleStructMarshall
,
159 NdrConformantStructMarshall
, NdrConformantStructMarshall
,
160 NdrConformantVaryingStructMarshall
,
161 NdrComplexStructMarshall
,
163 NdrConformantArrayMarshall
,
164 NdrConformantVaryingArrayMarshall
,
165 NdrFixedArrayMarshall
, NdrFixedArrayMarshall
,
166 NdrVaryingArrayMarshall
, NdrVaryingArrayMarshall
,
167 NdrComplexArrayMarshall
,
169 NdrConformantStringMarshall
, 0, 0,
170 NdrConformantStringMarshall
,
171 NdrNonConformantStringMarshall
, 0, 0, 0,
173 NdrEncapsulatedUnionMarshall
,
174 NdrNonEncapsulatedUnionMarshall
,
175 NdrByteCountPointerMarshall
,
176 NdrXmitOrRepAsMarshall
, NdrXmitOrRepAsMarshall
,
178 NdrInterfacePointerMarshall
,
180 NdrContextHandleMarshall
,
183 NdrUserMarshalMarshall
,
190 const NDR_UNMARSHALL NdrUnmarshaller
[NDR_TABLE_SIZE
] = {
192 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
193 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
194 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
195 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
197 NdrBaseTypeUnmarshall
,
199 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
200 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
202 NdrSimpleStructUnmarshall
, NdrSimpleStructUnmarshall
,
203 NdrConformantStructUnmarshall
, NdrConformantStructUnmarshall
,
204 NdrConformantVaryingStructUnmarshall
,
205 NdrComplexStructUnmarshall
,
207 NdrConformantArrayUnmarshall
,
208 NdrConformantVaryingArrayUnmarshall
,
209 NdrFixedArrayUnmarshall
, NdrFixedArrayUnmarshall
,
210 NdrVaryingArrayUnmarshall
, NdrVaryingArrayUnmarshall
,
211 NdrComplexArrayUnmarshall
,
213 NdrConformantStringUnmarshall
, 0, 0,
214 NdrConformantStringUnmarshall
,
215 NdrNonConformantStringUnmarshall
, 0, 0, 0,
217 NdrEncapsulatedUnionUnmarshall
,
218 NdrNonEncapsulatedUnionUnmarshall
,
219 NdrByteCountPointerUnmarshall
,
220 NdrXmitOrRepAsUnmarshall
, NdrXmitOrRepAsUnmarshall
,
222 NdrInterfacePointerUnmarshall
,
224 NdrContextHandleUnmarshall
,
227 NdrUserMarshalUnmarshall
,
231 NdrBaseTypeUnmarshall
,
232 NdrBaseTypeUnmarshall
234 const NDR_BUFFERSIZE NdrBufferSizer
[NDR_TABLE_SIZE
] = {
236 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
237 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
238 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
239 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
241 NdrBaseTypeBufferSize
,
243 NdrPointerBufferSize
, NdrPointerBufferSize
,
244 NdrPointerBufferSize
, NdrPointerBufferSize
,
246 NdrSimpleStructBufferSize
, NdrSimpleStructBufferSize
,
247 NdrConformantStructBufferSize
, NdrConformantStructBufferSize
,
248 NdrConformantVaryingStructBufferSize
,
249 NdrComplexStructBufferSize
,
251 NdrConformantArrayBufferSize
,
252 NdrConformantVaryingArrayBufferSize
,
253 NdrFixedArrayBufferSize
, NdrFixedArrayBufferSize
,
254 NdrVaryingArrayBufferSize
, NdrVaryingArrayBufferSize
,
255 NdrComplexArrayBufferSize
,
257 NdrConformantStringBufferSize
, 0, 0,
258 NdrConformantStringBufferSize
,
259 NdrNonConformantStringBufferSize
, 0, 0, 0,
261 NdrEncapsulatedUnionBufferSize
,
262 NdrNonEncapsulatedUnionBufferSize
,
263 NdrByteCountPointerBufferSize
,
264 NdrXmitOrRepAsBufferSize
, NdrXmitOrRepAsBufferSize
,
266 NdrInterfacePointerBufferSize
,
268 NdrContextHandleBufferSize
,
271 NdrUserMarshalBufferSize
,
275 NdrBaseTypeBufferSize
,
276 NdrBaseTypeBufferSize
278 const NDR_MEMORYSIZE NdrMemorySizer
[NDR_TABLE_SIZE
] = {
280 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
281 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
282 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
283 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
285 NdrBaseTypeMemorySize
,
287 NdrPointerMemorySize
, NdrPointerMemorySize
,
288 NdrPointerMemorySize
, NdrPointerMemorySize
,
290 NdrSimpleStructMemorySize
, NdrSimpleStructMemorySize
,
291 NdrConformantStructMemorySize
, NdrConformantStructMemorySize
,
292 NdrConformantVaryingStructMemorySize
,
293 NdrComplexStructMemorySize
,
295 NdrConformantArrayMemorySize
,
296 NdrConformantVaryingArrayMemorySize
,
297 NdrFixedArrayMemorySize
, NdrFixedArrayMemorySize
,
298 NdrVaryingArrayMemorySize
, NdrVaryingArrayMemorySize
,
299 NdrComplexArrayMemorySize
,
301 NdrConformantStringMemorySize
, 0, 0,
302 NdrConformantStringMemorySize
,
303 NdrNonConformantStringMemorySize
, 0, 0, 0,
305 NdrEncapsulatedUnionMemorySize
,
306 NdrNonEncapsulatedUnionMemorySize
,
307 NdrByteCountPointerMemorySize
,
308 NdrXmitOrRepAsMemorySize
, NdrXmitOrRepAsMemorySize
,
310 NdrInterfacePointerMemorySize
,
315 NdrUserMarshalMemorySize
,
319 NdrBaseTypeMemorySize
,
320 NdrBaseTypeMemorySize
322 const NDR_FREE NdrFreer
[NDR_TABLE_SIZE
] = {
324 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
325 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
326 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
327 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
331 NdrPointerFree
, NdrPointerFree
,
332 NdrPointerFree
, NdrPointerFree
,
334 NdrSimpleStructFree
, NdrSimpleStructFree
,
335 NdrConformantStructFree
, NdrConformantStructFree
,
336 NdrConformantVaryingStructFree
,
337 NdrComplexStructFree
,
339 NdrConformantArrayFree
,
340 NdrConformantVaryingArrayFree
,
341 NdrFixedArrayFree
, NdrFixedArrayFree
,
342 NdrVaryingArrayFree
, NdrVaryingArrayFree
,
348 NdrEncapsulatedUnionFree
,
349 NdrNonEncapsulatedUnionFree
,
351 NdrXmitOrRepAsFree
, NdrXmitOrRepAsFree
,
353 NdrInterfacePointerFree
,
366 typedef struct _NDR_MEMORY_LIST
371 struct _NDR_MEMORY_LIST
*next
;
374 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
376 /***********************************************************************
377 * NdrAllocate [RPCRT4.@]
379 * Allocates a block of memory using pStubMsg->pfnAllocate.
382 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
383 * len [I] Size of memory block to allocate.
386 * The memory block of size len that was allocated.
389 * The memory block is always 8-byte aligned.
390 * If the function is unable to allocate memory an RPC_X_NO_MEMORY
391 * exception is raised.
393 void * WINAPI
NdrAllocate(MIDL_STUB_MESSAGE
*pStubMsg
, SIZE_T len
)
398 NDR_MEMORY_LIST
*mem_list
;
400 aligned_len
= (len
+ 7) & ~7;
401 adjusted_len
= aligned_len
+ sizeof(NDR_MEMORY_LIST
);
402 /* check for overflow */
403 if (adjusted_len
< len
)
405 ERR("overflow of adjusted_len %ld, len %ld\n", adjusted_len
, len
);
406 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
409 p
= pStubMsg
->pfnAllocate(adjusted_len
);
410 if (!p
) RpcRaiseException(RPC_X_NO_MEMORY
);
412 mem_list
= (NDR_MEMORY_LIST
*)((char *)p
+ aligned_len
);
413 mem_list
->magic
= MEML_MAGIC
;
414 mem_list
->size
= aligned_len
;
415 mem_list
->reserved
= 0;
416 mem_list
->next
= pStubMsg
->pMemoryList
;
417 pStubMsg
->pMemoryList
= mem_list
;
423 static void NdrFree(MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *Pointer
)
425 TRACE("(%p, %p)\n", pStubMsg
, Pointer
);
427 pStubMsg
->pfnFree(Pointer
);
430 static inline BOOL
IsConformanceOrVariancePresent(PFORMAT_STRING pFormat
)
432 return (*(const ULONG
*)pFormat
!= -1);
435 static inline PFORMAT_STRING
SkipConformance(const PMIDL_STUB_MESSAGE pStubMsg
, const PFORMAT_STRING pFormat
)
437 return pFormat
+ 4 + pStubMsg
->CorrDespIncrement
;
440 static PFORMAT_STRING
ReadConformance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
)
442 align_pointer(&pStubMsg
->Buffer
, 4);
443 if (pStubMsg
->Buffer
+ 4 > pStubMsg
->BufferEnd
)
444 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
445 pStubMsg
->MaxCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
446 pStubMsg
->Buffer
+= 4;
447 TRACE("unmarshalled conformance is %ld\n", pStubMsg
->MaxCount
);
448 return SkipConformance(pStubMsg
, pFormat
);
451 static inline PFORMAT_STRING
ReadVariance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
, ULONG MaxValue
)
453 if (pFormat
&& !IsConformanceOrVariancePresent(pFormat
))
455 pStubMsg
->Offset
= 0;
456 pStubMsg
->ActualCount
= pStubMsg
->MaxCount
;
460 align_pointer(&pStubMsg
->Buffer
, 4);
461 if (pStubMsg
->Buffer
+ 8 > pStubMsg
->BufferEnd
)
462 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
463 pStubMsg
->Offset
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
464 pStubMsg
->Buffer
+= 4;
465 TRACE("offset is %d\n", pStubMsg
->Offset
);
466 pStubMsg
->ActualCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
467 pStubMsg
->Buffer
+= 4;
468 TRACE("variance is %d\n", pStubMsg
->ActualCount
);
470 if ((pStubMsg
->ActualCount
> MaxValue
) ||
471 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> MaxValue
))
473 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
474 pStubMsg
->ActualCount
, pStubMsg
->Offset
, MaxValue
);
475 RpcRaiseException(RPC_S_INVALID_BOUND
);
480 return SkipConformance(pStubMsg
, pFormat
);
483 /* writes the conformance value to the buffer */
484 static inline void WriteConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
486 align_pointer_clear(&pStubMsg
->Buffer
, 4);
487 if (pStubMsg
->Buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
488 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
489 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->MaxCount
);
490 pStubMsg
->Buffer
+= 4;
493 /* writes the variance values to the buffer */
494 static inline void WriteVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
496 align_pointer_clear(&pStubMsg
->Buffer
, 4);
497 if (pStubMsg
->Buffer
+ 8 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
498 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
499 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->Offset
);
500 pStubMsg
->Buffer
+= 4;
501 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->ActualCount
);
502 pStubMsg
->Buffer
+= 4;
505 /* requests buffer space for the conformance value */
506 static inline void SizeConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
508 align_length(&pStubMsg
->BufferLength
, 4);
509 if (pStubMsg
->BufferLength
+ 4 < pStubMsg
->BufferLength
)
510 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
511 pStubMsg
->BufferLength
+= 4;
514 /* requests buffer space for the variance values */
515 static inline void SizeVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
517 align_length(&pStubMsg
->BufferLength
, 4);
518 if (pStubMsg
->BufferLength
+ 8 < pStubMsg
->BufferLength
)
519 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
520 pStubMsg
->BufferLength
+= 8;
523 PFORMAT_STRING
ComputeConformanceOrVariance(
524 MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *pMemory
,
525 PFORMAT_STRING pFormat
, ULONG_PTR def
, ULONG_PTR
*pCount
)
527 BYTE dtype
= pFormat
[0] & 0xf;
528 short ofs
= *(const short *)&pFormat
[2];
532 if (!IsConformanceOrVariancePresent(pFormat
)) {
533 /* null descriptor */
538 switch (pFormat
[0] & 0xf0) {
539 case RPC_FC_NORMAL_CONFORMANCE
:
540 TRACE("normal conformance, ofs=%d\n", ofs
);
543 case RPC_FC_POINTER_CONFORMANCE
:
544 TRACE("pointer conformance, ofs=%d\n", ofs
);
545 ptr
= pStubMsg
->Memory
;
547 case RPC_FC_TOP_LEVEL_CONFORMANCE
:
548 TRACE("toplevel conformance, ofs=%d\n", ofs
);
549 if (pStubMsg
->StackTop
) {
550 ptr
= pStubMsg
->StackTop
;
553 /* -Os mode, *pCount is already set */
557 case RPC_FC_CONSTANT_CONFORMANCE
:
558 data
= ofs
| ((DWORD
)pFormat
[1] << 16);
559 TRACE("constant conformance, val=%ld\n", data
);
562 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE
:
563 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs
);
564 if (pStubMsg
->StackTop
) {
565 ptr
= pStubMsg
->StackTop
;
573 FIXME("unknown conformance type %x, expect crash.\n", pFormat
[0] & 0xf0);
577 switch (pFormat
[1]) {
578 case RPC_FC_DEREFERENCE
:
579 ptr
= *(LPVOID
*)((char *)ptr
+ ofs
);
581 case RPC_FC_CALLBACK
:
583 unsigned char *old_stack_top
= pStubMsg
->StackTop
;
584 ULONG_PTR max_count
, old_max_count
= pStubMsg
->MaxCount
;
586 pStubMsg
->StackTop
= ptr
;
588 /* ofs is index into StubDesc->apfnExprEval */
589 TRACE("callback conformance into apfnExprEval[%d]\n", ofs
);
590 pStubMsg
->StubDesc
->apfnExprEval
[ofs
](pStubMsg
);
592 pStubMsg
->StackTop
= old_stack_top
;
594 /* the callback function always stores the computed value in MaxCount */
595 max_count
= pStubMsg
->MaxCount
;
596 pStubMsg
->MaxCount
= old_max_count
;
601 ptr
= (char *)ptr
+ ofs
;
614 data
= *(USHORT
*)ptr
;
625 data
= *(ULONGLONG
*)ptr
;
628 FIXME("unknown conformance data type %x\n", dtype
);
631 TRACE("dereferenced data type %x at %p, got %ld\n", dtype
, ptr
, data
);
634 switch (pFormat
[1]) {
635 case RPC_FC_DEREFERENCE
: /* already handled */
652 FIXME("unknown conformance op %d\n", pFormat
[1]);
657 TRACE("resulting conformance is %ld\n", *pCount
);
659 return SkipConformance(pStubMsg
, pFormat
);
662 static inline PFORMAT_STRING
SkipVariance(PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
664 return SkipConformance( pStubMsg
, pFormat
);
667 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
668 * the result overflows 32-bits */
669 static inline ULONG
safe_multiply(ULONG a
, ULONG b
)
671 ULONGLONG ret
= (ULONGLONG
)a
* b
;
672 if (ret
> 0xffffffff)
674 RpcRaiseException(RPC_S_INVALID_BOUND
);
680 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
682 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
683 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
684 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
685 pStubMsg
->Buffer
+= size
;
688 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
690 if (pStubMsg
->BufferLength
+ size
< pStubMsg
->BufferLength
) /* integer overflow of pStubMsg->BufferSize */
692 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
693 pStubMsg
->BufferLength
, size
);
694 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
696 pStubMsg
->BufferLength
+= size
;
699 /* copies data from the buffer, checking that there is enough data in the buffer
701 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, void *p
, ULONG size
)
703 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
704 (pStubMsg
->Buffer
+ size
> pStubMsg
->BufferEnd
))
706 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
707 pStubMsg
->Buffer
, pStubMsg
->BufferEnd
, size
);
708 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
710 if (p
== pStubMsg
->Buffer
)
711 ERR("pointer is the same as the buffer\n");
712 memcpy(p
, pStubMsg
->Buffer
, size
);
713 pStubMsg
->Buffer
+= size
;
716 /* copies data to the buffer, checking that there is enough space to do so */
717 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, const void *p
, ULONG size
)
719 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
720 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
722 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
723 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
,
725 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
727 memcpy(pStubMsg
->Buffer
, p
, size
);
728 pStubMsg
->Buffer
+= size
;
731 /* verify that string data sitting in the buffer is valid and safe to
733 static void validate_string_data(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG bufsize
, ULONG esize
)
737 /* verify the buffer is safe to access */
738 if ((pStubMsg
->Buffer
+ bufsize
< pStubMsg
->Buffer
) ||
739 (pStubMsg
->Buffer
+ bufsize
> pStubMsg
->BufferEnd
))
741 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize
,
742 pStubMsg
->BufferEnd
, pStubMsg
->Buffer
);
743 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
746 /* strings must always have null terminating bytes */
749 ERR("invalid string length of %d\n", bufsize
/ esize
);
750 RpcRaiseException(RPC_S_INVALID_BOUND
);
753 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
754 if (pStubMsg
->Buffer
[i
] != 0)
756 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
757 i
, pStubMsg
->Buffer
[i
]);
758 RpcRaiseException(RPC_S_INVALID_BOUND
);
762 static inline void dump_pointer_attr(unsigned char attr
)
764 if (attr
& RPC_FC_P_ALLOCALLNODES
)
765 TRACE(" RPC_FC_P_ALLOCALLNODES");
766 if (attr
& RPC_FC_P_DONTFREE
)
767 TRACE(" RPC_FC_P_DONTFREE");
768 if (attr
& RPC_FC_P_ONSTACK
)
769 TRACE(" RPC_FC_P_ONSTACK");
770 if (attr
& RPC_FC_P_SIMPLEPOINTER
)
771 TRACE(" RPC_FC_P_SIMPLEPOINTER");
772 if (attr
& RPC_FC_P_DEREF
)
773 TRACE(" RPC_FC_P_DEREF");
777 /***********************************************************************
778 * PointerMarshall [internal]
780 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
781 unsigned char *Buffer
,
782 unsigned char *Pointer
,
783 PFORMAT_STRING pFormat
)
785 unsigned type
= pFormat
[0], attr
= pFormat
[1];
789 BOOL pointer_needs_marshaling
;
791 TRACE("(%p,%p,%p,%p)\n", pStubMsg
, Buffer
, Pointer
, pFormat
);
792 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
794 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
795 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
798 case RPC_FC_RP
: /* ref pointer (always non-null) */
801 ERR("NULL ref pointer is not allowed\n");
802 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
804 pointer_needs_marshaling
= TRUE
;
806 case RPC_FC_UP
: /* unique pointer */
807 case RPC_FC_OP
: /* object pointer - same as unique here */
809 pointer_needs_marshaling
= TRUE
;
811 pointer_needs_marshaling
= FALSE
;
812 pointer_id
= Pointer
? NDR_POINTER_ID(pStubMsg
) : 0;
813 TRACE("writing 0x%08x to buffer\n", pointer_id
);
814 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
817 pointer_needs_marshaling
= !NdrFullPointerQueryPointer(
818 pStubMsg
->FullPtrXlatTables
, Pointer
, 1, &pointer_id
);
819 TRACE("writing 0x%08x to buffer\n", pointer_id
);
820 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
823 FIXME("unhandled ptr type=%02x\n", type
);
824 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
828 TRACE("calling marshaller for type 0x%x\n", (int)*desc
);
830 if (pointer_needs_marshaling
) {
831 if (attr
& RPC_FC_P_DEREF
) {
832 Pointer
= *(unsigned char**)Pointer
;
833 TRACE("deref => %p\n", Pointer
);
835 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
836 if (m
) m(pStubMsg
, Pointer
, desc
);
837 else FIXME("no marshaller for data type=%02x\n", *desc
);
840 STD_OVERFLOW_CHECK(pStubMsg
);
843 /***********************************************************************
844 * PointerUnmarshall [internal]
846 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
847 unsigned char *Buffer
,
848 unsigned char **pPointer
,
849 unsigned char *pSrcPointer
,
850 PFORMAT_STRING pFormat
,
851 unsigned char fMustAlloc
)
853 unsigned type
= pFormat
[0], attr
= pFormat
[1];
856 DWORD pointer_id
= 0;
857 BOOL pointer_needs_unmarshaling
;
859 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg
, Buffer
, pPointer
, pSrcPointer
, pFormat
, fMustAlloc
);
860 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
862 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
863 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
866 case RPC_FC_RP
: /* ref pointer (always non-null) */
867 pointer_needs_unmarshaling
= TRUE
;
869 case RPC_FC_UP
: /* unique pointer */
870 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
871 TRACE("pointer_id is 0x%08x\n", pointer_id
);
873 pointer_needs_unmarshaling
= TRUE
;
876 pointer_needs_unmarshaling
= FALSE
;
879 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
880 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
881 TRACE("pointer_id is 0x%08x\n", pointer_id
);
882 if (!fMustAlloc
&& pSrcPointer
)
884 FIXME("free object pointer %p\n", pSrcPointer
);
888 pointer_needs_unmarshaling
= TRUE
;
892 pointer_needs_unmarshaling
= FALSE
;
896 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
897 TRACE("pointer_id is 0x%08x\n", pointer_id
);
898 pointer_needs_unmarshaling
= !NdrFullPointerQueryRefId(
899 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, (void **)pPointer
);
902 FIXME("unhandled ptr type=%02x\n", type
);
903 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
907 if (pointer_needs_unmarshaling
) {
908 unsigned char **current_ptr
= pPointer
;
909 if (pStubMsg
->IsClient
) {
911 /* if we aren't forcing allocation of memory then try to use the existing
912 * (source) pointer to unmarshall the data into so that [in,out]
913 * parameters behave correctly. it doesn't matter if the parameter is
914 * [out] only since in that case the pointer will be NULL. we force
915 * allocation when the source pointer is NULL here instead of in the type
916 * unmarshalling routine for the benefit of the deref code below */
919 TRACE("setting *pPointer to %p\n", pSrcPointer
);
920 *pPointer
= pSrcPointer
;
926 /* the memory in a stub is never initialised, so we have to work out here
927 * whether we have to initialise it so we can use the optimisation of
928 * setting the pointer to the buffer, if possible, or set fMustAlloc to
930 if (attr
& RPC_FC_P_DEREF
) {
937 if (attr
& RPC_FC_P_ALLOCALLNODES
)
938 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
940 if (attr
& RPC_FC_P_DEREF
) {
942 unsigned char *base_ptr_val
= NdrAllocate(pStubMsg
, sizeof(void *));
943 *pPointer
= base_ptr_val
;
944 current_ptr
= (unsigned char **)base_ptr_val
;
946 current_ptr
= *(unsigned char***)current_ptr
;
947 TRACE("deref => %p\n", current_ptr
);
948 if (!fMustAlloc
&& !*current_ptr
) fMustAlloc
= TRUE
;
950 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
951 if (m
) m(pStubMsg
, current_ptr
, desc
, fMustAlloc
);
952 else FIXME("no unmarshaller for data type=%02x\n", *desc
);
954 if (type
== RPC_FC_FP
)
955 NdrFullPointerInsertRefId(pStubMsg
->FullPtrXlatTables
, pointer_id
,
959 TRACE("pointer=%p\n", *pPointer
);
962 /***********************************************************************
963 * PointerBufferSize [internal]
965 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
966 unsigned char *Pointer
,
967 PFORMAT_STRING pFormat
)
969 unsigned type
= pFormat
[0], attr
= pFormat
[1];
972 BOOL pointer_needs_sizing
;
975 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
976 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
978 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
979 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
982 case RPC_FC_RP
: /* ref pointer (always non-null) */
985 ERR("NULL ref pointer is not allowed\n");
986 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
991 /* NULL pointer has no further representation */
996 pointer_needs_sizing
= !NdrFullPointerQueryPointer(
997 pStubMsg
->FullPtrXlatTables
, Pointer
, 0, &pointer_id
);
998 if (!pointer_needs_sizing
)
1002 FIXME("unhandled ptr type=%02x\n", type
);
1003 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1007 if (attr
& RPC_FC_P_DEREF
) {
1008 Pointer
= *(unsigned char**)Pointer
;
1009 TRACE("deref => %p\n", Pointer
);
1012 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
1013 if (m
) m(pStubMsg
, Pointer
, desc
);
1014 else FIXME("no buffersizer for data type=%02x\n", *desc
);
1017 /***********************************************************************
1018 * PointerMemorySize [internal]
1020 static ULONG
PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1021 unsigned char *Buffer
, PFORMAT_STRING pFormat
)
1023 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1024 PFORMAT_STRING desc
;
1026 DWORD pointer_id
= 0;
1027 BOOL pointer_needs_sizing
;
1029 TRACE("(%p,%p,%p)\n", pStubMsg
, Buffer
, pFormat
);
1030 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1032 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1033 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1036 case RPC_FC_RP
: /* ref pointer (always non-null) */
1037 pointer_needs_sizing
= TRUE
;
1039 case RPC_FC_UP
: /* unique pointer */
1040 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
1041 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1042 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1044 pointer_needs_sizing
= TRUE
;
1046 pointer_needs_sizing
= FALSE
;
1051 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1052 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1053 pointer_needs_sizing
= !NdrFullPointerQueryRefId(
1054 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, &pointer
);
1058 FIXME("unhandled ptr type=%02x\n", type
);
1059 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1063 if (attr
& RPC_FC_P_DEREF
) {
1064 align_length(&pStubMsg
->MemorySize
, sizeof(void*));
1065 pStubMsg
->MemorySize
+= sizeof(void*);
1069 if (pointer_needs_sizing
) {
1070 m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
1071 if (m
) m(pStubMsg
, desc
);
1072 else FIXME("no memorysizer for data type=%02x\n", *desc
);
1075 return pStubMsg
->MemorySize
;
1078 /***********************************************************************
1079 * PointerFree [internal]
1081 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1082 unsigned char *Pointer
,
1083 PFORMAT_STRING pFormat
)
1085 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1086 PFORMAT_STRING desc
;
1088 unsigned char *current_pointer
= Pointer
;
1090 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1091 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1092 if (attr
& RPC_FC_P_DONTFREE
) return;
1094 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1095 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1097 if (!Pointer
) return;
1099 if (type
== RPC_FC_FP
) {
1100 int pointer_needs_freeing
= NdrFullPointerFree(
1101 pStubMsg
->FullPtrXlatTables
, Pointer
);
1102 if (!pointer_needs_freeing
)
1106 if (attr
& RPC_FC_P_DEREF
) {
1107 current_pointer
= *(unsigned char**)Pointer
;
1108 TRACE("deref => %p\n", current_pointer
);
1111 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
1112 if (m
) m(pStubMsg
, current_pointer
, desc
);
1114 /* this check stops us from trying to free buffer memory. we don't have to
1115 * worry about clients, since they won't call this function.
1116 * we don't have to check for the buffer being reallocated because
1117 * BufferStart and BufferEnd won't be reset when allocating memory for
1118 * sending the response. we don't have to check for the new buffer here as
1119 * it won't be used a type memory, only for buffer memory */
1120 if (Pointer
>= pStubMsg
->BufferStart
&& Pointer
<= pStubMsg
->BufferEnd
)
1123 if (attr
& RPC_FC_P_ONSTACK
) {
1124 TRACE("not freeing stack ptr %p\n", Pointer
);
1127 TRACE("freeing %p\n", Pointer
);
1128 NdrFree(pStubMsg
, Pointer
);
1131 TRACE("not freeing %p\n", Pointer
);
1134 /***********************************************************************
1135 * EmbeddedPointerMarshall
1137 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1138 unsigned char *pMemory
,
1139 PFORMAT_STRING pFormat
)
1141 unsigned char *Mark
= pStubMsg
->BufferMark
;
1142 unsigned rep
, count
, stride
;
1144 unsigned char *saved_buffer
= NULL
;
1146 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1148 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1151 if (pStubMsg
->PointerBufferMark
)
1153 saved_buffer
= pStubMsg
->Buffer
;
1154 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1155 pStubMsg
->PointerBufferMark
= NULL
;
1158 while (pFormat
[0] != RPC_FC_END
) {
1159 switch (pFormat
[0]) {
1161 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat
[0]);
1163 case RPC_FC_NO_REPEAT
:
1169 case RPC_FC_FIXED_REPEAT
:
1170 rep
= *(const WORD
*)&pFormat
[2];
1171 stride
= *(const WORD
*)&pFormat
[4];
1172 count
= *(const WORD
*)&pFormat
[8];
1175 case RPC_FC_VARIABLE_REPEAT
:
1176 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1177 stride
= *(const WORD
*)&pFormat
[2];
1178 count
= *(const WORD
*)&pFormat
[6];
1182 for (i
= 0; i
< rep
; i
++) {
1183 PFORMAT_STRING info
= pFormat
;
1184 unsigned char *membase
= pMemory
+ (i
* stride
);
1185 unsigned char *bufbase
= Mark
+ (i
* stride
);
1188 for (u
=0; u
<count
; u
++,info
+=8) {
1189 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1190 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1191 unsigned char *saved_memory
= pStubMsg
->Memory
;
1193 pStubMsg
->Memory
= membase
;
1194 PointerMarshall(pStubMsg
, bufptr
, *(unsigned char**)memptr
, info
+4);
1195 pStubMsg
->Memory
= saved_memory
;
1198 pFormat
+= 8 * count
;
1203 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1204 pStubMsg
->Buffer
= saved_buffer
;
1207 STD_OVERFLOW_CHECK(pStubMsg
);
1212 /***********************************************************************
1213 * EmbeddedPointerUnmarshall
1215 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1216 unsigned char *pDstBuffer
,
1217 unsigned char *pSrcMemoryPtrs
,
1218 PFORMAT_STRING pFormat
,
1219 unsigned char fMustAlloc
)
1221 unsigned char *Mark
= pStubMsg
->BufferMark
;
1222 unsigned rep
, count
, stride
;
1224 unsigned char *saved_buffer
= NULL
;
1226 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg
, pDstBuffer
, pSrcMemoryPtrs
, pFormat
, fMustAlloc
);
1228 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1231 if (pStubMsg
->PointerBufferMark
)
1233 saved_buffer
= pStubMsg
->Buffer
;
1234 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1235 pStubMsg
->PointerBufferMark
= NULL
;
1238 while (pFormat
[0] != RPC_FC_END
) {
1239 TRACE("pFormat[0] = 0x%x\n", pFormat
[0]);
1240 switch (pFormat
[0]) {
1242 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat
[0]);
1244 case RPC_FC_NO_REPEAT
:
1250 case RPC_FC_FIXED_REPEAT
:
1251 rep
= *(const WORD
*)&pFormat
[2];
1252 stride
= *(const WORD
*)&pFormat
[4];
1253 count
= *(const WORD
*)&pFormat
[8];
1256 case RPC_FC_VARIABLE_REPEAT
:
1257 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1258 stride
= *(const WORD
*)&pFormat
[2];
1259 count
= *(const WORD
*)&pFormat
[6];
1263 for (i
= 0; i
< rep
; i
++) {
1264 PFORMAT_STRING info
= pFormat
;
1265 unsigned char *bufdstbase
= pDstBuffer
+ (i
* stride
);
1266 unsigned char *memsrcbase
= pSrcMemoryPtrs
+ (i
* stride
);
1267 unsigned char *bufbase
= Mark
+ (i
* stride
);
1270 for (u
=0; u
<count
; u
++,info
+=8) {
1271 unsigned char **bufdstptr
= (unsigned char **)(bufdstbase
+ *(const SHORT
*)&info
[2]);
1272 unsigned char **memsrcptr
= (unsigned char **)(memsrcbase
+ *(const SHORT
*)&info
[0]);
1273 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1274 PointerUnmarshall(pStubMsg
, bufptr
, bufdstptr
, *memsrcptr
, info
+4, fMustAlloc
);
1277 pFormat
+= 8 * count
;
1282 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1283 pStubMsg
->Buffer
= saved_buffer
;
1289 /***********************************************************************
1290 * EmbeddedPointerBufferSize
1292 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1293 unsigned char *pMemory
,
1294 PFORMAT_STRING pFormat
)
1296 unsigned rep
, count
, stride
;
1298 ULONG saved_buffer_length
= 0;
1300 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1302 if (pStubMsg
->IgnoreEmbeddedPointers
) return;
1304 if (*pFormat
!= RPC_FC_PP
) return;
1307 if (pStubMsg
->PointerLength
)
1309 saved_buffer_length
= pStubMsg
->BufferLength
;
1310 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
1311 pStubMsg
->PointerLength
= 0;
1314 while (pFormat
[0] != RPC_FC_END
) {
1315 switch (pFormat
[0]) {
1317 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat
[0]);
1319 case RPC_FC_NO_REPEAT
:
1325 case RPC_FC_FIXED_REPEAT
:
1326 rep
= *(const WORD
*)&pFormat
[2];
1327 stride
= *(const WORD
*)&pFormat
[4];
1328 count
= *(const WORD
*)&pFormat
[8];
1331 case RPC_FC_VARIABLE_REPEAT
:
1332 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1333 stride
= *(const WORD
*)&pFormat
[2];
1334 count
= *(const WORD
*)&pFormat
[6];
1338 for (i
= 0; i
< rep
; i
++) {
1339 PFORMAT_STRING info
= pFormat
;
1340 unsigned char *membase
= pMemory
+ (i
* stride
);
1343 for (u
=0; u
<count
; u
++,info
+=8) {
1344 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1345 unsigned char *saved_memory
= pStubMsg
->Memory
;
1347 pStubMsg
->Memory
= membase
;
1348 PointerBufferSize(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1349 pStubMsg
->Memory
= saved_memory
;
1352 pFormat
+= 8 * count
;
1355 if (saved_buffer_length
)
1357 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
1358 pStubMsg
->BufferLength
= saved_buffer_length
;
1362 /***********************************************************************
1363 * EmbeddedPointerMemorySize [internal]
1365 static ULONG
EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1366 PFORMAT_STRING pFormat
)
1368 unsigned char *Mark
= pStubMsg
->BufferMark
;
1369 unsigned rep
, count
, stride
;
1371 unsigned char *saved_buffer
= NULL
;
1373 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1375 if (pStubMsg
->IgnoreEmbeddedPointers
) return 0;
1377 if (pStubMsg
->PointerBufferMark
)
1379 saved_buffer
= pStubMsg
->Buffer
;
1380 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1381 pStubMsg
->PointerBufferMark
= NULL
;
1384 if (*pFormat
!= RPC_FC_PP
) return 0;
1387 while (pFormat
[0] != RPC_FC_END
) {
1388 switch (pFormat
[0]) {
1390 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat
[0]);
1392 case RPC_FC_NO_REPEAT
:
1398 case RPC_FC_FIXED_REPEAT
:
1399 rep
= *(const WORD
*)&pFormat
[2];
1400 stride
= *(const WORD
*)&pFormat
[4];
1401 count
= *(const WORD
*)&pFormat
[8];
1404 case RPC_FC_VARIABLE_REPEAT
:
1405 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1406 stride
= *(const WORD
*)&pFormat
[2];
1407 count
= *(const WORD
*)&pFormat
[6];
1411 for (i
= 0; i
< rep
; i
++) {
1412 PFORMAT_STRING info
= pFormat
;
1413 unsigned char *bufbase
= Mark
+ (i
* stride
);
1415 for (u
=0; u
<count
; u
++,info
+=8) {
1416 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1417 PointerMemorySize(pStubMsg
, bufptr
, info
+4);
1420 pFormat
+= 8 * count
;
1425 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1426 pStubMsg
->Buffer
= saved_buffer
;
1432 /***********************************************************************
1433 * EmbeddedPointerFree [internal]
1435 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1436 unsigned char *pMemory
,
1437 PFORMAT_STRING pFormat
)
1439 unsigned rep
, count
, stride
;
1442 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1443 if (*pFormat
!= RPC_FC_PP
) return;
1446 while (pFormat
[0] != RPC_FC_END
) {
1447 switch (pFormat
[0]) {
1449 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat
[0]);
1451 case RPC_FC_NO_REPEAT
:
1457 case RPC_FC_FIXED_REPEAT
:
1458 rep
= *(const WORD
*)&pFormat
[2];
1459 stride
= *(const WORD
*)&pFormat
[4];
1460 count
= *(const WORD
*)&pFormat
[8];
1463 case RPC_FC_VARIABLE_REPEAT
:
1464 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1465 stride
= *(const WORD
*)&pFormat
[2];
1466 count
= *(const WORD
*)&pFormat
[6];
1470 for (i
= 0; i
< rep
; i
++) {
1471 PFORMAT_STRING info
= pFormat
;
1472 unsigned char *membase
= pMemory
+ (i
* stride
);
1475 for (u
=0; u
<count
; u
++,info
+=8) {
1476 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1477 unsigned char *saved_memory
= pStubMsg
->Memory
;
1479 pStubMsg
->Memory
= membase
;
1480 PointerFree(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1481 pStubMsg
->Memory
= saved_memory
;
1484 pFormat
+= 8 * count
;
1488 /***********************************************************************
1489 * NdrPointerMarshall [RPCRT4.@]
1491 unsigned char * WINAPI
NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1492 unsigned char *pMemory
,
1493 PFORMAT_STRING pFormat
)
1495 unsigned char *Buffer
;
1497 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1499 /* Increment the buffer here instead of in PointerMarshall,
1500 * as that is used by embedded pointers which already handle the incrementing
1501 * the buffer, and shouldn't write any additional pointer data to the wire */
1502 if (*pFormat
!= RPC_FC_RP
)
1504 align_pointer_clear(&pStubMsg
->Buffer
, 4);
1505 Buffer
= pStubMsg
->Buffer
;
1506 safe_buffer_increment(pStubMsg
, 4);
1509 Buffer
= pStubMsg
->Buffer
;
1511 PointerMarshall(pStubMsg
, Buffer
, pMemory
, pFormat
);
1516 /***********************************************************************
1517 * NdrPointerUnmarshall [RPCRT4.@]
1519 unsigned char * WINAPI
NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1520 unsigned char **ppMemory
,
1521 PFORMAT_STRING pFormat
,
1522 unsigned char fMustAlloc
)
1524 unsigned char *Buffer
;
1526 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1528 if (*pFormat
== RPC_FC_RP
)
1530 Buffer
= pStubMsg
->Buffer
;
1531 /* Do the NULL ref pointer check here because embedded pointers can be
1532 * NULL if the type the pointer is embedded in was allocated rather than
1533 * being passed in by the client */
1534 if (pStubMsg
->IsClient
&& !*ppMemory
)
1536 ERR("NULL ref pointer is not allowed\n");
1537 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
1542 /* Increment the buffer here instead of in PointerUnmarshall,
1543 * as that is used by embedded pointers which already handle the incrementing
1544 * the buffer, and shouldn't read any additional pointer data from the
1546 align_pointer(&pStubMsg
->Buffer
, 4);
1547 Buffer
= pStubMsg
->Buffer
;
1548 safe_buffer_increment(pStubMsg
, 4);
1551 PointerUnmarshall(pStubMsg
, Buffer
, ppMemory
, *ppMemory
, pFormat
, fMustAlloc
);
1556 /***********************************************************************
1557 * NdrPointerBufferSize [RPCRT4.@]
1559 void WINAPI
NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1560 unsigned char *pMemory
,
1561 PFORMAT_STRING pFormat
)
1563 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1565 /* Increment the buffer length here instead of in PointerBufferSize,
1566 * as that is used by embedded pointers which already handle the buffer
1567 * length, and shouldn't write anything more to the wire */
1568 if (*pFormat
!= RPC_FC_RP
)
1570 align_length(&pStubMsg
->BufferLength
, 4);
1571 safe_buffer_length_increment(pStubMsg
, 4);
1574 PointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1577 /***********************************************************************
1578 * NdrPointerMemorySize [RPCRT4.@]
1580 ULONG WINAPI
NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1581 PFORMAT_STRING pFormat
)
1583 unsigned char *Buffer
= pStubMsg
->Buffer
;
1584 if (*pFormat
!= RPC_FC_RP
)
1586 align_pointer(&pStubMsg
->Buffer
, 4);
1587 safe_buffer_increment(pStubMsg
, 4);
1589 align_length(&pStubMsg
->MemorySize
, sizeof(void *));
1590 return PointerMemorySize(pStubMsg
, Buffer
, pFormat
);
1593 /***********************************************************************
1594 * NdrPointerFree [RPCRT4.@]
1596 void WINAPI
NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1597 unsigned char *pMemory
,
1598 PFORMAT_STRING pFormat
)
1600 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1601 PointerFree(pStubMsg
, pMemory
, pFormat
);
1604 /***********************************************************************
1605 * NdrSimpleTypeMarshall [RPCRT4.@]
1607 void WINAPI
NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1608 unsigned char FormatChar
)
1610 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &FormatChar
);
1613 /***********************************************************************
1614 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1616 * Unmarshall a base type.
1619 * Doesn't check that the buffer is long enough before copying, so the caller
1622 void WINAPI
NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1623 unsigned char FormatChar
)
1625 #define BASE_TYPE_UNMARSHALL(type) \
1626 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
1627 TRACE("pMemory: %p\n", pMemory); \
1628 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1629 pStubMsg->Buffer += sizeof(type);
1637 BASE_TYPE_UNMARSHALL(UCHAR
);
1638 TRACE("value: 0x%02x\n", *pMemory
);
1643 BASE_TYPE_UNMARSHALL(USHORT
);
1644 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
1648 case RPC_FC_ERROR_STATUS_T
:
1650 BASE_TYPE_UNMARSHALL(ULONG
);
1651 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
1654 BASE_TYPE_UNMARSHALL(float);
1655 TRACE("value: %f\n", *(float *)pMemory
);
1658 BASE_TYPE_UNMARSHALL(double);
1659 TRACE("value: %f\n", *(double *)pMemory
);
1662 BASE_TYPE_UNMARSHALL(ULONGLONG
);
1663 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
1666 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
1667 TRACE("pMemory: %p\n", pMemory
);
1668 /* 16-bits on the wire, but int in memory */
1669 *(UINT
*)pMemory
= *(USHORT
*)pStubMsg
->Buffer
;
1670 pStubMsg
->Buffer
+= sizeof(USHORT
);
1671 TRACE("value: 0x%08x\n", *(UINT
*)pMemory
);
1673 case RPC_FC_INT3264
:
1674 align_pointer(&pStubMsg
->Buffer
, sizeof(INT
));
1675 /* 32-bits on the wire, but int_ptr in memory */
1676 *(INT_PTR
*)pMemory
= *(INT
*)pStubMsg
->Buffer
;
1677 pStubMsg
->Buffer
+= sizeof(INT
);
1678 TRACE("value: 0x%08lx\n", *(INT_PTR
*)pMemory
);
1680 case RPC_FC_UINT3264
:
1681 align_pointer(&pStubMsg
->Buffer
, sizeof(UINT
));
1682 /* 32-bits on the wire, but int_ptr in memory */
1683 *(UINT_PTR
*)pMemory
= *(UINT
*)pStubMsg
->Buffer
;
1684 pStubMsg
->Buffer
+= sizeof(UINT
);
1685 TRACE("value: 0x%08lx\n", *(UINT_PTR
*)pMemory
);
1690 FIXME("Unhandled base type: 0x%02x\n", FormatChar
);
1692 #undef BASE_TYPE_UNMARSHALL
1695 /***********************************************************************
1696 * NdrSimpleStructMarshall [RPCRT4.@]
1698 unsigned char * WINAPI
NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1699 unsigned char *pMemory
,
1700 PFORMAT_STRING pFormat
)
1702 unsigned size
= *(const WORD
*)(pFormat
+2);
1703 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1705 align_pointer_clear(&pStubMsg
->Buffer
, pFormat
[1] + 1);
1707 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1708 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
1710 if (pFormat
[0] != RPC_FC_STRUCT
)
1711 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
+4);
1716 /***********************************************************************
1717 * NdrSimpleStructUnmarshall [RPCRT4.@]
1719 unsigned char * WINAPI
NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1720 unsigned char **ppMemory
,
1721 PFORMAT_STRING pFormat
,
1722 unsigned char fMustAlloc
)
1724 unsigned size
= *(const WORD
*)(pFormat
+2);
1725 unsigned char *saved_buffer
;
1726 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1728 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
1731 *ppMemory
= NdrAllocate(pStubMsg
, size
);
1734 if (!pStubMsg
->IsClient
&& !*ppMemory
)
1735 /* for servers, we just point straight into the RPC buffer */
1736 *ppMemory
= pStubMsg
->Buffer
;
1739 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1740 safe_buffer_increment(pStubMsg
, size
);
1741 if (pFormat
[0] == RPC_FC_PSTRUCT
)
1742 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
+4, fMustAlloc
);
1744 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
1745 if (*ppMemory
!= saved_buffer
)
1746 memcpy(*ppMemory
, saved_buffer
, size
);
1751 /***********************************************************************
1752 * NdrSimpleStructBufferSize [RPCRT4.@]
1754 void WINAPI
NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1755 unsigned char *pMemory
,
1756 PFORMAT_STRING pFormat
)
1758 unsigned size
= *(const WORD
*)(pFormat
+2);
1759 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1761 align_length(&pStubMsg
->BufferLength
, pFormat
[1] + 1);
1763 safe_buffer_length_increment(pStubMsg
, size
);
1764 if (pFormat
[0] != RPC_FC_STRUCT
)
1765 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
+4);
1768 /***********************************************************************
1769 * NdrSimpleStructMemorySize [RPCRT4.@]
1771 ULONG WINAPI
NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1772 PFORMAT_STRING pFormat
)
1774 unsigned short size
= *(const WORD
*)(pFormat
+2);
1776 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1778 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
1779 pStubMsg
->MemorySize
+= size
;
1780 safe_buffer_increment(pStubMsg
, size
);
1782 if (pFormat
[0] != RPC_FC_STRUCT
)
1783 EmbeddedPointerMemorySize(pStubMsg
, pFormat
+4);
1784 return pStubMsg
->MemorySize
;
1787 /***********************************************************************
1788 * NdrSimpleStructFree [RPCRT4.@]
1790 void WINAPI
NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
1791 unsigned char *pMemory
,
1792 PFORMAT_STRING pFormat
)
1794 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1795 if (pFormat
[0] != RPC_FC_STRUCT
)
1796 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
+4);
1801 static inline void array_compute_and_size_conformance(
1802 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1803 PFORMAT_STRING pFormat
)
1810 ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1811 SizeConformance(pStubMsg
);
1813 case RPC_FC_CVARRAY
:
1814 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, 0);
1815 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
1816 SizeConformance(pStubMsg
);
1818 case RPC_FC_C_CSTRING
:
1819 case RPC_FC_C_WSTRING
:
1820 if (fc
== RPC_FC_C_CSTRING
)
1822 TRACE("string=%s\n", debugstr_a((const char *)pMemory
));
1823 pStubMsg
->ActualCount
= strlen((const char *)pMemory
)+1;
1827 TRACE("string=%s\n", debugstr_w((LPCWSTR
)pMemory
));
1828 pStubMsg
->ActualCount
= strlenW((LPCWSTR
)pMemory
)+1;
1831 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
1832 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
1834 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
1836 SizeConformance(pStubMsg
);
1838 case RPC_FC_BOGUS_ARRAY
:
1839 count
= *(const WORD
*)(pFormat
+ 2);
1841 if (IsConformanceOrVariancePresent(pFormat
)) SizeConformance(pStubMsg
);
1842 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, count
);
1843 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
1846 ERR("unknown array format 0x%x\n", fc
);
1847 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1851 static inline void array_buffer_size(
1852 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1853 PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
1857 unsigned char alignment
;
1862 esize
= *(const WORD
*)(pFormat
+2);
1863 alignment
= pFormat
[1] + 1;
1865 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1867 align_length(&pStubMsg
->BufferLength
, alignment
);
1869 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
1870 /* conformance value plus array */
1871 safe_buffer_length_increment(pStubMsg
, size
);
1874 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1876 case RPC_FC_CVARRAY
:
1877 esize
= *(const WORD
*)(pFormat
+2);
1878 alignment
= pFormat
[1] + 1;
1880 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1881 pFormat
= SkipVariance(pStubMsg
, pFormat
);
1883 SizeVariance(pStubMsg
);
1885 align_length(&pStubMsg
->BufferLength
, alignment
);
1887 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1888 safe_buffer_length_increment(pStubMsg
, size
);
1891 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1893 case RPC_FC_C_CSTRING
:
1894 case RPC_FC_C_WSTRING
:
1895 if (fc
== RPC_FC_C_CSTRING
)
1900 SizeVariance(pStubMsg
);
1902 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1903 safe_buffer_length_increment(pStubMsg
, size
);
1905 case RPC_FC_BOGUS_ARRAY
:
1906 alignment
= pFormat
[1] + 1;
1907 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1908 if (IsConformanceOrVariancePresent(pFormat
)) SizeVariance(pStubMsg
);
1909 pFormat
= SkipVariance(pStubMsg
, pFormat
);
1911 align_length(&pStubMsg
->BufferLength
, alignment
);
1913 size
= pStubMsg
->ActualCount
;
1914 for (i
= 0; i
< size
; i
++)
1915 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
1918 ERR("unknown array format 0x%x\n", fc
);
1919 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1923 static inline void array_compute_and_write_conformance(
1924 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1925 PFORMAT_STRING pFormat
)
1928 BOOL conformance_present
;
1933 ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1934 WriteConformance(pStubMsg
);
1936 case RPC_FC_CVARRAY
:
1937 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, 0);
1938 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
1939 WriteConformance(pStubMsg
);
1941 case RPC_FC_C_CSTRING
:
1942 case RPC_FC_C_WSTRING
:
1943 if (fc
== RPC_FC_C_CSTRING
)
1945 TRACE("string=%s\n", debugstr_a((const char *)pMemory
));
1946 pStubMsg
->ActualCount
= strlen((const char *)pMemory
)+1;
1950 TRACE("string=%s\n", debugstr_w((LPCWSTR
)pMemory
));
1951 pStubMsg
->ActualCount
= strlenW((LPCWSTR
)pMemory
)+1;
1953 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
1954 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
1956 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
1957 pStubMsg
->Offset
= 0;
1958 WriteConformance(pStubMsg
);
1960 case RPC_FC_BOGUS_ARRAY
:
1961 def
= *(const WORD
*)(pFormat
+ 2);
1963 conformance_present
= IsConformanceOrVariancePresent(pFormat
);
1964 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
1965 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
1966 if (conformance_present
) WriteConformance(pStubMsg
);
1969 ERR("unknown array format 0x%x\n", fc
);
1970 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1974 static inline void array_write_variance_and_marshall(
1975 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1976 PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
1980 unsigned char alignment
;
1985 esize
= *(const WORD
*)(pFormat
+2);
1986 alignment
= pFormat
[1] + 1;
1988 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1990 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
1992 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
1994 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1995 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
1998 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2000 case RPC_FC_CVARRAY
:
2001 esize
= *(const WORD
*)(pFormat
+2);
2002 alignment
= pFormat
[1] + 1;
2004 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2005 pFormat
= SkipVariance(pStubMsg
, pFormat
);
2007 WriteVariance(pStubMsg
);
2009 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
2011 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2014 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2015 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, size
);
2018 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2020 case RPC_FC_C_CSTRING
:
2021 case RPC_FC_C_WSTRING
:
2022 if (fc
== RPC_FC_C_CSTRING
)
2027 WriteVariance(pStubMsg
);
2029 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2030 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
2032 case RPC_FC_BOGUS_ARRAY
:
2033 alignment
= pFormat
[1] + 1;
2034 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2035 if (IsConformanceOrVariancePresent(pFormat
)) WriteVariance(pStubMsg
);
2036 pFormat
= SkipVariance(pStubMsg
, pFormat
);
2038 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
2040 size
= pStubMsg
->ActualCount
;
2041 for (i
= 0; i
< size
; i
++)
2042 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
2045 ERR("unknown array format 0x%x\n", fc
);
2046 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2050 static inline ULONG
array_read_conformance(
2051 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
2058 esize
= *(const WORD
*)(pFormat
+2);
2059 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2060 return safe_multiply(esize
, pStubMsg
->MaxCount
);
2061 case RPC_FC_CVARRAY
:
2062 esize
= *(const WORD
*)(pFormat
+2);
2063 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2064 return safe_multiply(esize
, pStubMsg
->MaxCount
);
2065 case RPC_FC_C_CSTRING
:
2066 case RPC_FC_C_WSTRING
:
2067 if (fc
== RPC_FC_C_CSTRING
)
2072 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
2073 ReadConformance(pStubMsg
, pFormat
+ 2);
2075 ReadConformance(pStubMsg
, NULL
);
2076 return safe_multiply(esize
, pStubMsg
->MaxCount
);
2077 case RPC_FC_BOGUS_ARRAY
:
2078 def
= *(const WORD
*)(pFormat
+ 2);
2080 if (IsConformanceOrVariancePresent(pFormat
)) pFormat
= ReadConformance(pStubMsg
, pFormat
);
2083 pStubMsg
->MaxCount
= def
;
2084 pFormat
= SkipConformance( pStubMsg
, pFormat
);
2086 pFormat
= SkipVariance( pStubMsg
, pFormat
);
2088 esize
= ComplexStructSize(pStubMsg
, pFormat
);
2089 return safe_multiply(pStubMsg
->MaxCount
, esize
);
2091 ERR("unknown array format 0x%x\n", fc
);
2092 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2096 static inline ULONG
array_read_variance_and_unmarshall(
2097 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char **ppMemory
,
2098 PFORMAT_STRING pFormat
, unsigned char fMustAlloc
,
2099 unsigned char fUseBufferMemoryServer
, unsigned char fUnmarshall
)
2101 ULONG bufsize
, memsize
;
2103 unsigned char alignment
;
2104 unsigned char *saved_buffer
, *pMemory
;
2105 ULONG i
, offset
, count
;
2110 esize
= *(const WORD
*)(pFormat
+2);
2111 alignment
= pFormat
[1] + 1;
2113 bufsize
= memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2115 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2117 align_pointer(&pStubMsg
->Buffer
, alignment
);
2122 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2125 if (fUseBufferMemoryServer
&& !pStubMsg
->IsClient
&& !*ppMemory
)
2126 /* for servers, we just point straight into the RPC buffer */
2127 *ppMemory
= pStubMsg
->Buffer
;
2130 saved_buffer
= pStubMsg
->Buffer
;
2131 safe_buffer_increment(pStubMsg
, bufsize
);
2133 pStubMsg
->BufferMark
= saved_buffer
;
2134 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
2136 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
2137 if (*ppMemory
!= saved_buffer
)
2138 memcpy(*ppMemory
, saved_buffer
, bufsize
);
2141 case RPC_FC_CVARRAY
:
2142 esize
= *(const WORD
*)(pFormat
+2);
2143 alignment
= pFormat
[1] + 1;
2145 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2147 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2149 align_pointer(&pStubMsg
->Buffer
, alignment
);
2151 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2152 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2156 offset
= pStubMsg
->Offset
;
2158 if (!fMustAlloc
&& !*ppMemory
)
2161 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2162 saved_buffer
= pStubMsg
->Buffer
;
2163 safe_buffer_increment(pStubMsg
, bufsize
);
2165 pStubMsg
->BufferMark
= saved_buffer
;
2166 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
,
2169 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
2172 case RPC_FC_C_CSTRING
:
2173 case RPC_FC_C_WSTRING
:
2174 if (fc
== RPC_FC_C_CSTRING
)
2179 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
2181 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
2183 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2184 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
2185 RpcRaiseException(RPC_S_INVALID_BOUND
);
2187 if (pStubMsg
->Offset
)
2189 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2190 RpcRaiseException(RPC_S_INVALID_BOUND
);
2193 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2194 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2196 validate_string_data(pStubMsg
, bufsize
, esize
);
2201 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2204 if (fUseBufferMemoryServer
&& !pStubMsg
->IsClient
&&
2205 !*ppMemory
&& (pStubMsg
->MaxCount
== pStubMsg
->ActualCount
))
2206 /* if the data in the RPC buffer is big enough, we just point
2207 * straight into it */
2208 *ppMemory
= pStubMsg
->Buffer
;
2209 else if (!*ppMemory
)
2210 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2213 if (*ppMemory
== pStubMsg
->Buffer
)
2214 safe_buffer_increment(pStubMsg
, bufsize
);
2216 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
2218 if (*pFormat
== RPC_FC_C_CSTRING
)
2219 TRACE("string=%s\n", debugstr_a((char*)*ppMemory
));
2221 TRACE("string=%s\n", debugstr_w((LPWSTR
)*ppMemory
));
2225 case RPC_FC_BOGUS_ARRAY
:
2226 alignment
= pFormat
[1] + 1;
2227 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2228 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2230 esize
= ComplexStructSize(pStubMsg
, pFormat
);
2231 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2233 assert( fUnmarshall
);
2235 if (!fMustAlloc
&& !*ppMemory
)
2238 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2240 align_pointer(&pStubMsg
->Buffer
, alignment
);
2241 saved_buffer
= pStubMsg
->Buffer
;
2243 pMemory
= *ppMemory
;
2244 count
= pStubMsg
->ActualCount
;
2245 for (i
= 0; i
< count
; i
++)
2246 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
, fMustAlloc
);
2247 return pStubMsg
->Buffer
- saved_buffer
;
2250 ERR("unknown array format 0x%x\n", fc
);
2251 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2255 static inline void array_memory_size(
2256 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
,
2257 unsigned char fHasPointers
)
2259 ULONG i
, count
, SavedMemorySize
;
2260 ULONG bufsize
, memsize
;
2262 unsigned char alignment
;
2267 esize
= *(const WORD
*)(pFormat
+2);
2268 alignment
= pFormat
[1] + 1;
2270 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2272 bufsize
= memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2273 pStubMsg
->MemorySize
+= memsize
;
2275 align_pointer(&pStubMsg
->Buffer
, alignment
);
2277 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2278 safe_buffer_increment(pStubMsg
, bufsize
);
2281 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2283 case RPC_FC_CVARRAY
:
2284 esize
= *(const WORD
*)(pFormat
+2);
2285 alignment
= pFormat
[1] + 1;
2287 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2289 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2291 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2292 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2293 pStubMsg
->MemorySize
+= memsize
;
2295 align_pointer(&pStubMsg
->Buffer
, alignment
);
2297 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2298 safe_buffer_increment(pStubMsg
, bufsize
);
2301 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2303 case RPC_FC_C_CSTRING
:
2304 case RPC_FC_C_WSTRING
:
2305 if (fc
== RPC_FC_C_CSTRING
)
2310 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
2312 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
2314 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2315 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
2316 RpcRaiseException(RPC_S_INVALID_BOUND
);
2318 if (pStubMsg
->Offset
)
2320 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2321 RpcRaiseException(RPC_S_INVALID_BOUND
);
2324 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2325 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2327 validate_string_data(pStubMsg
, bufsize
, esize
);
2329 safe_buffer_increment(pStubMsg
, bufsize
);
2330 pStubMsg
->MemorySize
+= memsize
;
2332 case RPC_FC_BOGUS_ARRAY
:
2333 alignment
= pFormat
[1] + 1;
2334 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2335 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2337 align_pointer(&pStubMsg
->Buffer
, alignment
);
2339 SavedMemorySize
= pStubMsg
->MemorySize
;
2341 esize
= ComplexStructSize(pStubMsg
, pFormat
);
2342 memsize
= safe_multiply(pStubMsg
->MaxCount
, esize
);
2344 count
= pStubMsg
->ActualCount
;
2345 for (i
= 0; i
< count
; i
++)
2346 ComplexStructMemorySize(pStubMsg
, pFormat
, NULL
);
2348 pStubMsg
->MemorySize
= SavedMemorySize
+ memsize
;
2351 ERR("unknown array format 0x%x\n", fc
);
2352 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2356 static inline void array_free(
2357 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
,
2358 unsigned char *pMemory
, PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
2365 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2367 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2369 case RPC_FC_CVARRAY
:
2370 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2371 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2373 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2375 case RPC_FC_C_CSTRING
:
2376 case RPC_FC_C_WSTRING
:
2377 /* No embedded pointers so nothing to do */
2379 case RPC_FC_BOGUS_ARRAY
:
2380 count
= *(const WORD
*)(pFormat
+ 2);
2381 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, count
);
2382 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
2384 count
= pStubMsg
->ActualCount
;
2385 for (i
= 0; i
< count
; i
++)
2386 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
2389 ERR("unknown array format 0x%x\n", fc
);
2390 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2395 * NdrConformantString:
2397 * What MS calls a ConformantString is, in DCE terminology,
2398 * a Varying-Conformant String.
2400 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2401 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2402 * into unmarshalled string)
2403 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2405 * data: CHARTYPE[maxlen]
2407 * ], where CHARTYPE is the appropriate character type (specified externally)
2411 /***********************************************************************
2412 * NdrConformantStringMarshall [RPCRT4.@]
2414 unsigned char *WINAPI
NdrConformantStringMarshall(MIDL_STUB_MESSAGE
*pStubMsg
,
2415 unsigned char *pszMessage
, PFORMAT_STRING pFormat
)
2417 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg
, pszMessage
, pFormat
);
2419 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2420 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2421 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2424 /* allow compiler to optimise inline function by passing constant into
2425 * these functions */
2426 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2427 array_compute_and_write_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pszMessage
,
2429 array_write_variance_and_marshall(RPC_FC_C_CSTRING
, pStubMsg
, pszMessage
,
2430 pFormat
, TRUE
/* fHasPointers */);
2432 array_compute_and_write_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pszMessage
,
2434 array_write_variance_and_marshall(RPC_FC_C_WSTRING
, pStubMsg
, pszMessage
,
2435 pFormat
, TRUE
/* fHasPointers */);
2441 /***********************************************************************
2442 * NdrConformantStringBufferSize [RPCRT4.@]
2444 void WINAPI
NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2445 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
2447 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2449 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2450 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2451 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2454 /* allow compiler to optimise inline function by passing constant into
2455 * these functions */
2456 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2457 array_compute_and_size_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pMemory
,
2459 array_buffer_size(RPC_FC_C_CSTRING
, pStubMsg
, pMemory
, pFormat
,
2460 TRUE
/* fHasPointers */);
2462 array_compute_and_size_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pMemory
,
2464 array_buffer_size(RPC_FC_C_WSTRING
, pStubMsg
, pMemory
, pFormat
,
2465 TRUE
/* fHasPointers */);
2469 /************************************************************************
2470 * NdrConformantStringMemorySize [RPCRT4.@]
2472 ULONG WINAPI
NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
2473 PFORMAT_STRING pFormat
)
2475 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
2477 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2478 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2479 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2482 /* allow compiler to optimise inline function by passing constant into
2483 * these functions */
2484 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2485 array_read_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
);
2486 array_memory_size(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
,
2487 TRUE
/* fHasPointers */);
2489 array_read_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
);
2490 array_memory_size(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
,
2491 TRUE
/* fHasPointers */);
2494 return pStubMsg
->MemorySize
;
2497 /************************************************************************
2498 * NdrConformantStringUnmarshall [RPCRT4.@]
2500 unsigned char *WINAPI
NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2501 unsigned char** ppMemory
, PFORMAT_STRING pFormat
, unsigned char fMustAlloc
)
2503 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2504 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
2506 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2507 ERR("Unhandled string type: %#x\n", *pFormat
);
2508 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2511 /* allow compiler to optimise inline function by passing constant into
2512 * these functions */
2513 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2514 array_read_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
);
2515 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING
, pStubMsg
, ppMemory
,
2516 pFormat
, fMustAlloc
,
2517 TRUE
/* fUseBufferMemoryServer */,
2518 TRUE
/* fUnmarshall */);
2520 array_read_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
);
2521 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING
, pStubMsg
, ppMemory
,
2522 pFormat
, fMustAlloc
,
2523 TRUE
/* fUseBufferMemoryServer */,
2524 TRUE
/* fUnmarshall */);
2530 /***********************************************************************
2531 * NdrNonConformantStringMarshall [RPCRT4.@]
2533 unsigned char * WINAPI
NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2534 unsigned char *pMemory
,
2535 PFORMAT_STRING pFormat
)
2537 ULONG esize
, size
, maxsize
;
2539 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2541 maxsize
= *(const USHORT
*)&pFormat
[2];
2543 if (*pFormat
== RPC_FC_CSTRING
)
2546 const char *str
= (const char *)pMemory
;
2547 while (i
< maxsize
&& str
[i
]) i
++;
2548 TRACE("string=%s\n", debugstr_an(str
, i
));
2549 pStubMsg
->ActualCount
= i
+ 1;
2552 else if (*pFormat
== RPC_FC_WSTRING
)
2555 const WCHAR
*str
= (const WCHAR
*)pMemory
;
2556 while (i
< maxsize
&& str
[i
]) i
++;
2557 TRACE("string=%s\n", debugstr_wn(str
, i
));
2558 pStubMsg
->ActualCount
= i
+ 1;
2563 ERR("Unhandled string type: %#x\n", *pFormat
);
2564 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2567 pStubMsg
->Offset
= 0;
2568 WriteVariance(pStubMsg
);
2570 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2571 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
2576 /***********************************************************************
2577 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2579 unsigned char * WINAPI
NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2580 unsigned char **ppMemory
,
2581 PFORMAT_STRING pFormat
,
2582 unsigned char fMustAlloc
)
2584 ULONG bufsize
, memsize
, esize
, maxsize
;
2586 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2587 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
2589 maxsize
= *(const USHORT
*)&pFormat
[2];
2591 ReadVariance(pStubMsg
, NULL
, maxsize
);
2592 if (pStubMsg
->Offset
)
2594 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2595 RpcRaiseException(RPC_S_INVALID_BOUND
);
2598 if (*pFormat
== RPC_FC_CSTRING
) esize
= 1;
2599 else if (*pFormat
== RPC_FC_WSTRING
) esize
= 2;
2602 ERR("Unhandled string type: %#x\n", *pFormat
);
2603 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2606 memsize
= esize
* maxsize
;
2607 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2609 validate_string_data(pStubMsg
, bufsize
, esize
);
2611 if (!fMustAlloc
&& !*ppMemory
)
2614 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2616 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
2618 if (*pFormat
== RPC_FC_CSTRING
) {
2619 TRACE("string=%s\n", debugstr_an((char*)*ppMemory
, pStubMsg
->ActualCount
));
2621 else if (*pFormat
== RPC_FC_WSTRING
) {
2622 TRACE("string=%s\n", debugstr_wn((LPWSTR
)*ppMemory
, pStubMsg
->ActualCount
));
2628 /***********************************************************************
2629 * NdrNonConformantStringBufferSize [RPCRT4.@]
2631 void WINAPI
NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2632 unsigned char *pMemory
,
2633 PFORMAT_STRING pFormat
)
2635 ULONG esize
, maxsize
;
2637 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2639 maxsize
= *(const USHORT
*)&pFormat
[2];
2641 SizeVariance(pStubMsg
);
2643 if (*pFormat
== RPC_FC_CSTRING
)
2646 const char *str
= (const char *)pMemory
;
2647 while (i
< maxsize
&& str
[i
]) i
++;
2648 TRACE("string=%s\n", debugstr_an(str
, i
));
2649 pStubMsg
->ActualCount
= i
+ 1;
2652 else if (*pFormat
== RPC_FC_WSTRING
)
2655 const WCHAR
*str
= (const WCHAR
*)pMemory
;
2656 while (i
< maxsize
&& str
[i
]) i
++;
2657 TRACE("string=%s\n", debugstr_wn(str
, i
));
2658 pStubMsg
->ActualCount
= i
+ 1;
2663 ERR("Unhandled string type: %#x\n", *pFormat
);
2664 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2667 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
2670 /***********************************************************************
2671 * NdrNonConformantStringMemorySize [RPCRT4.@]
2673 ULONG WINAPI
NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2674 PFORMAT_STRING pFormat
)
2676 ULONG bufsize
, memsize
, esize
, maxsize
;
2678 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
2680 maxsize
= *(const USHORT
*)&pFormat
[2];
2682 ReadVariance(pStubMsg
, NULL
, maxsize
);
2684 if (pStubMsg
->Offset
)
2686 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2687 RpcRaiseException(RPC_S_INVALID_BOUND
);
2690 if (*pFormat
== RPC_FC_CSTRING
) esize
= 1;
2691 else if (*pFormat
== RPC_FC_WSTRING
) esize
= 2;
2694 ERR("Unhandled string type: %#x\n", *pFormat
);
2695 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2698 memsize
= esize
* maxsize
;
2699 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2701 validate_string_data(pStubMsg
, bufsize
, esize
);
2703 safe_buffer_increment(pStubMsg
, bufsize
);
2704 pStubMsg
->MemorySize
+= memsize
;
2706 return pStubMsg
->MemorySize
;
2711 #include "pshpack1.h"
2715 unsigned char flags_type
; /* flags in upper nibble, type in lower nibble */
2719 #include "poppack.h"
2721 static ULONG
EmbeddedComplexSize(MIDL_STUB_MESSAGE
*pStubMsg
,
2722 PFORMAT_STRING pFormat
)
2726 case RPC_FC_PSTRUCT
:
2727 case RPC_FC_CSTRUCT
:
2728 case RPC_FC_BOGUS_STRUCT
:
2729 case RPC_FC_SMFARRAY
:
2730 case RPC_FC_SMVARRAY
:
2731 case RPC_FC_CSTRING
:
2732 return *(const WORD
*)&pFormat
[2];
2733 case RPC_FC_USER_MARSHAL
:
2734 return *(const WORD
*)&pFormat
[4];
2735 case RPC_FC_RANGE
: {
2736 switch (((const NDR_RANGE
*)pFormat
)->flags_type
& 0xf) {
2741 return sizeof(UCHAR
);
2745 return sizeof(USHORT
);
2749 case RPC_FC_INT3264
:
2750 case RPC_FC_UINT3264
:
2751 return sizeof(ULONG
);
2753 return sizeof(float);
2755 return sizeof(double);
2757 return sizeof(ULONGLONG
);
2759 return sizeof(UINT
);
2761 ERR("unknown type 0x%x\n", ((const NDR_RANGE
*)pFormat
)->flags_type
& 0xf);
2762 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2765 case RPC_FC_NON_ENCAPSULATED_UNION
:
2767 pFormat
= SkipConformance(pStubMsg
, pFormat
);
2768 pFormat
+= *(const SHORT
*)pFormat
;
2769 return *(const SHORT
*)pFormat
;
2771 return sizeof(void *);
2772 case RPC_FC_WSTRING
:
2773 return *(const WORD
*)&pFormat
[2] * 2;
2775 FIXME("unhandled embedded type %02x\n", *pFormat
);
2781 static ULONG
EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2782 PFORMAT_STRING pFormat
)
2784 NDR_MEMORYSIZE m
= NdrMemorySizer
[*pFormat
& NDR_TABLE_MASK
];
2788 FIXME("no memorysizer for data type=%02x\n", *pFormat
);
2792 return m(pStubMsg
, pFormat
);
2796 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2797 unsigned char *pMemory
,
2798 PFORMAT_STRING pFormat
,
2799 PFORMAT_STRING pPointer
)
2801 PFORMAT_STRING desc
;
2805 while (*pFormat
!= RPC_FC_END
) {
2811 TRACE("byte=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2812 safe_copy_to_buffer(pStubMsg
, pMemory
, 1);
2818 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2819 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
2824 USHORT val
= *(DWORD
*)pMemory
;
2825 TRACE("enum16=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2826 if (32767 < *(DWORD
*)pMemory
)
2827 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
2828 safe_copy_to_buffer(pStubMsg
, &val
, 2);
2835 TRACE("long=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2836 safe_copy_to_buffer(pStubMsg
, pMemory
, 4);
2839 case RPC_FC_INT3264
:
2840 case RPC_FC_UINT3264
:
2842 UINT val
= *(UINT_PTR
*)pMemory
;
2843 TRACE("int3264=%ld <= %p\n", *(UINT_PTR
*)pMemory
, pMemory
);
2844 safe_copy_to_buffer(pStubMsg
, &val
, sizeof(UINT
));
2845 pMemory
+= sizeof(UINT_PTR
);
2849 TRACE("float=%f <= %p\n", *(float*)pMemory
, pMemory
);
2850 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
2851 pMemory
+= sizeof(float);
2854 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2855 safe_copy_to_buffer(pStubMsg
, pMemory
, 8);
2859 TRACE("double=%f <= %p\n", *(double*)pMemory
, pMemory
);
2860 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
2861 pMemory
+= sizeof(double);
2867 case RPC_FC_POINTER
:
2869 unsigned char *saved_buffer
;
2870 BOOL pointer_buffer_mark_set
= FALSE
;
2871 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
2872 TRACE("pStubMsg->Buffer before %p\n", pStubMsg
->Buffer
);
2873 if (*pFormat
!= RPC_FC_POINTER
)
2875 if (*pPointer
!= RPC_FC_RP
)
2876 align_pointer_clear(&pStubMsg
->Buffer
, 4);
2877 saved_buffer
= pStubMsg
->Buffer
;
2878 if (pStubMsg
->PointerBufferMark
)
2880 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2881 pStubMsg
->PointerBufferMark
= NULL
;
2882 pointer_buffer_mark_set
= TRUE
;
2884 else if (*pPointer
!= RPC_FC_RP
)
2885 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2886 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char**)pMemory
, pPointer
);
2887 if (pointer_buffer_mark_set
)
2889 STD_OVERFLOW_CHECK(pStubMsg
);
2890 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2891 pStubMsg
->Buffer
= saved_buffer
;
2892 if (*pPointer
!= RPC_FC_RP
)
2893 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2895 TRACE("pStubMsg->Buffer after %p\n", pStubMsg
->Buffer
);
2896 if (*pFormat
== RPC_FC_POINTER
)
2900 pMemory
+= sizeof(void *);
2903 case RPC_FC_ALIGNM2
:
2904 align_pointer(&pMemory
, 2);
2906 case RPC_FC_ALIGNM4
:
2907 align_pointer(&pMemory
, 4);
2909 case RPC_FC_ALIGNM8
:
2910 align_pointer(&pMemory
, 8);
2912 case RPC_FC_STRUCTPAD1
:
2913 case RPC_FC_STRUCTPAD2
:
2914 case RPC_FC_STRUCTPAD3
:
2915 case RPC_FC_STRUCTPAD4
:
2916 case RPC_FC_STRUCTPAD5
:
2917 case RPC_FC_STRUCTPAD6
:
2918 case RPC_FC_STRUCTPAD7
:
2919 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2921 case RPC_FC_EMBEDDED_COMPLEX
:
2922 pMemory
+= pFormat
[1];
2924 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2925 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2926 TRACE("embedded complex (size=%d) <= %p\n", size
, pMemory
);
2927 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
2930 /* for some reason interface pointers aren't generated as
2931 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2932 * they still need the derefencing treatment that pointers are
2934 if (*desc
== RPC_FC_IP
)
2935 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2937 m(pStubMsg
, pMemory
, desc
);
2939 else FIXME("no marshaller for embedded type %02x\n", *desc
);
2946 FIXME("unhandled format 0x%02x\n", *pFormat
);
2954 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2955 unsigned char *pMemory
,
2956 PFORMAT_STRING pFormat
,
2957 PFORMAT_STRING pPointer
,
2958 unsigned char fMustAlloc
)
2960 PFORMAT_STRING desc
;
2964 while (*pFormat
!= RPC_FC_END
) {
2970 safe_copy_from_buffer(pStubMsg
, pMemory
, 1);
2971 TRACE("byte=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2977 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
2978 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2984 safe_copy_from_buffer(pStubMsg
, &val
, 2);
2985 *(DWORD
*)pMemory
= val
;
2986 TRACE("enum16=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
2987 if (32767 < *(DWORD
*)pMemory
)
2988 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
2995 safe_copy_from_buffer(pStubMsg
, pMemory
, 4);
2996 TRACE("long=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
2999 case RPC_FC_INT3264
:
3002 safe_copy_from_buffer(pStubMsg
, &val
, 4);
3003 *(INT_PTR
*)pMemory
= val
;
3004 TRACE("int3264=%ld => %p\n", *(INT_PTR
*)pMemory
, pMemory
);
3005 pMemory
+= sizeof(INT_PTR
);
3008 case RPC_FC_UINT3264
:
3011 safe_copy_from_buffer(pStubMsg
, &val
, 4);
3012 *(UINT_PTR
*)pMemory
= val
;
3013 TRACE("uint3264=%ld => %p\n", *(UINT_PTR
*)pMemory
, pMemory
);
3014 pMemory
+= sizeof(UINT_PTR
);
3018 safe_copy_from_buffer(pStubMsg
, pMemory
, sizeof(float));
3019 TRACE("float=%f => %p\n", *(float*)pMemory
, pMemory
);
3020 pMemory
+= sizeof(float);
3023 safe_copy_from_buffer(pStubMsg
, pMemory
, 8);
3024 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
3028 safe_copy_from_buffer(pStubMsg
, pMemory
, sizeof(double));
3029 TRACE("double=%f => %p\n", *(double*)pMemory
, pMemory
);
3030 pMemory
+= sizeof(double);
3036 case RPC_FC_POINTER
:
3038 unsigned char *saved_buffer
;
3039 BOOL pointer_buffer_mark_set
= FALSE
;
3040 TRACE("pointer => %p\n", pMemory
);
3041 if (*pFormat
!= RPC_FC_POINTER
)
3043 if (*pPointer
!= RPC_FC_RP
)
3044 align_pointer(&pStubMsg
->Buffer
, 4);
3045 saved_buffer
= pStubMsg
->Buffer
;
3046 if (pStubMsg
->PointerBufferMark
)
3048 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3049 pStubMsg
->PointerBufferMark
= NULL
;
3050 pointer_buffer_mark_set
= TRUE
;
3052 else if (*pPointer
!= RPC_FC_RP
)
3053 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3055 PointerUnmarshall(pStubMsg
, saved_buffer
, (unsigned char**)pMemory
, *(unsigned char**)pMemory
, pPointer
, fMustAlloc
);
3056 if (pointer_buffer_mark_set
)
3058 STD_OVERFLOW_CHECK(pStubMsg
);
3059 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3060 pStubMsg
->Buffer
= saved_buffer
;
3061 if (*pPointer
!= RPC_FC_RP
)
3062 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3064 if (*pFormat
== RPC_FC_POINTER
)
3068 pMemory
+= sizeof(void *);
3071 case RPC_FC_ALIGNM2
:
3072 align_pointer_clear(&pMemory
, 2);
3074 case RPC_FC_ALIGNM4
:
3075 align_pointer_clear(&pMemory
, 4);
3077 case RPC_FC_ALIGNM8
:
3078 align_pointer_clear(&pMemory
, 8);
3080 case RPC_FC_STRUCTPAD1
:
3081 case RPC_FC_STRUCTPAD2
:
3082 case RPC_FC_STRUCTPAD3
:
3083 case RPC_FC_STRUCTPAD4
:
3084 case RPC_FC_STRUCTPAD5
:
3085 case RPC_FC_STRUCTPAD6
:
3086 case RPC_FC_STRUCTPAD7
:
3087 memset(pMemory
, 0, *pFormat
- RPC_FC_STRUCTPAD1
+ 1);
3088 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3090 case RPC_FC_EMBEDDED_COMPLEX
:
3091 pMemory
+= pFormat
[1];
3093 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3094 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3095 TRACE("embedded complex (size=%d) => %p\n", size
, pMemory
);
3097 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
3098 * since the type is part of the memory block that is encompassed by
3099 * the whole complex type. Memory is forced to allocate when pointers
3100 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
3101 * clearing the memory we pass in to the unmarshaller */
3102 memset(pMemory
, 0, size
);
3103 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
3106 /* for some reason interface pointers aren't generated as
3107 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3108 * they still need the derefencing treatment that pointers are
3110 if (*desc
== RPC_FC_IP
)
3111 m(pStubMsg
, (unsigned char **)pMemory
, desc
, FALSE
);
3113 m(pStubMsg
, &pMemory
, desc
, FALSE
);
3115 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
3122 FIXME("unhandled format %d\n", *pFormat
);
3130 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3131 unsigned char *pMemory
,
3132 PFORMAT_STRING pFormat
,
3133 PFORMAT_STRING pPointer
)
3135 PFORMAT_STRING desc
;
3139 while (*pFormat
!= RPC_FC_END
) {
3145 safe_buffer_length_increment(pStubMsg
, 1);
3151 safe_buffer_length_increment(pStubMsg
, 2);
3155 safe_buffer_length_increment(pStubMsg
, 2);
3162 safe_buffer_length_increment(pStubMsg
, 4);
3165 case RPC_FC_INT3264
:
3166 case RPC_FC_UINT3264
:
3167 safe_buffer_length_increment(pStubMsg
, 4);
3168 pMemory
+= sizeof(INT_PTR
);
3172 safe_buffer_length_increment(pStubMsg
, 8);
3179 case RPC_FC_POINTER
:
3180 if (*pFormat
!= RPC_FC_POINTER
)
3182 if (!pStubMsg
->IgnoreEmbeddedPointers
)
3184 int saved_buffer_length
= pStubMsg
->BufferLength
;
3185 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3186 pStubMsg
->PointerLength
= 0;
3187 if(!pStubMsg
->BufferLength
)
3188 ERR("BufferLength == 0??\n");
3189 PointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
3190 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3191 pStubMsg
->BufferLength
= saved_buffer_length
;
3193 if (*pPointer
!= RPC_FC_RP
)
3195 align_length(&pStubMsg
->BufferLength
, 4);
3196 safe_buffer_length_increment(pStubMsg
, 4);
3198 if (*pFormat
== RPC_FC_POINTER
)
3202 pMemory
+= sizeof(void*);
3204 case RPC_FC_ALIGNM2
:
3205 align_pointer(&pMemory
, 2);
3207 case RPC_FC_ALIGNM4
:
3208 align_pointer(&pMemory
, 4);
3210 case RPC_FC_ALIGNM8
:
3211 align_pointer(&pMemory
, 8);
3213 case RPC_FC_STRUCTPAD1
:
3214 case RPC_FC_STRUCTPAD2
:
3215 case RPC_FC_STRUCTPAD3
:
3216 case RPC_FC_STRUCTPAD4
:
3217 case RPC_FC_STRUCTPAD5
:
3218 case RPC_FC_STRUCTPAD6
:
3219 case RPC_FC_STRUCTPAD7
:
3220 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3222 case RPC_FC_EMBEDDED_COMPLEX
:
3223 pMemory
+= pFormat
[1];
3225 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3226 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3227 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
3230 /* for some reason interface pointers aren't generated as
3231 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3232 * they still need the derefencing treatment that pointers are
3234 if (*desc
== RPC_FC_IP
)
3235 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
3237 m(pStubMsg
, pMemory
, desc
);
3239 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
3246 FIXME("unhandled format 0x%02x\n", *pFormat
);
3254 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
3255 unsigned char *pMemory
,
3256 PFORMAT_STRING pFormat
,
3257 PFORMAT_STRING pPointer
)
3259 PFORMAT_STRING desc
;
3263 while (*pFormat
!= RPC_FC_END
) {
3283 case RPC_FC_INT3264
:
3284 case RPC_FC_UINT3264
:
3285 pMemory
+= sizeof(INT_PTR
);
3295 case RPC_FC_POINTER
:
3296 if (*pFormat
!= RPC_FC_POINTER
)
3298 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
3299 if (*pFormat
== RPC_FC_POINTER
)
3303 pMemory
+= sizeof(void *);
3305 case RPC_FC_ALIGNM2
:
3306 align_pointer(&pMemory
, 2);
3308 case RPC_FC_ALIGNM4
:
3309 align_pointer(&pMemory
, 4);
3311 case RPC_FC_ALIGNM8
:
3312 align_pointer(&pMemory
, 8);
3314 case RPC_FC_STRUCTPAD1
:
3315 case RPC_FC_STRUCTPAD2
:
3316 case RPC_FC_STRUCTPAD3
:
3317 case RPC_FC_STRUCTPAD4
:
3318 case RPC_FC_STRUCTPAD5
:
3319 case RPC_FC_STRUCTPAD6
:
3320 case RPC_FC_STRUCTPAD7
:
3321 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3323 case RPC_FC_EMBEDDED_COMPLEX
:
3324 pMemory
+= pFormat
[1];
3326 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3327 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3328 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
3331 /* for some reason interface pointers aren't generated as
3332 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3333 * they still need the derefencing treatment that pointers are
3335 if (*desc
== RPC_FC_IP
)
3336 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
3338 m(pStubMsg
, pMemory
, desc
);
3346 FIXME("unhandled format 0x%02x\n", *pFormat
);
3354 static ULONG
ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3355 PFORMAT_STRING pFormat
,
3356 PFORMAT_STRING pPointer
)
3358 PFORMAT_STRING desc
;
3361 while (*pFormat
!= RPC_FC_END
) {
3368 safe_buffer_increment(pStubMsg
, 1);
3374 safe_buffer_increment(pStubMsg
, 2);
3378 safe_buffer_increment(pStubMsg
, 2);
3385 safe_buffer_increment(pStubMsg
, 4);
3387 case RPC_FC_INT3264
:
3388 case RPC_FC_UINT3264
:
3389 size
+= sizeof(INT_PTR
);
3390 safe_buffer_increment(pStubMsg
, 4);
3395 safe_buffer_increment(pStubMsg
, 8);
3401 case RPC_FC_POINTER
:
3403 unsigned char *saved_buffer
;
3404 BOOL pointer_buffer_mark_set
= FALSE
;
3405 if (*pFormat
!= RPC_FC_POINTER
)
3407 if (*pPointer
!= RPC_FC_RP
)
3408 align_pointer(&pStubMsg
->Buffer
, 4);
3409 saved_buffer
= pStubMsg
->Buffer
;
3410 if (pStubMsg
->PointerBufferMark
)
3412 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3413 pStubMsg
->PointerBufferMark
= NULL
;
3414 pointer_buffer_mark_set
= TRUE
;
3416 else if (*pPointer
!= RPC_FC_RP
)
3417 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3419 if (!pStubMsg
->IgnoreEmbeddedPointers
)
3420 PointerMemorySize(pStubMsg
, saved_buffer
, pPointer
);
3421 if (pointer_buffer_mark_set
)
3423 STD_OVERFLOW_CHECK(pStubMsg
);
3424 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3425 pStubMsg
->Buffer
= saved_buffer
;
3426 if (*pPointer
!= RPC_FC_RP
)
3427 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3429 if (*pFormat
== RPC_FC_POINTER
)
3433 size
+= sizeof(void *);
3436 case RPC_FC_ALIGNM2
:
3437 align_length(&size
, 2);
3439 case RPC_FC_ALIGNM4
:
3440 align_length(&size
, 4);
3442 case RPC_FC_ALIGNM8
:
3443 align_length(&size
, 8);
3445 case RPC_FC_STRUCTPAD1
:
3446 case RPC_FC_STRUCTPAD2
:
3447 case RPC_FC_STRUCTPAD3
:
3448 case RPC_FC_STRUCTPAD4
:
3449 case RPC_FC_STRUCTPAD5
:
3450 case RPC_FC_STRUCTPAD6
:
3451 case RPC_FC_STRUCTPAD7
:
3452 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3454 case RPC_FC_EMBEDDED_COMPLEX
:
3457 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3458 size
+= EmbeddedComplexMemorySize(pStubMsg
, desc
);
3464 FIXME("unhandled format 0x%02x\n", *pFormat
);
3472 ULONG
ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
3474 PFORMAT_STRING desc
;
3477 while (*pFormat
!= RPC_FC_END
) {
3497 case RPC_FC_INT3264
:
3498 case RPC_FC_UINT3264
:
3499 size
+= sizeof(INT_PTR
);
3509 case RPC_FC_POINTER
:
3510 size
+= sizeof(void *);
3511 if (*pFormat
!= RPC_FC_POINTER
)
3514 case RPC_FC_ALIGNM2
:
3515 align_length(&size
, 2);
3517 case RPC_FC_ALIGNM4
:
3518 align_length(&size
, 4);
3520 case RPC_FC_ALIGNM8
:
3521 align_length(&size
, 8);
3523 case RPC_FC_STRUCTPAD1
:
3524 case RPC_FC_STRUCTPAD2
:
3525 case RPC_FC_STRUCTPAD3
:
3526 case RPC_FC_STRUCTPAD4
:
3527 case RPC_FC_STRUCTPAD5
:
3528 case RPC_FC_STRUCTPAD6
:
3529 case RPC_FC_STRUCTPAD7
:
3530 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3532 case RPC_FC_EMBEDDED_COMPLEX
:
3535 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3536 size
+= EmbeddedComplexSize(pStubMsg
, desc
);
3542 FIXME("unhandled format 0x%02x\n", *pFormat
);
3550 /***********************************************************************
3551 * NdrComplexStructMarshall [RPCRT4.@]
3553 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3554 unsigned char *pMemory
,
3555 PFORMAT_STRING pFormat
)
3557 PFORMAT_STRING conf_array
= NULL
;
3558 PFORMAT_STRING pointer_desc
= NULL
;
3559 unsigned char *OldMemory
= pStubMsg
->Memory
;
3560 BOOL pointer_buffer_mark_set
= FALSE
;
3562 ULONG max_count
= 0;
3565 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3567 if (!pStubMsg
->PointerBufferMark
)
3569 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3570 /* save buffer length */
3571 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
3573 /* get the buffer pointer after complex array data, but before
3575 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
;
3576 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3577 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
3578 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3580 /* save it for use by embedded pointer code later */
3581 pStubMsg
->PointerBufferMark
= (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
;
3582 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->PointerBufferMark
- pStubMsg
->Buffer
));
3583 pointer_buffer_mark_set
= TRUE
;
3585 /* restore the original buffer length */
3586 pStubMsg
->BufferLength
= saved_buffer_length
;
3589 align_pointer_clear(&pStubMsg
->Buffer
, pFormat
[1] + 1);
3592 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3594 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3597 pStubMsg
->Memory
= pMemory
;
3601 ULONG struct_size
= ComplexStructSize(pStubMsg
, pFormat
);
3602 array_compute_and_write_conformance(conf_array
[0], pStubMsg
,
3603 pMemory
+ struct_size
, conf_array
);
3604 /* these could be changed in ComplexMarshall so save them for later */
3605 max_count
= pStubMsg
->MaxCount
;
3606 count
= pStubMsg
->ActualCount
;
3607 offset
= pStubMsg
->Offset
;
3610 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3614 pStubMsg
->MaxCount
= max_count
;
3615 pStubMsg
->ActualCount
= count
;
3616 pStubMsg
->Offset
= offset
;
3617 array_write_variance_and_marshall(conf_array
[0], pStubMsg
, pMemory
,
3618 conf_array
, TRUE
/* fHasPointers */);
3621 pStubMsg
->Memory
= OldMemory
;
3623 if (pointer_buffer_mark_set
)
3625 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3626 pStubMsg
->PointerBufferMark
= NULL
;
3629 STD_OVERFLOW_CHECK(pStubMsg
);
3634 /***********************************************************************
3635 * NdrComplexStructUnmarshall [RPCRT4.@]
3637 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3638 unsigned char **ppMemory
,
3639 PFORMAT_STRING pFormat
,
3640 unsigned char fMustAlloc
)
3642 unsigned size
= *(const WORD
*)(pFormat
+2);
3643 PFORMAT_STRING conf_array
= NULL
;
3644 PFORMAT_STRING pointer_desc
= NULL
;
3645 unsigned char *pMemory
;
3646 BOOL pointer_buffer_mark_set
= FALSE
;
3648 ULONG max_count
= 0;
3650 ULONG array_size
= 0;
3652 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3654 if (!pStubMsg
->PointerBufferMark
)
3656 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3657 /* save buffer pointer */
3658 unsigned char *saved_buffer
= pStubMsg
->Buffer
;
3660 /* get the buffer pointer after complex array data, but before
3662 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3663 NdrComplexStructMemorySize(pStubMsg
, pFormat
);
3664 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3666 /* save it for use by embedded pointer code later */
3667 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3668 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->PointerBufferMark
- saved_buffer
));
3669 pointer_buffer_mark_set
= TRUE
;
3671 /* restore the original buffer */
3672 pStubMsg
->Buffer
= saved_buffer
;
3675 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
3678 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3680 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3685 array_size
= array_read_conformance(conf_array
[0], pStubMsg
, conf_array
);
3688 /* these could be changed in ComplexMarshall so save them for later */
3689 max_count
= pStubMsg
->MaxCount
;
3690 count
= pStubMsg
->ActualCount
;
3691 offset
= pStubMsg
->Offset
;
3694 if (!fMustAlloc
&& !*ppMemory
)
3697 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3699 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
, fMustAlloc
);
3703 pStubMsg
->MaxCount
= max_count
;
3704 pStubMsg
->ActualCount
= count
;
3705 pStubMsg
->Offset
= offset
;
3707 memset(pMemory
, 0, array_size
);
3708 array_read_variance_and_unmarshall(conf_array
[0], pStubMsg
, &pMemory
,
3710 FALSE
/* fUseBufferMemoryServer */,
3711 TRUE
/* fUnmarshall */);
3714 if (pointer_buffer_mark_set
)
3716 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3717 pStubMsg
->PointerBufferMark
= NULL
;
3723 /***********************************************************************
3724 * NdrComplexStructBufferSize [RPCRT4.@]
3726 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3727 unsigned char *pMemory
,
3728 PFORMAT_STRING pFormat
)
3730 PFORMAT_STRING conf_array
= NULL
;
3731 PFORMAT_STRING pointer_desc
= NULL
;
3732 unsigned char *OldMemory
= pStubMsg
->Memory
;
3733 int pointer_length_set
= 0;
3735 ULONG max_count
= 0;
3738 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3740 align_length(&pStubMsg
->BufferLength
, pFormat
[1] + 1);
3742 if(!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
3744 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3745 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
3747 /* get the buffer length after complex struct data, but before
3749 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3750 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
3751 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3753 /* save it for use by embedded pointer code later */
3754 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3755 pointer_length_set
= 1;
3756 TRACE("difference = 0x%x\n", pStubMsg
->PointerLength
- saved_buffer_length
);
3758 /* restore the original buffer length */
3759 pStubMsg
->BufferLength
= saved_buffer_length
;
3763 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3765 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3768 pStubMsg
->Memory
= pMemory
;
3772 ULONG struct_size
= ComplexStructSize(pStubMsg
, pFormat
);
3773 array_compute_and_size_conformance(conf_array
[0], pStubMsg
, pMemory
+ struct_size
,
3776 /* these could be changed in ComplexMarshall so save them for later */
3777 max_count
= pStubMsg
->MaxCount
;
3778 count
= pStubMsg
->ActualCount
;
3779 offset
= pStubMsg
->Offset
;
3782 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3786 pStubMsg
->MaxCount
= max_count
;
3787 pStubMsg
->ActualCount
= count
;
3788 pStubMsg
->Offset
= offset
;
3789 array_buffer_size(conf_array
[0], pStubMsg
, pMemory
, conf_array
,
3790 TRUE
/* fHasPointers */);
3793 pStubMsg
->Memory
= OldMemory
;
3795 if(pointer_length_set
)
3797 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3798 pStubMsg
->PointerLength
= 0;
3803 /***********************************************************************
3804 * NdrComplexStructMemorySize [RPCRT4.@]
3806 ULONG WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3807 PFORMAT_STRING pFormat
)
3809 unsigned size
= *(const WORD
*)(pFormat
+2);
3810 PFORMAT_STRING conf_array
= NULL
;
3811 PFORMAT_STRING pointer_desc
= NULL
;
3813 ULONG max_count
= 0;
3816 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3818 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
3821 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3823 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3828 array_read_conformance(conf_array
[0], pStubMsg
, conf_array
);
3830 /* these could be changed in ComplexStructMemorySize so save them for
3832 max_count
= pStubMsg
->MaxCount
;
3833 count
= pStubMsg
->ActualCount
;
3834 offset
= pStubMsg
->Offset
;
3837 ComplexStructMemorySize(pStubMsg
, pFormat
, pointer_desc
);
3841 pStubMsg
->MaxCount
= max_count
;
3842 pStubMsg
->ActualCount
= count
;
3843 pStubMsg
->Offset
= offset
;
3844 array_memory_size(conf_array
[0], pStubMsg
, conf_array
,
3845 TRUE
/* fHasPointers */);
3851 /***********************************************************************
3852 * NdrComplexStructFree [RPCRT4.@]
3854 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3855 unsigned char *pMemory
,
3856 PFORMAT_STRING pFormat
)
3858 PFORMAT_STRING conf_array
= NULL
;
3859 PFORMAT_STRING pointer_desc
= NULL
;
3860 unsigned char *OldMemory
= pStubMsg
->Memory
;
3862 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3865 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3867 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3870 pStubMsg
->Memory
= pMemory
;
3872 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3875 array_free(conf_array
[0], pStubMsg
, pMemory
, conf_array
,
3876 TRUE
/* fHasPointers */);
3878 pStubMsg
->Memory
= OldMemory
;
3881 /***********************************************************************
3882 * NdrConformantArrayMarshall [RPCRT4.@]
3884 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3885 unsigned char *pMemory
,
3886 PFORMAT_STRING pFormat
)
3888 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3889 if (pFormat
[0] != RPC_FC_CARRAY
)
3891 ERR("invalid format = 0x%x\n", pFormat
[0]);
3892 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3895 array_compute_and_write_conformance(RPC_FC_CARRAY
, pStubMsg
, pMemory
,
3897 array_write_variance_and_marshall(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3898 TRUE
/* fHasPointers */);
3903 /***********************************************************************
3904 * NdrConformantArrayUnmarshall [RPCRT4.@]
3906 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3907 unsigned char **ppMemory
,
3908 PFORMAT_STRING pFormat
,
3909 unsigned char fMustAlloc
)
3911 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3912 if (pFormat
[0] != RPC_FC_CARRAY
)
3914 ERR("invalid format = 0x%x\n", pFormat
[0]);
3915 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3918 array_read_conformance(RPC_FC_CARRAY
, pStubMsg
, pFormat
);
3919 array_read_variance_and_unmarshall(RPC_FC_CARRAY
, pStubMsg
, ppMemory
, pFormat
,
3921 TRUE
/* fUseBufferMemoryServer */,
3922 TRUE
/* fUnmarshall */);
3927 /***********************************************************************
3928 * NdrConformantArrayBufferSize [RPCRT4.@]
3930 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3931 unsigned char *pMemory
,
3932 PFORMAT_STRING pFormat
)
3934 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3935 if (pFormat
[0] != RPC_FC_CARRAY
)
3937 ERR("invalid format = 0x%x\n", pFormat
[0]);
3938 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3941 array_compute_and_size_conformance(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
);
3942 array_buffer_size(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3943 TRUE
/* fHasPointers */);
3946 /***********************************************************************
3947 * NdrConformantArrayMemorySize [RPCRT4.@]
3949 ULONG WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3950 PFORMAT_STRING pFormat
)
3952 TRACE("(%p,%p)\n", pStubMsg
, 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_read_conformance(RPC_FC_CARRAY
, pStubMsg
, pFormat
);
3960 array_memory_size(RPC_FC_CARRAY
, pStubMsg
, pFormat
, TRUE
/* fHasPointers */);
3962 return pStubMsg
->MemorySize
;
3965 /***********************************************************************
3966 * NdrConformantArrayFree [RPCRT4.@]
3968 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3969 unsigned char *pMemory
,
3970 PFORMAT_STRING pFormat
)
3972 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3973 if (pFormat
[0] != RPC_FC_CARRAY
)
3975 ERR("invalid format = 0x%x\n", pFormat
[0]);
3976 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3979 array_free(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3980 TRUE
/* fHasPointers */);
3984 /***********************************************************************
3985 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3987 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
3988 unsigned char* pMemory
,
3989 PFORMAT_STRING pFormat
)
3991 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3993 if (pFormat
[0] != RPC_FC_CVARRAY
)
3995 ERR("invalid format type %x\n", pFormat
[0]);
3996 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4000 array_compute_and_write_conformance(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
4002 array_write_variance_and_marshall(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
4003 pFormat
, TRUE
/* fHasPointers */);
4009 /***********************************************************************
4010 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
4012 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
4013 unsigned char** ppMemory
,
4014 PFORMAT_STRING pFormat
,
4015 unsigned char fMustAlloc
)
4017 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4019 if (pFormat
[0] != RPC_FC_CVARRAY
)
4021 ERR("invalid format type %x\n", pFormat
[0]);
4022 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4026 array_read_conformance(RPC_FC_CVARRAY
, pStubMsg
, pFormat
);
4027 array_read_variance_and_unmarshall(RPC_FC_CVARRAY
, pStubMsg
, ppMemory
,
4028 pFormat
, fMustAlloc
,
4029 TRUE
/* fUseBufferMemoryServer */,
4030 TRUE
/* fUnmarshall */);
4036 /***********************************************************************
4037 * NdrConformantVaryingArrayFree [RPCRT4.@]
4039 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
4040 unsigned char* pMemory
,
4041 PFORMAT_STRING pFormat
)
4043 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4045 if (pFormat
[0] != RPC_FC_CVARRAY
)
4047 ERR("invalid format type %x\n", pFormat
[0]);
4048 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4052 array_free(RPC_FC_CVARRAY
, pStubMsg
, pMemory
, pFormat
,
4053 TRUE
/* fHasPointers */);
4057 /***********************************************************************
4058 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
4060 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
4061 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
4063 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4065 if (pFormat
[0] != RPC_FC_CVARRAY
)
4067 ERR("invalid format type %x\n", pFormat
[0]);
4068 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4072 array_compute_and_size_conformance(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
4074 array_buffer_size(RPC_FC_CVARRAY
, pStubMsg
, pMemory
, pFormat
,
4075 TRUE
/* fHasPointers */);
4079 /***********************************************************************
4080 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
4082 ULONG WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
4083 PFORMAT_STRING pFormat
)
4085 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4087 if (pFormat
[0] != RPC_FC_CVARRAY
)
4089 ERR("invalid format type %x\n", pFormat
[0]);
4090 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4091 return pStubMsg
->MemorySize
;
4094 array_read_conformance(RPC_FC_CVARRAY
, pStubMsg
, pFormat
);
4095 array_memory_size(RPC_FC_CVARRAY
, pStubMsg
, pFormat
,
4096 TRUE
/* fHasPointers */);
4098 return pStubMsg
->MemorySize
;
4102 /***********************************************************************
4103 * NdrComplexArrayMarshall [RPCRT4.@]
4105 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4106 unsigned char *pMemory
,
4107 PFORMAT_STRING pFormat
)
4109 BOOL pointer_buffer_mark_set
= FALSE
;
4111 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4113 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4115 ERR("invalid format type %x\n", pFormat
[0]);
4116 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4120 if (!pStubMsg
->PointerBufferMark
)
4122 /* save buffer fields that may be changed by buffer sizer functions
4123 * and that may be needed later on */
4124 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
4125 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
4126 ULONG_PTR saved_max_count
= pStubMsg
->MaxCount
;
4127 ULONG saved_offset
= pStubMsg
->Offset
;
4128 ULONG saved_actual_count
= pStubMsg
->ActualCount
;
4130 /* get the buffer pointer after complex array data, but before
4132 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
;
4133 pStubMsg
->IgnoreEmbeddedPointers
= 1;
4134 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
4135 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
4137 /* save it for use by embedded pointer code later */
4138 pStubMsg
->PointerBufferMark
= (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
;
4139 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
));
4140 pointer_buffer_mark_set
= TRUE
;
4142 /* restore fields */
4143 pStubMsg
->ActualCount
= saved_actual_count
;
4144 pStubMsg
->Offset
= saved_offset
;
4145 pStubMsg
->MaxCount
= saved_max_count
;
4146 pStubMsg
->BufferLength
= saved_buffer_length
;
4149 array_compute_and_write_conformance(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pMemory
, pFormat
);
4150 array_write_variance_and_marshall(RPC_FC_BOGUS_ARRAY
, pStubMsg
,
4151 pMemory
, pFormat
, TRUE
/* fHasPointers */);
4153 STD_OVERFLOW_CHECK(pStubMsg
);
4155 if (pointer_buffer_mark_set
)
4157 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4158 pStubMsg
->PointerBufferMark
= NULL
;
4164 /***********************************************************************
4165 * NdrComplexArrayUnmarshall [RPCRT4.@]
4167 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4168 unsigned char **ppMemory
,
4169 PFORMAT_STRING pFormat
,
4170 unsigned char fMustAlloc
)
4172 unsigned char *saved_buffer
;
4173 BOOL pointer_buffer_mark_set
= FALSE
;
4174 int saved_ignore_embedded
;
4176 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4178 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4180 ERR("invalid format type %x\n", pFormat
[0]);
4181 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4185 saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
4186 /* save buffer pointer */
4187 saved_buffer
= pStubMsg
->Buffer
;
4188 /* get the buffer pointer after complex array data, but before
4190 pStubMsg
->IgnoreEmbeddedPointers
= 1;
4191 pStubMsg
->MemorySize
= 0;
4192 NdrComplexArrayMemorySize(pStubMsg
, pFormat
);
4193 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
4195 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->Buffer
- saved_buffer
));
4196 if (!pStubMsg
->PointerBufferMark
)
4198 /* save it for use by embedded pointer code later */
4199 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4200 pointer_buffer_mark_set
= TRUE
;
4202 /* restore the original buffer */
4203 pStubMsg
->Buffer
= saved_buffer
;
4205 array_read_conformance(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pFormat
);
4206 array_read_variance_and_unmarshall(RPC_FC_BOGUS_ARRAY
, pStubMsg
, ppMemory
, pFormat
, fMustAlloc
,
4207 TRUE
/* fUseBufferMemoryServer */, TRUE
/* fUnmarshall */);
4209 if (pointer_buffer_mark_set
)
4211 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4212 pStubMsg
->PointerBufferMark
= NULL
;
4218 /***********************************************************************
4219 * NdrComplexArrayBufferSize [RPCRT4.@]
4221 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4222 unsigned char *pMemory
,
4223 PFORMAT_STRING pFormat
)
4225 int pointer_length_set
= 0;
4227 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4229 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4231 ERR("invalid format type %x\n", pFormat
[0]);
4232 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4236 if (!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
4238 /* save buffer fields that may be changed by buffer sizer functions
4239 * and that may be needed later on */
4240 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
4241 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
4242 ULONG_PTR saved_max_count
= pStubMsg
->MaxCount
;
4243 ULONG saved_offset
= pStubMsg
->Offset
;
4244 ULONG saved_actual_count
= pStubMsg
->ActualCount
;
4246 /* get the buffer pointer after complex array data, but before
4248 pStubMsg
->IgnoreEmbeddedPointers
= 1;
4249 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
4250 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
4252 /* save it for use by embedded pointer code later */
4253 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4254 pointer_length_set
= 1;
4256 /* restore fields */
4257 pStubMsg
->ActualCount
= saved_actual_count
;
4258 pStubMsg
->Offset
= saved_offset
;
4259 pStubMsg
->MaxCount
= saved_max_count
;
4260 pStubMsg
->BufferLength
= saved_buffer_length
;
4263 array_compute_and_size_conformance(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pMemory
, pFormat
);
4264 array_buffer_size(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pMemory
, pFormat
, TRUE
/* fHasPointers */);
4266 if(pointer_length_set
)
4268 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4269 pStubMsg
->PointerLength
= 0;
4273 /***********************************************************************
4274 * NdrComplexArrayMemorySize [RPCRT4.@]
4276 ULONG WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4277 PFORMAT_STRING pFormat
)
4279 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
4281 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4283 ERR("invalid format type %x\n", pFormat
[0]);
4284 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4288 array_read_conformance(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pFormat
);
4289 array_memory_size(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pFormat
, TRUE
/* fHasPointers */);
4290 return pStubMsg
->MemorySize
;
4293 /***********************************************************************
4294 * NdrComplexArrayFree [RPCRT4.@]
4296 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4297 unsigned char *pMemory
,
4298 PFORMAT_STRING pFormat
)
4300 ULONG i
, count
, def
;
4302 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4304 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4306 ERR("invalid format type %x\n", pFormat
[0]);
4307 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4311 def
= *(const WORD
*)&pFormat
[2];
4314 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
4315 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
4317 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
4318 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
4320 count
= pStubMsg
->ActualCount
;
4321 for (i
= 0; i
< count
; i
++)
4322 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
4325 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg
,
4326 USER_MARSHAL_CB_TYPE cbtype
, PFORMAT_STRING pFormat
,
4327 USER_MARSHAL_CB
*umcb
)
4329 umcb
->Flags
= MAKELONG(pStubMsg
->dwDestContext
,
4330 pStubMsg
->RpcMsg
->DataRepresentation
);
4331 umcb
->pStubMsg
= pStubMsg
;
4332 umcb
->pReserve
= NULL
;
4333 umcb
->Signature
= USER_MARSHAL_CB_SIGNATURE
;
4334 umcb
->CBType
= cbtype
;
4335 umcb
->pFormat
= pFormat
;
4336 umcb
->pTypeFormat
= NULL
/* FIXME */;
4339 #define USER_MARSHAL_PTR_PREFIX \
4340 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4341 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4343 /***********************************************************************
4344 * NdrUserMarshalMarshall [RPCRT4.@]
4346 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4347 unsigned char *pMemory
,
4348 PFORMAT_STRING pFormat
)
4350 unsigned flags
= pFormat
[1];
4351 unsigned index
= *(const WORD
*)&pFormat
[2];
4352 unsigned char *saved_buffer
= NULL
;
4353 USER_MARSHAL_CB umcb
;
4355 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4356 TRACE("index=%d\n", index
);
4358 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_MARSHALL
, pFormat
, &umcb
);
4360 if (flags
& USER_MARSHAL_POINTER
)
4362 align_pointer_clear(&pStubMsg
->Buffer
, 4);
4363 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, USER_MARSHAL_PTR_PREFIX
);
4364 pStubMsg
->Buffer
+= 4;
4365 if (pStubMsg
->PointerBufferMark
)
4367 saved_buffer
= pStubMsg
->Buffer
;
4368 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4369 pStubMsg
->PointerBufferMark
= NULL
;
4371 align_pointer_clear(&pStubMsg
->Buffer
, 8);
4374 align_pointer_clear(&pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4377 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
4378 &umcb
.Flags
, pStubMsg
->Buffer
, pMemory
);
4382 STD_OVERFLOW_CHECK(pStubMsg
);
4383 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4384 pStubMsg
->Buffer
= saved_buffer
;
4387 STD_OVERFLOW_CHECK(pStubMsg
);
4392 /***********************************************************************
4393 * NdrUserMarshalUnmarshall [RPCRT4.@]
4395 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4396 unsigned char **ppMemory
,
4397 PFORMAT_STRING pFormat
,
4398 unsigned char fMustAlloc
)
4400 unsigned flags
= pFormat
[1];
4401 unsigned index
= *(const WORD
*)&pFormat
[2];
4402 DWORD memsize
= *(const WORD
*)&pFormat
[4];
4403 unsigned char *saved_buffer
= NULL
;
4404 USER_MARSHAL_CB umcb
;
4406 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4407 TRACE("index=%d\n", index
);
4409 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_UNMARSHALL
, pFormat
, &umcb
);
4411 if (flags
& USER_MARSHAL_POINTER
)
4413 align_pointer(&pStubMsg
->Buffer
, 4);
4414 /* skip pointer prefix */
4415 pStubMsg
->Buffer
+= 4;
4416 if (pStubMsg
->PointerBufferMark
)
4418 saved_buffer
= pStubMsg
->Buffer
;
4419 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4420 pStubMsg
->PointerBufferMark
= NULL
;
4422 align_pointer(&pStubMsg
->Buffer
, 8);
4425 align_pointer(&pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4427 if (!fMustAlloc
&& !*ppMemory
)
4431 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
4432 memset(*ppMemory
, 0, memsize
);
4436 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
4437 &umcb
.Flags
, pStubMsg
->Buffer
, *ppMemory
);
4441 STD_OVERFLOW_CHECK(pStubMsg
);
4442 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4443 pStubMsg
->Buffer
= saved_buffer
;
4449 /***********************************************************************
4450 * NdrUserMarshalBufferSize [RPCRT4.@]
4452 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4453 unsigned char *pMemory
,
4454 PFORMAT_STRING pFormat
)
4456 unsigned flags
= pFormat
[1];
4457 unsigned index
= *(const WORD
*)&pFormat
[2];
4458 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
4459 USER_MARSHAL_CB umcb
;
4460 ULONG saved_buffer_length
= 0;
4462 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4463 TRACE("index=%d\n", index
);
4465 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_BUFFER_SIZE
, pFormat
, &umcb
);
4467 if (flags
& USER_MARSHAL_POINTER
)
4469 align_length(&pStubMsg
->BufferLength
, 4);
4470 /* skip pointer prefix */
4471 safe_buffer_length_increment(pStubMsg
, 4);
4472 if (pStubMsg
->IgnoreEmbeddedPointers
)
4474 if (pStubMsg
->PointerLength
)
4476 saved_buffer_length
= pStubMsg
->BufferLength
;
4477 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4478 pStubMsg
->PointerLength
= 0;
4480 align_length(&pStubMsg
->BufferLength
, 8);
4483 align_length(&pStubMsg
->BufferLength
, (flags
& 0xf) + 1);
4486 TRACE("size=%d\n", bufsize
);
4487 safe_buffer_length_increment(pStubMsg
, bufsize
);
4490 pStubMsg
->BufferLength
=
4491 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
4492 &umcb
.Flags
, pStubMsg
->BufferLength
, pMemory
);
4494 if (saved_buffer_length
)
4496 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4497 pStubMsg
->BufferLength
= saved_buffer_length
;
4502 /***********************************************************************
4503 * NdrUserMarshalMemorySize [RPCRT4.@]
4505 ULONG WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4506 PFORMAT_STRING pFormat
)
4508 unsigned flags
= pFormat
[1];
4509 unsigned index
= *(const WORD
*)&pFormat
[2];
4510 DWORD memsize
= *(const WORD
*)&pFormat
[4];
4511 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
4513 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
4514 TRACE("index=%d\n", index
);
4516 pStubMsg
->MemorySize
+= memsize
;
4518 if (flags
& USER_MARSHAL_POINTER
)
4520 align_pointer(&pStubMsg
->Buffer
, 4);
4521 /* skip pointer prefix */
4522 pStubMsg
->Buffer
+= 4;
4523 if (pStubMsg
->IgnoreEmbeddedPointers
)
4524 return pStubMsg
->MemorySize
;
4525 align_pointer(&pStubMsg
->Buffer
, 8);
4528 align_pointer(&pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4531 FIXME("not implemented for varying buffer size\n");
4533 pStubMsg
->Buffer
+= bufsize
;
4535 return pStubMsg
->MemorySize
;
4538 /***********************************************************************
4539 * NdrUserMarshalFree [RPCRT4.@]
4541 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
4542 unsigned char *pMemory
,
4543 PFORMAT_STRING pFormat
)
4545 /* unsigned flags = pFormat[1]; */
4546 unsigned index
= *(const WORD
*)&pFormat
[2];
4547 USER_MARSHAL_CB umcb
;
4549 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4550 TRACE("index=%d\n", index
);
4552 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_FREE
, pFormat
, &umcb
);
4554 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
4555 &umcb
.Flags
, pMemory
);
4558 /***********************************************************************
4559 * NdrGetUserMarshalInfo [RPCRT4.@]
4561 RPC_STATUS RPC_ENTRY
NdrGetUserMarshalInfo(ULONG
*flags
, ULONG level
, NDR_USER_MARSHAL_INFO
*umi
)
4563 USER_MARSHAL_CB
*umcb
= CONTAINING_RECORD(flags
, USER_MARSHAL_CB
, Flags
);
4565 TRACE("(%p,%u,%p)\n", flags
, level
, umi
);
4568 return RPC_S_INVALID_ARG
;
4570 memset(&umi
->u1
.Level1
, 0, sizeof(umi
->u1
.Level1
));
4571 umi
->InformationLevel
= level
;
4573 if (umcb
->Signature
!= USER_MARSHAL_CB_SIGNATURE
)
4574 return RPC_S_INVALID_ARG
;
4576 umi
->u1
.Level1
.pfnAllocate
= umcb
->pStubMsg
->pfnAllocate
;
4577 umi
->u1
.Level1
.pfnFree
= umcb
->pStubMsg
->pfnFree
;
4578 umi
->u1
.Level1
.pRpcChannelBuffer
= umcb
->pStubMsg
->pRpcChannelBuffer
;
4580 switch (umcb
->CBType
)
4582 case USER_MARSHAL_CB_MARSHALL
:
4583 case USER_MARSHAL_CB_UNMARSHALL
:
4585 RPC_MESSAGE
*msg
= umcb
->pStubMsg
->RpcMsg
;
4586 unsigned char *buffer_start
= msg
->Buffer
;
4587 unsigned char *buffer_end
=
4588 (unsigned char *)msg
->Buffer
+ msg
->BufferLength
;
4590 if (umcb
->pStubMsg
->Buffer
< buffer_start
||
4591 umcb
->pStubMsg
->Buffer
> buffer_end
)
4592 return RPC_X_INVALID_BUFFER
;
4594 umi
->u1
.Level1
.Buffer
= umcb
->pStubMsg
->Buffer
;
4595 umi
->u1
.Level1
.BufferSize
= buffer_end
- umcb
->pStubMsg
->Buffer
;
4598 case USER_MARSHAL_CB_BUFFER_SIZE
:
4599 case USER_MARSHAL_CB_FREE
:
4602 WARN("unrecognised CBType %d\n", umcb
->CBType
);
4608 /***********************************************************************
4609 * NdrClearOutParameters [RPCRT4.@]
4611 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
4612 PFORMAT_STRING pFormat
,
4615 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
4618 /***********************************************************************
4619 * NdrConvert [RPCRT4.@]
4621 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
4623 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
4624 /* FIXME: since this stub doesn't do any converting, the proper behavior
4625 is to raise an exception */
4628 /***********************************************************************
4629 * NdrConvert2 [RPCRT4.@]
4631 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, LONG NumberParams
)
4633 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4634 pStubMsg
, pFormat
, NumberParams
);
4635 /* FIXME: since this stub doesn't do any converting, the proper behavior
4636 is to raise an exception */
4639 #include "pshpack1.h"
4640 typedef struct _NDR_CSTRUCT_FORMAT
4643 unsigned char alignment
;
4644 unsigned short memory_size
;
4645 short offset_to_array_description
;
4646 } NDR_CSTRUCT_FORMAT
, NDR_CVSTRUCT_FORMAT
;
4647 #include "poppack.h"
4649 /***********************************************************************
4650 * NdrConformantStructMarshall [RPCRT4.@]
4652 unsigned char * WINAPI
NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4653 unsigned char *pMemory
,
4654 PFORMAT_STRING pFormat
)
4656 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4657 PFORMAT_STRING pCArrayFormat
;
4658 ULONG esize
, bufsize
;
4660 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4662 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4663 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4665 ERR("invalid format type %x\n", pCStructFormat
->type
);
4666 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4670 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4671 pCStructFormat
->offset_to_array_description
;
4672 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4674 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4675 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4678 esize
= *(const WORD
*)(pCArrayFormat
+2);
4680 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4681 pCArrayFormat
+ 4, 0);
4683 WriteConformance(pStubMsg
);
4685 align_pointer_clear(&pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4687 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4689 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4690 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4692 ERR("integer overflow of memory_size %u with bufsize %u\n",
4693 pCStructFormat
->memory_size
, bufsize
);
4694 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4696 /* copy constant sized part of struct */
4697 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4698 safe_copy_to_buffer(pStubMsg
, pMemory
, pCStructFormat
->memory_size
+ bufsize
);
4700 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4701 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4706 /***********************************************************************
4707 * NdrConformantStructUnmarshall [RPCRT4.@]
4709 unsigned char * WINAPI
NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4710 unsigned char **ppMemory
,
4711 PFORMAT_STRING pFormat
,
4712 unsigned char fMustAlloc
)
4714 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4715 PFORMAT_STRING pCArrayFormat
;
4716 ULONG esize
, bufsize
;
4717 unsigned char *saved_buffer
;
4719 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4721 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4722 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4724 ERR("invalid format type %x\n", pCStructFormat
->type
);
4725 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4728 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4729 pCStructFormat
->offset_to_array_description
;
4730 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4732 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4733 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4736 esize
= *(const WORD
*)(pCArrayFormat
+2);
4738 pCArrayFormat
= ReadConformance(pStubMsg
, pCArrayFormat
+ 4);
4740 align_pointer(&pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4742 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4744 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4745 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4747 ERR("integer overflow of memory_size %u with bufsize %u\n",
4748 pCStructFormat
->memory_size
, bufsize
);
4749 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4754 SIZE_T size
= pCStructFormat
->memory_size
+ bufsize
;
4755 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4759 if (!pStubMsg
->IsClient
&& !*ppMemory
)
4760 /* for servers, we just point straight into the RPC buffer */
4761 *ppMemory
= pStubMsg
->Buffer
;
4764 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4765 safe_buffer_increment(pStubMsg
, pCStructFormat
->memory_size
+ bufsize
);
4766 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4767 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4769 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
4770 if (*ppMemory
!= saved_buffer
)
4771 memcpy(*ppMemory
, saved_buffer
, pCStructFormat
->memory_size
+ bufsize
);
4776 /***********************************************************************
4777 * NdrConformantStructBufferSize [RPCRT4.@]
4779 void WINAPI
NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4780 unsigned char *pMemory
,
4781 PFORMAT_STRING pFormat
)
4783 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4784 PFORMAT_STRING pCArrayFormat
;
4787 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4789 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4790 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4792 ERR("invalid format type %x\n", pCStructFormat
->type
);
4793 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4796 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4797 pCStructFormat
->offset_to_array_description
;
4798 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4800 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4801 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4804 esize
= *(const WORD
*)(pCArrayFormat
+2);
4806 pCArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
, pCArrayFormat
+4, 0);
4807 SizeConformance(pStubMsg
);
4809 align_length(&pStubMsg
->BufferLength
, pCStructFormat
->alignment
+ 1);
4811 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4813 safe_buffer_length_increment(pStubMsg
, pCStructFormat
->memory_size
);
4814 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
4816 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4817 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4820 /***********************************************************************
4821 * NdrConformantStructMemorySize [RPCRT4.@]
4823 ULONG WINAPI
NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4824 PFORMAT_STRING pFormat
)
4830 /***********************************************************************
4831 * NdrConformantStructFree [RPCRT4.@]
4833 void WINAPI
NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
4834 unsigned char *pMemory
,
4835 PFORMAT_STRING pFormat
)
4837 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4838 PFORMAT_STRING pCArrayFormat
;
4840 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4842 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4843 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4845 ERR("invalid format type %x\n", pCStructFormat
->type
);
4846 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4850 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4851 pCStructFormat
->offset_to_array_description
;
4852 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4854 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4855 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4859 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4860 pCArrayFormat
+ 4, 0);
4862 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4864 /* copy constant sized part of struct */
4865 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4867 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4868 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4871 /***********************************************************************
4872 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4874 unsigned char * WINAPI
NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4875 unsigned char *pMemory
,
4876 PFORMAT_STRING pFormat
)
4878 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4879 PFORMAT_STRING pCVArrayFormat
;
4881 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4883 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4884 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4886 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4887 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4891 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4892 pCVStructFormat
->offset_to_array_description
;
4894 array_compute_and_write_conformance(*pCVArrayFormat
, pStubMsg
,
4895 pMemory
+ pCVStructFormat
->memory_size
,
4898 align_pointer_clear(&pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4900 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4902 /* write constant sized part */
4903 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4904 safe_copy_to_buffer(pStubMsg
, pMemory
, pCVStructFormat
->memory_size
);
4906 array_write_variance_and_marshall(*pCVArrayFormat
, pStubMsg
,
4907 pMemory
+ pCVStructFormat
->memory_size
,
4908 pCVArrayFormat
, FALSE
/* fHasPointers */);
4910 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4915 /***********************************************************************
4916 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4918 unsigned char * WINAPI
NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4919 unsigned char **ppMemory
,
4920 PFORMAT_STRING pFormat
,
4921 unsigned char fMustAlloc
)
4923 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4924 PFORMAT_STRING pCVArrayFormat
;
4925 ULONG memsize
, bufsize
;
4926 unsigned char *saved_buffer
, *saved_array_buffer
;
4928 unsigned char *array_memory
;
4930 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4932 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4933 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4935 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4936 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4940 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4941 pCVStructFormat
->offset_to_array_description
;
4943 memsize
= array_read_conformance(*pCVArrayFormat
, pStubMsg
,
4946 align_pointer(&pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4948 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4950 /* work out how much memory to allocate if we need to do so */
4951 if (!fMustAlloc
&& !*ppMemory
)
4955 SIZE_T size
= pCVStructFormat
->memory_size
+ memsize
;
4956 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4959 /* mark the start of the constant data */
4960 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4961 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4963 array_memory
= *ppMemory
+ pCVStructFormat
->memory_size
;
4964 bufsize
= array_read_variance_and_unmarshall(*pCVArrayFormat
, pStubMsg
,
4965 &array_memory
, pCVArrayFormat
,
4966 FALSE
/* fMustAlloc */,
4967 FALSE
/* fUseServerBufferMemory */,
4968 FALSE
/* fUnmarshall */);
4970 /* save offset in case unmarshalling pointers changes it */
4971 offset
= pStubMsg
->Offset
;
4973 /* mark the start of the array data */
4974 saved_array_buffer
= pStubMsg
->Buffer
;
4975 safe_buffer_increment(pStubMsg
, bufsize
);
4977 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4979 /* copy the constant data */
4980 memcpy(*ppMemory
, saved_buffer
, pCVStructFormat
->memory_size
);
4981 /* copy the array data */
4982 TRACE("copying %p to %p\n", saved_array_buffer
, *ppMemory
+ pCVStructFormat
->memory_size
);
4983 memcpy(*ppMemory
+ pCVStructFormat
->memory_size
+ offset
,
4984 saved_array_buffer
, bufsize
);
4986 if (*pCVArrayFormat
== RPC_FC_C_CSTRING
)
4987 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory
+ pCVStructFormat
->memory_size
)));
4988 else if (*pCVArrayFormat
== RPC_FC_C_WSTRING
)
4989 TRACE("string=%s\n", debugstr_w((WCHAR
*)(*ppMemory
+ pCVStructFormat
->memory_size
)));
4994 /***********************************************************************
4995 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
4997 void WINAPI
NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4998 unsigned char *pMemory
,
4999 PFORMAT_STRING pFormat
)
5001 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
5002 PFORMAT_STRING pCVArrayFormat
;
5004 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5006 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
5007 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
5009 ERR("invalid format type %x\n", pCVStructFormat
->type
);
5010 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5014 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
5015 pCVStructFormat
->offset_to_array_description
;
5016 array_compute_and_size_conformance(*pCVArrayFormat
, pStubMsg
,
5017 pMemory
+ pCVStructFormat
->memory_size
,
5020 align_length(&pStubMsg
->BufferLength
, pCVStructFormat
->alignment
+ 1);
5022 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
5024 safe_buffer_length_increment(pStubMsg
, pCVStructFormat
->memory_size
);
5026 array_buffer_size(*pCVArrayFormat
, pStubMsg
,
5027 pMemory
+ pCVStructFormat
->memory_size
, pCVArrayFormat
,
5028 FALSE
/* fHasPointers */);
5030 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5033 /***********************************************************************
5034 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
5036 ULONG WINAPI
NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5037 PFORMAT_STRING pFormat
)
5039 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
5040 PFORMAT_STRING pCVArrayFormat
;
5042 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5044 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
5045 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
5047 ERR("invalid format type %x\n", pCVStructFormat
->type
);
5048 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5052 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
5053 pCVStructFormat
->offset_to_array_description
;
5054 array_read_conformance(*pCVArrayFormat
, pStubMsg
, pCVArrayFormat
);
5056 align_pointer(&pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
5058 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
5060 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
5061 array_memory_size(*pCVArrayFormat
, pStubMsg
, pCVArrayFormat
,
5062 FALSE
/* fHasPointers */);
5064 pStubMsg
->MemorySize
+= pCVStructFormat
->memory_size
;
5066 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5068 return pStubMsg
->MemorySize
;
5071 /***********************************************************************
5072 * NdrConformantVaryingStructFree [RPCRT4.@]
5074 void WINAPI
NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
5075 unsigned char *pMemory
,
5076 PFORMAT_STRING pFormat
)
5078 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
5079 PFORMAT_STRING pCVArrayFormat
;
5081 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5083 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
5084 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
5086 ERR("invalid format type %x\n", pCVStructFormat
->type
);
5087 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5091 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
5092 pCVStructFormat
->offset_to_array_description
;
5093 array_free(*pCVArrayFormat
, pStubMsg
,
5094 pMemory
+ pCVStructFormat
->memory_size
, pCVArrayFormat
,
5095 FALSE
/* fHasPointers */);
5097 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
5099 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5102 #include "pshpack1.h"
5106 unsigned char alignment
;
5107 unsigned short total_size
;
5108 } NDR_SMFARRAY_FORMAT
;
5113 unsigned char alignment
;
5115 } NDR_LGFARRAY_FORMAT
;
5116 #include "poppack.h"
5118 /***********************************************************************
5119 * NdrFixedArrayMarshall [RPCRT4.@]
5121 unsigned char * WINAPI
NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5122 unsigned char *pMemory
,
5123 PFORMAT_STRING pFormat
)
5125 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5128 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5130 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5131 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5133 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5134 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5138 align_pointer_clear(&pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
5140 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5142 total_size
= pSmFArrayFormat
->total_size
;
5143 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5147 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5148 total_size
= pLgFArrayFormat
->total_size
;
5149 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5152 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5153 safe_copy_to_buffer(pStubMsg
, pMemory
, total_size
);
5155 pFormat
= EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
5160 /***********************************************************************
5161 * NdrFixedArrayUnmarshall [RPCRT4.@]
5163 unsigned char * WINAPI
NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5164 unsigned char **ppMemory
,
5165 PFORMAT_STRING pFormat
,
5166 unsigned char fMustAlloc
)
5168 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5170 unsigned char *saved_buffer
;
5172 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5174 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5175 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5177 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5178 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5182 align_pointer(&pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
5184 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5186 total_size
= pSmFArrayFormat
->total_size
;
5187 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5191 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5192 total_size
= pLgFArrayFormat
->total_size
;
5193 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5197 *ppMemory
= NdrAllocate(pStubMsg
, total_size
);
5200 if (!pStubMsg
->IsClient
&& !*ppMemory
)
5201 /* for servers, we just point straight into the RPC buffer */
5202 *ppMemory
= pStubMsg
->Buffer
;
5205 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5206 safe_buffer_increment(pStubMsg
, total_size
);
5207 pFormat
= EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
5209 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
5210 if (*ppMemory
!= saved_buffer
)
5211 memcpy(*ppMemory
, saved_buffer
, total_size
);
5216 /***********************************************************************
5217 * NdrFixedArrayBufferSize [RPCRT4.@]
5219 void WINAPI
NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5220 unsigned char *pMemory
,
5221 PFORMAT_STRING pFormat
)
5223 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5226 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5228 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5229 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5231 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5232 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5236 align_length(&pStubMsg
->BufferLength
, pSmFArrayFormat
->alignment
+ 1);
5238 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5240 total_size
= pSmFArrayFormat
->total_size
;
5241 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5245 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5246 total_size
= pLgFArrayFormat
->total_size
;
5247 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5249 safe_buffer_length_increment(pStubMsg
, total_size
);
5251 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5254 /***********************************************************************
5255 * NdrFixedArrayMemorySize [RPCRT4.@]
5257 ULONG WINAPI
NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5258 PFORMAT_STRING pFormat
)
5260 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5263 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5265 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5266 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5268 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5269 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5273 align_pointer(&pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
5275 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5277 total_size
= pSmFArrayFormat
->total_size
;
5278 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5282 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5283 total_size
= pLgFArrayFormat
->total_size
;
5284 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5286 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5287 safe_buffer_increment(pStubMsg
, total_size
);
5288 pStubMsg
->MemorySize
+= total_size
;
5290 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5295 /***********************************************************************
5296 * NdrFixedArrayFree [RPCRT4.@]
5298 void WINAPI
NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
5299 unsigned char *pMemory
,
5300 PFORMAT_STRING pFormat
)
5302 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5304 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5306 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5307 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5309 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5310 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5314 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5315 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5318 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5319 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5322 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5325 /***********************************************************************
5326 * NdrVaryingArrayMarshall [RPCRT4.@]
5328 unsigned char * WINAPI
NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5329 unsigned char *pMemory
,
5330 PFORMAT_STRING pFormat
)
5332 unsigned char alignment
;
5333 DWORD elements
, esize
;
5336 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5338 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5339 (pFormat
[0] != RPC_FC_LGVARRAY
))
5341 ERR("invalid format type %x\n", pFormat
[0]);
5342 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5346 alignment
= pFormat
[1] + 1;
5348 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5351 pFormat
+= sizeof(WORD
);
5352 elements
= *(const WORD
*)pFormat
;
5353 pFormat
+= sizeof(WORD
);
5358 pFormat
+= sizeof(DWORD
);
5359 elements
= *(const DWORD
*)pFormat
;
5360 pFormat
+= sizeof(DWORD
);
5363 esize
= *(const WORD
*)pFormat
;
5364 pFormat
+= sizeof(WORD
);
5366 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5367 if ((pStubMsg
->ActualCount
> elements
) ||
5368 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5370 RpcRaiseException(RPC_S_INVALID_BOUND
);
5374 WriteVariance(pStubMsg
);
5376 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
5378 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
5379 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5380 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
5382 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
5387 /***********************************************************************
5388 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5390 unsigned char * WINAPI
NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5391 unsigned char **ppMemory
,
5392 PFORMAT_STRING pFormat
,
5393 unsigned char fMustAlloc
)
5395 unsigned char alignment
;
5396 DWORD size
, elements
, esize
;
5398 unsigned char *saved_buffer
;
5401 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5403 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5404 (pFormat
[0] != RPC_FC_LGVARRAY
))
5406 ERR("invalid format type %x\n", pFormat
[0]);
5407 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5411 alignment
= pFormat
[1] + 1;
5413 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5416 size
= *(const WORD
*)pFormat
;
5417 pFormat
+= sizeof(WORD
);
5418 elements
= *(const WORD
*)pFormat
;
5419 pFormat
+= sizeof(WORD
);
5424 size
= *(const DWORD
*)pFormat
;
5425 pFormat
+= sizeof(DWORD
);
5426 elements
= *(const DWORD
*)pFormat
;
5427 pFormat
+= sizeof(DWORD
);
5430 esize
= *(const WORD
*)pFormat
;
5431 pFormat
+= sizeof(WORD
);
5433 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
5435 align_pointer(&pStubMsg
->Buffer
, alignment
);
5437 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
5438 offset
= pStubMsg
->Offset
;
5440 if (!fMustAlloc
&& !*ppMemory
)
5443 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5444 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5445 safe_buffer_increment(pStubMsg
, bufsize
);
5447 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
5449 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
5454 /***********************************************************************
5455 * NdrVaryingArrayBufferSize [RPCRT4.@]
5457 void WINAPI
NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5458 unsigned char *pMemory
,
5459 PFORMAT_STRING pFormat
)
5461 unsigned char alignment
;
5462 DWORD elements
, esize
;
5464 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5466 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5467 (pFormat
[0] != RPC_FC_LGVARRAY
))
5469 ERR("invalid format type %x\n", pFormat
[0]);
5470 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5474 alignment
= pFormat
[1] + 1;
5476 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5479 pFormat
+= sizeof(WORD
);
5480 elements
= *(const WORD
*)pFormat
;
5481 pFormat
+= sizeof(WORD
);
5486 pFormat
+= sizeof(DWORD
);
5487 elements
= *(const DWORD
*)pFormat
;
5488 pFormat
+= sizeof(DWORD
);
5491 esize
= *(const WORD
*)pFormat
;
5492 pFormat
+= sizeof(WORD
);
5494 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5495 if ((pStubMsg
->ActualCount
> elements
) ||
5496 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5498 RpcRaiseException(RPC_S_INVALID_BOUND
);
5502 SizeVariance(pStubMsg
);
5504 align_length(&pStubMsg
->BufferLength
, alignment
);
5506 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
5508 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5511 /***********************************************************************
5512 * NdrVaryingArrayMemorySize [RPCRT4.@]
5514 ULONG WINAPI
NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5515 PFORMAT_STRING pFormat
)
5517 unsigned char alignment
;
5518 DWORD size
, elements
, esize
;
5520 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5522 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5523 (pFormat
[0] != RPC_FC_LGVARRAY
))
5525 ERR("invalid format type %x\n", pFormat
[0]);
5526 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5530 alignment
= pFormat
[1] + 1;
5532 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5535 size
= *(const WORD
*)pFormat
;
5536 pFormat
+= sizeof(WORD
);
5537 elements
= *(const WORD
*)pFormat
;
5538 pFormat
+= sizeof(WORD
);
5543 size
= *(const DWORD
*)pFormat
;
5544 pFormat
+= sizeof(DWORD
);
5545 elements
= *(const DWORD
*)pFormat
;
5546 pFormat
+= sizeof(DWORD
);
5549 esize
= *(const WORD
*)pFormat
;
5550 pFormat
+= sizeof(WORD
);
5552 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
5554 align_pointer(&pStubMsg
->Buffer
, alignment
);
5556 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
5557 pStubMsg
->MemorySize
+= size
;
5559 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5561 return pStubMsg
->MemorySize
;
5564 /***********************************************************************
5565 * NdrVaryingArrayFree [RPCRT4.@]
5567 void WINAPI
NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
5568 unsigned char *pMemory
,
5569 PFORMAT_STRING pFormat
)
5573 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5575 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5576 (pFormat
[0] != RPC_FC_LGVARRAY
))
5578 ERR("invalid format type %x\n", pFormat
[0]);
5579 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5583 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5586 pFormat
+= sizeof(WORD
);
5587 elements
= *(const WORD
*)pFormat
;
5588 pFormat
+= sizeof(WORD
);
5593 pFormat
+= sizeof(DWORD
);
5594 elements
= *(const DWORD
*)pFormat
;
5595 pFormat
+= sizeof(DWORD
);
5598 pFormat
+= sizeof(WORD
);
5600 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5601 if ((pStubMsg
->ActualCount
> elements
) ||
5602 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5604 RpcRaiseException(RPC_S_INVALID_BOUND
);
5608 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5611 static ULONG
get_discriminant(unsigned char fc
, const unsigned char *pMemory
)
5624 return *(const USHORT
*)pMemory
;
5628 return *(const ULONG
*)pMemory
;
5629 case RPC_FC_INT3264
:
5630 case RPC_FC_UINT3264
:
5631 return *(const ULONG_PTR
*)pMemory
;
5633 FIXME("Unhandled base type: 0x%02x\n", fc
);
5638 static PFORMAT_STRING
get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg
,
5640 PFORMAT_STRING pFormat
)
5642 unsigned short num_arms
, arm
, type
;
5644 num_arms
= *(const SHORT
*)pFormat
& 0x0fff;
5646 for(arm
= 0; arm
< num_arms
; arm
++)
5648 if(discriminant
== *(const ULONG
*)pFormat
)
5656 type
= *(const unsigned short*)pFormat
;
5657 TRACE("type %04x\n", type
);
5658 if(arm
== num_arms
) /* default arm extras */
5662 ERR("no arm for 0x%x and no default case\n", discriminant
);
5663 RpcRaiseException(RPC_S_INVALID_TAG
);
5668 TRACE("falling back to empty default case for 0x%x\n", discriminant
);
5675 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
, ULONG discriminant
, PFORMAT_STRING pFormat
)
5677 unsigned short type
;
5681 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5685 type
= *(const unsigned short*)pFormat
;
5686 if((type
& 0xff00) == 0x8000)
5688 unsigned char basetype
= LOBYTE(type
);
5689 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &basetype
);
5693 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5694 NDR_MARSHALL m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
5697 unsigned char *saved_buffer
= NULL
;
5698 BOOL pointer_buffer_mark_set
= FALSE
;
5705 align_pointer_clear(&pStubMsg
->Buffer
, 4);
5706 saved_buffer
= pStubMsg
->Buffer
;
5707 if (pStubMsg
->PointerBufferMark
)
5709 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5710 pStubMsg
->PointerBufferMark
= NULL
;
5711 pointer_buffer_mark_set
= TRUE
;
5714 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
5716 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char **)pMemory
, desc
);
5717 if (pointer_buffer_mark_set
)
5719 STD_OVERFLOW_CHECK(pStubMsg
);
5720 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5721 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5723 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5724 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
5725 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5727 pStubMsg
->Buffer
= saved_buffer
+ 4;
5731 m(pStubMsg
, pMemory
, desc
);
5734 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5739 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5740 unsigned char **ppMemory
,
5742 PFORMAT_STRING pFormat
,
5743 unsigned char fMustAlloc
)
5745 unsigned short type
;
5749 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5753 type
= *(const unsigned short*)pFormat
;
5754 if((type
& 0xff00) == 0x8000)
5756 unsigned char basetype
= LOBYTE(type
);
5757 return NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &basetype
, FALSE
);
5761 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5762 NDR_UNMARSHALL m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
5765 unsigned char *saved_buffer
= NULL
;
5766 BOOL pointer_buffer_mark_set
= FALSE
;
5773 align_pointer(&pStubMsg
->Buffer
, 4);
5774 saved_buffer
= pStubMsg
->Buffer
;
5775 if (pStubMsg
->PointerBufferMark
)
5777 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5778 pStubMsg
->PointerBufferMark
= NULL
;
5779 pointer_buffer_mark_set
= TRUE
;
5782 pStubMsg
->Buffer
+= 4; /* for pointer ID */
5784 if (saved_buffer
+ 4 > pStubMsg
->BufferEnd
)
5786 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5787 saved_buffer
, pStubMsg
->BufferEnd
);
5788 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5791 PointerUnmarshall(pStubMsg
, saved_buffer
, *(unsigned char ***)ppMemory
, **(unsigned char ***)ppMemory
, desc
, fMustAlloc
);
5792 if (pointer_buffer_mark_set
)
5794 STD_OVERFLOW_CHECK(pStubMsg
);
5795 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5796 pStubMsg
->Buffer
= saved_buffer
+ 4;
5800 m(pStubMsg
, ppMemory
, desc
, fMustAlloc
);
5803 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5808 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg
,
5809 unsigned char *pMemory
,
5811 PFORMAT_STRING pFormat
)
5813 unsigned short type
;
5817 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5821 type
= *(const unsigned short*)pFormat
;
5822 if((type
& 0xff00) == 0x8000)
5824 unsigned char basetype
= LOBYTE(type
);
5825 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &basetype
);
5829 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5830 NDR_BUFFERSIZE m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
5839 align_length(&pStubMsg
->BufferLength
, 4);
5840 safe_buffer_length_increment(pStubMsg
, 4); /* for pointer ID */
5841 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5843 int saved_buffer_length
= pStubMsg
->BufferLength
;
5844 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
5845 pStubMsg
->PointerLength
= 0;
5846 if(!pStubMsg
->BufferLength
)
5847 ERR("BufferLength == 0??\n");
5848 PointerBufferSize(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5849 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
5850 pStubMsg
->BufferLength
= saved_buffer_length
;
5854 m(pStubMsg
, pMemory
, desc
);
5857 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
5861 static ULONG
union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg
,
5863 PFORMAT_STRING pFormat
)
5865 unsigned short type
, size
;
5867 size
= *(const unsigned short*)pFormat
;
5868 pStubMsg
->Memory
+= size
;
5871 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5875 type
= *(const unsigned short*)pFormat
;
5876 if((type
& 0xff00) == 0x8000)
5878 return NdrBaseTypeMemorySize(pStubMsg
, pFormat
);
5882 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5883 NDR_MEMORYSIZE m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
5884 unsigned char *saved_buffer
;
5893 align_pointer(&pStubMsg
->Buffer
, 4);
5894 saved_buffer
= pStubMsg
->Buffer
;
5895 safe_buffer_increment(pStubMsg
, 4);
5896 align_length(&pStubMsg
->MemorySize
, sizeof(void *));
5897 pStubMsg
->MemorySize
+= sizeof(void *);
5898 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5899 PointerMemorySize(pStubMsg
, saved_buffer
, pFormat
);
5902 return m(pStubMsg
, desc
);
5905 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5908 TRACE("size %d\n", size
);
5912 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg
,
5913 unsigned char *pMemory
,
5915 PFORMAT_STRING pFormat
)
5917 unsigned short type
;
5921 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5925 type
= *(const unsigned short*)pFormat
;
5926 if((type
& 0xff00) != 0x8000)
5928 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5929 NDR_FREE m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
5938 PointerFree(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5941 m(pStubMsg
, pMemory
, desc
);
5947 /***********************************************************************
5948 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5950 unsigned char * WINAPI
NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5951 unsigned char *pMemory
,
5952 PFORMAT_STRING pFormat
)
5954 unsigned char switch_type
;
5955 unsigned char increment
;
5958 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5961 switch_type
= *pFormat
& 0xf;
5962 increment
= (*pFormat
& 0xf0) >> 4;
5965 align_pointer_clear(&pStubMsg
->Buffer
, increment
);
5967 switch_value
= get_discriminant(switch_type
, pMemory
);
5968 TRACE("got switch value 0x%x\n", switch_value
);
5970 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &switch_type
);
5971 pMemory
+= increment
;
5973 return union_arm_marshall(pStubMsg
, pMemory
, switch_value
, pFormat
);
5976 /***********************************************************************
5977 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5979 unsigned char * WINAPI
NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5980 unsigned char **ppMemory
,
5981 PFORMAT_STRING pFormat
,
5982 unsigned char fMustAlloc
)
5984 unsigned char switch_type
;
5985 unsigned char increment
;
5987 unsigned short size
;
5988 unsigned char *pMemoryArm
;
5990 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5993 switch_type
= *pFormat
& 0xf;
5994 increment
= (*pFormat
& 0xf0) >> 4;
5997 align_pointer(&pStubMsg
->Buffer
, increment
);
5998 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
5999 TRACE("got switch value 0x%x\n", switch_value
);
6001 size
= *(const unsigned short*)pFormat
+ increment
;
6002 if (!fMustAlloc
&& !*ppMemory
)
6005 *ppMemory
= NdrAllocate(pStubMsg
, size
);
6007 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6008 * since the arm is part of the memory block that is encompassed by
6009 * the whole union. Memory is forced to allocate when pointers
6010 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6011 * clearing the memory we pass in to the unmarshaller */
6013 memset(*ppMemory
, 0, size
);
6015 NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &switch_type
, FALSE
);
6016 pMemoryArm
= *ppMemory
+ increment
;
6018 return union_arm_unmarshall(pStubMsg
, &pMemoryArm
, switch_value
, pFormat
, FALSE
);
6021 /***********************************************************************
6022 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
6024 void WINAPI
NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6025 unsigned char *pMemory
,
6026 PFORMAT_STRING pFormat
)
6028 unsigned char switch_type
;
6029 unsigned char increment
;
6032 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6035 switch_type
= *pFormat
& 0xf;
6036 increment
= (*pFormat
& 0xf0) >> 4;
6039 align_length(&pStubMsg
->BufferLength
, increment
);
6040 switch_value
= get_discriminant(switch_type
, pMemory
);
6041 TRACE("got switch value 0x%x\n", switch_value
);
6043 /* Add discriminant size */
6044 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&switch_value
, &switch_type
);
6045 pMemory
+= increment
;
6047 union_arm_buffer_size(pStubMsg
, pMemory
, switch_value
, pFormat
);
6050 /***********************************************************************
6051 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
6053 ULONG WINAPI
NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6054 PFORMAT_STRING pFormat
)
6056 unsigned char switch_type
;
6057 unsigned char increment
;
6060 switch_type
= *pFormat
& 0xf;
6061 increment
= (*pFormat
& 0xf0) >> 4;
6064 align_pointer(&pStubMsg
->Buffer
, increment
);
6065 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
6066 TRACE("got switch value 0x%x\n", switch_value
);
6068 pStubMsg
->Memory
+= increment
;
6070 return increment
+ union_arm_memory_size(pStubMsg
, switch_value
, pFormat
+ *(const SHORT
*)pFormat
);
6073 /***********************************************************************
6074 * NdrEncapsulatedUnionFree [RPCRT4.@]
6076 void WINAPI
NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
6077 unsigned char *pMemory
,
6078 PFORMAT_STRING pFormat
)
6080 unsigned char switch_type
;
6081 unsigned char increment
;
6084 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6087 switch_type
= *pFormat
& 0xf;
6088 increment
= (*pFormat
& 0xf0) >> 4;
6091 switch_value
= get_discriminant(switch_type
, pMemory
);
6092 TRACE("got switch value 0x%x\n", switch_value
);
6094 pMemory
+= increment
;
6096 union_arm_free(pStubMsg
, pMemory
, switch_value
, pFormat
);
6099 /***********************************************************************
6100 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
6102 unsigned char * WINAPI
NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6103 unsigned char *pMemory
,
6104 PFORMAT_STRING pFormat
)
6106 unsigned char switch_type
;
6108 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6111 switch_type
= *pFormat
;
6114 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6115 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6116 /* Marshall discriminant */
6117 NdrBaseTypeMarshall(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
6119 return union_arm_marshall(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6122 static LONG
unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg
,
6123 PFORMAT_STRING
*ppFormat
)
6125 LONG discriminant
= 0;
6135 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
6145 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6146 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
6154 align_pointer(&pStubMsg
->Buffer
, sizeof(ULONG
));
6155 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
6160 FIXME("Unhandled base type: 0x%02x\n", **ppFormat
);
6164 *ppFormat
= SkipConformance(pStubMsg
, *ppFormat
);
6165 return discriminant
;
6168 /**********************************************************************
6169 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
6171 unsigned char * WINAPI
NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6172 unsigned char **ppMemory
,
6173 PFORMAT_STRING pFormat
,
6174 unsigned char fMustAlloc
)
6177 unsigned short size
;
6179 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
6182 /* Unmarshall discriminant */
6183 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
6184 TRACE("unmarshalled discriminant %x\n", discriminant
);
6186 pFormat
+= *(const SHORT
*)pFormat
;
6188 size
= *(const unsigned short*)pFormat
;
6190 if (!fMustAlloc
&& !*ppMemory
)
6193 *ppMemory
= NdrAllocate(pStubMsg
, size
);
6195 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6196 * since the arm is part of the memory block that is encompassed by
6197 * the whole union. Memory is forced to allocate when pointers
6198 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6199 * clearing the memory we pass in to the unmarshaller */
6201 memset(*ppMemory
, 0, size
);
6203 return union_arm_unmarshall(pStubMsg
, ppMemory
, discriminant
, pFormat
, FALSE
);
6206 /***********************************************************************
6207 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
6209 void WINAPI
NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6210 unsigned char *pMemory
,
6211 PFORMAT_STRING pFormat
)
6213 unsigned char switch_type
;
6215 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6218 switch_type
= *pFormat
;
6221 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6222 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6223 /* Add discriminant size */
6224 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
6226 union_arm_buffer_size(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6229 /***********************************************************************
6230 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
6232 ULONG WINAPI
NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6233 PFORMAT_STRING pFormat
)
6238 /* Unmarshall discriminant */
6239 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
6240 TRACE("unmarshalled discriminant 0x%x\n", discriminant
);
6242 return union_arm_memory_size(pStubMsg
, discriminant
, pFormat
+ *(const SHORT
*)pFormat
);
6245 /***********************************************************************
6246 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6248 void WINAPI
NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
6249 unsigned char *pMemory
,
6250 PFORMAT_STRING pFormat
)
6252 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6256 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6257 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6259 union_arm_free(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6262 /***********************************************************************
6263 * NdrByteCountPointerMarshall [RPCRT4.@]
6265 unsigned char * WINAPI
NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6266 unsigned char *pMemory
,
6267 PFORMAT_STRING pFormat
)
6273 /***********************************************************************
6274 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6276 unsigned char * WINAPI
NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6277 unsigned char **ppMemory
,
6278 PFORMAT_STRING pFormat
,
6279 unsigned char fMustAlloc
)
6285 /***********************************************************************
6286 * NdrByteCountPointerBufferSize [RPCRT4.@]
6288 void WINAPI
NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6289 unsigned char *pMemory
,
6290 PFORMAT_STRING pFormat
)
6295 /***********************************************************************
6296 * NdrByteCountPointerMemorySize [internal]
6298 static ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6299 PFORMAT_STRING pFormat
)
6305 /***********************************************************************
6306 * NdrByteCountPointerFree [RPCRT4.@]
6308 void WINAPI
NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
6309 unsigned char *pMemory
,
6310 PFORMAT_STRING pFormat
)
6315 /***********************************************************************
6316 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6318 unsigned char * WINAPI
NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6319 unsigned char *pMemory
,
6320 PFORMAT_STRING pFormat
)
6326 /***********************************************************************
6327 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6329 unsigned char * WINAPI
NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6330 unsigned char **ppMemory
,
6331 PFORMAT_STRING pFormat
,
6332 unsigned char fMustAlloc
)
6338 /***********************************************************************
6339 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6341 void WINAPI
NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6342 unsigned char *pMemory
,
6343 PFORMAT_STRING pFormat
)
6348 /***********************************************************************
6349 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6351 ULONG WINAPI
NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6352 PFORMAT_STRING pFormat
)
6358 /***********************************************************************
6359 * NdrXmitOrRepAsFree [RPCRT4.@]
6361 void WINAPI
NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg
,
6362 unsigned char *pMemory
,
6363 PFORMAT_STRING pFormat
)
6368 /***********************************************************************
6369 * NdrRangeMarshall [internal]
6371 static unsigned char *WINAPI
NdrRangeMarshall(
6372 PMIDL_STUB_MESSAGE pStubMsg
,
6373 unsigned char *pMemory
,
6374 PFORMAT_STRING pFormat
)
6376 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6377 unsigned char base_type
;
6379 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6381 if (pRange
->type
!= RPC_FC_RANGE
)
6383 ERR("invalid format type %x\n", pRange
->type
);
6384 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6388 base_type
= pRange
->flags_type
& 0xf;
6390 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &base_type
);
6393 /***********************************************************************
6394 * NdrRangeUnmarshall [RPCRT4.@]
6396 unsigned char *WINAPI
NdrRangeUnmarshall(
6397 PMIDL_STUB_MESSAGE pStubMsg
,
6398 unsigned char **ppMemory
,
6399 PFORMAT_STRING pFormat
,
6400 unsigned char fMustAlloc
)
6402 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6403 unsigned char base_type
;
6405 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6407 if (pRange
->type
!= RPC_FC_RANGE
)
6409 ERR("invalid format type %x\n", pRange
->type
);
6410 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6413 base_type
= pRange
->flags_type
& 0xf;
6415 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6416 base_type
, pRange
->low_value
, pRange
->high_value
);
6418 #define RANGE_UNMARSHALL(mem_type, wire_type, format_spec) \
6421 align_pointer(&pStubMsg->Buffer, sizeof(wire_type)); \
6422 if (!fMustAlloc && !*ppMemory) \
6423 fMustAlloc = TRUE; \
6425 *ppMemory = NdrAllocate(pStubMsg, sizeof(mem_type)); \
6426 if (pStubMsg->Buffer + sizeof(wire_type) > pStubMsg->BufferEnd) \
6428 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6429 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6430 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6432 if ((*(wire_type *)pStubMsg->Buffer < (mem_type)pRange->low_value) || \
6433 (*(wire_type *)pStubMsg->Buffer > (mem_type)pRange->high_value)) \
6435 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6436 *(wire_type *)pStubMsg->Buffer, (mem_type)pRange->low_value, \
6437 (mem_type)pRange->high_value); \
6438 RpcRaiseException(RPC_S_INVALID_BOUND); \
6441 TRACE("*ppMemory: %p\n", *ppMemory); \
6442 **(mem_type **)ppMemory = *(wire_type *)pStubMsg->Buffer; \
6443 pStubMsg->Buffer += sizeof(wire_type); \
6450 RANGE_UNMARSHALL(UCHAR
, UCHAR
, "%d");
6451 TRACE("value: 0x%02x\n", **ppMemory
);
6455 RANGE_UNMARSHALL(CHAR
, CHAR
, "%u");
6456 TRACE("value: 0x%02x\n", **ppMemory
);
6458 case RPC_FC_WCHAR
: /* FIXME: valid? */
6460 RANGE_UNMARSHALL(USHORT
, USHORT
, "%u");
6461 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6464 RANGE_UNMARSHALL(SHORT
, SHORT
, "%d");
6465 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6469 RANGE_UNMARSHALL(LONG
, LONG
, "%d");
6470 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6473 RANGE_UNMARSHALL(ULONG
, ULONG
, "%u");
6474 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6477 RANGE_UNMARSHALL(UINT
, USHORT
, "%u");
6478 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
6484 ERR("invalid range base type: 0x%02x\n", base_type
);
6485 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6491 /***********************************************************************
6492 * NdrRangeBufferSize [internal]
6494 static void WINAPI
NdrRangeBufferSize(
6495 PMIDL_STUB_MESSAGE pStubMsg
,
6496 unsigned char *pMemory
,
6497 PFORMAT_STRING pFormat
)
6499 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6500 unsigned char base_type
;
6502 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6504 if (pRange
->type
!= RPC_FC_RANGE
)
6506 ERR("invalid format type %x\n", pRange
->type
);
6507 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6509 base_type
= pRange
->flags_type
& 0xf;
6511 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &base_type
);
6514 /***********************************************************************
6515 * NdrRangeMemorySize [internal]
6517 static ULONG WINAPI
NdrRangeMemorySize(
6518 PMIDL_STUB_MESSAGE pStubMsg
,
6519 PFORMAT_STRING pFormat
)
6521 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6522 unsigned char base_type
;
6524 if (pRange
->type
!= RPC_FC_RANGE
)
6526 ERR("invalid format type %x\n", pRange
->type
);
6527 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6530 base_type
= pRange
->flags_type
& 0xf;
6532 return NdrBaseTypeMemorySize(pStubMsg
, &base_type
);
6535 /***********************************************************************
6536 * NdrRangeFree [internal]
6538 static void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6539 unsigned char *pMemory
,
6540 PFORMAT_STRING pFormat
)
6542 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6547 /***********************************************************************
6548 * NdrBaseTypeMarshall [internal]
6550 static unsigned char *WINAPI
NdrBaseTypeMarshall(
6551 PMIDL_STUB_MESSAGE pStubMsg
,
6552 unsigned char *pMemory
,
6553 PFORMAT_STRING pFormat
)
6555 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6563 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(UCHAR
));
6564 TRACE("value: 0x%02x\n", *pMemory
);
6569 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(USHORT
));
6570 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(USHORT
));
6571 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
6575 case RPC_FC_ERROR_STATUS_T
:
6577 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(ULONG
));
6578 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONG
));
6579 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
6582 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(float));
6583 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
6586 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(double));
6587 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
6590 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(ULONGLONG
));
6591 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONGLONG
));
6592 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
6596 USHORT val
= *(UINT
*)pMemory
;
6597 /* only 16-bits on the wire, so do a sanity check */
6598 if (*(UINT
*)pMemory
> SHRT_MAX
)
6599 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
6600 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(USHORT
));
6601 safe_copy_to_buffer(pStubMsg
, &val
, sizeof(val
));
6602 TRACE("value: 0x%04x\n", *(UINT
*)pMemory
);
6605 case RPC_FC_INT3264
:
6606 case RPC_FC_UINT3264
:
6608 UINT val
= *(UINT_PTR
*)pMemory
;
6609 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(UINT
));
6610 safe_copy_to_buffer(pStubMsg
, &val
, sizeof(val
));
6616 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6619 /* FIXME: what is the correct return value? */
6623 /***********************************************************************
6624 * NdrBaseTypeUnmarshall [internal]
6626 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(
6627 PMIDL_STUB_MESSAGE pStubMsg
,
6628 unsigned char **ppMemory
,
6629 PFORMAT_STRING pFormat
,
6630 unsigned char fMustAlloc
)
6632 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6634 #define BASE_TYPE_UNMARSHALL(type) do { \
6635 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
6636 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6638 *ppMemory = pStubMsg->Buffer; \
6639 TRACE("*ppMemory: %p\n", *ppMemory); \
6640 safe_buffer_increment(pStubMsg, sizeof(type)); \
6645 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6646 TRACE("*ppMemory: %p\n", *ppMemory); \
6647 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6657 BASE_TYPE_UNMARSHALL(UCHAR
);
6658 TRACE("value: 0x%02x\n", **ppMemory
);
6663 BASE_TYPE_UNMARSHALL(USHORT
);
6664 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6668 case RPC_FC_ERROR_STATUS_T
:
6670 BASE_TYPE_UNMARSHALL(ULONG
);
6671 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6674 BASE_TYPE_UNMARSHALL(float);
6675 TRACE("value: %f\n", **(float **)ppMemory
);
6678 BASE_TYPE_UNMARSHALL(double);
6679 TRACE("value: %f\n", **(double **)ppMemory
);
6682 BASE_TYPE_UNMARSHALL(ULONGLONG
);
6683 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG
**)ppMemory
));
6688 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6689 if (!fMustAlloc
&& !*ppMemory
)
6692 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT
));
6693 safe_copy_from_buffer(pStubMsg
, &val
, sizeof(USHORT
));
6694 /* 16-bits on the wire, but int in memory */
6695 **(UINT
**)ppMemory
= val
;
6696 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
6699 case RPC_FC_INT3264
:
6700 if (sizeof(INT_PTR
) == sizeof(INT
)) BASE_TYPE_UNMARSHALL(INT
);
6704 align_pointer(&pStubMsg
->Buffer
, sizeof(INT
));
6705 if (!fMustAlloc
&& !*ppMemory
)
6708 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(INT_PTR
));
6709 safe_copy_from_buffer(pStubMsg
, &val
, sizeof(INT
));
6710 **(INT_PTR
**)ppMemory
= val
;
6711 TRACE("value: 0x%08lx\n", **(INT_PTR
**)ppMemory
);
6714 case RPC_FC_UINT3264
:
6715 if (sizeof(UINT_PTR
) == sizeof(UINT
)) BASE_TYPE_UNMARSHALL(UINT
);
6719 align_pointer(&pStubMsg
->Buffer
, sizeof(UINT
));
6720 if (!fMustAlloc
&& !*ppMemory
)
6723 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT_PTR
));
6724 safe_copy_from_buffer(pStubMsg
, &val
, sizeof(UINT
));
6725 **(UINT_PTR
**)ppMemory
= val
;
6726 TRACE("value: 0x%08lx\n", **(UINT_PTR
**)ppMemory
);
6732 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6734 #undef BASE_TYPE_UNMARSHALL
6736 /* FIXME: what is the correct return value? */
6741 /***********************************************************************
6742 * NdrBaseTypeBufferSize [internal]
6744 static void WINAPI
NdrBaseTypeBufferSize(
6745 PMIDL_STUB_MESSAGE pStubMsg
,
6746 unsigned char *pMemory
,
6747 PFORMAT_STRING pFormat
)
6749 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6757 safe_buffer_length_increment(pStubMsg
, sizeof(UCHAR
));
6763 align_length(&pStubMsg
->BufferLength
, sizeof(USHORT
));
6764 safe_buffer_length_increment(pStubMsg
, sizeof(USHORT
));
6769 case RPC_FC_INT3264
:
6770 case RPC_FC_UINT3264
:
6771 align_length(&pStubMsg
->BufferLength
, sizeof(ULONG
));
6772 safe_buffer_length_increment(pStubMsg
, sizeof(ULONG
));
6775 align_length(&pStubMsg
->BufferLength
, sizeof(float));
6776 safe_buffer_length_increment(pStubMsg
, sizeof(float));
6779 align_length(&pStubMsg
->BufferLength
, sizeof(double));
6780 safe_buffer_length_increment(pStubMsg
, sizeof(double));
6783 align_length(&pStubMsg
->BufferLength
, sizeof(ULONGLONG
));
6784 safe_buffer_length_increment(pStubMsg
, sizeof(ULONGLONG
));
6786 case RPC_FC_ERROR_STATUS_T
:
6787 align_length(&pStubMsg
->BufferLength
, sizeof(error_status_t
));
6788 safe_buffer_length_increment(pStubMsg
, sizeof(error_status_t
));
6793 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6797 /***********************************************************************
6798 * NdrBaseTypeMemorySize [internal]
6800 static ULONG WINAPI
NdrBaseTypeMemorySize(
6801 PMIDL_STUB_MESSAGE pStubMsg
,
6802 PFORMAT_STRING pFormat
)
6804 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg
, *pFormat
);
6812 safe_buffer_increment(pStubMsg
, sizeof(UCHAR
));
6813 pStubMsg
->MemorySize
+= sizeof(UCHAR
);
6814 return sizeof(UCHAR
);
6818 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6819 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6820 align_length(&pStubMsg
->MemorySize
, sizeof(USHORT
));
6821 pStubMsg
->MemorySize
+= sizeof(USHORT
);
6822 return sizeof(USHORT
);
6826 align_pointer(&pStubMsg
->Buffer
, sizeof(ULONG
));
6827 safe_buffer_increment(pStubMsg
, sizeof(ULONG
));
6828 align_length(&pStubMsg
->MemorySize
, sizeof(ULONG
));
6829 pStubMsg
->MemorySize
+= sizeof(ULONG
);
6830 return sizeof(ULONG
);
6832 align_pointer(&pStubMsg
->Buffer
, sizeof(float));
6833 safe_buffer_increment(pStubMsg
, sizeof(float));
6834 align_length(&pStubMsg
->MemorySize
, sizeof(float));
6835 pStubMsg
->MemorySize
+= sizeof(float);
6836 return sizeof(float);
6838 align_pointer(&pStubMsg
->Buffer
, sizeof(double));
6839 safe_buffer_increment(pStubMsg
, sizeof(double));
6840 align_length(&pStubMsg
->MemorySize
, sizeof(double));
6841 pStubMsg
->MemorySize
+= sizeof(double);
6842 return sizeof(double);
6844 align_pointer(&pStubMsg
->Buffer
, sizeof(ULONGLONG
));
6845 safe_buffer_increment(pStubMsg
, sizeof(ULONGLONG
));
6846 align_length(&pStubMsg
->MemorySize
, sizeof(ULONGLONG
));
6847 pStubMsg
->MemorySize
+= sizeof(ULONGLONG
);
6848 return sizeof(ULONGLONG
);
6849 case RPC_FC_ERROR_STATUS_T
:
6850 align_pointer(&pStubMsg
->Buffer
, sizeof(error_status_t
));
6851 safe_buffer_increment(pStubMsg
, sizeof(error_status_t
));
6852 align_length(&pStubMsg
->MemorySize
, sizeof(error_status_t
));
6853 pStubMsg
->MemorySize
+= sizeof(error_status_t
);
6854 return sizeof(error_status_t
);
6856 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6857 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6858 align_length(&pStubMsg
->MemorySize
, sizeof(UINT
));
6859 pStubMsg
->MemorySize
+= sizeof(UINT
);
6860 return sizeof(UINT
);
6861 case RPC_FC_INT3264
:
6862 case RPC_FC_UINT3264
:
6863 align_pointer(&pStubMsg
->Buffer
, sizeof(UINT
));
6864 safe_buffer_increment(pStubMsg
, sizeof(UINT
));
6865 align_length(&pStubMsg
->MemorySize
, sizeof(UINT_PTR
));
6866 pStubMsg
->MemorySize
+= sizeof(UINT_PTR
);
6867 return sizeof(UINT_PTR
);
6869 align_length(&pStubMsg
->MemorySize
, sizeof(void *));
6870 pStubMsg
->MemorySize
+= sizeof(void *);
6871 return sizeof(void *);
6873 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6878 /***********************************************************************
6879 * NdrBaseTypeFree [internal]
6881 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6882 unsigned char *pMemory
,
6883 PFORMAT_STRING pFormat
)
6885 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6890 /***********************************************************************
6891 * NdrContextHandleBufferSize [internal]
6893 static void WINAPI
NdrContextHandleBufferSize(
6894 PMIDL_STUB_MESSAGE pStubMsg
,
6895 unsigned char *pMemory
,
6896 PFORMAT_STRING pFormat
)
6898 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6900 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6902 ERR("invalid format type %x\n", *pFormat
);
6903 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6905 align_length(&pStubMsg
->BufferLength
, 4);
6906 safe_buffer_length_increment(pStubMsg
, cbNDRContext
);
6909 /***********************************************************************
6910 * NdrContextHandleMarshall [internal]
6912 static unsigned char *WINAPI
NdrContextHandleMarshall(
6913 PMIDL_STUB_MESSAGE pStubMsg
,
6914 unsigned char *pMemory
,
6915 PFORMAT_STRING pFormat
)
6917 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6919 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6921 ERR("invalid format type %x\n", *pFormat
);
6922 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6924 TRACE("flags: 0x%02x\n", pFormat
[1]);
6926 if (pStubMsg
->IsClient
)
6928 if (pFormat
[1] & HANDLE_PARAM_IS_VIA_PTR
)
6929 NdrClientContextMarshall(pStubMsg
, *(NDR_CCONTEXT
**)pMemory
, FALSE
);
6931 NdrClientContextMarshall(pStubMsg
, pMemory
, FALSE
);
6935 NDR_SCONTEXT ctxt
= NDRSContextFromValue(pMemory
);
6936 NDR_RUNDOWN rundown
= pStubMsg
->StubDesc
->apfnNdrRundownRoutines
[pFormat
[2]];
6937 NdrServerContextNewMarshall(pStubMsg
, ctxt
, rundown
, pFormat
);
6943 /***********************************************************************
6944 * NdrContextHandleUnmarshall [internal]
6946 static unsigned char *WINAPI
NdrContextHandleUnmarshall(
6947 PMIDL_STUB_MESSAGE pStubMsg
,
6948 unsigned char **ppMemory
,
6949 PFORMAT_STRING pFormat
,
6950 unsigned char fMustAlloc
)
6952 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg
,
6953 ppMemory
, pFormat
, fMustAlloc
? "TRUE": "FALSE");
6955 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6957 ERR("invalid format type %x\n", *pFormat
);
6958 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6960 TRACE("flags: 0x%02x\n", pFormat
[1]);
6962 if (pStubMsg
->IsClient
)
6964 /* [out]-only or [ret] param */
6965 if ((pFormat
[1] & (HANDLE_PARAM_IS_IN
|HANDLE_PARAM_IS_OUT
)) == HANDLE_PARAM_IS_OUT
)
6966 **(NDR_CCONTEXT
**)ppMemory
= NULL
;
6967 NdrClientContextUnmarshall(pStubMsg
, *(NDR_CCONTEXT
**)ppMemory
, pStubMsg
->RpcMsg
->Handle
);
6972 ctxt
= NdrServerContextNewUnmarshall(pStubMsg
, pFormat
);
6973 if (pFormat
[1] & HANDLE_PARAM_IS_VIA_PTR
)
6974 *(void **)ppMemory
= NDRSContextValue(ctxt
);
6976 *(void **)ppMemory
= *NDRSContextValue(ctxt
);
6982 /***********************************************************************
6983 * NdrClientContextMarshall [RPCRT4.@]
6985 void WINAPI
NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6986 NDR_CCONTEXT ContextHandle
,
6989 TRACE("(%p, %p, %d)\n", pStubMsg
, ContextHandle
, fCheck
);
6991 align_pointer_clear(&pStubMsg
->Buffer
, 4);
6993 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6995 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6996 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6997 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7000 /* FIXME: what does fCheck do? */
7001 NDRCContextMarshall(ContextHandle
,
7004 pStubMsg
->Buffer
+= cbNDRContext
;
7007 /***********************************************************************
7008 * NdrClientContextUnmarshall [RPCRT4.@]
7010 void WINAPI
NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7011 NDR_CCONTEXT
* pContextHandle
,
7012 RPC_BINDING_HANDLE BindHandle
)
7014 TRACE("(%p, %p, %p)\n", pStubMsg
, pContextHandle
, BindHandle
);
7016 align_pointer(&pStubMsg
->Buffer
, 4);
7018 if (pStubMsg
->Buffer
+ cbNDRContext
> pStubMsg
->BufferEnd
)
7019 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7021 NDRCContextUnmarshall(pContextHandle
,
7024 pStubMsg
->RpcMsg
->DataRepresentation
);
7026 pStubMsg
->Buffer
+= cbNDRContext
;
7029 void WINAPI
NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7030 NDR_SCONTEXT ContextHandle
,
7031 NDR_RUNDOWN RundownRoutine
)
7033 TRACE("(%p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
);
7035 align_pointer(&pStubMsg
->Buffer
, 4);
7037 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7039 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7040 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7041 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7044 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
7045 pStubMsg
->Buffer
, RundownRoutine
, NULL
,
7046 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
7047 pStubMsg
->Buffer
+= cbNDRContext
;
7050 NDR_SCONTEXT WINAPI
NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
)
7052 NDR_SCONTEXT ContextHandle
;
7054 TRACE("(%p)\n", pStubMsg
);
7056 align_pointer(&pStubMsg
->Buffer
, 4);
7058 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7060 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7061 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7062 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7065 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
7067 pStubMsg
->RpcMsg
->DataRepresentation
,
7068 NULL
, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
7069 pStubMsg
->Buffer
+= cbNDRContext
;
7071 return ContextHandle
;
7074 void WINAPI
NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg
,
7075 unsigned char* pMemory
,
7076 PFORMAT_STRING pFormat
)
7078 FIXME("(%p, %p, %p): stub\n", pStubMsg
, pMemory
, pFormat
);
7081 NDR_SCONTEXT WINAPI
NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg
,
7082 PFORMAT_STRING pFormat
)
7084 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
7085 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
7087 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
7089 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
7090 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
7091 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
7092 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
7093 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
7095 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
7096 if_id
= &sif
->InterfaceId
;
7099 return NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
, NULL
,
7100 pStubMsg
->RpcMsg
->DataRepresentation
, if_id
,
7104 void WINAPI
NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7105 NDR_SCONTEXT ContextHandle
,
7106 NDR_RUNDOWN RundownRoutine
,
7107 PFORMAT_STRING pFormat
)
7109 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
7110 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
7112 TRACE("(%p, %p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
, pFormat
);
7114 align_pointer(&pStubMsg
->Buffer
, 4);
7116 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7118 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7119 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7120 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7123 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
7124 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
7125 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
7126 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
7127 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
7129 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
7130 if_id
= &sif
->InterfaceId
;
7133 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
7134 pStubMsg
->Buffer
, RundownRoutine
, if_id
, flags
);
7135 pStubMsg
->Buffer
+= cbNDRContext
;
7138 NDR_SCONTEXT WINAPI
NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7139 PFORMAT_STRING pFormat
)
7141 NDR_SCONTEXT ContextHandle
;
7142 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
7143 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
7145 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
7147 align_pointer(&pStubMsg
->Buffer
, 4);
7149 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7151 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7152 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7153 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7156 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
7157 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
7158 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
7159 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
7160 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
7162 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
7163 if_id
= &sif
->InterfaceId
;
7166 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
7168 pStubMsg
->RpcMsg
->DataRepresentation
,
7170 pStubMsg
->Buffer
+= cbNDRContext
;
7172 return ContextHandle
;
7175 /***********************************************************************
7176 * NdrCorrelationInitialize [RPCRT4.@]
7178 * Initializes correlation validity checking.
7181 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7182 * pMemory [I] Pointer to memory to use as a cache.
7183 * CacheSize [I] Size of the memory pointed to by pMemory.
7184 * Flags [I] Reserved. Set to zero.
7189 void WINAPI
NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg
, void *pMemory
, ULONG CacheSize
, ULONG Flags
)
7191 FIXME("(%p, %p, %d, 0x%x): semi-stub\n", pStubMsg
, pMemory
, CacheSize
, Flags
);
7193 if (pStubMsg
->CorrDespIncrement
== 0)
7194 pStubMsg
->CorrDespIncrement
= 2; /* size of the normal (non-range) /robust payload */
7196 pStubMsg
->fHasNewCorrDesc
= TRUE
;
7199 /***********************************************************************
7200 * NdrCorrelationPass [RPCRT4.@]
7202 * Performs correlation validity checking.
7205 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7210 void WINAPI
NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg
)
7212 FIXME("(%p): stub\n", pStubMsg
);
7215 /***********************************************************************
7216 * NdrCorrelationFree [RPCRT4.@]
7218 * Frees any resources used while unmarshalling parameters that need
7219 * correlation validity checking.
7222 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7227 void WINAPI
NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg
)
7229 FIXME("(%p): stub\n", pStubMsg
);