4 * Copyright 2002 Greg Turner
5 * Copyright 2003-2006 CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 * - Byte count pointers
24 * - transmit_as/represent as
25 * - Multi-dimensional arrays
26 * - Conversion functions (NdrConvert)
27 * - Checks for integer addition overflow in user marshall functions
36 #define NONAMELESSUNION
45 #include "wine/unicode.h"
46 #include "wine/rpcfc.h"
48 #include "wine/debug.h"
50 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
53 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
54 (*((UINT32 *)(pchar)) = (uint32))
56 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
57 (*((UINT32 *)(pchar)))
59 /* these would work for i386 too, but less efficient */
60 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
61 (*(pchar) = LOBYTE(LOWORD(uint32)), \
62 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
63 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
64 *((pchar)+3) = HIBYTE(HIWORD(uint32)))
66 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
68 MAKEWORD(*(pchar), *((pchar)+1)), \
69 MAKEWORD(*((pchar)+2), *((pchar)+3))))
72 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
73 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
74 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
75 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
76 *(pchar) = HIBYTE(HIWORD(uint32)))
78 #define BIG_ENDIAN_UINT32_READ(pchar) \
80 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
81 MAKEWORD(*((pchar)+1), *(pchar))))
83 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
84 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
85 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
86 # define NDR_LOCAL_UINT32_READ(pchar) \
87 BIG_ENDIAN_UINT32_READ(pchar)
89 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
90 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
91 # define NDR_LOCAL_UINT32_READ(pchar) \
92 LITTLE_ENDIAN_UINT32_READ(pchar)
95 static inline void align_length( ULONG
*len
, unsigned int align
)
97 *len
= (*len
+ align
- 1) & ~(align
- 1);
100 static inline void align_pointer( unsigned char **ptr
, unsigned int align
)
102 ULONG_PTR mask
= align
- 1;
103 *ptr
= (unsigned char *)(((ULONG_PTR
)*ptr
+ mask
) & ~mask
);
106 static inline void align_pointer_clear( unsigned char **ptr
, unsigned int align
)
108 ULONG_PTR mask
= align
- 1;
109 memset( *ptr
, 0, (align
- (ULONG_PTR
)*ptr
) & mask
);
110 *ptr
= (unsigned char *)(((ULONG_PTR
)*ptr
+ mask
) & ~mask
);
113 #define STD_OVERFLOW_CHECK(_Msg) do { \
114 TRACE("buffer=%d/%d\n", (ULONG)(_Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer), _Msg->BufferLength); \
115 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
116 ERR("buffer overflow %d bytes\n", (ULONG)(_Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength))); \
119 #define NDR_POINTER_ID_BASE 0x20000
120 #define NDR_POINTER_ID(pStubMsg) (NDR_POINTER_ID_BASE + ((pStubMsg)->UniquePtrCount++) * 4)
121 #define NDR_TABLE_SIZE 128
122 #define NDR_TABLE_MASK 127
124 #define NDRSContextFromValue(user_context) (NDR_SCONTEXT)((char *)(user_context) - (char *)NDRSContextValue((NDR_SCONTEXT)NULL))
126 static unsigned char *WINAPI
NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
127 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
128 static void WINAPI
NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
129 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
130 static ULONG WINAPI
NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
132 static unsigned char *WINAPI
NdrContextHandleMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
133 static void WINAPI
NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
134 static unsigned char *WINAPI
NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
136 static unsigned char *WINAPI
NdrRangeMarshall(PMIDL_STUB_MESSAGE
,unsigned char *, PFORMAT_STRING
);
137 static void WINAPI
NdrRangeBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
138 static ULONG WINAPI
NdrRangeMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
139 static void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
141 static ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
143 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
144 unsigned char *pMemory
,
145 PFORMAT_STRING pFormat
,
146 PFORMAT_STRING pPointer
);
147 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
148 unsigned char *pMemory
,
149 PFORMAT_STRING pFormat
,
150 PFORMAT_STRING pPointer
);
151 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
152 unsigned char *pMemory
,
153 PFORMAT_STRING pFormat
,
154 PFORMAT_STRING pPointer
,
155 unsigned char fMustAlloc
);
156 static ULONG
ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
157 PFORMAT_STRING pFormat
,
158 PFORMAT_STRING pPointer
);
159 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
160 unsigned char *pMemory
,
161 PFORMAT_STRING pFormat
,
162 PFORMAT_STRING pPointer
);
164 const NDR_MARSHALL NdrMarshaller
[NDR_TABLE_SIZE
] = {
166 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
167 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
168 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
169 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
173 NdrPointerMarshall
, NdrPointerMarshall
,
174 NdrPointerMarshall
, NdrPointerMarshall
,
176 NdrSimpleStructMarshall
, NdrSimpleStructMarshall
,
177 NdrConformantStructMarshall
, NdrConformantStructMarshall
,
178 NdrConformantVaryingStructMarshall
,
179 NdrComplexStructMarshall
,
181 NdrConformantArrayMarshall
,
182 NdrConformantVaryingArrayMarshall
,
183 NdrFixedArrayMarshall
, NdrFixedArrayMarshall
,
184 NdrVaryingArrayMarshall
, NdrVaryingArrayMarshall
,
185 NdrComplexArrayMarshall
,
187 NdrConformantStringMarshall
, 0, 0,
188 NdrConformantStringMarshall
,
189 NdrNonConformantStringMarshall
, 0, 0, 0,
191 NdrEncapsulatedUnionMarshall
,
192 NdrNonEncapsulatedUnionMarshall
,
193 NdrByteCountPointerMarshall
,
194 NdrXmitOrRepAsMarshall
, NdrXmitOrRepAsMarshall
,
196 NdrInterfacePointerMarshall
,
198 NdrContextHandleMarshall
,
201 NdrUserMarshalMarshall
,
206 const NDR_UNMARSHALL NdrUnmarshaller
[NDR_TABLE_SIZE
] = {
208 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
209 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
210 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
211 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
213 NdrBaseTypeUnmarshall
,
215 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
216 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
218 NdrSimpleStructUnmarshall
, NdrSimpleStructUnmarshall
,
219 NdrConformantStructUnmarshall
, NdrConformantStructUnmarshall
,
220 NdrConformantVaryingStructUnmarshall
,
221 NdrComplexStructUnmarshall
,
223 NdrConformantArrayUnmarshall
,
224 NdrConformantVaryingArrayUnmarshall
,
225 NdrFixedArrayUnmarshall
, NdrFixedArrayUnmarshall
,
226 NdrVaryingArrayUnmarshall
, NdrVaryingArrayUnmarshall
,
227 NdrComplexArrayUnmarshall
,
229 NdrConformantStringUnmarshall
, 0, 0,
230 NdrConformantStringUnmarshall
,
231 NdrNonConformantStringUnmarshall
, 0, 0, 0,
233 NdrEncapsulatedUnionUnmarshall
,
234 NdrNonEncapsulatedUnionUnmarshall
,
235 NdrByteCountPointerUnmarshall
,
236 NdrXmitOrRepAsUnmarshall
, NdrXmitOrRepAsUnmarshall
,
238 NdrInterfacePointerUnmarshall
,
240 NdrContextHandleUnmarshall
,
243 NdrUserMarshalUnmarshall
,
248 const NDR_BUFFERSIZE NdrBufferSizer
[NDR_TABLE_SIZE
] = {
250 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
251 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
252 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
253 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
255 NdrBaseTypeBufferSize
,
257 NdrPointerBufferSize
, NdrPointerBufferSize
,
258 NdrPointerBufferSize
, NdrPointerBufferSize
,
260 NdrSimpleStructBufferSize
, NdrSimpleStructBufferSize
,
261 NdrConformantStructBufferSize
, NdrConformantStructBufferSize
,
262 NdrConformantVaryingStructBufferSize
,
263 NdrComplexStructBufferSize
,
265 NdrConformantArrayBufferSize
,
266 NdrConformantVaryingArrayBufferSize
,
267 NdrFixedArrayBufferSize
, NdrFixedArrayBufferSize
,
268 NdrVaryingArrayBufferSize
, NdrVaryingArrayBufferSize
,
269 NdrComplexArrayBufferSize
,
271 NdrConformantStringBufferSize
, 0, 0,
272 NdrConformantStringBufferSize
,
273 NdrNonConformantStringBufferSize
, 0, 0, 0,
275 NdrEncapsulatedUnionBufferSize
,
276 NdrNonEncapsulatedUnionBufferSize
,
277 NdrByteCountPointerBufferSize
,
278 NdrXmitOrRepAsBufferSize
, NdrXmitOrRepAsBufferSize
,
280 NdrInterfacePointerBufferSize
,
282 NdrContextHandleBufferSize
,
285 NdrUserMarshalBufferSize
,
290 const NDR_MEMORYSIZE NdrMemorySizer
[NDR_TABLE_SIZE
] = {
292 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
293 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
294 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
295 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
297 NdrBaseTypeMemorySize
,
299 NdrPointerMemorySize
, NdrPointerMemorySize
,
300 NdrPointerMemorySize
, NdrPointerMemorySize
,
302 NdrSimpleStructMemorySize
, NdrSimpleStructMemorySize
,
303 NdrConformantStructMemorySize
, NdrConformantStructMemorySize
,
304 NdrConformantVaryingStructMemorySize
,
305 NdrComplexStructMemorySize
,
307 NdrConformantArrayMemorySize
,
308 NdrConformantVaryingArrayMemorySize
,
309 NdrFixedArrayMemorySize
, NdrFixedArrayMemorySize
,
310 NdrVaryingArrayMemorySize
, NdrVaryingArrayMemorySize
,
311 NdrComplexArrayMemorySize
,
313 NdrConformantStringMemorySize
, 0, 0,
314 NdrConformantStringMemorySize
,
315 NdrNonConformantStringMemorySize
, 0, 0, 0,
317 NdrEncapsulatedUnionMemorySize
,
318 NdrNonEncapsulatedUnionMemorySize
,
319 NdrByteCountPointerMemorySize
,
320 NdrXmitOrRepAsMemorySize
, NdrXmitOrRepAsMemorySize
,
322 NdrInterfacePointerMemorySize
,
327 NdrUserMarshalMemorySize
,
332 const NDR_FREE NdrFreer
[NDR_TABLE_SIZE
] = {
334 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
335 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
336 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
337 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
341 NdrPointerFree
, NdrPointerFree
,
342 NdrPointerFree
, NdrPointerFree
,
344 NdrSimpleStructFree
, NdrSimpleStructFree
,
345 NdrConformantStructFree
, NdrConformantStructFree
,
346 NdrConformantVaryingStructFree
,
347 NdrComplexStructFree
,
349 NdrConformantArrayFree
,
350 NdrConformantVaryingArrayFree
,
351 NdrFixedArrayFree
, NdrFixedArrayFree
,
352 NdrVaryingArrayFree
, NdrVaryingArrayFree
,
358 NdrEncapsulatedUnionFree
,
359 NdrNonEncapsulatedUnionFree
,
361 NdrXmitOrRepAsFree
, NdrXmitOrRepAsFree
,
363 NdrInterfacePointerFree
,
374 typedef struct _NDR_MEMORY_LIST
379 struct _NDR_MEMORY_LIST
*next
;
382 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
384 /***********************************************************************
385 * NdrAllocate [RPCRT4.@]
387 * Allocates a block of memory using pStubMsg->pfnAllocate.
390 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
391 * len [I] Size of memory block to allocate.
394 * The memory block of size len that was allocated.
397 * The memory block is always 8-byte aligned.
398 * If the function is unable to allocate memory an RPC_X_NO_MEMORY
399 * exception is raised.
401 void * WINAPI
NdrAllocate(MIDL_STUB_MESSAGE
*pStubMsg
, SIZE_T len
)
406 NDR_MEMORY_LIST
*mem_list
;
408 aligned_len
= (len
+ 7) & ~7;
409 adjusted_len
= aligned_len
+ sizeof(NDR_MEMORY_LIST
);
410 /* check for overflow */
411 if (adjusted_len
< len
)
413 ERR("overflow of adjusted_len %ld, len %ld\n", adjusted_len
, len
);
414 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
417 p
= pStubMsg
->pfnAllocate(adjusted_len
);
418 if (!p
) RpcRaiseException(RPC_X_NO_MEMORY
);
420 mem_list
= (NDR_MEMORY_LIST
*)((char *)p
+ aligned_len
);
421 mem_list
->magic
= MEML_MAGIC
;
422 mem_list
->size
= aligned_len
;
423 mem_list
->reserved
= 0;
424 mem_list
->next
= pStubMsg
->pMemoryList
;
425 pStubMsg
->pMemoryList
= mem_list
;
431 static void NdrFree(MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *Pointer
)
433 TRACE("(%p, %p)\n", pStubMsg
, Pointer
);
435 pStubMsg
->pfnFree(Pointer
);
438 static inline BOOL
IsConformanceOrVariancePresent(PFORMAT_STRING pFormat
)
440 return (*(const ULONG
*)pFormat
!= -1);
443 static inline PFORMAT_STRING
SkipConformance(const PMIDL_STUB_MESSAGE pStubMsg
, const PFORMAT_STRING pFormat
)
445 return pStubMsg
->fHasNewCorrDesc
? pFormat
+ 6 : pFormat
+ 4;
448 static PFORMAT_STRING
ReadConformance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
)
450 align_pointer(&pStubMsg
->Buffer
, 4);
451 if (pStubMsg
->Buffer
+ 4 > pStubMsg
->BufferEnd
)
452 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
453 pStubMsg
->MaxCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
454 pStubMsg
->Buffer
+= 4;
455 TRACE("unmarshalled conformance is %ld\n", pStubMsg
->MaxCount
);
456 return SkipConformance(pStubMsg
, pFormat
);
459 static inline PFORMAT_STRING
ReadVariance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
, ULONG MaxValue
)
461 if (pFormat
&& !IsConformanceOrVariancePresent(pFormat
))
463 pStubMsg
->Offset
= 0;
464 pStubMsg
->ActualCount
= pStubMsg
->MaxCount
;
468 align_pointer(&pStubMsg
->Buffer
, 4);
469 if (pStubMsg
->Buffer
+ 8 > pStubMsg
->BufferEnd
)
470 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
471 pStubMsg
->Offset
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
472 pStubMsg
->Buffer
+= 4;
473 TRACE("offset is %d\n", pStubMsg
->Offset
);
474 pStubMsg
->ActualCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
475 pStubMsg
->Buffer
+= 4;
476 TRACE("variance is %d\n", pStubMsg
->ActualCount
);
478 if ((pStubMsg
->ActualCount
> MaxValue
) ||
479 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> MaxValue
))
481 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
482 pStubMsg
->ActualCount
, pStubMsg
->Offset
, MaxValue
);
483 RpcRaiseException(RPC_S_INVALID_BOUND
);
488 return SkipConformance(pStubMsg
, pFormat
);
491 /* writes the conformance value to the buffer */
492 static inline void WriteConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
494 align_pointer_clear(&pStubMsg
->Buffer
, 4);
495 if (pStubMsg
->Buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
496 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
497 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->MaxCount
);
498 pStubMsg
->Buffer
+= 4;
501 /* writes the variance values to the buffer */
502 static inline void WriteVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
504 align_pointer_clear(&pStubMsg
->Buffer
, 4);
505 if (pStubMsg
->Buffer
+ 8 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
506 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
507 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->Offset
);
508 pStubMsg
->Buffer
+= 4;
509 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->ActualCount
);
510 pStubMsg
->Buffer
+= 4;
513 /* requests buffer space for the conformance value */
514 static inline void SizeConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
516 align_length(&pStubMsg
->BufferLength
, 4);
517 if (pStubMsg
->BufferLength
+ 4 < pStubMsg
->BufferLength
)
518 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
519 pStubMsg
->BufferLength
+= 4;
522 /* requests buffer space for the variance values */
523 static inline void SizeVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
525 align_length(&pStubMsg
->BufferLength
, 4);
526 if (pStubMsg
->BufferLength
+ 8 < pStubMsg
->BufferLength
)
527 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
528 pStubMsg
->BufferLength
+= 8;
531 PFORMAT_STRING
ComputeConformanceOrVariance(
532 MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *pMemory
,
533 PFORMAT_STRING pFormat
, ULONG_PTR def
, ULONG_PTR
*pCount
)
535 BYTE dtype
= pFormat
[0] & 0xf;
536 short ofs
= *(const short *)&pFormat
[2];
540 if (!IsConformanceOrVariancePresent(pFormat
)) {
541 /* null descriptor */
546 switch (pFormat
[0] & 0xf0) {
547 case RPC_FC_NORMAL_CONFORMANCE
:
548 TRACE("normal conformance, ofs=%d\n", ofs
);
551 case RPC_FC_POINTER_CONFORMANCE
:
552 TRACE("pointer conformance, ofs=%d\n", ofs
);
553 ptr
= pStubMsg
->Memory
;
555 case RPC_FC_TOP_LEVEL_CONFORMANCE
:
556 TRACE("toplevel conformance, ofs=%d\n", ofs
);
557 if (pStubMsg
->StackTop
) {
558 ptr
= pStubMsg
->StackTop
;
561 /* -Os mode, *pCount is already set */
565 case RPC_FC_CONSTANT_CONFORMANCE
:
566 data
= ofs
| ((DWORD
)pFormat
[1] << 16);
567 TRACE("constant conformance, val=%ld\n", data
);
570 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE
:
571 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs
);
572 if (pStubMsg
->StackTop
) {
573 ptr
= pStubMsg
->StackTop
;
581 FIXME("unknown conformance type %x, expect crash.\n", pFormat
[0] & 0xf0);
585 switch (pFormat
[1]) {
586 case RPC_FC_DEREFERENCE
:
587 ptr
= *(LPVOID
*)((char *)ptr
+ ofs
);
589 case RPC_FC_CALLBACK
:
591 unsigned char *old_stack_top
= pStubMsg
->StackTop
;
592 ULONG_PTR max_count
, old_max_count
= pStubMsg
->MaxCount
;
594 pStubMsg
->StackTop
= ptr
;
596 /* ofs is index into StubDesc->apfnExprEval */
597 TRACE("callback conformance into apfnExprEval[%d]\n", ofs
);
598 pStubMsg
->StubDesc
->apfnExprEval
[ofs
](pStubMsg
);
600 pStubMsg
->StackTop
= old_stack_top
;
602 /* the callback function always stores the computed value in MaxCount */
603 max_count
= pStubMsg
->MaxCount
;
604 pStubMsg
->MaxCount
= old_max_count
;
609 ptr
= (char *)ptr
+ ofs
;
622 data
= *(USHORT
*)ptr
;
633 data
= *(ULONGLONG
*)ptr
;
636 FIXME("unknown conformance data type %x\n", dtype
);
639 TRACE("dereferenced data type %x at %p, got %ld\n", dtype
, ptr
, data
);
642 switch (pFormat
[1]) {
643 case RPC_FC_DEREFERENCE
: /* already handled */
660 FIXME("unknown conformance op %d\n", pFormat
[1]);
665 TRACE("resulting conformance is %ld\n", *pCount
);
667 return SkipConformance(pStubMsg
, pFormat
);
670 static inline PFORMAT_STRING
SkipVariance(PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
672 return SkipConformance( pStubMsg
, pFormat
);
675 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
676 * the result overflows 32-bits */
677 static inline ULONG
safe_multiply(ULONG a
, ULONG b
)
679 ULONGLONG ret
= (ULONGLONG
)a
* b
;
680 if (ret
> 0xffffffff)
682 RpcRaiseException(RPC_S_INVALID_BOUND
);
688 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
690 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
691 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
692 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
693 pStubMsg
->Buffer
+= size
;
696 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
698 if (pStubMsg
->BufferLength
+ size
< pStubMsg
->BufferLength
) /* integer overflow of pStubMsg->BufferSize */
700 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
701 pStubMsg
->BufferLength
, size
);
702 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
704 pStubMsg
->BufferLength
+= size
;
707 /* copies data from the buffer, checking that there is enough data in the buffer
709 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, void *p
, ULONG size
)
711 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
712 (pStubMsg
->Buffer
+ size
> pStubMsg
->BufferEnd
))
714 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
715 pStubMsg
->Buffer
, pStubMsg
->BufferEnd
, size
);
716 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
718 if (p
== pStubMsg
->Buffer
)
719 ERR("pointer is the same as the buffer\n");
720 memcpy(p
, pStubMsg
->Buffer
, size
);
721 pStubMsg
->Buffer
+= size
;
724 /* copies data to the buffer, checking that there is enough space to do so */
725 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, const void *p
, ULONG size
)
727 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
728 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
730 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
731 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
,
733 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
735 memcpy(pStubMsg
->Buffer
, p
, size
);
736 pStubMsg
->Buffer
+= size
;
739 /* verify that string data sitting in the buffer is valid and safe to
741 static void validate_string_data(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG bufsize
, ULONG esize
)
745 /* verify the buffer is safe to access */
746 if ((pStubMsg
->Buffer
+ bufsize
< pStubMsg
->Buffer
) ||
747 (pStubMsg
->Buffer
+ bufsize
> pStubMsg
->BufferEnd
))
749 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize
,
750 pStubMsg
->BufferEnd
, pStubMsg
->Buffer
);
751 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
754 /* strings must always have null terminating bytes */
757 ERR("invalid string length of %d\n", bufsize
/ esize
);
758 RpcRaiseException(RPC_S_INVALID_BOUND
);
761 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
762 if (pStubMsg
->Buffer
[i
] != 0)
764 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
765 i
, pStubMsg
->Buffer
[i
]);
766 RpcRaiseException(RPC_S_INVALID_BOUND
);
770 static inline void dump_pointer_attr(unsigned char attr
)
772 if (attr
& RPC_FC_P_ALLOCALLNODES
)
773 TRACE(" RPC_FC_P_ALLOCALLNODES");
774 if (attr
& RPC_FC_P_DONTFREE
)
775 TRACE(" RPC_FC_P_DONTFREE");
776 if (attr
& RPC_FC_P_ONSTACK
)
777 TRACE(" RPC_FC_P_ONSTACK");
778 if (attr
& RPC_FC_P_SIMPLEPOINTER
)
779 TRACE(" RPC_FC_P_SIMPLEPOINTER");
780 if (attr
& RPC_FC_P_DEREF
)
781 TRACE(" RPC_FC_P_DEREF");
785 /***********************************************************************
786 * PointerMarshall [internal]
788 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
789 unsigned char *Buffer
,
790 unsigned char *Pointer
,
791 PFORMAT_STRING pFormat
)
793 unsigned type
= pFormat
[0], attr
= pFormat
[1];
797 BOOL pointer_needs_marshaling
;
799 TRACE("(%p,%p,%p,%p)\n", pStubMsg
, Buffer
, Pointer
, pFormat
);
800 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
802 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
803 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
806 case RPC_FC_RP
: /* ref pointer (always non-null) */
809 ERR("NULL ref pointer is not allowed\n");
810 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
812 pointer_needs_marshaling
= TRUE
;
814 case RPC_FC_UP
: /* unique pointer */
815 case RPC_FC_OP
: /* object pointer - same as unique here */
817 pointer_needs_marshaling
= TRUE
;
819 pointer_needs_marshaling
= FALSE
;
820 pointer_id
= Pointer
? NDR_POINTER_ID(pStubMsg
) : 0;
821 TRACE("writing 0x%08x to buffer\n", pointer_id
);
822 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
825 pointer_needs_marshaling
= !NdrFullPointerQueryPointer(
826 pStubMsg
->FullPtrXlatTables
, Pointer
, 1, &pointer_id
);
827 TRACE("writing 0x%08x to buffer\n", pointer_id
);
828 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
831 FIXME("unhandled ptr type=%02x\n", type
);
832 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
836 TRACE("calling marshaller for type 0x%x\n", (int)*desc
);
838 if (pointer_needs_marshaling
) {
839 if (attr
& RPC_FC_P_DEREF
) {
840 Pointer
= *(unsigned char**)Pointer
;
841 TRACE("deref => %p\n", Pointer
);
843 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
844 if (m
) m(pStubMsg
, Pointer
, desc
);
845 else FIXME("no marshaller for data type=%02x\n", *desc
);
848 STD_OVERFLOW_CHECK(pStubMsg
);
851 /***********************************************************************
852 * PointerUnmarshall [internal]
854 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
855 unsigned char *Buffer
,
856 unsigned char **pPointer
,
857 unsigned char *pSrcPointer
,
858 PFORMAT_STRING pFormat
,
859 unsigned char fMustAlloc
)
861 unsigned type
= pFormat
[0], attr
= pFormat
[1];
864 DWORD pointer_id
= 0;
865 BOOL pointer_needs_unmarshaling
;
867 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg
, Buffer
, pPointer
, pSrcPointer
, pFormat
, fMustAlloc
);
868 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
870 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
871 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
874 case RPC_FC_RP
: /* ref pointer (always non-null) */
875 pointer_needs_unmarshaling
= TRUE
;
877 case RPC_FC_UP
: /* unique pointer */
878 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
879 TRACE("pointer_id is 0x%08x\n", pointer_id
);
881 pointer_needs_unmarshaling
= TRUE
;
884 pointer_needs_unmarshaling
= FALSE
;
887 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
888 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
889 TRACE("pointer_id is 0x%08x\n", pointer_id
);
890 if (!fMustAlloc
&& pSrcPointer
)
892 FIXME("free object pointer %p\n", pSrcPointer
);
896 pointer_needs_unmarshaling
= TRUE
;
900 pointer_needs_unmarshaling
= FALSE
;
904 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
905 TRACE("pointer_id is 0x%08x\n", pointer_id
);
906 pointer_needs_unmarshaling
= !NdrFullPointerQueryRefId(
907 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, (void **)pPointer
);
910 FIXME("unhandled ptr type=%02x\n", type
);
911 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
915 if (pointer_needs_unmarshaling
) {
916 unsigned char **current_ptr
= pPointer
;
917 if (pStubMsg
->IsClient
) {
919 /* if we aren't forcing allocation of memory then try to use the existing
920 * (source) pointer to unmarshall the data into so that [in,out]
921 * parameters behave correctly. it doesn't matter if the parameter is
922 * [out] only since in that case the pointer will be NULL. we force
923 * allocation when the source pointer is NULL here instead of in the type
924 * unmarshalling routine for the benefit of the deref code below */
927 TRACE("setting *pPointer to %p\n", pSrcPointer
);
928 *pPointer
= pSrcPointer
;
934 /* the memory in a stub is never initialised, so we have to work out here
935 * whether we have to initialise it so we can use the optimisation of
936 * setting the pointer to the buffer, if possible, or set fMustAlloc to
938 if (attr
& RPC_FC_P_DEREF
) {
945 if (attr
& RPC_FC_P_ALLOCALLNODES
)
946 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
948 if (attr
& RPC_FC_P_DEREF
) {
950 unsigned char *base_ptr_val
= NdrAllocate(pStubMsg
, sizeof(void *));
951 *pPointer
= base_ptr_val
;
952 current_ptr
= (unsigned char **)base_ptr_val
;
954 current_ptr
= *(unsigned char***)current_ptr
;
955 TRACE("deref => %p\n", current_ptr
);
956 if (!fMustAlloc
&& !*current_ptr
) fMustAlloc
= TRUE
;
958 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
959 if (m
) m(pStubMsg
, current_ptr
, desc
, fMustAlloc
);
960 else FIXME("no unmarshaller for data type=%02x\n", *desc
);
962 if (type
== RPC_FC_FP
)
963 NdrFullPointerInsertRefId(pStubMsg
->FullPtrXlatTables
, pointer_id
,
967 TRACE("pointer=%p\n", *pPointer
);
970 /***********************************************************************
971 * PointerBufferSize [internal]
973 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
974 unsigned char *Pointer
,
975 PFORMAT_STRING pFormat
)
977 unsigned type
= pFormat
[0], attr
= pFormat
[1];
980 BOOL pointer_needs_sizing
;
983 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
984 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
986 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
987 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
990 case RPC_FC_RP
: /* ref pointer (always non-null) */
993 ERR("NULL ref pointer is not allowed\n");
994 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
999 /* NULL pointer has no further representation */
1004 pointer_needs_sizing
= !NdrFullPointerQueryPointer(
1005 pStubMsg
->FullPtrXlatTables
, Pointer
, 0, &pointer_id
);
1006 if (!pointer_needs_sizing
)
1010 FIXME("unhandled ptr type=%02x\n", type
);
1011 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1015 if (attr
& RPC_FC_P_DEREF
) {
1016 Pointer
= *(unsigned char**)Pointer
;
1017 TRACE("deref => %p\n", Pointer
);
1020 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
1021 if (m
) m(pStubMsg
, Pointer
, desc
);
1022 else FIXME("no buffersizer for data type=%02x\n", *desc
);
1025 /***********************************************************************
1026 * PointerMemorySize [internal]
1028 static ULONG
PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1029 unsigned char *Buffer
, PFORMAT_STRING pFormat
)
1031 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1032 PFORMAT_STRING desc
;
1034 DWORD pointer_id
= 0;
1035 BOOL pointer_needs_sizing
;
1037 TRACE("(%p,%p,%p)\n", pStubMsg
, Buffer
, pFormat
);
1038 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1040 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1041 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1044 case RPC_FC_RP
: /* ref pointer (always non-null) */
1045 pointer_needs_sizing
= TRUE
;
1047 case RPC_FC_UP
: /* unique pointer */
1048 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
1049 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1050 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1052 pointer_needs_sizing
= TRUE
;
1054 pointer_needs_sizing
= FALSE
;
1059 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1060 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1061 pointer_needs_sizing
= !NdrFullPointerQueryRefId(
1062 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, &pointer
);
1066 FIXME("unhandled ptr type=%02x\n", type
);
1067 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1071 if (attr
& RPC_FC_P_DEREF
) {
1072 align_length(&pStubMsg
->MemorySize
, sizeof(void*));
1073 pStubMsg
->MemorySize
+= sizeof(void*);
1077 if (pointer_needs_sizing
) {
1078 m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
1079 if (m
) m(pStubMsg
, desc
);
1080 else FIXME("no memorysizer for data type=%02x\n", *desc
);
1083 return pStubMsg
->MemorySize
;
1086 /***********************************************************************
1087 * PointerFree [internal]
1089 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1090 unsigned char *Pointer
,
1091 PFORMAT_STRING pFormat
)
1093 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1094 PFORMAT_STRING desc
;
1096 unsigned char *current_pointer
= Pointer
;
1098 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1099 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1100 if (attr
& RPC_FC_P_DONTFREE
) return;
1102 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1103 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1105 if (!Pointer
) return;
1107 if (type
== RPC_FC_FP
) {
1108 int pointer_needs_freeing
= NdrFullPointerFree(
1109 pStubMsg
->FullPtrXlatTables
, Pointer
);
1110 if (!pointer_needs_freeing
)
1114 if (attr
& RPC_FC_P_DEREF
) {
1115 current_pointer
= *(unsigned char**)Pointer
;
1116 TRACE("deref => %p\n", current_pointer
);
1119 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
1120 if (m
) m(pStubMsg
, current_pointer
, desc
);
1122 /* this check stops us from trying to free buffer memory. we don't have to
1123 * worry about clients, since they won't call this function.
1124 * we don't have to check for the buffer being reallocated because
1125 * BufferStart and BufferEnd won't be reset when allocating memory for
1126 * sending the response. we don't have to check for the new buffer here as
1127 * it won't be used a type memory, only for buffer memory */
1128 if (Pointer
>= pStubMsg
->BufferStart
&& Pointer
<= pStubMsg
->BufferEnd
)
1131 if (attr
& RPC_FC_P_ONSTACK
) {
1132 TRACE("not freeing stack ptr %p\n", Pointer
);
1135 TRACE("freeing %p\n", Pointer
);
1136 NdrFree(pStubMsg
, Pointer
);
1139 TRACE("not freeing %p\n", Pointer
);
1142 /***********************************************************************
1143 * EmbeddedPointerMarshall
1145 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1146 unsigned char *pMemory
,
1147 PFORMAT_STRING pFormat
)
1149 unsigned char *Mark
= pStubMsg
->BufferMark
;
1150 unsigned rep
, count
, stride
;
1152 unsigned char *saved_buffer
= NULL
;
1154 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1156 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1159 if (pStubMsg
->PointerBufferMark
)
1161 saved_buffer
= pStubMsg
->Buffer
;
1162 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1163 pStubMsg
->PointerBufferMark
= NULL
;
1166 while (pFormat
[0] != RPC_FC_END
) {
1167 switch (pFormat
[0]) {
1169 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat
[0]);
1171 case RPC_FC_NO_REPEAT
:
1177 case RPC_FC_FIXED_REPEAT
:
1178 rep
= *(const WORD
*)&pFormat
[2];
1179 stride
= *(const WORD
*)&pFormat
[4];
1180 count
= *(const WORD
*)&pFormat
[8];
1183 case RPC_FC_VARIABLE_REPEAT
:
1184 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1185 stride
= *(const WORD
*)&pFormat
[2];
1186 count
= *(const WORD
*)&pFormat
[6];
1190 for (i
= 0; i
< rep
; i
++) {
1191 PFORMAT_STRING info
= pFormat
;
1192 unsigned char *membase
= pMemory
+ (i
* stride
);
1193 unsigned char *bufbase
= Mark
+ (i
* stride
);
1196 for (u
=0; u
<count
; u
++,info
+=8) {
1197 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1198 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1199 unsigned char *saved_memory
= pStubMsg
->Memory
;
1201 pStubMsg
->Memory
= membase
;
1202 PointerMarshall(pStubMsg
, bufptr
, *(unsigned char**)memptr
, info
+4);
1203 pStubMsg
->Memory
= saved_memory
;
1206 pFormat
+= 8 * count
;
1211 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1212 pStubMsg
->Buffer
= saved_buffer
;
1215 STD_OVERFLOW_CHECK(pStubMsg
);
1220 /***********************************************************************
1221 * EmbeddedPointerUnmarshall
1223 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1224 unsigned char *pDstBuffer
,
1225 unsigned char *pSrcMemoryPtrs
,
1226 PFORMAT_STRING pFormat
,
1227 unsigned char fMustAlloc
)
1229 unsigned char *Mark
= pStubMsg
->BufferMark
;
1230 unsigned rep
, count
, stride
;
1232 unsigned char *saved_buffer
= NULL
;
1234 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg
, pDstBuffer
, pSrcMemoryPtrs
, pFormat
, fMustAlloc
);
1236 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1239 if (pStubMsg
->PointerBufferMark
)
1241 saved_buffer
= pStubMsg
->Buffer
;
1242 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1243 pStubMsg
->PointerBufferMark
= NULL
;
1246 while (pFormat
[0] != RPC_FC_END
) {
1247 TRACE("pFormat[0] = 0x%x\n", pFormat
[0]);
1248 switch (pFormat
[0]) {
1250 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat
[0]);
1252 case RPC_FC_NO_REPEAT
:
1258 case RPC_FC_FIXED_REPEAT
:
1259 rep
= *(const WORD
*)&pFormat
[2];
1260 stride
= *(const WORD
*)&pFormat
[4];
1261 count
= *(const WORD
*)&pFormat
[8];
1264 case RPC_FC_VARIABLE_REPEAT
:
1265 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1266 stride
= *(const WORD
*)&pFormat
[2];
1267 count
= *(const WORD
*)&pFormat
[6];
1271 for (i
= 0; i
< rep
; i
++) {
1272 PFORMAT_STRING info
= pFormat
;
1273 unsigned char *bufdstbase
= pDstBuffer
+ (i
* stride
);
1274 unsigned char *memsrcbase
= pSrcMemoryPtrs
+ (i
* stride
);
1275 unsigned char *bufbase
= Mark
+ (i
* stride
);
1278 for (u
=0; u
<count
; u
++,info
+=8) {
1279 unsigned char **bufdstptr
= (unsigned char **)(bufdstbase
+ *(const SHORT
*)&info
[2]);
1280 unsigned char **memsrcptr
= (unsigned char **)(memsrcbase
+ *(const SHORT
*)&info
[0]);
1281 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1282 PointerUnmarshall(pStubMsg
, bufptr
, bufdstptr
, *memsrcptr
, info
+4, fMustAlloc
);
1285 pFormat
+= 8 * count
;
1290 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1291 pStubMsg
->Buffer
= saved_buffer
;
1297 /***********************************************************************
1298 * EmbeddedPointerBufferSize
1300 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1301 unsigned char *pMemory
,
1302 PFORMAT_STRING pFormat
)
1304 unsigned rep
, count
, stride
;
1306 ULONG saved_buffer_length
= 0;
1308 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1310 if (pStubMsg
->IgnoreEmbeddedPointers
) return;
1312 if (*pFormat
!= RPC_FC_PP
) return;
1315 if (pStubMsg
->PointerLength
)
1317 saved_buffer_length
= pStubMsg
->BufferLength
;
1318 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
1319 pStubMsg
->PointerLength
= 0;
1322 while (pFormat
[0] != RPC_FC_END
) {
1323 switch (pFormat
[0]) {
1325 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat
[0]);
1327 case RPC_FC_NO_REPEAT
:
1333 case RPC_FC_FIXED_REPEAT
:
1334 rep
= *(const WORD
*)&pFormat
[2];
1335 stride
= *(const WORD
*)&pFormat
[4];
1336 count
= *(const WORD
*)&pFormat
[8];
1339 case RPC_FC_VARIABLE_REPEAT
:
1340 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1341 stride
= *(const WORD
*)&pFormat
[2];
1342 count
= *(const WORD
*)&pFormat
[6];
1346 for (i
= 0; i
< rep
; i
++) {
1347 PFORMAT_STRING info
= pFormat
;
1348 unsigned char *membase
= pMemory
+ (i
* stride
);
1351 for (u
=0; u
<count
; u
++,info
+=8) {
1352 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1353 unsigned char *saved_memory
= pStubMsg
->Memory
;
1355 pStubMsg
->Memory
= membase
;
1356 PointerBufferSize(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1357 pStubMsg
->Memory
= saved_memory
;
1360 pFormat
+= 8 * count
;
1363 if (saved_buffer_length
)
1365 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
1366 pStubMsg
->BufferLength
= saved_buffer_length
;
1370 /***********************************************************************
1371 * EmbeddedPointerMemorySize [internal]
1373 static ULONG
EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1374 PFORMAT_STRING pFormat
)
1376 unsigned char *Mark
= pStubMsg
->BufferMark
;
1377 unsigned rep
, count
, stride
;
1379 unsigned char *saved_buffer
= NULL
;
1381 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1383 if (pStubMsg
->IgnoreEmbeddedPointers
) return 0;
1385 if (pStubMsg
->PointerBufferMark
)
1387 saved_buffer
= pStubMsg
->Buffer
;
1388 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1389 pStubMsg
->PointerBufferMark
= NULL
;
1392 if (*pFormat
!= RPC_FC_PP
) return 0;
1395 while (pFormat
[0] != RPC_FC_END
) {
1396 switch (pFormat
[0]) {
1398 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat
[0]);
1400 case RPC_FC_NO_REPEAT
:
1406 case RPC_FC_FIXED_REPEAT
:
1407 rep
= *(const WORD
*)&pFormat
[2];
1408 stride
= *(const WORD
*)&pFormat
[4];
1409 count
= *(const WORD
*)&pFormat
[8];
1412 case RPC_FC_VARIABLE_REPEAT
:
1413 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1414 stride
= *(const WORD
*)&pFormat
[2];
1415 count
= *(const WORD
*)&pFormat
[6];
1419 for (i
= 0; i
< rep
; i
++) {
1420 PFORMAT_STRING info
= pFormat
;
1421 unsigned char *bufbase
= Mark
+ (i
* stride
);
1423 for (u
=0; u
<count
; u
++,info
+=8) {
1424 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1425 PointerMemorySize(pStubMsg
, bufptr
, info
+4);
1428 pFormat
+= 8 * count
;
1433 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1434 pStubMsg
->Buffer
= saved_buffer
;
1440 /***********************************************************************
1441 * EmbeddedPointerFree [internal]
1443 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1444 unsigned char *pMemory
,
1445 PFORMAT_STRING pFormat
)
1447 unsigned rep
, count
, stride
;
1450 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1451 if (*pFormat
!= RPC_FC_PP
) return;
1454 while (pFormat
[0] != RPC_FC_END
) {
1455 switch (pFormat
[0]) {
1457 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat
[0]);
1459 case RPC_FC_NO_REPEAT
:
1465 case RPC_FC_FIXED_REPEAT
:
1466 rep
= *(const WORD
*)&pFormat
[2];
1467 stride
= *(const WORD
*)&pFormat
[4];
1468 count
= *(const WORD
*)&pFormat
[8];
1471 case RPC_FC_VARIABLE_REPEAT
:
1472 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1473 stride
= *(const WORD
*)&pFormat
[2];
1474 count
= *(const WORD
*)&pFormat
[6];
1478 for (i
= 0; i
< rep
; i
++) {
1479 PFORMAT_STRING info
= pFormat
;
1480 unsigned char *membase
= pMemory
+ (i
* stride
);
1483 for (u
=0; u
<count
; u
++,info
+=8) {
1484 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1485 unsigned char *saved_memory
= pStubMsg
->Memory
;
1487 pStubMsg
->Memory
= membase
;
1488 PointerFree(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1489 pStubMsg
->Memory
= saved_memory
;
1492 pFormat
+= 8 * count
;
1496 /***********************************************************************
1497 * NdrPointerMarshall [RPCRT4.@]
1499 unsigned char * WINAPI
NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1500 unsigned char *pMemory
,
1501 PFORMAT_STRING pFormat
)
1503 unsigned char *Buffer
;
1505 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1507 /* Increment the buffer here instead of in PointerMarshall,
1508 * as that is used by embedded pointers which already handle the incrementing
1509 * the buffer, and shouldn't write any additional pointer data to the wire */
1510 if (*pFormat
!= RPC_FC_RP
)
1512 align_pointer_clear(&pStubMsg
->Buffer
, 4);
1513 Buffer
= pStubMsg
->Buffer
;
1514 safe_buffer_increment(pStubMsg
, 4);
1517 Buffer
= pStubMsg
->Buffer
;
1519 PointerMarshall(pStubMsg
, Buffer
, pMemory
, pFormat
);
1524 /***********************************************************************
1525 * NdrPointerUnmarshall [RPCRT4.@]
1527 unsigned char * WINAPI
NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1528 unsigned char **ppMemory
,
1529 PFORMAT_STRING pFormat
,
1530 unsigned char fMustAlloc
)
1532 unsigned char *Buffer
;
1534 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1536 if (*pFormat
== RPC_FC_RP
)
1538 Buffer
= pStubMsg
->Buffer
;
1539 /* Do the NULL ref pointer check here because embedded pointers can be
1540 * NULL if the type the pointer is embedded in was allocated rather than
1541 * being passed in by the client */
1542 if (pStubMsg
->IsClient
&& !*ppMemory
)
1544 ERR("NULL ref pointer is not allowed\n");
1545 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
1550 /* Increment the buffer here instead of in PointerUnmarshall,
1551 * as that is used by embedded pointers which already handle the incrementing
1552 * the buffer, and shouldn't read any additional pointer data from the
1554 align_pointer(&pStubMsg
->Buffer
, 4);
1555 Buffer
= pStubMsg
->Buffer
;
1556 safe_buffer_increment(pStubMsg
, 4);
1559 PointerUnmarshall(pStubMsg
, Buffer
, ppMemory
, *ppMemory
, pFormat
, fMustAlloc
);
1564 /***********************************************************************
1565 * NdrPointerBufferSize [RPCRT4.@]
1567 void WINAPI
NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1568 unsigned char *pMemory
,
1569 PFORMAT_STRING pFormat
)
1571 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1573 /* Increment the buffer length here instead of in PointerBufferSize,
1574 * as that is used by embedded pointers which already handle the buffer
1575 * length, and shouldn't write anything more to the wire */
1576 if (*pFormat
!= RPC_FC_RP
)
1578 align_length(&pStubMsg
->BufferLength
, 4);
1579 safe_buffer_length_increment(pStubMsg
, 4);
1582 PointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1585 /***********************************************************************
1586 * NdrPointerMemorySize [RPCRT4.@]
1588 ULONG WINAPI
NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1589 PFORMAT_STRING pFormat
)
1591 unsigned char *Buffer
= pStubMsg
->Buffer
;
1592 if (*pFormat
!= RPC_FC_RP
)
1594 align_pointer(&pStubMsg
->Buffer
, 4);
1595 safe_buffer_increment(pStubMsg
, 4);
1597 align_length(&pStubMsg
->MemorySize
, sizeof(void *));
1598 return PointerMemorySize(pStubMsg
, Buffer
, pFormat
);
1601 /***********************************************************************
1602 * NdrPointerFree [RPCRT4.@]
1604 void WINAPI
NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1605 unsigned char *pMemory
,
1606 PFORMAT_STRING pFormat
)
1608 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1609 PointerFree(pStubMsg
, pMemory
, pFormat
);
1612 /***********************************************************************
1613 * NdrSimpleTypeMarshall [RPCRT4.@]
1615 void WINAPI
NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1616 unsigned char FormatChar
)
1618 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &FormatChar
);
1621 /***********************************************************************
1622 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1624 * Unmarshall a base type.
1627 * Doesn't check that the buffer is long enough before copying, so the caller
1630 void WINAPI
NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1631 unsigned char FormatChar
)
1633 #define BASE_TYPE_UNMARSHALL(type) \
1634 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
1635 TRACE("pMemory: %p\n", pMemory); \
1636 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1637 pStubMsg->Buffer += sizeof(type);
1645 BASE_TYPE_UNMARSHALL(UCHAR
);
1646 TRACE("value: 0x%02x\n", *pMemory
);
1651 BASE_TYPE_UNMARSHALL(USHORT
);
1652 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
1656 case RPC_FC_ERROR_STATUS_T
:
1658 BASE_TYPE_UNMARSHALL(ULONG
);
1659 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
1662 BASE_TYPE_UNMARSHALL(float);
1663 TRACE("value: %f\n", *(float *)pMemory
);
1666 BASE_TYPE_UNMARSHALL(double);
1667 TRACE("value: %f\n", *(double *)pMemory
);
1670 BASE_TYPE_UNMARSHALL(ULONGLONG
);
1671 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
1674 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
1675 TRACE("pMemory: %p\n", pMemory
);
1676 /* 16-bits on the wire, but int in memory */
1677 *(UINT
*)pMemory
= *(USHORT
*)pStubMsg
->Buffer
;
1678 pStubMsg
->Buffer
+= sizeof(USHORT
);
1679 TRACE("value: 0x%08x\n", *(UINT
*)pMemory
);
1681 case RPC_FC_INT3264
:
1682 align_pointer(&pStubMsg
->Buffer
, sizeof(INT
));
1683 /* 32-bits on the wire, but int_ptr in memory */
1684 *(INT_PTR
*)pMemory
= *(INT
*)pStubMsg
->Buffer
;
1685 pStubMsg
->Buffer
+= sizeof(INT
);
1686 TRACE("value: 0x%08lx\n", *(INT_PTR
*)pMemory
);
1688 case RPC_FC_UINT3264
:
1689 align_pointer(&pStubMsg
->Buffer
, sizeof(UINT
));
1690 /* 32-bits on the wire, but int_ptr in memory */
1691 *(UINT_PTR
*)pMemory
= *(UINT
*)pStubMsg
->Buffer
;
1692 pStubMsg
->Buffer
+= sizeof(UINT
);
1693 TRACE("value: 0x%08lx\n", *(UINT_PTR
*)pMemory
);
1698 FIXME("Unhandled base type: 0x%02x\n", FormatChar
);
1700 #undef BASE_TYPE_UNMARSHALL
1703 /***********************************************************************
1704 * NdrSimpleStructMarshall [RPCRT4.@]
1706 unsigned char * WINAPI
NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1707 unsigned char *pMemory
,
1708 PFORMAT_STRING pFormat
)
1710 unsigned size
= *(const WORD
*)(pFormat
+2);
1711 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1713 align_pointer_clear(&pStubMsg
->Buffer
, pFormat
[1] + 1);
1715 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1716 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
1718 if (pFormat
[0] != RPC_FC_STRUCT
)
1719 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
+4);
1724 /***********************************************************************
1725 * NdrSimpleStructUnmarshall [RPCRT4.@]
1727 unsigned char * WINAPI
NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1728 unsigned char **ppMemory
,
1729 PFORMAT_STRING pFormat
,
1730 unsigned char fMustAlloc
)
1732 unsigned size
= *(const WORD
*)(pFormat
+2);
1733 unsigned char *saved_buffer
;
1734 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1736 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
1739 *ppMemory
= NdrAllocate(pStubMsg
, size
);
1742 if (!pStubMsg
->IsClient
&& !*ppMemory
)
1743 /* for servers, we just point straight into the RPC buffer */
1744 *ppMemory
= pStubMsg
->Buffer
;
1747 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1748 safe_buffer_increment(pStubMsg
, size
);
1749 if (pFormat
[0] == RPC_FC_PSTRUCT
)
1750 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
+4, fMustAlloc
);
1752 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
1753 if (*ppMemory
!= saved_buffer
)
1754 memcpy(*ppMemory
, saved_buffer
, size
);
1759 /***********************************************************************
1760 * NdrSimpleStructBufferSize [RPCRT4.@]
1762 void WINAPI
NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1763 unsigned char *pMemory
,
1764 PFORMAT_STRING pFormat
)
1766 unsigned size
= *(const WORD
*)(pFormat
+2);
1767 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1769 align_length(&pStubMsg
->BufferLength
, pFormat
[1] + 1);
1771 safe_buffer_length_increment(pStubMsg
, size
);
1772 if (pFormat
[0] != RPC_FC_STRUCT
)
1773 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
+4);
1776 /***********************************************************************
1777 * NdrSimpleStructMemorySize [RPCRT4.@]
1779 ULONG WINAPI
NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1780 PFORMAT_STRING pFormat
)
1782 unsigned short size
= *(const WORD
*)(pFormat
+2);
1784 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1786 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
1787 pStubMsg
->MemorySize
+= size
;
1788 safe_buffer_increment(pStubMsg
, size
);
1790 if (pFormat
[0] != RPC_FC_STRUCT
)
1791 EmbeddedPointerMemorySize(pStubMsg
, pFormat
+4);
1792 return pStubMsg
->MemorySize
;
1795 /***********************************************************************
1796 * NdrSimpleStructFree [RPCRT4.@]
1798 void WINAPI
NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
1799 unsigned char *pMemory
,
1800 PFORMAT_STRING pFormat
)
1802 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1803 if (pFormat
[0] != RPC_FC_STRUCT
)
1804 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
+4);
1809 static inline void array_compute_and_size_conformance(
1810 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1811 PFORMAT_STRING pFormat
)
1818 ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1819 SizeConformance(pStubMsg
);
1821 case RPC_FC_CVARRAY
:
1822 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, 0);
1823 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
1824 SizeConformance(pStubMsg
);
1826 case RPC_FC_C_CSTRING
:
1827 case RPC_FC_C_WSTRING
:
1828 if (fc
== RPC_FC_C_CSTRING
)
1830 TRACE("string=%s\n", debugstr_a((const char *)pMemory
));
1831 pStubMsg
->ActualCount
= strlen((const char *)pMemory
)+1;
1835 TRACE("string=%s\n", debugstr_w((LPCWSTR
)pMemory
));
1836 pStubMsg
->ActualCount
= strlenW((LPCWSTR
)pMemory
)+1;
1839 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
1840 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
1842 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
1844 SizeConformance(pStubMsg
);
1846 case RPC_FC_BOGUS_ARRAY
:
1847 count
= *(const WORD
*)(pFormat
+ 2);
1849 if (IsConformanceOrVariancePresent(pFormat
)) SizeConformance(pStubMsg
);
1850 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, count
);
1851 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
1854 ERR("unknown array format 0x%x\n", fc
);
1855 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1859 static inline void array_buffer_size(
1860 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1861 PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
1865 unsigned char alignment
;
1870 esize
= *(const WORD
*)(pFormat
+2);
1871 alignment
= pFormat
[1] + 1;
1873 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1875 align_length(&pStubMsg
->BufferLength
, alignment
);
1877 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
1878 /* conformance value plus array */
1879 safe_buffer_length_increment(pStubMsg
, size
);
1882 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1884 case RPC_FC_CVARRAY
:
1885 esize
= *(const WORD
*)(pFormat
+2);
1886 alignment
= pFormat
[1] + 1;
1888 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1889 pFormat
= SkipVariance(pStubMsg
, pFormat
);
1891 SizeVariance(pStubMsg
);
1893 align_length(&pStubMsg
->BufferLength
, alignment
);
1895 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1896 safe_buffer_length_increment(pStubMsg
, size
);
1899 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1901 case RPC_FC_C_CSTRING
:
1902 case RPC_FC_C_WSTRING
:
1903 if (fc
== RPC_FC_C_CSTRING
)
1908 SizeVariance(pStubMsg
);
1910 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1911 safe_buffer_length_increment(pStubMsg
, size
);
1913 case RPC_FC_BOGUS_ARRAY
:
1914 alignment
= pFormat
[1] + 1;
1915 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1916 if (IsConformanceOrVariancePresent(pFormat
)) SizeVariance(pStubMsg
);
1917 pFormat
= SkipVariance(pStubMsg
, pFormat
);
1919 align_length(&pStubMsg
->BufferLength
, alignment
);
1921 size
= pStubMsg
->ActualCount
;
1922 for (i
= 0; i
< size
; i
++)
1923 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
1926 ERR("unknown array format 0x%x\n", fc
);
1927 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1931 static inline void array_compute_and_write_conformance(
1932 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1933 PFORMAT_STRING pFormat
)
1936 BOOL conformance_present
;
1941 ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1942 WriteConformance(pStubMsg
);
1944 case RPC_FC_CVARRAY
:
1945 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, 0);
1946 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
1947 WriteConformance(pStubMsg
);
1949 case RPC_FC_C_CSTRING
:
1950 case RPC_FC_C_WSTRING
:
1951 if (fc
== RPC_FC_C_CSTRING
)
1953 TRACE("string=%s\n", debugstr_a((const char *)pMemory
));
1954 pStubMsg
->ActualCount
= strlen((const char *)pMemory
)+1;
1958 TRACE("string=%s\n", debugstr_w((LPCWSTR
)pMemory
));
1959 pStubMsg
->ActualCount
= strlenW((LPCWSTR
)pMemory
)+1;
1961 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
1962 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
1964 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
1965 pStubMsg
->Offset
= 0;
1966 WriteConformance(pStubMsg
);
1968 case RPC_FC_BOGUS_ARRAY
:
1969 def
= *(const WORD
*)(pFormat
+ 2);
1971 conformance_present
= IsConformanceOrVariancePresent(pFormat
);
1972 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
1973 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
1974 if (conformance_present
) WriteConformance(pStubMsg
);
1977 ERR("unknown array format 0x%x\n", fc
);
1978 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1982 static inline void array_write_variance_and_marshall(
1983 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1984 PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
1988 unsigned char alignment
;
1993 esize
= *(const WORD
*)(pFormat
+2);
1994 alignment
= pFormat
[1] + 1;
1996 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1998 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
2000 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2002 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2003 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
2006 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2008 case RPC_FC_CVARRAY
:
2009 esize
= *(const WORD
*)(pFormat
+2);
2010 alignment
= pFormat
[1] + 1;
2012 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2013 pFormat
= SkipVariance(pStubMsg
, pFormat
);
2015 WriteVariance(pStubMsg
);
2017 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
2019 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2022 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2023 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, size
);
2026 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2028 case RPC_FC_C_CSTRING
:
2029 case RPC_FC_C_WSTRING
:
2030 if (fc
== RPC_FC_C_CSTRING
)
2035 WriteVariance(pStubMsg
);
2037 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2038 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
2040 case RPC_FC_BOGUS_ARRAY
:
2041 alignment
= pFormat
[1] + 1;
2042 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2043 if (IsConformanceOrVariancePresent(pFormat
)) WriteVariance(pStubMsg
);
2044 pFormat
= SkipVariance(pStubMsg
, pFormat
);
2046 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
2048 size
= pStubMsg
->ActualCount
;
2049 for (i
= 0; i
< size
; i
++)
2050 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
2053 ERR("unknown array format 0x%x\n", fc
);
2054 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2058 static inline ULONG
array_read_conformance(
2059 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
2066 esize
= *(const WORD
*)(pFormat
+2);
2067 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2068 return safe_multiply(esize
, pStubMsg
->MaxCount
);
2069 case RPC_FC_CVARRAY
:
2070 esize
= *(const WORD
*)(pFormat
+2);
2071 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2072 return safe_multiply(esize
, pStubMsg
->MaxCount
);
2073 case RPC_FC_C_CSTRING
:
2074 case RPC_FC_C_WSTRING
:
2075 if (fc
== RPC_FC_C_CSTRING
)
2080 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
2081 ReadConformance(pStubMsg
, pFormat
+ 2);
2083 ReadConformance(pStubMsg
, NULL
);
2084 return safe_multiply(esize
, pStubMsg
->MaxCount
);
2085 case RPC_FC_BOGUS_ARRAY
:
2086 def
= *(const WORD
*)(pFormat
+ 2);
2088 if (IsConformanceOrVariancePresent(pFormat
)) pFormat
= ReadConformance(pStubMsg
, pFormat
);
2091 pStubMsg
->MaxCount
= def
;
2092 pFormat
= SkipConformance( pStubMsg
, pFormat
);
2094 pFormat
= SkipVariance( pStubMsg
, pFormat
);
2096 esize
= ComplexStructSize(pStubMsg
, pFormat
);
2097 return safe_multiply(pStubMsg
->MaxCount
, esize
);
2099 ERR("unknown array format 0x%x\n", fc
);
2100 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2104 static inline ULONG
array_read_variance_and_unmarshall(
2105 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char **ppMemory
,
2106 PFORMAT_STRING pFormat
, unsigned char fMustAlloc
,
2107 unsigned char fUseBufferMemoryServer
, unsigned char fUnmarshall
)
2109 ULONG bufsize
, memsize
;
2111 unsigned char alignment
;
2112 unsigned char *saved_buffer
, *pMemory
;
2113 ULONG i
, offset
, count
;
2118 esize
= *(const WORD
*)(pFormat
+2);
2119 alignment
= pFormat
[1] + 1;
2121 bufsize
= memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2123 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2125 align_pointer(&pStubMsg
->Buffer
, alignment
);
2130 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2133 if (fUseBufferMemoryServer
&& !pStubMsg
->IsClient
&& !*ppMemory
)
2134 /* for servers, we just point straight into the RPC buffer */
2135 *ppMemory
= pStubMsg
->Buffer
;
2138 saved_buffer
= pStubMsg
->Buffer
;
2139 safe_buffer_increment(pStubMsg
, bufsize
);
2141 pStubMsg
->BufferMark
= saved_buffer
;
2142 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
2144 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
2145 if (*ppMemory
!= saved_buffer
)
2146 memcpy(*ppMemory
, saved_buffer
, bufsize
);
2149 case RPC_FC_CVARRAY
:
2150 esize
= *(const WORD
*)(pFormat
+2);
2151 alignment
= pFormat
[1] + 1;
2153 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2155 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2157 align_pointer(&pStubMsg
->Buffer
, alignment
);
2159 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2160 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2164 offset
= pStubMsg
->Offset
;
2166 if (!fMustAlloc
&& !*ppMemory
)
2169 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2170 saved_buffer
= pStubMsg
->Buffer
;
2171 safe_buffer_increment(pStubMsg
, bufsize
);
2173 pStubMsg
->BufferMark
= saved_buffer
;
2174 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
,
2177 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
2180 case RPC_FC_C_CSTRING
:
2181 case RPC_FC_C_WSTRING
:
2182 if (fc
== RPC_FC_C_CSTRING
)
2187 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
2189 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
2191 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2192 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
2193 RpcRaiseException(RPC_S_INVALID_BOUND
);
2195 if (pStubMsg
->Offset
)
2197 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2198 RpcRaiseException(RPC_S_INVALID_BOUND
);
2201 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2202 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2204 validate_string_data(pStubMsg
, bufsize
, esize
);
2209 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2212 if (fUseBufferMemoryServer
&& !pStubMsg
->IsClient
&&
2213 !*ppMemory
&& (pStubMsg
->MaxCount
== pStubMsg
->ActualCount
))
2214 /* if the data in the RPC buffer is big enough, we just point
2215 * straight into it */
2216 *ppMemory
= pStubMsg
->Buffer
;
2217 else if (!*ppMemory
)
2218 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2221 if (*ppMemory
== pStubMsg
->Buffer
)
2222 safe_buffer_increment(pStubMsg
, bufsize
);
2224 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
2226 if (*pFormat
== RPC_FC_C_CSTRING
)
2227 TRACE("string=%s\n", debugstr_a((char*)*ppMemory
));
2229 TRACE("string=%s\n", debugstr_w((LPWSTR
)*ppMemory
));
2233 case RPC_FC_BOGUS_ARRAY
:
2234 alignment
= pFormat
[1] + 1;
2235 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2236 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2238 esize
= ComplexStructSize(pStubMsg
, pFormat
);
2239 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2241 assert( fUnmarshall
);
2243 if (!fMustAlloc
&& !*ppMemory
)
2246 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2248 align_pointer(&pStubMsg
->Buffer
, alignment
);
2249 saved_buffer
= pStubMsg
->Buffer
;
2251 pMemory
= *ppMemory
;
2252 count
= pStubMsg
->ActualCount
;
2253 for (i
= 0; i
< count
; i
++)
2254 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
, fMustAlloc
);
2255 return pStubMsg
->Buffer
- saved_buffer
;
2258 ERR("unknown array format 0x%x\n", fc
);
2259 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2263 static inline void array_memory_size(
2264 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
,
2265 unsigned char fHasPointers
)
2267 ULONG i
, count
, SavedMemorySize
;
2268 ULONG bufsize
, memsize
;
2270 unsigned char alignment
;
2275 esize
= *(const WORD
*)(pFormat
+2);
2276 alignment
= pFormat
[1] + 1;
2278 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2280 bufsize
= memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2281 pStubMsg
->MemorySize
+= memsize
;
2283 align_pointer(&pStubMsg
->Buffer
, alignment
);
2285 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2286 safe_buffer_increment(pStubMsg
, bufsize
);
2289 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2291 case RPC_FC_CVARRAY
:
2292 esize
= *(const WORD
*)(pFormat
+2);
2293 alignment
= pFormat
[1] + 1;
2295 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2297 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2299 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2300 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2301 pStubMsg
->MemorySize
+= memsize
;
2303 align_pointer(&pStubMsg
->Buffer
, alignment
);
2305 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2306 safe_buffer_increment(pStubMsg
, bufsize
);
2309 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2311 case RPC_FC_C_CSTRING
:
2312 case RPC_FC_C_WSTRING
:
2313 if (fc
== RPC_FC_C_CSTRING
)
2318 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
2320 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
2322 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2323 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
2324 RpcRaiseException(RPC_S_INVALID_BOUND
);
2326 if (pStubMsg
->Offset
)
2328 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2329 RpcRaiseException(RPC_S_INVALID_BOUND
);
2332 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2333 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2335 validate_string_data(pStubMsg
, bufsize
, esize
);
2337 safe_buffer_increment(pStubMsg
, bufsize
);
2338 pStubMsg
->MemorySize
+= memsize
;
2340 case RPC_FC_BOGUS_ARRAY
:
2341 alignment
= pFormat
[1] + 1;
2342 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2343 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2345 align_pointer(&pStubMsg
->Buffer
, alignment
);
2347 SavedMemorySize
= pStubMsg
->MemorySize
;
2349 esize
= ComplexStructSize(pStubMsg
, pFormat
);
2350 memsize
= safe_multiply(pStubMsg
->MaxCount
, esize
);
2352 count
= pStubMsg
->ActualCount
;
2353 for (i
= 0; i
< count
; i
++)
2354 ComplexStructMemorySize(pStubMsg
, pFormat
, NULL
);
2356 pStubMsg
->MemorySize
= SavedMemorySize
+ memsize
;
2359 ERR("unknown array format 0x%x\n", fc
);
2360 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2364 static inline void array_free(
2365 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
,
2366 unsigned char *pMemory
, PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
2373 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2375 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2377 case RPC_FC_CVARRAY
:
2378 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2379 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2381 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2383 case RPC_FC_C_CSTRING
:
2384 case RPC_FC_C_WSTRING
:
2385 /* No embedded pointers so nothing to do */
2387 case RPC_FC_BOGUS_ARRAY
:
2388 count
= *(const WORD
*)(pFormat
+ 2);
2389 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, count
);
2390 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
2392 count
= pStubMsg
->ActualCount
;
2393 for (i
= 0; i
< count
; i
++)
2394 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
2397 ERR("unknown array format 0x%x\n", fc
);
2398 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2403 * NdrConformantString:
2405 * What MS calls a ConformantString is, in DCE terminology,
2406 * a Varying-Conformant String.
2408 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2409 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2410 * into unmarshalled string)
2411 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2413 * data: CHARTYPE[maxlen]
2415 * ], where CHARTYPE is the appropriate character type (specified externally)
2419 /***********************************************************************
2420 * NdrConformantStringMarshall [RPCRT4.@]
2422 unsigned char *WINAPI
NdrConformantStringMarshall(MIDL_STUB_MESSAGE
*pStubMsg
,
2423 unsigned char *pszMessage
, PFORMAT_STRING pFormat
)
2425 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg
, pszMessage
, pFormat
);
2427 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2428 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2429 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2432 /* allow compiler to optimise inline function by passing constant into
2433 * these functions */
2434 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2435 array_compute_and_write_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pszMessage
,
2437 array_write_variance_and_marshall(RPC_FC_C_CSTRING
, pStubMsg
, pszMessage
,
2438 pFormat
, TRUE
/* fHasPointers */);
2440 array_compute_and_write_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pszMessage
,
2442 array_write_variance_and_marshall(RPC_FC_C_WSTRING
, pStubMsg
, pszMessage
,
2443 pFormat
, TRUE
/* fHasPointers */);
2449 /***********************************************************************
2450 * NdrConformantStringBufferSize [RPCRT4.@]
2452 void WINAPI
NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2453 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
2455 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2457 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2458 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2459 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2462 /* allow compiler to optimise inline function by passing constant into
2463 * these functions */
2464 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2465 array_compute_and_size_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pMemory
,
2467 array_buffer_size(RPC_FC_C_CSTRING
, pStubMsg
, pMemory
, pFormat
,
2468 TRUE
/* fHasPointers */);
2470 array_compute_and_size_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pMemory
,
2472 array_buffer_size(RPC_FC_C_WSTRING
, pStubMsg
, pMemory
, pFormat
,
2473 TRUE
/* fHasPointers */);
2477 /************************************************************************
2478 * NdrConformantStringMemorySize [RPCRT4.@]
2480 ULONG WINAPI
NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
2481 PFORMAT_STRING pFormat
)
2483 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
2485 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2486 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2487 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2490 /* allow compiler to optimise inline function by passing constant into
2491 * these functions */
2492 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2493 array_read_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
);
2494 array_memory_size(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
,
2495 TRUE
/* fHasPointers */);
2497 array_read_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
);
2498 array_memory_size(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
,
2499 TRUE
/* fHasPointers */);
2502 return pStubMsg
->MemorySize
;
2505 /************************************************************************
2506 * NdrConformantStringUnmarshall [RPCRT4.@]
2508 unsigned char *WINAPI
NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2509 unsigned char** ppMemory
, PFORMAT_STRING pFormat
, unsigned char fMustAlloc
)
2511 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2512 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
2514 if (pFormat
[0] != RPC_FC_C_CSTRING
&& pFormat
[0] != RPC_FC_C_WSTRING
) {
2515 ERR("Unhandled string type: %#x\n", *pFormat
);
2516 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2519 /* allow compiler to optimise inline function by passing constant into
2520 * these functions */
2521 if (pFormat
[0] == RPC_FC_C_CSTRING
) {
2522 array_read_conformance(RPC_FC_C_CSTRING
, pStubMsg
, pFormat
);
2523 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING
, pStubMsg
, ppMemory
,
2524 pFormat
, fMustAlloc
,
2525 TRUE
/* fUseBufferMemoryServer */,
2526 TRUE
/* fUnmarshall */);
2528 array_read_conformance(RPC_FC_C_WSTRING
, pStubMsg
, pFormat
);
2529 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING
, pStubMsg
, ppMemory
,
2530 pFormat
, fMustAlloc
,
2531 TRUE
/* fUseBufferMemoryServer */,
2532 TRUE
/* fUnmarshall */);
2538 /***********************************************************************
2539 * NdrNonConformantStringMarshall [RPCRT4.@]
2541 unsigned char * WINAPI
NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2542 unsigned char *pMemory
,
2543 PFORMAT_STRING pFormat
)
2545 ULONG esize
, size
, maxsize
;
2547 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2549 maxsize
= *(const USHORT
*)&pFormat
[2];
2551 if (*pFormat
== RPC_FC_CSTRING
)
2554 const char *str
= (const char *)pMemory
;
2555 while (i
< maxsize
&& str
[i
]) i
++;
2556 TRACE("string=%s\n", debugstr_an(str
, i
));
2557 pStubMsg
->ActualCount
= i
+ 1;
2560 else if (*pFormat
== RPC_FC_WSTRING
)
2563 const WCHAR
*str
= (const WCHAR
*)pMemory
;
2564 while (i
< maxsize
&& str
[i
]) i
++;
2565 TRACE("string=%s\n", debugstr_wn(str
, i
));
2566 pStubMsg
->ActualCount
= i
+ 1;
2571 ERR("Unhandled string type: %#x\n", *pFormat
);
2572 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2575 pStubMsg
->Offset
= 0;
2576 WriteVariance(pStubMsg
);
2578 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2579 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
2584 /***********************************************************************
2585 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2587 unsigned char * WINAPI
NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2588 unsigned char **ppMemory
,
2589 PFORMAT_STRING pFormat
,
2590 unsigned char fMustAlloc
)
2592 ULONG bufsize
, memsize
, esize
, maxsize
;
2594 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2595 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
2597 maxsize
= *(const USHORT
*)&pFormat
[2];
2599 ReadVariance(pStubMsg
, NULL
, maxsize
);
2600 if (pStubMsg
->Offset
)
2602 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2603 RpcRaiseException(RPC_S_INVALID_BOUND
);
2606 if (*pFormat
== RPC_FC_CSTRING
) esize
= 1;
2607 else if (*pFormat
== RPC_FC_WSTRING
) esize
= 2;
2610 ERR("Unhandled string type: %#x\n", *pFormat
);
2611 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2614 memsize
= esize
* maxsize
;
2615 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2617 validate_string_data(pStubMsg
, bufsize
, esize
);
2619 if (!fMustAlloc
&& !*ppMemory
)
2622 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2624 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
2626 if (*pFormat
== RPC_FC_CSTRING
) {
2627 TRACE("string=%s\n", debugstr_an((char*)*ppMemory
, pStubMsg
->ActualCount
));
2629 else if (*pFormat
== RPC_FC_WSTRING
) {
2630 TRACE("string=%s\n", debugstr_wn((LPWSTR
)*ppMemory
, pStubMsg
->ActualCount
));
2636 /***********************************************************************
2637 * NdrNonConformantStringBufferSize [RPCRT4.@]
2639 void WINAPI
NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2640 unsigned char *pMemory
,
2641 PFORMAT_STRING pFormat
)
2643 ULONG esize
, maxsize
;
2645 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2647 maxsize
= *(const USHORT
*)&pFormat
[2];
2649 SizeVariance(pStubMsg
);
2651 if (*pFormat
== RPC_FC_CSTRING
)
2654 const char *str
= (const char *)pMemory
;
2655 while (i
< maxsize
&& str
[i
]) i
++;
2656 TRACE("string=%s\n", debugstr_an(str
, i
));
2657 pStubMsg
->ActualCount
= i
+ 1;
2660 else if (*pFormat
== RPC_FC_WSTRING
)
2663 const WCHAR
*str
= (const WCHAR
*)pMemory
;
2664 while (i
< maxsize
&& str
[i
]) i
++;
2665 TRACE("string=%s\n", debugstr_wn(str
, i
));
2666 pStubMsg
->ActualCount
= i
+ 1;
2671 ERR("Unhandled string type: %#x\n", *pFormat
);
2672 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2675 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
2678 /***********************************************************************
2679 * NdrNonConformantStringMemorySize [RPCRT4.@]
2681 ULONG WINAPI
NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2682 PFORMAT_STRING pFormat
)
2684 ULONG bufsize
, memsize
, esize
, maxsize
;
2686 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
2688 maxsize
= *(const USHORT
*)&pFormat
[2];
2690 ReadVariance(pStubMsg
, NULL
, maxsize
);
2692 if (pStubMsg
->Offset
)
2694 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2695 RpcRaiseException(RPC_S_INVALID_BOUND
);
2698 if (*pFormat
== RPC_FC_CSTRING
) esize
= 1;
2699 else if (*pFormat
== RPC_FC_WSTRING
) esize
= 2;
2702 ERR("Unhandled string type: %#x\n", *pFormat
);
2703 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2706 memsize
= esize
* maxsize
;
2707 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2709 validate_string_data(pStubMsg
, bufsize
, esize
);
2711 safe_buffer_increment(pStubMsg
, bufsize
);
2712 pStubMsg
->MemorySize
+= memsize
;
2714 return pStubMsg
->MemorySize
;
2719 #include "pshpack1.h"
2723 unsigned char flags_type
; /* flags in upper nibble, type in lower nibble */
2727 #include "poppack.h"
2729 static ULONG
EmbeddedComplexSize(MIDL_STUB_MESSAGE
*pStubMsg
,
2730 PFORMAT_STRING pFormat
)
2734 case RPC_FC_PSTRUCT
:
2735 case RPC_FC_CSTRUCT
:
2736 case RPC_FC_BOGUS_STRUCT
:
2737 case RPC_FC_SMFARRAY
:
2738 case RPC_FC_SMVARRAY
:
2739 case RPC_FC_CSTRING
:
2740 return *(const WORD
*)&pFormat
[2];
2741 case RPC_FC_USER_MARSHAL
:
2742 return *(const WORD
*)&pFormat
[4];
2743 case RPC_FC_RANGE
: {
2744 switch (((const NDR_RANGE
*)pFormat
)->flags_type
& 0xf) {
2749 return sizeof(UCHAR
);
2753 return sizeof(USHORT
);
2757 case RPC_FC_INT3264
:
2758 case RPC_FC_UINT3264
:
2759 return sizeof(ULONG
);
2761 return sizeof(float);
2763 return sizeof(double);
2765 return sizeof(ULONGLONG
);
2767 return sizeof(UINT
);
2769 ERR("unknown type 0x%x\n", ((const NDR_RANGE
*)pFormat
)->flags_type
& 0xf);
2770 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2773 case RPC_FC_NON_ENCAPSULATED_UNION
:
2775 pFormat
= SkipConformance(pStubMsg
, pFormat
);
2776 pFormat
+= *(const SHORT
*)pFormat
;
2777 return *(const SHORT
*)pFormat
;
2779 return sizeof(void *);
2780 case RPC_FC_WSTRING
:
2781 return *(const WORD
*)&pFormat
[2] * 2;
2783 FIXME("unhandled embedded type %02x\n", *pFormat
);
2789 static ULONG
EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2790 PFORMAT_STRING pFormat
)
2792 NDR_MEMORYSIZE m
= NdrMemorySizer
[*pFormat
& NDR_TABLE_MASK
];
2796 FIXME("no memorysizer for data type=%02x\n", *pFormat
);
2800 return m(pStubMsg
, pFormat
);
2804 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2805 unsigned char *pMemory
,
2806 PFORMAT_STRING pFormat
,
2807 PFORMAT_STRING pPointer
)
2809 PFORMAT_STRING desc
;
2813 while (*pFormat
!= RPC_FC_END
) {
2819 TRACE("byte=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2820 safe_copy_to_buffer(pStubMsg
, pMemory
, 1);
2826 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2827 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
2832 USHORT val
= *(DWORD
*)pMemory
;
2833 TRACE("enum16=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2834 if (32767 < *(DWORD
*)pMemory
)
2835 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
2836 safe_copy_to_buffer(pStubMsg
, &val
, 2);
2843 TRACE("long=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2844 safe_copy_to_buffer(pStubMsg
, pMemory
, 4);
2847 case RPC_FC_INT3264
:
2848 case RPC_FC_UINT3264
:
2850 UINT val
= *(UINT_PTR
*)pMemory
;
2851 TRACE("int3264=%ld <= %p\n", *(UINT_PTR
*)pMemory
, pMemory
);
2852 safe_copy_to_buffer(pStubMsg
, &val
, sizeof(UINT
));
2853 pMemory
+= sizeof(UINT_PTR
);
2857 TRACE("float=%f <= %p\n", *(float*)pMemory
, pMemory
);
2858 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
2859 pMemory
+= sizeof(float);
2862 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2863 safe_copy_to_buffer(pStubMsg
, pMemory
, 8);
2867 TRACE("double=%f <= %p\n", *(double*)pMemory
, pMemory
);
2868 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
2869 pMemory
+= sizeof(double);
2875 case RPC_FC_POINTER
:
2877 unsigned char *saved_buffer
;
2878 BOOL pointer_buffer_mark_set
= FALSE
;
2879 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
2880 TRACE("pStubMsg->Buffer before %p\n", pStubMsg
->Buffer
);
2881 if (*pFormat
!= RPC_FC_POINTER
)
2883 if (*pPointer
!= RPC_FC_RP
)
2884 align_pointer_clear(&pStubMsg
->Buffer
, 4);
2885 saved_buffer
= pStubMsg
->Buffer
;
2886 if (pStubMsg
->PointerBufferMark
)
2888 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2889 pStubMsg
->PointerBufferMark
= NULL
;
2890 pointer_buffer_mark_set
= TRUE
;
2892 else if (*pPointer
!= RPC_FC_RP
)
2893 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2894 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char**)pMemory
, pPointer
);
2895 if (pointer_buffer_mark_set
)
2897 STD_OVERFLOW_CHECK(pStubMsg
);
2898 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2899 pStubMsg
->Buffer
= saved_buffer
;
2900 if (*pPointer
!= RPC_FC_RP
)
2901 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2903 TRACE("pStubMsg->Buffer after %p\n", pStubMsg
->Buffer
);
2904 if (*pFormat
== RPC_FC_POINTER
)
2908 pMemory
+= sizeof(void *);
2911 case RPC_FC_ALIGNM2
:
2912 align_pointer(&pMemory
, 2);
2914 case RPC_FC_ALIGNM4
:
2915 align_pointer(&pMemory
, 4);
2917 case RPC_FC_ALIGNM8
:
2918 align_pointer(&pMemory
, 8);
2920 case RPC_FC_STRUCTPAD1
:
2921 case RPC_FC_STRUCTPAD2
:
2922 case RPC_FC_STRUCTPAD3
:
2923 case RPC_FC_STRUCTPAD4
:
2924 case RPC_FC_STRUCTPAD5
:
2925 case RPC_FC_STRUCTPAD6
:
2926 case RPC_FC_STRUCTPAD7
:
2927 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2929 case RPC_FC_EMBEDDED_COMPLEX
:
2930 pMemory
+= pFormat
[1];
2932 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2933 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2934 TRACE("embedded complex (size=%d) <= %p\n", size
, pMemory
);
2935 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
2938 /* for some reason interface pointers aren't generated as
2939 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2940 * they still need the derefencing treatment that pointers are
2942 if (*desc
== RPC_FC_IP
)
2943 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2945 m(pStubMsg
, pMemory
, desc
);
2947 else FIXME("no marshaller for embedded type %02x\n", *desc
);
2954 FIXME("unhandled format 0x%02x\n", *pFormat
);
2962 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2963 unsigned char *pMemory
,
2964 PFORMAT_STRING pFormat
,
2965 PFORMAT_STRING pPointer
,
2966 unsigned char fMustAlloc
)
2968 PFORMAT_STRING desc
;
2972 while (*pFormat
!= RPC_FC_END
) {
2978 safe_copy_from_buffer(pStubMsg
, pMemory
, 1);
2979 TRACE("byte=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2985 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
2986 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2992 safe_copy_from_buffer(pStubMsg
, &val
, 2);
2993 *(DWORD
*)pMemory
= val
;
2994 TRACE("enum16=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
2995 if (32767 < *(DWORD
*)pMemory
)
2996 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
3003 safe_copy_from_buffer(pStubMsg
, pMemory
, 4);
3004 TRACE("long=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
3007 case RPC_FC_INT3264
:
3010 safe_copy_from_buffer(pStubMsg
, &val
, 4);
3011 *(INT_PTR
*)pMemory
= val
;
3012 TRACE("int3264=%ld => %p\n", *(INT_PTR
*)pMemory
, pMemory
);
3013 pMemory
+= sizeof(INT_PTR
);
3016 case RPC_FC_UINT3264
:
3019 safe_copy_from_buffer(pStubMsg
, &val
, 4);
3020 *(UINT_PTR
*)pMemory
= val
;
3021 TRACE("uint3264=%ld => %p\n", *(UINT_PTR
*)pMemory
, pMemory
);
3022 pMemory
+= sizeof(UINT_PTR
);
3026 safe_copy_from_buffer(pStubMsg
, pMemory
, sizeof(float));
3027 TRACE("float=%f => %p\n", *(float*)pMemory
, pMemory
);
3028 pMemory
+= sizeof(float);
3031 safe_copy_from_buffer(pStubMsg
, pMemory
, 8);
3032 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
3036 safe_copy_from_buffer(pStubMsg
, pMemory
, sizeof(double));
3037 TRACE("double=%f => %p\n", *(double*)pMemory
, pMemory
);
3038 pMemory
+= sizeof(double);
3044 case RPC_FC_POINTER
:
3046 unsigned char *saved_buffer
;
3047 BOOL pointer_buffer_mark_set
= FALSE
;
3048 TRACE("pointer => %p\n", pMemory
);
3049 if (*pFormat
!= RPC_FC_POINTER
)
3051 if (*pPointer
!= RPC_FC_RP
)
3052 align_pointer(&pStubMsg
->Buffer
, 4);
3053 saved_buffer
= pStubMsg
->Buffer
;
3054 if (pStubMsg
->PointerBufferMark
)
3056 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3057 pStubMsg
->PointerBufferMark
= NULL
;
3058 pointer_buffer_mark_set
= TRUE
;
3060 else if (*pPointer
!= RPC_FC_RP
)
3061 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3063 PointerUnmarshall(pStubMsg
, saved_buffer
, (unsigned char**)pMemory
, *(unsigned char**)pMemory
, pPointer
, fMustAlloc
);
3064 if (pointer_buffer_mark_set
)
3066 STD_OVERFLOW_CHECK(pStubMsg
);
3067 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3068 pStubMsg
->Buffer
= saved_buffer
;
3069 if (*pPointer
!= RPC_FC_RP
)
3070 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3072 if (*pFormat
== RPC_FC_POINTER
)
3076 pMemory
+= sizeof(void *);
3079 case RPC_FC_ALIGNM2
:
3080 align_pointer_clear(&pMemory
, 2);
3082 case RPC_FC_ALIGNM4
:
3083 align_pointer_clear(&pMemory
, 4);
3085 case RPC_FC_ALIGNM8
:
3086 align_pointer_clear(&pMemory
, 8);
3088 case RPC_FC_STRUCTPAD1
:
3089 case RPC_FC_STRUCTPAD2
:
3090 case RPC_FC_STRUCTPAD3
:
3091 case RPC_FC_STRUCTPAD4
:
3092 case RPC_FC_STRUCTPAD5
:
3093 case RPC_FC_STRUCTPAD6
:
3094 case RPC_FC_STRUCTPAD7
:
3095 memset(pMemory
, 0, *pFormat
- RPC_FC_STRUCTPAD1
+ 1);
3096 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3098 case RPC_FC_EMBEDDED_COMPLEX
:
3099 pMemory
+= pFormat
[1];
3101 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3102 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3103 TRACE("embedded complex (size=%d) => %p\n", size
, pMemory
);
3105 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
3106 * since the type is part of the memory block that is encompassed by
3107 * the whole complex type. Memory is forced to allocate when pointers
3108 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
3109 * clearing the memory we pass in to the unmarshaller */
3110 memset(pMemory
, 0, size
);
3111 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
3114 /* for some reason interface pointers aren't generated as
3115 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3116 * they still need the derefencing treatment that pointers are
3118 if (*desc
== RPC_FC_IP
)
3119 m(pStubMsg
, (unsigned char **)pMemory
, desc
, FALSE
);
3121 m(pStubMsg
, &pMemory
, desc
, FALSE
);
3123 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
3130 FIXME("unhandled format %d\n", *pFormat
);
3138 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3139 unsigned char *pMemory
,
3140 PFORMAT_STRING pFormat
,
3141 PFORMAT_STRING pPointer
)
3143 PFORMAT_STRING desc
;
3147 while (*pFormat
!= RPC_FC_END
) {
3153 safe_buffer_length_increment(pStubMsg
, 1);
3159 safe_buffer_length_increment(pStubMsg
, 2);
3163 safe_buffer_length_increment(pStubMsg
, 2);
3170 safe_buffer_length_increment(pStubMsg
, 4);
3173 case RPC_FC_INT3264
:
3174 case RPC_FC_UINT3264
:
3175 safe_buffer_length_increment(pStubMsg
, 4);
3176 pMemory
+= sizeof(INT_PTR
);
3180 safe_buffer_length_increment(pStubMsg
, 8);
3187 case RPC_FC_POINTER
:
3188 if (*pFormat
!= RPC_FC_POINTER
)
3190 if (!pStubMsg
->IgnoreEmbeddedPointers
)
3192 int saved_buffer_length
= pStubMsg
->BufferLength
;
3193 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3194 pStubMsg
->PointerLength
= 0;
3195 if(!pStubMsg
->BufferLength
)
3196 ERR("BufferLength == 0??\n");
3197 PointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
3198 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3199 pStubMsg
->BufferLength
= saved_buffer_length
;
3201 if (*pPointer
!= RPC_FC_RP
)
3203 align_length(&pStubMsg
->BufferLength
, 4);
3204 safe_buffer_length_increment(pStubMsg
, 4);
3206 if (*pFormat
== RPC_FC_POINTER
)
3210 pMemory
+= sizeof(void*);
3212 case RPC_FC_ALIGNM2
:
3213 align_pointer(&pMemory
, 2);
3215 case RPC_FC_ALIGNM4
:
3216 align_pointer(&pMemory
, 4);
3218 case RPC_FC_ALIGNM8
:
3219 align_pointer(&pMemory
, 8);
3221 case RPC_FC_STRUCTPAD1
:
3222 case RPC_FC_STRUCTPAD2
:
3223 case RPC_FC_STRUCTPAD3
:
3224 case RPC_FC_STRUCTPAD4
:
3225 case RPC_FC_STRUCTPAD5
:
3226 case RPC_FC_STRUCTPAD6
:
3227 case RPC_FC_STRUCTPAD7
:
3228 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3230 case RPC_FC_EMBEDDED_COMPLEX
:
3231 pMemory
+= pFormat
[1];
3233 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3234 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3235 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
3238 /* for some reason interface pointers aren't generated as
3239 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3240 * they still need the derefencing treatment that pointers are
3242 if (*desc
== RPC_FC_IP
)
3243 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
3245 m(pStubMsg
, pMemory
, desc
);
3247 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
3254 FIXME("unhandled format 0x%02x\n", *pFormat
);
3262 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
3263 unsigned char *pMemory
,
3264 PFORMAT_STRING pFormat
,
3265 PFORMAT_STRING pPointer
)
3267 PFORMAT_STRING desc
;
3271 while (*pFormat
!= RPC_FC_END
) {
3291 case RPC_FC_INT3264
:
3292 case RPC_FC_UINT3264
:
3293 pMemory
+= sizeof(INT_PTR
);
3303 case RPC_FC_POINTER
:
3304 if (*pFormat
!= RPC_FC_POINTER
)
3306 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
3307 if (*pFormat
== RPC_FC_POINTER
)
3311 pMemory
+= sizeof(void *);
3313 case RPC_FC_ALIGNM2
:
3314 align_pointer(&pMemory
, 2);
3316 case RPC_FC_ALIGNM4
:
3317 align_pointer(&pMemory
, 4);
3319 case RPC_FC_ALIGNM8
:
3320 align_pointer(&pMemory
, 8);
3322 case RPC_FC_STRUCTPAD1
:
3323 case RPC_FC_STRUCTPAD2
:
3324 case RPC_FC_STRUCTPAD3
:
3325 case RPC_FC_STRUCTPAD4
:
3326 case RPC_FC_STRUCTPAD5
:
3327 case RPC_FC_STRUCTPAD6
:
3328 case RPC_FC_STRUCTPAD7
:
3329 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3331 case RPC_FC_EMBEDDED_COMPLEX
:
3332 pMemory
+= pFormat
[1];
3334 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3335 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3336 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
3339 /* for some reason interface pointers aren't generated as
3340 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3341 * they still need the derefencing treatment that pointers are
3343 if (*desc
== RPC_FC_IP
)
3344 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
3346 m(pStubMsg
, pMemory
, desc
);
3354 FIXME("unhandled format 0x%02x\n", *pFormat
);
3362 static ULONG
ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3363 PFORMAT_STRING pFormat
,
3364 PFORMAT_STRING pPointer
)
3366 PFORMAT_STRING desc
;
3369 while (*pFormat
!= RPC_FC_END
) {
3376 safe_buffer_increment(pStubMsg
, 1);
3382 safe_buffer_increment(pStubMsg
, 2);
3386 safe_buffer_increment(pStubMsg
, 2);
3393 safe_buffer_increment(pStubMsg
, 4);
3395 case RPC_FC_INT3264
:
3396 case RPC_FC_UINT3264
:
3397 size
+= sizeof(INT_PTR
);
3398 safe_buffer_increment(pStubMsg
, 4);
3403 safe_buffer_increment(pStubMsg
, 8);
3409 case RPC_FC_POINTER
:
3411 unsigned char *saved_buffer
;
3412 BOOL pointer_buffer_mark_set
= FALSE
;
3413 if (*pFormat
!= RPC_FC_POINTER
)
3415 if (*pPointer
!= RPC_FC_RP
)
3416 align_pointer(&pStubMsg
->Buffer
, 4);
3417 saved_buffer
= pStubMsg
->Buffer
;
3418 if (pStubMsg
->PointerBufferMark
)
3420 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3421 pStubMsg
->PointerBufferMark
= NULL
;
3422 pointer_buffer_mark_set
= TRUE
;
3424 else if (*pPointer
!= RPC_FC_RP
)
3425 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3427 if (!pStubMsg
->IgnoreEmbeddedPointers
)
3428 PointerMemorySize(pStubMsg
, saved_buffer
, pPointer
);
3429 if (pointer_buffer_mark_set
)
3431 STD_OVERFLOW_CHECK(pStubMsg
);
3432 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3433 pStubMsg
->Buffer
= saved_buffer
;
3434 if (*pPointer
!= RPC_FC_RP
)
3435 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3437 if (*pFormat
== RPC_FC_POINTER
)
3441 size
+= sizeof(void *);
3444 case RPC_FC_ALIGNM2
:
3445 align_length(&size
, 2);
3447 case RPC_FC_ALIGNM4
:
3448 align_length(&size
, 4);
3450 case RPC_FC_ALIGNM8
:
3451 align_length(&size
, 8);
3453 case RPC_FC_STRUCTPAD1
:
3454 case RPC_FC_STRUCTPAD2
:
3455 case RPC_FC_STRUCTPAD3
:
3456 case RPC_FC_STRUCTPAD4
:
3457 case RPC_FC_STRUCTPAD5
:
3458 case RPC_FC_STRUCTPAD6
:
3459 case RPC_FC_STRUCTPAD7
:
3460 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3462 case RPC_FC_EMBEDDED_COMPLEX
:
3465 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3466 size
+= EmbeddedComplexMemorySize(pStubMsg
, desc
);
3472 FIXME("unhandled format 0x%02x\n", *pFormat
);
3480 ULONG
ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
3482 PFORMAT_STRING desc
;
3485 while (*pFormat
!= RPC_FC_END
) {
3505 case RPC_FC_INT3264
:
3506 case RPC_FC_UINT3264
:
3507 size
+= sizeof(INT_PTR
);
3517 case RPC_FC_POINTER
:
3518 size
+= sizeof(void *);
3519 if (*pFormat
!= RPC_FC_POINTER
)
3522 case RPC_FC_ALIGNM2
:
3523 align_length(&size
, 2);
3525 case RPC_FC_ALIGNM4
:
3526 align_length(&size
, 4);
3528 case RPC_FC_ALIGNM8
:
3529 align_length(&size
, 8);
3531 case RPC_FC_STRUCTPAD1
:
3532 case RPC_FC_STRUCTPAD2
:
3533 case RPC_FC_STRUCTPAD3
:
3534 case RPC_FC_STRUCTPAD4
:
3535 case RPC_FC_STRUCTPAD5
:
3536 case RPC_FC_STRUCTPAD6
:
3537 case RPC_FC_STRUCTPAD7
:
3538 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
3540 case RPC_FC_EMBEDDED_COMPLEX
:
3543 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3544 size
+= EmbeddedComplexSize(pStubMsg
, desc
);
3550 FIXME("unhandled format 0x%02x\n", *pFormat
);
3558 /***********************************************************************
3559 * NdrComplexStructMarshall [RPCRT4.@]
3561 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3562 unsigned char *pMemory
,
3563 PFORMAT_STRING pFormat
)
3565 PFORMAT_STRING conf_array
= NULL
;
3566 PFORMAT_STRING pointer_desc
= NULL
;
3567 unsigned char *OldMemory
= pStubMsg
->Memory
;
3568 BOOL pointer_buffer_mark_set
= FALSE
;
3570 ULONG max_count
= 0;
3573 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3575 if (!pStubMsg
->PointerBufferMark
)
3577 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3578 /* save buffer length */
3579 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
3581 /* get the buffer pointer after complex array data, but before
3583 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
;
3584 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3585 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
3586 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3588 /* save it for use by embedded pointer code later */
3589 pStubMsg
->PointerBufferMark
= (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
;
3590 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->PointerBufferMark
- pStubMsg
->Buffer
));
3591 pointer_buffer_mark_set
= TRUE
;
3593 /* restore the original buffer length */
3594 pStubMsg
->BufferLength
= saved_buffer_length
;
3597 align_pointer_clear(&pStubMsg
->Buffer
, pFormat
[1] + 1);
3600 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3602 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3605 pStubMsg
->Memory
= pMemory
;
3609 ULONG struct_size
= ComplexStructSize(pStubMsg
, pFormat
);
3610 array_compute_and_write_conformance(conf_array
[0], pStubMsg
,
3611 pMemory
+ struct_size
, conf_array
);
3612 /* these could be changed in ComplexMarshall so save them for later */
3613 max_count
= pStubMsg
->MaxCount
;
3614 count
= pStubMsg
->ActualCount
;
3615 offset
= pStubMsg
->Offset
;
3618 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3622 pStubMsg
->MaxCount
= max_count
;
3623 pStubMsg
->ActualCount
= count
;
3624 pStubMsg
->Offset
= offset
;
3625 array_write_variance_and_marshall(conf_array
[0], pStubMsg
, pMemory
,
3626 conf_array
, TRUE
/* fHasPointers */);
3629 pStubMsg
->Memory
= OldMemory
;
3631 if (pointer_buffer_mark_set
)
3633 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3634 pStubMsg
->PointerBufferMark
= NULL
;
3637 STD_OVERFLOW_CHECK(pStubMsg
);
3642 /***********************************************************************
3643 * NdrComplexStructUnmarshall [RPCRT4.@]
3645 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3646 unsigned char **ppMemory
,
3647 PFORMAT_STRING pFormat
,
3648 unsigned char fMustAlloc
)
3650 unsigned size
= *(const WORD
*)(pFormat
+2);
3651 PFORMAT_STRING conf_array
= NULL
;
3652 PFORMAT_STRING pointer_desc
= NULL
;
3653 unsigned char *pMemory
;
3654 BOOL pointer_buffer_mark_set
= FALSE
;
3656 ULONG max_count
= 0;
3658 ULONG array_size
= 0;
3660 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3662 if (!pStubMsg
->PointerBufferMark
)
3664 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3665 /* save buffer pointer */
3666 unsigned char *saved_buffer
= pStubMsg
->Buffer
;
3668 /* get the buffer pointer after complex array data, but before
3670 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3671 NdrComplexStructMemorySize(pStubMsg
, pFormat
);
3672 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3674 /* save it for use by embedded pointer code later */
3675 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3676 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->PointerBufferMark
- saved_buffer
));
3677 pointer_buffer_mark_set
= TRUE
;
3679 /* restore the original buffer */
3680 pStubMsg
->Buffer
= saved_buffer
;
3683 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
3686 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3688 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3693 array_size
= array_read_conformance(conf_array
[0], pStubMsg
, conf_array
);
3696 /* these could be changed in ComplexMarshall so save them for later */
3697 max_count
= pStubMsg
->MaxCount
;
3698 count
= pStubMsg
->ActualCount
;
3699 offset
= pStubMsg
->Offset
;
3702 if (!fMustAlloc
&& !*ppMemory
)
3705 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3707 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
, fMustAlloc
);
3711 pStubMsg
->MaxCount
= max_count
;
3712 pStubMsg
->ActualCount
= count
;
3713 pStubMsg
->Offset
= offset
;
3715 memset(pMemory
, 0, array_size
);
3716 array_read_variance_and_unmarshall(conf_array
[0], pStubMsg
, &pMemory
,
3718 FALSE
/* fUseBufferMemoryServer */,
3719 TRUE
/* fUnmarshall */);
3722 if (pointer_buffer_mark_set
)
3724 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3725 pStubMsg
->PointerBufferMark
= NULL
;
3731 /***********************************************************************
3732 * NdrComplexStructBufferSize [RPCRT4.@]
3734 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3735 unsigned char *pMemory
,
3736 PFORMAT_STRING pFormat
)
3738 PFORMAT_STRING conf_array
= NULL
;
3739 PFORMAT_STRING pointer_desc
= NULL
;
3740 unsigned char *OldMemory
= pStubMsg
->Memory
;
3741 int pointer_length_set
= 0;
3743 ULONG max_count
= 0;
3746 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3748 align_length(&pStubMsg
->BufferLength
, pFormat
[1] + 1);
3750 if(!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
3752 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3753 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
3755 /* get the buffer length after complex struct data, but before
3757 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3758 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
3759 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3761 /* save it for use by embedded pointer code later */
3762 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3763 pointer_length_set
= 1;
3764 TRACE("difference = 0x%x\n", pStubMsg
->PointerLength
- saved_buffer_length
);
3766 /* restore the original buffer length */
3767 pStubMsg
->BufferLength
= saved_buffer_length
;
3771 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3773 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3776 pStubMsg
->Memory
= pMemory
;
3780 ULONG struct_size
= ComplexStructSize(pStubMsg
, pFormat
);
3781 array_compute_and_size_conformance(conf_array
[0], pStubMsg
, pMemory
+ struct_size
,
3784 /* these could be changed in ComplexMarshall so save them for later */
3785 max_count
= pStubMsg
->MaxCount
;
3786 count
= pStubMsg
->ActualCount
;
3787 offset
= pStubMsg
->Offset
;
3790 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3794 pStubMsg
->MaxCount
= max_count
;
3795 pStubMsg
->ActualCount
= count
;
3796 pStubMsg
->Offset
= offset
;
3797 array_buffer_size(conf_array
[0], pStubMsg
, pMemory
, conf_array
,
3798 TRUE
/* fHasPointers */);
3801 pStubMsg
->Memory
= OldMemory
;
3803 if(pointer_length_set
)
3805 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3806 pStubMsg
->PointerLength
= 0;
3811 /***********************************************************************
3812 * NdrComplexStructMemorySize [RPCRT4.@]
3814 ULONG WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3815 PFORMAT_STRING pFormat
)
3817 unsigned size
= *(const WORD
*)(pFormat
+2);
3818 PFORMAT_STRING conf_array
= NULL
;
3819 PFORMAT_STRING pointer_desc
= NULL
;
3821 ULONG max_count
= 0;
3824 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3826 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
3829 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3831 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3836 array_read_conformance(conf_array
[0], pStubMsg
, conf_array
);
3838 /* these could be changed in ComplexStructMemorySize so save them for
3840 max_count
= pStubMsg
->MaxCount
;
3841 count
= pStubMsg
->ActualCount
;
3842 offset
= pStubMsg
->Offset
;
3845 ComplexStructMemorySize(pStubMsg
, pFormat
, pointer_desc
);
3849 pStubMsg
->MaxCount
= max_count
;
3850 pStubMsg
->ActualCount
= count
;
3851 pStubMsg
->Offset
= offset
;
3852 array_memory_size(conf_array
[0], pStubMsg
, conf_array
,
3853 TRUE
/* fHasPointers */);
3859 /***********************************************************************
3860 * NdrComplexStructFree [RPCRT4.@]
3862 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3863 unsigned char *pMemory
,
3864 PFORMAT_STRING pFormat
)
3866 PFORMAT_STRING conf_array
= NULL
;
3867 PFORMAT_STRING pointer_desc
= NULL
;
3868 unsigned char *OldMemory
= pStubMsg
->Memory
;
3870 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3873 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3875 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3878 pStubMsg
->Memory
= pMemory
;
3880 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3883 array_free(conf_array
[0], pStubMsg
, pMemory
, conf_array
,
3884 TRUE
/* fHasPointers */);
3886 pStubMsg
->Memory
= OldMemory
;
3889 /***********************************************************************
3890 * NdrConformantArrayMarshall [RPCRT4.@]
3892 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3893 unsigned char *pMemory
,
3894 PFORMAT_STRING pFormat
)
3896 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3897 if (pFormat
[0] != RPC_FC_CARRAY
)
3899 ERR("invalid format = 0x%x\n", pFormat
[0]);
3900 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3903 array_compute_and_write_conformance(RPC_FC_CARRAY
, pStubMsg
, pMemory
,
3905 array_write_variance_and_marshall(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3906 TRUE
/* fHasPointers */);
3911 /***********************************************************************
3912 * NdrConformantArrayUnmarshall [RPCRT4.@]
3914 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3915 unsigned char **ppMemory
,
3916 PFORMAT_STRING pFormat
,
3917 unsigned char fMustAlloc
)
3919 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3920 if (pFormat
[0] != RPC_FC_CARRAY
)
3922 ERR("invalid format = 0x%x\n", pFormat
[0]);
3923 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3926 array_read_conformance(RPC_FC_CARRAY
, pStubMsg
, pFormat
);
3927 array_read_variance_and_unmarshall(RPC_FC_CARRAY
, pStubMsg
, ppMemory
, pFormat
,
3929 TRUE
/* fUseBufferMemoryServer */,
3930 TRUE
/* fUnmarshall */);
3935 /***********************************************************************
3936 * NdrConformantArrayBufferSize [RPCRT4.@]
3938 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3939 unsigned char *pMemory
,
3940 PFORMAT_STRING pFormat
)
3942 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3943 if (pFormat
[0] != RPC_FC_CARRAY
)
3945 ERR("invalid format = 0x%x\n", pFormat
[0]);
3946 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3949 array_compute_and_size_conformance(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
);
3950 array_buffer_size(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3951 TRUE
/* fHasPointers */);
3954 /***********************************************************************
3955 * NdrConformantArrayMemorySize [RPCRT4.@]
3957 ULONG WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3958 PFORMAT_STRING pFormat
)
3960 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3961 if (pFormat
[0] != RPC_FC_CARRAY
)
3963 ERR("invalid format = 0x%x\n", pFormat
[0]);
3964 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3967 array_read_conformance(RPC_FC_CARRAY
, pStubMsg
, pFormat
);
3968 array_memory_size(RPC_FC_CARRAY
, pStubMsg
, pFormat
, TRUE
/* fHasPointers */);
3970 return pStubMsg
->MemorySize
;
3973 /***********************************************************************
3974 * NdrConformantArrayFree [RPCRT4.@]
3976 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3977 unsigned char *pMemory
,
3978 PFORMAT_STRING pFormat
)
3980 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3981 if (pFormat
[0] != RPC_FC_CARRAY
)
3983 ERR("invalid format = 0x%x\n", pFormat
[0]);
3984 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3987 array_free(RPC_FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3988 TRUE
/* fHasPointers */);
3992 /***********************************************************************
3993 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3995 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
3996 unsigned char* pMemory
,
3997 PFORMAT_STRING pFormat
)
3999 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4001 if (pFormat
[0] != RPC_FC_CVARRAY
)
4003 ERR("invalid format type %x\n", pFormat
[0]);
4004 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4008 array_compute_and_write_conformance(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
4010 array_write_variance_and_marshall(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
4011 pFormat
, TRUE
/* fHasPointers */);
4017 /***********************************************************************
4018 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
4020 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
4021 unsigned char** ppMemory
,
4022 PFORMAT_STRING pFormat
,
4023 unsigned char fMustAlloc
)
4025 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4027 if (pFormat
[0] != RPC_FC_CVARRAY
)
4029 ERR("invalid format type %x\n", pFormat
[0]);
4030 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4034 array_read_conformance(RPC_FC_CVARRAY
, pStubMsg
, pFormat
);
4035 array_read_variance_and_unmarshall(RPC_FC_CVARRAY
, pStubMsg
, ppMemory
,
4036 pFormat
, fMustAlloc
,
4037 TRUE
/* fUseBufferMemoryServer */,
4038 TRUE
/* fUnmarshall */);
4044 /***********************************************************************
4045 * NdrConformantVaryingArrayFree [RPCRT4.@]
4047 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
4048 unsigned char* pMemory
,
4049 PFORMAT_STRING pFormat
)
4051 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4053 if (pFormat
[0] != RPC_FC_CVARRAY
)
4055 ERR("invalid format type %x\n", pFormat
[0]);
4056 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4060 array_free(RPC_FC_CVARRAY
, pStubMsg
, pMemory
, pFormat
,
4061 TRUE
/* fHasPointers */);
4065 /***********************************************************************
4066 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
4068 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
4069 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
4071 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4073 if (pFormat
[0] != RPC_FC_CVARRAY
)
4075 ERR("invalid format type %x\n", pFormat
[0]);
4076 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4080 array_compute_and_size_conformance(RPC_FC_CVARRAY
, pStubMsg
, pMemory
,
4082 array_buffer_size(RPC_FC_CVARRAY
, pStubMsg
, pMemory
, pFormat
,
4083 TRUE
/* fHasPointers */);
4087 /***********************************************************************
4088 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
4090 ULONG WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
4091 PFORMAT_STRING pFormat
)
4093 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4095 if (pFormat
[0] != RPC_FC_CVARRAY
)
4097 ERR("invalid format type %x\n", pFormat
[0]);
4098 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4099 return pStubMsg
->MemorySize
;
4102 array_read_conformance(RPC_FC_CVARRAY
, pStubMsg
, pFormat
);
4103 array_memory_size(RPC_FC_CVARRAY
, pStubMsg
, pFormat
,
4104 TRUE
/* fHasPointers */);
4106 return pStubMsg
->MemorySize
;
4110 /***********************************************************************
4111 * NdrComplexArrayMarshall [RPCRT4.@]
4113 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4114 unsigned char *pMemory
,
4115 PFORMAT_STRING pFormat
)
4117 BOOL pointer_buffer_mark_set
= FALSE
;
4119 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4121 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4123 ERR("invalid format type %x\n", pFormat
[0]);
4124 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4128 if (!pStubMsg
->PointerBufferMark
)
4130 /* save buffer fields that may be changed by buffer sizer functions
4131 * and that may be needed later on */
4132 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
4133 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
4134 ULONG_PTR saved_max_count
= pStubMsg
->MaxCount
;
4135 ULONG saved_offset
= pStubMsg
->Offset
;
4136 ULONG saved_actual_count
= pStubMsg
->ActualCount
;
4138 /* get the buffer pointer after complex array data, but before
4140 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
;
4141 pStubMsg
->IgnoreEmbeddedPointers
= 1;
4142 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
4143 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
4145 /* save it for use by embedded pointer code later */
4146 pStubMsg
->PointerBufferMark
= (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
;
4147 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
));
4148 pointer_buffer_mark_set
= TRUE
;
4150 /* restore fields */
4151 pStubMsg
->ActualCount
= saved_actual_count
;
4152 pStubMsg
->Offset
= saved_offset
;
4153 pStubMsg
->MaxCount
= saved_max_count
;
4154 pStubMsg
->BufferLength
= saved_buffer_length
;
4157 array_compute_and_write_conformance(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pMemory
, pFormat
);
4158 array_write_variance_and_marshall(RPC_FC_BOGUS_ARRAY
, pStubMsg
,
4159 pMemory
, pFormat
, TRUE
/* fHasPointers */);
4161 STD_OVERFLOW_CHECK(pStubMsg
);
4163 if (pointer_buffer_mark_set
)
4165 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4166 pStubMsg
->PointerBufferMark
= NULL
;
4172 /***********************************************************************
4173 * NdrComplexArrayUnmarshall [RPCRT4.@]
4175 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4176 unsigned char **ppMemory
,
4177 PFORMAT_STRING pFormat
,
4178 unsigned char fMustAlloc
)
4180 unsigned char *saved_buffer
;
4181 BOOL pointer_buffer_mark_set
= FALSE
;
4182 int saved_ignore_embedded
;
4184 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4186 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4188 ERR("invalid format type %x\n", pFormat
[0]);
4189 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4193 saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
4194 /* save buffer pointer */
4195 saved_buffer
= pStubMsg
->Buffer
;
4196 /* get the buffer pointer after complex array data, but before
4198 pStubMsg
->IgnoreEmbeddedPointers
= 1;
4199 pStubMsg
->MemorySize
= 0;
4200 NdrComplexArrayMemorySize(pStubMsg
, pFormat
);
4201 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
4203 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->Buffer
- saved_buffer
));
4204 if (!pStubMsg
->PointerBufferMark
)
4206 /* save it for use by embedded pointer code later */
4207 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4208 pointer_buffer_mark_set
= TRUE
;
4210 /* restore the original buffer */
4211 pStubMsg
->Buffer
= saved_buffer
;
4213 array_read_conformance(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pFormat
);
4214 array_read_variance_and_unmarshall(RPC_FC_BOGUS_ARRAY
, pStubMsg
, ppMemory
, pFormat
, fMustAlloc
,
4215 TRUE
/* fUseBufferMemoryServer */, TRUE
/* fUnmarshall */);
4217 if (pointer_buffer_mark_set
)
4219 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4220 pStubMsg
->PointerBufferMark
= NULL
;
4226 /***********************************************************************
4227 * NdrComplexArrayBufferSize [RPCRT4.@]
4229 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4230 unsigned char *pMemory
,
4231 PFORMAT_STRING pFormat
)
4233 int pointer_length_set
= 0;
4235 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4237 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4239 ERR("invalid format type %x\n", pFormat
[0]);
4240 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4244 if (!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
4246 /* save buffer fields that may be changed by buffer sizer functions
4247 * and that may be needed later on */
4248 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
4249 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
4250 ULONG_PTR saved_max_count
= pStubMsg
->MaxCount
;
4251 ULONG saved_offset
= pStubMsg
->Offset
;
4252 ULONG saved_actual_count
= pStubMsg
->ActualCount
;
4254 /* get the buffer pointer after complex array data, but before
4256 pStubMsg
->IgnoreEmbeddedPointers
= 1;
4257 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
4258 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
4260 /* save it for use by embedded pointer code later */
4261 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4262 pointer_length_set
= 1;
4264 /* restore fields */
4265 pStubMsg
->ActualCount
= saved_actual_count
;
4266 pStubMsg
->Offset
= saved_offset
;
4267 pStubMsg
->MaxCount
= saved_max_count
;
4268 pStubMsg
->BufferLength
= saved_buffer_length
;
4271 array_compute_and_size_conformance(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pMemory
, pFormat
);
4272 array_buffer_size(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pMemory
, pFormat
, TRUE
/* fHasPointers */);
4274 if(pointer_length_set
)
4276 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4277 pStubMsg
->PointerLength
= 0;
4281 /***********************************************************************
4282 * NdrComplexArrayMemorySize [RPCRT4.@]
4284 ULONG WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4285 PFORMAT_STRING pFormat
)
4287 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
4289 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4291 ERR("invalid format type %x\n", pFormat
[0]);
4292 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4296 array_read_conformance(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pFormat
);
4297 array_memory_size(RPC_FC_BOGUS_ARRAY
, pStubMsg
, pFormat
, TRUE
/* fHasPointers */);
4298 return pStubMsg
->MemorySize
;
4301 /***********************************************************************
4302 * NdrComplexArrayFree [RPCRT4.@]
4304 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4305 unsigned char *pMemory
,
4306 PFORMAT_STRING pFormat
)
4308 ULONG i
, count
, def
;
4310 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4312 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
4314 ERR("invalid format type %x\n", pFormat
[0]);
4315 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4319 def
= *(const WORD
*)&pFormat
[2];
4322 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
4323 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
4325 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
4326 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
4328 count
= pStubMsg
->ActualCount
;
4329 for (i
= 0; i
< count
; i
++)
4330 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
4333 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg
,
4334 USER_MARSHAL_CB_TYPE cbtype
, PFORMAT_STRING pFormat
,
4335 USER_MARSHAL_CB
*umcb
)
4337 umcb
->Flags
= MAKELONG(pStubMsg
->dwDestContext
,
4338 pStubMsg
->RpcMsg
->DataRepresentation
);
4339 umcb
->pStubMsg
= pStubMsg
;
4340 umcb
->pReserve
= NULL
;
4341 umcb
->Signature
= USER_MARSHAL_CB_SIGNATURE
;
4342 umcb
->CBType
= cbtype
;
4343 umcb
->pFormat
= pFormat
;
4344 umcb
->pTypeFormat
= NULL
/* FIXME */;
4347 #define USER_MARSHAL_PTR_PREFIX \
4348 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4349 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4351 /***********************************************************************
4352 * NdrUserMarshalMarshall [RPCRT4.@]
4354 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4355 unsigned char *pMemory
,
4356 PFORMAT_STRING pFormat
)
4358 unsigned flags
= pFormat
[1];
4359 unsigned index
= *(const WORD
*)&pFormat
[2];
4360 unsigned char *saved_buffer
= NULL
;
4361 USER_MARSHAL_CB umcb
;
4363 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4364 TRACE("index=%d\n", index
);
4366 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_MARSHALL
, pFormat
, &umcb
);
4368 if (flags
& USER_MARSHAL_POINTER
)
4370 align_pointer_clear(&pStubMsg
->Buffer
, 4);
4371 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, USER_MARSHAL_PTR_PREFIX
);
4372 pStubMsg
->Buffer
+= 4;
4373 if (pStubMsg
->PointerBufferMark
)
4375 saved_buffer
= pStubMsg
->Buffer
;
4376 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4377 pStubMsg
->PointerBufferMark
= NULL
;
4379 align_pointer_clear(&pStubMsg
->Buffer
, 8);
4382 align_pointer_clear(&pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4385 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
4386 &umcb
.Flags
, pStubMsg
->Buffer
, pMemory
);
4390 STD_OVERFLOW_CHECK(pStubMsg
);
4391 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4392 pStubMsg
->Buffer
= saved_buffer
;
4395 STD_OVERFLOW_CHECK(pStubMsg
);
4400 /***********************************************************************
4401 * NdrUserMarshalUnmarshall [RPCRT4.@]
4403 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4404 unsigned char **ppMemory
,
4405 PFORMAT_STRING pFormat
,
4406 unsigned char fMustAlloc
)
4408 unsigned flags
= pFormat
[1];
4409 unsigned index
= *(const WORD
*)&pFormat
[2];
4410 DWORD memsize
= *(const WORD
*)&pFormat
[4];
4411 unsigned char *saved_buffer
= NULL
;
4412 USER_MARSHAL_CB umcb
;
4414 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4415 TRACE("index=%d\n", index
);
4417 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_UNMARSHALL
, pFormat
, &umcb
);
4419 if (flags
& USER_MARSHAL_POINTER
)
4421 align_pointer(&pStubMsg
->Buffer
, 4);
4422 /* skip pointer prefix */
4423 pStubMsg
->Buffer
+= 4;
4424 if (pStubMsg
->PointerBufferMark
)
4426 saved_buffer
= pStubMsg
->Buffer
;
4427 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4428 pStubMsg
->PointerBufferMark
= NULL
;
4430 align_pointer(&pStubMsg
->Buffer
, 8);
4433 align_pointer(&pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4435 if (!fMustAlloc
&& !*ppMemory
)
4439 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
4440 memset(*ppMemory
, 0, memsize
);
4444 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
4445 &umcb
.Flags
, pStubMsg
->Buffer
, *ppMemory
);
4449 STD_OVERFLOW_CHECK(pStubMsg
);
4450 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4451 pStubMsg
->Buffer
= saved_buffer
;
4457 /***********************************************************************
4458 * NdrUserMarshalBufferSize [RPCRT4.@]
4460 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4461 unsigned char *pMemory
,
4462 PFORMAT_STRING pFormat
)
4464 unsigned flags
= pFormat
[1];
4465 unsigned index
= *(const WORD
*)&pFormat
[2];
4466 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
4467 USER_MARSHAL_CB umcb
;
4468 ULONG saved_buffer_length
= 0;
4470 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4471 TRACE("index=%d\n", index
);
4473 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_BUFFER_SIZE
, pFormat
, &umcb
);
4475 if (flags
& USER_MARSHAL_POINTER
)
4477 align_length(&pStubMsg
->BufferLength
, 4);
4478 /* skip pointer prefix */
4479 safe_buffer_length_increment(pStubMsg
, 4);
4480 if (pStubMsg
->IgnoreEmbeddedPointers
)
4482 if (pStubMsg
->PointerLength
)
4484 saved_buffer_length
= pStubMsg
->BufferLength
;
4485 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4486 pStubMsg
->PointerLength
= 0;
4488 align_length(&pStubMsg
->BufferLength
, 8);
4491 align_length(&pStubMsg
->BufferLength
, (flags
& 0xf) + 1);
4494 TRACE("size=%d\n", bufsize
);
4495 safe_buffer_length_increment(pStubMsg
, bufsize
);
4498 pStubMsg
->BufferLength
=
4499 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
4500 &umcb
.Flags
, pStubMsg
->BufferLength
, pMemory
);
4502 if (saved_buffer_length
)
4504 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4505 pStubMsg
->BufferLength
= saved_buffer_length
;
4510 /***********************************************************************
4511 * NdrUserMarshalMemorySize [RPCRT4.@]
4513 ULONG WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4514 PFORMAT_STRING pFormat
)
4516 unsigned flags
= pFormat
[1];
4517 unsigned index
= *(const WORD
*)&pFormat
[2];
4518 DWORD memsize
= *(const WORD
*)&pFormat
[4];
4519 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
4521 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
4522 TRACE("index=%d\n", index
);
4524 pStubMsg
->MemorySize
+= memsize
;
4526 if (flags
& USER_MARSHAL_POINTER
)
4528 align_pointer(&pStubMsg
->Buffer
, 4);
4529 /* skip pointer prefix */
4530 pStubMsg
->Buffer
+= 4;
4531 if (pStubMsg
->IgnoreEmbeddedPointers
)
4532 return pStubMsg
->MemorySize
;
4533 align_pointer(&pStubMsg
->Buffer
, 8);
4536 align_pointer(&pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4539 FIXME("not implemented for varying buffer size\n");
4541 pStubMsg
->Buffer
+= bufsize
;
4543 return pStubMsg
->MemorySize
;
4546 /***********************************************************************
4547 * NdrUserMarshalFree [RPCRT4.@]
4549 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
4550 unsigned char *pMemory
,
4551 PFORMAT_STRING pFormat
)
4553 /* unsigned flags = pFormat[1]; */
4554 unsigned index
= *(const WORD
*)&pFormat
[2];
4555 USER_MARSHAL_CB umcb
;
4557 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4558 TRACE("index=%d\n", index
);
4560 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_FREE
, pFormat
, &umcb
);
4562 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
4563 &umcb
.Flags
, pMemory
);
4566 /***********************************************************************
4567 * NdrGetUserMarshalInfo [RPCRT4.@]
4569 RPC_STATUS RPC_ENTRY
NdrGetUserMarshalInfo(ULONG
*flags
, ULONG level
, NDR_USER_MARSHAL_INFO
*umi
)
4571 USER_MARSHAL_CB
*umcb
= CONTAINING_RECORD(flags
, USER_MARSHAL_CB
, Flags
);
4573 TRACE("(%p,%u,%p)\n", flags
, level
, umi
);
4576 return RPC_S_INVALID_ARG
;
4578 memset(&umi
->u1
.Level1
, 0, sizeof(umi
->u1
.Level1
));
4579 umi
->InformationLevel
= level
;
4581 if (umcb
->Signature
!= USER_MARSHAL_CB_SIGNATURE
)
4582 return RPC_S_INVALID_ARG
;
4584 umi
->u1
.Level1
.pfnAllocate
= umcb
->pStubMsg
->pfnAllocate
;
4585 umi
->u1
.Level1
.pfnFree
= umcb
->pStubMsg
->pfnFree
;
4586 umi
->u1
.Level1
.pRpcChannelBuffer
= umcb
->pStubMsg
->pRpcChannelBuffer
;
4588 switch (umcb
->CBType
)
4590 case USER_MARSHAL_CB_MARSHALL
:
4591 case USER_MARSHAL_CB_UNMARSHALL
:
4593 RPC_MESSAGE
*msg
= umcb
->pStubMsg
->RpcMsg
;
4594 unsigned char *buffer_start
= msg
->Buffer
;
4595 unsigned char *buffer_end
=
4596 (unsigned char *)msg
->Buffer
+ msg
->BufferLength
;
4598 if (umcb
->pStubMsg
->Buffer
< buffer_start
||
4599 umcb
->pStubMsg
->Buffer
> buffer_end
)
4600 return RPC_X_INVALID_BUFFER
;
4602 umi
->u1
.Level1
.Buffer
= umcb
->pStubMsg
->Buffer
;
4603 umi
->u1
.Level1
.BufferSize
= buffer_end
- umcb
->pStubMsg
->Buffer
;
4606 case USER_MARSHAL_CB_BUFFER_SIZE
:
4607 case USER_MARSHAL_CB_FREE
:
4610 WARN("unrecognised CBType %d\n", umcb
->CBType
);
4616 /***********************************************************************
4617 * NdrClearOutParameters [RPCRT4.@]
4619 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
4620 PFORMAT_STRING pFormat
,
4623 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
4626 /***********************************************************************
4627 * NdrConvert [RPCRT4.@]
4629 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
4631 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
4632 /* FIXME: since this stub doesn't do any converting, the proper behavior
4633 is to raise an exception */
4636 /***********************************************************************
4637 * NdrConvert2 [RPCRT4.@]
4639 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, LONG NumberParams
)
4641 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4642 pStubMsg
, pFormat
, NumberParams
);
4643 /* FIXME: since this stub doesn't do any converting, the proper behavior
4644 is to raise an exception */
4647 #include "pshpack1.h"
4648 typedef struct _NDR_CSTRUCT_FORMAT
4651 unsigned char alignment
;
4652 unsigned short memory_size
;
4653 short offset_to_array_description
;
4654 } NDR_CSTRUCT_FORMAT
, NDR_CVSTRUCT_FORMAT
;
4655 #include "poppack.h"
4657 /***********************************************************************
4658 * NdrConformantStructMarshall [RPCRT4.@]
4660 unsigned char * WINAPI
NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4661 unsigned char *pMemory
,
4662 PFORMAT_STRING pFormat
)
4664 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4665 PFORMAT_STRING pCArrayFormat
;
4666 ULONG esize
, bufsize
;
4668 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4670 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4671 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4673 ERR("invalid format type %x\n", pCStructFormat
->type
);
4674 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4678 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4679 pCStructFormat
->offset_to_array_description
;
4680 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4682 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4683 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4686 esize
= *(const WORD
*)(pCArrayFormat
+2);
4688 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4689 pCArrayFormat
+ 4, 0);
4691 WriteConformance(pStubMsg
);
4693 align_pointer_clear(&pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4695 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4697 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4698 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4700 ERR("integer overflow of memory_size %u with bufsize %u\n",
4701 pCStructFormat
->memory_size
, bufsize
);
4702 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4704 /* copy constant sized part of struct */
4705 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4706 safe_copy_to_buffer(pStubMsg
, pMemory
, pCStructFormat
->memory_size
+ bufsize
);
4708 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4709 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4714 /***********************************************************************
4715 * NdrConformantStructUnmarshall [RPCRT4.@]
4717 unsigned char * WINAPI
NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4718 unsigned char **ppMemory
,
4719 PFORMAT_STRING pFormat
,
4720 unsigned char fMustAlloc
)
4722 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4723 PFORMAT_STRING pCArrayFormat
;
4724 ULONG esize
, bufsize
;
4725 unsigned char *saved_buffer
;
4727 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4729 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4730 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4732 ERR("invalid format type %x\n", pCStructFormat
->type
);
4733 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4736 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4737 pCStructFormat
->offset_to_array_description
;
4738 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4740 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4741 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4744 esize
= *(const WORD
*)(pCArrayFormat
+2);
4746 pCArrayFormat
= ReadConformance(pStubMsg
, pCArrayFormat
+ 4);
4748 align_pointer(&pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4750 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4752 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4753 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4755 ERR("integer overflow of memory_size %u with bufsize %u\n",
4756 pCStructFormat
->memory_size
, bufsize
);
4757 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4762 SIZE_T size
= pCStructFormat
->memory_size
+ bufsize
;
4763 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4767 if (!pStubMsg
->IsClient
&& !*ppMemory
)
4768 /* for servers, we just point straight into the RPC buffer */
4769 *ppMemory
= pStubMsg
->Buffer
;
4772 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4773 safe_buffer_increment(pStubMsg
, pCStructFormat
->memory_size
+ bufsize
);
4774 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4775 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4777 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
4778 if (*ppMemory
!= saved_buffer
)
4779 memcpy(*ppMemory
, saved_buffer
, pCStructFormat
->memory_size
+ bufsize
);
4784 /***********************************************************************
4785 * NdrConformantStructBufferSize [RPCRT4.@]
4787 void WINAPI
NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4788 unsigned char *pMemory
,
4789 PFORMAT_STRING pFormat
)
4791 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4792 PFORMAT_STRING pCArrayFormat
;
4795 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4797 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4798 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4800 ERR("invalid format type %x\n", pCStructFormat
->type
);
4801 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4804 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4805 pCStructFormat
->offset_to_array_description
;
4806 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4808 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4809 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4812 esize
= *(const WORD
*)(pCArrayFormat
+2);
4814 pCArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
, pCArrayFormat
+4, 0);
4815 SizeConformance(pStubMsg
);
4817 align_length(&pStubMsg
->BufferLength
, pCStructFormat
->alignment
+ 1);
4819 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4821 safe_buffer_length_increment(pStubMsg
, pCStructFormat
->memory_size
);
4822 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
4824 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4825 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4828 /***********************************************************************
4829 * NdrConformantStructMemorySize [RPCRT4.@]
4831 ULONG WINAPI
NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4832 PFORMAT_STRING pFormat
)
4838 /***********************************************************************
4839 * NdrConformantStructFree [RPCRT4.@]
4841 void WINAPI
NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
4842 unsigned char *pMemory
,
4843 PFORMAT_STRING pFormat
)
4845 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4846 PFORMAT_STRING pCArrayFormat
;
4848 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4850 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4851 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
4853 ERR("invalid format type %x\n", pCStructFormat
->type
);
4854 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4858 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4859 pCStructFormat
->offset_to_array_description
;
4860 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
4862 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4863 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4867 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4868 pCArrayFormat
+ 4, 0);
4870 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4872 /* copy constant sized part of struct */
4873 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4875 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
4876 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4879 /***********************************************************************
4880 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4882 unsigned char * WINAPI
NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4883 unsigned char *pMemory
,
4884 PFORMAT_STRING pFormat
)
4886 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4887 PFORMAT_STRING pCVArrayFormat
;
4889 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4891 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4892 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4894 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4895 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4899 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4900 pCVStructFormat
->offset_to_array_description
;
4902 array_compute_and_write_conformance(*pCVArrayFormat
, pStubMsg
,
4903 pMemory
+ pCVStructFormat
->memory_size
,
4906 align_pointer_clear(&pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4908 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4910 /* write constant sized part */
4911 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4912 safe_copy_to_buffer(pStubMsg
, pMemory
, pCVStructFormat
->memory_size
);
4914 array_write_variance_and_marshall(*pCVArrayFormat
, pStubMsg
,
4915 pMemory
+ pCVStructFormat
->memory_size
,
4916 pCVArrayFormat
, FALSE
/* fHasPointers */);
4918 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4923 /***********************************************************************
4924 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4926 unsigned char * WINAPI
NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4927 unsigned char **ppMemory
,
4928 PFORMAT_STRING pFormat
,
4929 unsigned char fMustAlloc
)
4931 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4932 PFORMAT_STRING pCVArrayFormat
;
4933 ULONG memsize
, bufsize
;
4934 unsigned char *saved_buffer
, *saved_array_buffer
;
4936 unsigned char *array_memory
;
4938 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4940 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4941 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4943 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4944 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4948 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4949 pCVStructFormat
->offset_to_array_description
;
4951 memsize
= array_read_conformance(*pCVArrayFormat
, pStubMsg
,
4954 align_pointer(&pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4956 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4958 /* work out how much memory to allocate if we need to do so */
4959 if (!fMustAlloc
&& !*ppMemory
)
4963 SIZE_T size
= pCVStructFormat
->memory_size
+ memsize
;
4964 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4967 /* mark the start of the constant data */
4968 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4969 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4971 array_memory
= *ppMemory
+ pCVStructFormat
->memory_size
;
4972 bufsize
= array_read_variance_and_unmarshall(*pCVArrayFormat
, pStubMsg
,
4973 &array_memory
, pCVArrayFormat
,
4974 FALSE
/* fMustAlloc */,
4975 FALSE
/* fUseServerBufferMemory */,
4976 FALSE
/* fUnmarshall */);
4978 /* save offset in case unmarshalling pointers changes it */
4979 offset
= pStubMsg
->Offset
;
4981 /* mark the start of the array data */
4982 saved_array_buffer
= pStubMsg
->Buffer
;
4983 safe_buffer_increment(pStubMsg
, bufsize
);
4985 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4987 /* copy the constant data */
4988 memcpy(*ppMemory
, saved_buffer
, pCVStructFormat
->memory_size
);
4989 /* copy the array data */
4990 TRACE("copying %p to %p\n", saved_array_buffer
, *ppMemory
+ pCVStructFormat
->memory_size
);
4991 memcpy(*ppMemory
+ pCVStructFormat
->memory_size
+ offset
,
4992 saved_array_buffer
, bufsize
);
4994 if (*pCVArrayFormat
== RPC_FC_C_CSTRING
)
4995 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory
+ pCVStructFormat
->memory_size
)));
4996 else if (*pCVArrayFormat
== RPC_FC_C_WSTRING
)
4997 TRACE("string=%s\n", debugstr_w((WCHAR
*)(*ppMemory
+ pCVStructFormat
->memory_size
)));
5002 /***********************************************************************
5003 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
5005 void WINAPI
NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5006 unsigned char *pMemory
,
5007 PFORMAT_STRING pFormat
)
5009 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
5010 PFORMAT_STRING pCVArrayFormat
;
5012 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5014 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
5015 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
5017 ERR("invalid format type %x\n", pCVStructFormat
->type
);
5018 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5022 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
5023 pCVStructFormat
->offset_to_array_description
;
5024 array_compute_and_size_conformance(*pCVArrayFormat
, pStubMsg
,
5025 pMemory
+ pCVStructFormat
->memory_size
,
5028 align_length(&pStubMsg
->BufferLength
, pCVStructFormat
->alignment
+ 1);
5030 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
5032 safe_buffer_length_increment(pStubMsg
, pCVStructFormat
->memory_size
);
5034 array_buffer_size(*pCVArrayFormat
, pStubMsg
,
5035 pMemory
+ pCVStructFormat
->memory_size
, pCVArrayFormat
,
5036 FALSE
/* fHasPointers */);
5038 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5041 /***********************************************************************
5042 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
5044 ULONG WINAPI
NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5045 PFORMAT_STRING pFormat
)
5047 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
5048 PFORMAT_STRING pCVArrayFormat
;
5050 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5052 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
5053 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
5055 ERR("invalid format type %x\n", pCVStructFormat
->type
);
5056 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5060 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
5061 pCVStructFormat
->offset_to_array_description
;
5062 array_read_conformance(*pCVArrayFormat
, pStubMsg
, pCVArrayFormat
);
5064 align_pointer(&pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
5066 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
5068 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
5069 array_memory_size(*pCVArrayFormat
, pStubMsg
, pCVArrayFormat
,
5070 FALSE
/* fHasPointers */);
5072 pStubMsg
->MemorySize
+= pCVStructFormat
->memory_size
;
5074 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5076 return pStubMsg
->MemorySize
;
5079 /***********************************************************************
5080 * NdrConformantVaryingStructFree [RPCRT4.@]
5082 void WINAPI
NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
5083 unsigned char *pMemory
,
5084 PFORMAT_STRING pFormat
)
5086 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
5087 PFORMAT_STRING pCVArrayFormat
;
5089 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5091 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
5092 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
5094 ERR("invalid format type %x\n", pCVStructFormat
->type
);
5095 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5099 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
5100 pCVStructFormat
->offset_to_array_description
;
5101 array_free(*pCVArrayFormat
, pStubMsg
,
5102 pMemory
+ pCVStructFormat
->memory_size
, pCVArrayFormat
,
5103 FALSE
/* fHasPointers */);
5105 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
5107 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5110 #include "pshpack1.h"
5114 unsigned char alignment
;
5115 unsigned short total_size
;
5116 } NDR_SMFARRAY_FORMAT
;
5121 unsigned char alignment
;
5123 } NDR_LGFARRAY_FORMAT
;
5124 #include "poppack.h"
5126 /***********************************************************************
5127 * NdrFixedArrayMarshall [RPCRT4.@]
5129 unsigned char * WINAPI
NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5130 unsigned char *pMemory
,
5131 PFORMAT_STRING pFormat
)
5133 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5136 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5138 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5139 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5141 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5142 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5146 align_pointer_clear(&pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
5148 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5150 total_size
= pSmFArrayFormat
->total_size
;
5151 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5155 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5156 total_size
= pLgFArrayFormat
->total_size
;
5157 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5160 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5161 safe_copy_to_buffer(pStubMsg
, pMemory
, total_size
);
5163 pFormat
= EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
5168 /***********************************************************************
5169 * NdrFixedArrayUnmarshall [RPCRT4.@]
5171 unsigned char * WINAPI
NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5172 unsigned char **ppMemory
,
5173 PFORMAT_STRING pFormat
,
5174 unsigned char fMustAlloc
)
5176 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5178 unsigned char *saved_buffer
;
5180 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5182 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5183 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5185 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5186 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5190 align_pointer(&pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
5192 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5194 total_size
= pSmFArrayFormat
->total_size
;
5195 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5199 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5200 total_size
= pLgFArrayFormat
->total_size
;
5201 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5205 *ppMemory
= NdrAllocate(pStubMsg
, total_size
);
5208 if (!pStubMsg
->IsClient
&& !*ppMemory
)
5209 /* for servers, we just point straight into the RPC buffer */
5210 *ppMemory
= pStubMsg
->Buffer
;
5213 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5214 safe_buffer_increment(pStubMsg
, total_size
);
5215 pFormat
= EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
5217 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
5218 if (*ppMemory
!= saved_buffer
)
5219 memcpy(*ppMemory
, saved_buffer
, total_size
);
5224 /***********************************************************************
5225 * NdrFixedArrayBufferSize [RPCRT4.@]
5227 void WINAPI
NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5228 unsigned char *pMemory
,
5229 PFORMAT_STRING pFormat
)
5231 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5234 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5236 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5237 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5239 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5240 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5244 align_length(&pStubMsg
->BufferLength
, pSmFArrayFormat
->alignment
+ 1);
5246 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5248 total_size
= pSmFArrayFormat
->total_size
;
5249 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5253 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5254 total_size
= pLgFArrayFormat
->total_size
;
5255 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5257 safe_buffer_length_increment(pStubMsg
, total_size
);
5259 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5262 /***********************************************************************
5263 * NdrFixedArrayMemorySize [RPCRT4.@]
5265 ULONG WINAPI
NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5266 PFORMAT_STRING pFormat
)
5268 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5271 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5273 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5274 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5276 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5277 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5281 align_pointer(&pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
5283 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5285 total_size
= pSmFArrayFormat
->total_size
;
5286 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5290 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5291 total_size
= pLgFArrayFormat
->total_size
;
5292 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5294 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5295 safe_buffer_increment(pStubMsg
, total_size
);
5296 pStubMsg
->MemorySize
+= total_size
;
5298 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5303 /***********************************************************************
5304 * NdrFixedArrayFree [RPCRT4.@]
5306 void WINAPI
NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
5307 unsigned char *pMemory
,
5308 PFORMAT_STRING pFormat
)
5310 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5312 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5314 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
5315 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
5317 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5318 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5322 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
5323 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5326 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5327 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5330 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5333 /***********************************************************************
5334 * NdrVaryingArrayMarshall [RPCRT4.@]
5336 unsigned char * WINAPI
NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5337 unsigned char *pMemory
,
5338 PFORMAT_STRING pFormat
)
5340 unsigned char alignment
;
5341 DWORD elements
, esize
;
5344 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5346 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5347 (pFormat
[0] != RPC_FC_LGVARRAY
))
5349 ERR("invalid format type %x\n", pFormat
[0]);
5350 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5354 alignment
= pFormat
[1] + 1;
5356 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5359 pFormat
+= sizeof(WORD
);
5360 elements
= *(const WORD
*)pFormat
;
5361 pFormat
+= sizeof(WORD
);
5366 pFormat
+= sizeof(DWORD
);
5367 elements
= *(const DWORD
*)pFormat
;
5368 pFormat
+= sizeof(DWORD
);
5371 esize
= *(const WORD
*)pFormat
;
5372 pFormat
+= sizeof(WORD
);
5374 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5375 if ((pStubMsg
->ActualCount
> elements
) ||
5376 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5378 RpcRaiseException(RPC_S_INVALID_BOUND
);
5382 WriteVariance(pStubMsg
);
5384 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
5386 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
5387 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5388 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
5390 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
5395 /***********************************************************************
5396 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5398 unsigned char * WINAPI
NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5399 unsigned char **ppMemory
,
5400 PFORMAT_STRING pFormat
,
5401 unsigned char fMustAlloc
)
5403 unsigned char alignment
;
5404 DWORD size
, elements
, esize
;
5406 unsigned char *saved_buffer
;
5409 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5411 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5412 (pFormat
[0] != RPC_FC_LGVARRAY
))
5414 ERR("invalid format type %x\n", pFormat
[0]);
5415 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5419 alignment
= pFormat
[1] + 1;
5421 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5424 size
= *(const WORD
*)pFormat
;
5425 pFormat
+= sizeof(WORD
);
5426 elements
= *(const WORD
*)pFormat
;
5427 pFormat
+= sizeof(WORD
);
5432 size
= *(const DWORD
*)pFormat
;
5433 pFormat
+= sizeof(DWORD
);
5434 elements
= *(const DWORD
*)pFormat
;
5435 pFormat
+= sizeof(DWORD
);
5438 esize
= *(const WORD
*)pFormat
;
5439 pFormat
+= sizeof(WORD
);
5441 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
5443 align_pointer(&pStubMsg
->Buffer
, alignment
);
5445 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
5446 offset
= pStubMsg
->Offset
;
5448 if (!fMustAlloc
&& !*ppMemory
)
5451 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5452 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5453 safe_buffer_increment(pStubMsg
, bufsize
);
5455 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
5457 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
5462 /***********************************************************************
5463 * NdrVaryingArrayBufferSize [RPCRT4.@]
5465 void WINAPI
NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5466 unsigned char *pMemory
,
5467 PFORMAT_STRING pFormat
)
5469 unsigned char alignment
;
5470 DWORD elements
, esize
;
5472 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5474 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5475 (pFormat
[0] != RPC_FC_LGVARRAY
))
5477 ERR("invalid format type %x\n", pFormat
[0]);
5478 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5482 alignment
= pFormat
[1] + 1;
5484 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5487 pFormat
+= sizeof(WORD
);
5488 elements
= *(const WORD
*)pFormat
;
5489 pFormat
+= sizeof(WORD
);
5494 pFormat
+= sizeof(DWORD
);
5495 elements
= *(const DWORD
*)pFormat
;
5496 pFormat
+= sizeof(DWORD
);
5499 esize
= *(const WORD
*)pFormat
;
5500 pFormat
+= sizeof(WORD
);
5502 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5503 if ((pStubMsg
->ActualCount
> elements
) ||
5504 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5506 RpcRaiseException(RPC_S_INVALID_BOUND
);
5510 SizeVariance(pStubMsg
);
5512 align_length(&pStubMsg
->BufferLength
, alignment
);
5514 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
5516 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5519 /***********************************************************************
5520 * NdrVaryingArrayMemorySize [RPCRT4.@]
5522 ULONG WINAPI
NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5523 PFORMAT_STRING pFormat
)
5525 unsigned char alignment
;
5526 DWORD size
, elements
, esize
;
5528 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5530 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5531 (pFormat
[0] != RPC_FC_LGVARRAY
))
5533 ERR("invalid format type %x\n", pFormat
[0]);
5534 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5538 alignment
= pFormat
[1] + 1;
5540 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5543 size
= *(const WORD
*)pFormat
;
5544 pFormat
+= sizeof(WORD
);
5545 elements
= *(const WORD
*)pFormat
;
5546 pFormat
+= sizeof(WORD
);
5551 size
= *(const DWORD
*)pFormat
;
5552 pFormat
+= sizeof(DWORD
);
5553 elements
= *(const DWORD
*)pFormat
;
5554 pFormat
+= sizeof(DWORD
);
5557 esize
= *(const WORD
*)pFormat
;
5558 pFormat
+= sizeof(WORD
);
5560 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
5562 align_pointer(&pStubMsg
->Buffer
, alignment
);
5564 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
5565 pStubMsg
->MemorySize
+= size
;
5567 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5569 return pStubMsg
->MemorySize
;
5572 /***********************************************************************
5573 * NdrVaryingArrayFree [RPCRT4.@]
5575 void WINAPI
NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
5576 unsigned char *pMemory
,
5577 PFORMAT_STRING pFormat
)
5581 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5583 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
5584 (pFormat
[0] != RPC_FC_LGVARRAY
))
5586 ERR("invalid format type %x\n", pFormat
[0]);
5587 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5591 if (pFormat
[0] == RPC_FC_SMVARRAY
)
5594 pFormat
+= sizeof(WORD
);
5595 elements
= *(const WORD
*)pFormat
;
5596 pFormat
+= sizeof(WORD
);
5601 pFormat
+= sizeof(DWORD
);
5602 elements
= *(const DWORD
*)pFormat
;
5603 pFormat
+= sizeof(DWORD
);
5606 pFormat
+= sizeof(WORD
);
5608 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5609 if ((pStubMsg
->ActualCount
> elements
) ||
5610 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5612 RpcRaiseException(RPC_S_INVALID_BOUND
);
5616 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5619 static ULONG
get_discriminant(unsigned char fc
, const unsigned char *pMemory
)
5632 return *(const USHORT
*)pMemory
;
5636 return *(const ULONG
*)pMemory
;
5637 case RPC_FC_INT3264
:
5638 case RPC_FC_UINT3264
:
5639 return *(const ULONG_PTR
*)pMemory
;
5641 FIXME("Unhandled base type: 0x%02x\n", fc
);
5646 static PFORMAT_STRING
get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg
,
5648 PFORMAT_STRING pFormat
)
5650 unsigned short num_arms
, arm
, type
;
5652 num_arms
= *(const SHORT
*)pFormat
& 0x0fff;
5654 for(arm
= 0; arm
< num_arms
; arm
++)
5656 if(discriminant
== *(const ULONG
*)pFormat
)
5664 type
= *(const unsigned short*)pFormat
;
5665 TRACE("type %04x\n", type
);
5666 if(arm
== num_arms
) /* default arm extras */
5670 ERR("no arm for 0x%x and no default case\n", discriminant
);
5671 RpcRaiseException(RPC_S_INVALID_TAG
);
5676 TRACE("falling back to empty default case for 0x%x\n", discriminant
);
5683 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
, ULONG discriminant
, PFORMAT_STRING pFormat
)
5685 unsigned short type
;
5689 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5693 type
= *(const unsigned short*)pFormat
;
5694 if((type
& 0xff00) == 0x8000)
5696 unsigned char basetype
= LOBYTE(type
);
5697 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &basetype
);
5701 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5702 NDR_MARSHALL m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
5705 unsigned char *saved_buffer
= NULL
;
5706 BOOL pointer_buffer_mark_set
= FALSE
;
5713 align_pointer_clear(&pStubMsg
->Buffer
, 4);
5714 saved_buffer
= pStubMsg
->Buffer
;
5715 if (pStubMsg
->PointerBufferMark
)
5717 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5718 pStubMsg
->PointerBufferMark
= NULL
;
5719 pointer_buffer_mark_set
= TRUE
;
5722 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
5724 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char **)pMemory
, desc
);
5725 if (pointer_buffer_mark_set
)
5727 STD_OVERFLOW_CHECK(pStubMsg
);
5728 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5729 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5731 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5732 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
5733 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5735 pStubMsg
->Buffer
= saved_buffer
+ 4;
5739 m(pStubMsg
, pMemory
, desc
);
5742 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5747 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5748 unsigned char **ppMemory
,
5750 PFORMAT_STRING pFormat
,
5751 unsigned char fMustAlloc
)
5753 unsigned short type
;
5757 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5761 type
= *(const unsigned short*)pFormat
;
5762 if((type
& 0xff00) == 0x8000)
5764 unsigned char basetype
= LOBYTE(type
);
5765 return NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &basetype
, FALSE
);
5769 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5770 NDR_UNMARSHALL m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
5773 unsigned char *saved_buffer
= NULL
;
5774 BOOL pointer_buffer_mark_set
= FALSE
;
5781 align_pointer(&pStubMsg
->Buffer
, 4);
5782 saved_buffer
= pStubMsg
->Buffer
;
5783 if (pStubMsg
->PointerBufferMark
)
5785 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5786 pStubMsg
->PointerBufferMark
= NULL
;
5787 pointer_buffer_mark_set
= TRUE
;
5790 pStubMsg
->Buffer
+= 4; /* for pointer ID */
5792 if (saved_buffer
+ 4 > pStubMsg
->BufferEnd
)
5794 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5795 saved_buffer
, pStubMsg
->BufferEnd
);
5796 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5799 PointerUnmarshall(pStubMsg
, saved_buffer
, *(unsigned char ***)ppMemory
, **(unsigned char ***)ppMemory
, desc
, fMustAlloc
);
5800 if (pointer_buffer_mark_set
)
5802 STD_OVERFLOW_CHECK(pStubMsg
);
5803 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5804 pStubMsg
->Buffer
= saved_buffer
+ 4;
5808 m(pStubMsg
, ppMemory
, desc
, fMustAlloc
);
5811 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5816 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg
,
5817 unsigned char *pMemory
,
5819 PFORMAT_STRING pFormat
)
5821 unsigned short type
;
5825 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5829 type
= *(const unsigned short*)pFormat
;
5830 if((type
& 0xff00) == 0x8000)
5832 unsigned char basetype
= LOBYTE(type
);
5833 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &basetype
);
5837 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5838 NDR_BUFFERSIZE m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
5847 align_length(&pStubMsg
->BufferLength
, 4);
5848 safe_buffer_length_increment(pStubMsg
, 4); /* for pointer ID */
5849 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5851 int saved_buffer_length
= pStubMsg
->BufferLength
;
5852 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
5853 pStubMsg
->PointerLength
= 0;
5854 if(!pStubMsg
->BufferLength
)
5855 ERR("BufferLength == 0??\n");
5856 PointerBufferSize(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5857 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
5858 pStubMsg
->BufferLength
= saved_buffer_length
;
5862 m(pStubMsg
, pMemory
, desc
);
5865 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
5869 static ULONG
union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg
,
5871 PFORMAT_STRING pFormat
)
5873 unsigned short type
, size
;
5875 size
= *(const unsigned short*)pFormat
;
5876 pStubMsg
->Memory
+= size
;
5879 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5883 type
= *(const unsigned short*)pFormat
;
5884 if((type
& 0xff00) == 0x8000)
5886 return NdrBaseTypeMemorySize(pStubMsg
, pFormat
);
5890 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5891 NDR_MEMORYSIZE m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
5892 unsigned char *saved_buffer
;
5901 align_pointer(&pStubMsg
->Buffer
, 4);
5902 saved_buffer
= pStubMsg
->Buffer
;
5903 safe_buffer_increment(pStubMsg
, 4);
5904 align_length(&pStubMsg
->MemorySize
, sizeof(void *));
5905 pStubMsg
->MemorySize
+= sizeof(void *);
5906 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5907 PointerMemorySize(pStubMsg
, saved_buffer
, pFormat
);
5910 return m(pStubMsg
, desc
);
5913 else FIXME("no marshaller for embedded type %02x\n", *desc
);
5916 TRACE("size %d\n", size
);
5920 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg
,
5921 unsigned char *pMemory
,
5923 PFORMAT_STRING pFormat
)
5925 unsigned short type
;
5929 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5933 type
= *(const unsigned short*)pFormat
;
5934 if((type
& 0xff00) != 0x8000)
5936 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5937 NDR_FREE m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
5946 PointerFree(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5949 m(pStubMsg
, pMemory
, desc
);
5955 /***********************************************************************
5956 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5958 unsigned char * WINAPI
NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5959 unsigned char *pMemory
,
5960 PFORMAT_STRING pFormat
)
5962 unsigned char switch_type
;
5963 unsigned char increment
;
5966 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5969 switch_type
= *pFormat
& 0xf;
5970 increment
= (*pFormat
& 0xf0) >> 4;
5973 align_pointer_clear(&pStubMsg
->Buffer
, increment
);
5975 switch_value
= get_discriminant(switch_type
, pMemory
);
5976 TRACE("got switch value 0x%x\n", switch_value
);
5978 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &switch_type
);
5979 pMemory
+= increment
;
5981 return union_arm_marshall(pStubMsg
, pMemory
, switch_value
, pFormat
);
5984 /***********************************************************************
5985 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5987 unsigned char * WINAPI
NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5988 unsigned char **ppMemory
,
5989 PFORMAT_STRING pFormat
,
5990 unsigned char fMustAlloc
)
5992 unsigned char switch_type
;
5993 unsigned char increment
;
5995 unsigned short size
;
5996 unsigned char *pMemoryArm
;
5998 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
6001 switch_type
= *pFormat
& 0xf;
6002 increment
= (*pFormat
& 0xf0) >> 4;
6005 align_pointer(&pStubMsg
->Buffer
, increment
);
6006 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
6007 TRACE("got switch value 0x%x\n", switch_value
);
6009 size
= *(const unsigned short*)pFormat
+ increment
;
6010 if (!fMustAlloc
&& !*ppMemory
)
6013 *ppMemory
= NdrAllocate(pStubMsg
, size
);
6015 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6016 * since the arm is part of the memory block that is encompassed by
6017 * the whole union. Memory is forced to allocate when pointers
6018 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6019 * clearing the memory we pass in to the unmarshaller */
6021 memset(*ppMemory
, 0, size
);
6023 NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &switch_type
, FALSE
);
6024 pMemoryArm
= *ppMemory
+ increment
;
6026 return union_arm_unmarshall(pStubMsg
, &pMemoryArm
, switch_value
, pFormat
, FALSE
);
6029 /***********************************************************************
6030 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
6032 void WINAPI
NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6033 unsigned char *pMemory
,
6034 PFORMAT_STRING pFormat
)
6036 unsigned char switch_type
;
6037 unsigned char increment
;
6040 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6043 switch_type
= *pFormat
& 0xf;
6044 increment
= (*pFormat
& 0xf0) >> 4;
6047 align_length(&pStubMsg
->BufferLength
, increment
);
6048 switch_value
= get_discriminant(switch_type
, pMemory
);
6049 TRACE("got switch value 0x%x\n", switch_value
);
6051 /* Add discriminant size */
6052 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&switch_value
, &switch_type
);
6053 pMemory
+= increment
;
6055 union_arm_buffer_size(pStubMsg
, pMemory
, switch_value
, pFormat
);
6058 /***********************************************************************
6059 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
6061 ULONG WINAPI
NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6062 PFORMAT_STRING pFormat
)
6064 unsigned char switch_type
;
6065 unsigned char increment
;
6068 switch_type
= *pFormat
& 0xf;
6069 increment
= (*pFormat
& 0xf0) >> 4;
6072 align_pointer(&pStubMsg
->Buffer
, increment
);
6073 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
6074 TRACE("got switch value 0x%x\n", switch_value
);
6076 pStubMsg
->Memory
+= increment
;
6078 return increment
+ union_arm_memory_size(pStubMsg
, switch_value
, pFormat
+ *(const SHORT
*)pFormat
);
6081 /***********************************************************************
6082 * NdrEncapsulatedUnionFree [RPCRT4.@]
6084 void WINAPI
NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
6085 unsigned char *pMemory
,
6086 PFORMAT_STRING pFormat
)
6088 unsigned char switch_type
;
6089 unsigned char increment
;
6092 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6095 switch_type
= *pFormat
& 0xf;
6096 increment
= (*pFormat
& 0xf0) >> 4;
6099 switch_value
= get_discriminant(switch_type
, pMemory
);
6100 TRACE("got switch value 0x%x\n", switch_value
);
6102 pMemory
+= increment
;
6104 union_arm_free(pStubMsg
, pMemory
, switch_value
, pFormat
);
6107 /***********************************************************************
6108 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
6110 unsigned char * WINAPI
NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6111 unsigned char *pMemory
,
6112 PFORMAT_STRING pFormat
)
6114 unsigned char switch_type
;
6116 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6119 switch_type
= *pFormat
;
6122 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6123 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6124 /* Marshall discriminant */
6125 NdrBaseTypeMarshall(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
6127 return union_arm_marshall(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6130 static LONG
unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg
,
6131 PFORMAT_STRING
*ppFormat
)
6133 LONG discriminant
= 0;
6143 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
6153 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6154 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
6162 align_pointer(&pStubMsg
->Buffer
, sizeof(ULONG
));
6163 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
6168 FIXME("Unhandled base type: 0x%02x\n", **ppFormat
);
6172 *ppFormat
= SkipConformance(pStubMsg
, *ppFormat
);
6173 return discriminant
;
6176 /**********************************************************************
6177 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
6179 unsigned char * WINAPI
NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6180 unsigned char **ppMemory
,
6181 PFORMAT_STRING pFormat
,
6182 unsigned char fMustAlloc
)
6185 unsigned short size
;
6187 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
6190 /* Unmarshall discriminant */
6191 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
6192 TRACE("unmarshalled discriminant %x\n", discriminant
);
6194 pFormat
+= *(const SHORT
*)pFormat
;
6196 size
= *(const unsigned short*)pFormat
;
6198 if (!fMustAlloc
&& !*ppMemory
)
6201 *ppMemory
= NdrAllocate(pStubMsg
, size
);
6203 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6204 * since the arm is part of the memory block that is encompassed by
6205 * the whole union. Memory is forced to allocate when pointers
6206 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6207 * clearing the memory we pass in to the unmarshaller */
6209 memset(*ppMemory
, 0, size
);
6211 return union_arm_unmarshall(pStubMsg
, ppMemory
, discriminant
, pFormat
, FALSE
);
6214 /***********************************************************************
6215 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
6217 void WINAPI
NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6218 unsigned char *pMemory
,
6219 PFORMAT_STRING pFormat
)
6221 unsigned char switch_type
;
6223 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6226 switch_type
= *pFormat
;
6229 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6230 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6231 /* Add discriminant size */
6232 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
6234 union_arm_buffer_size(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6237 /***********************************************************************
6238 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
6240 ULONG WINAPI
NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6241 PFORMAT_STRING pFormat
)
6246 /* Unmarshall discriminant */
6247 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
6248 TRACE("unmarshalled discriminant 0x%x\n", discriminant
);
6250 return union_arm_memory_size(pStubMsg
, discriminant
, pFormat
+ *(const SHORT
*)pFormat
);
6253 /***********************************************************************
6254 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6256 void WINAPI
NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
6257 unsigned char *pMemory
,
6258 PFORMAT_STRING pFormat
)
6260 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6264 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6265 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6267 union_arm_free(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6270 /***********************************************************************
6271 * NdrByteCountPointerMarshall [RPCRT4.@]
6273 unsigned char * WINAPI
NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6274 unsigned char *pMemory
,
6275 PFORMAT_STRING pFormat
)
6281 /***********************************************************************
6282 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6284 unsigned char * WINAPI
NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6285 unsigned char **ppMemory
,
6286 PFORMAT_STRING pFormat
,
6287 unsigned char fMustAlloc
)
6293 /***********************************************************************
6294 * NdrByteCountPointerBufferSize [RPCRT4.@]
6296 void WINAPI
NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6297 unsigned char *pMemory
,
6298 PFORMAT_STRING pFormat
)
6303 /***********************************************************************
6304 * NdrByteCountPointerMemorySize [internal]
6306 static ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6307 PFORMAT_STRING pFormat
)
6313 /***********************************************************************
6314 * NdrByteCountPointerFree [RPCRT4.@]
6316 void WINAPI
NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
6317 unsigned char *pMemory
,
6318 PFORMAT_STRING pFormat
)
6323 /***********************************************************************
6324 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6326 unsigned char * WINAPI
NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6327 unsigned char *pMemory
,
6328 PFORMAT_STRING pFormat
)
6334 /***********************************************************************
6335 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6337 unsigned char * WINAPI
NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6338 unsigned char **ppMemory
,
6339 PFORMAT_STRING pFormat
,
6340 unsigned char fMustAlloc
)
6346 /***********************************************************************
6347 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6349 void WINAPI
NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6350 unsigned char *pMemory
,
6351 PFORMAT_STRING pFormat
)
6356 /***********************************************************************
6357 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6359 ULONG WINAPI
NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6360 PFORMAT_STRING pFormat
)
6366 /***********************************************************************
6367 * NdrXmitOrRepAsFree [RPCRT4.@]
6369 void WINAPI
NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg
,
6370 unsigned char *pMemory
,
6371 PFORMAT_STRING pFormat
)
6376 /***********************************************************************
6377 * NdrRangeMarshall [internal]
6379 static unsigned char *WINAPI
NdrRangeMarshall(
6380 PMIDL_STUB_MESSAGE pStubMsg
,
6381 unsigned char *pMemory
,
6382 PFORMAT_STRING pFormat
)
6384 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6385 unsigned char base_type
;
6387 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6389 if (pRange
->type
!= RPC_FC_RANGE
)
6391 ERR("invalid format type %x\n", pRange
->type
);
6392 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6396 base_type
= pRange
->flags_type
& 0xf;
6398 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &base_type
);
6401 /***********************************************************************
6402 * NdrRangeUnmarshall [RPCRT4.@]
6404 unsigned char *WINAPI
NdrRangeUnmarshall(
6405 PMIDL_STUB_MESSAGE pStubMsg
,
6406 unsigned char **ppMemory
,
6407 PFORMAT_STRING pFormat
,
6408 unsigned char fMustAlloc
)
6410 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6411 unsigned char base_type
;
6413 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6415 if (pRange
->type
!= RPC_FC_RANGE
)
6417 ERR("invalid format type %x\n", pRange
->type
);
6418 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6421 base_type
= pRange
->flags_type
& 0xf;
6423 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6424 base_type
, pRange
->low_value
, pRange
->high_value
);
6426 #define RANGE_UNMARSHALL(mem_type, wire_type, format_spec) \
6429 align_pointer(&pStubMsg->Buffer, sizeof(wire_type)); \
6430 if (!fMustAlloc && !*ppMemory) \
6431 fMustAlloc = TRUE; \
6433 *ppMemory = NdrAllocate(pStubMsg, sizeof(mem_type)); \
6434 if (pStubMsg->Buffer + sizeof(wire_type) > pStubMsg->BufferEnd) \
6436 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6437 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6438 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6440 if ((*(wire_type *)pStubMsg->Buffer < (mem_type)pRange->low_value) || \
6441 (*(wire_type *)pStubMsg->Buffer > (mem_type)pRange->high_value)) \
6443 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6444 *(wire_type *)pStubMsg->Buffer, (mem_type)pRange->low_value, \
6445 (mem_type)pRange->high_value); \
6446 RpcRaiseException(RPC_S_INVALID_BOUND); \
6449 TRACE("*ppMemory: %p\n", *ppMemory); \
6450 **(mem_type **)ppMemory = *(wire_type *)pStubMsg->Buffer; \
6451 pStubMsg->Buffer += sizeof(wire_type); \
6458 RANGE_UNMARSHALL(UCHAR
, UCHAR
, "%d");
6459 TRACE("value: 0x%02x\n", **ppMemory
);
6463 RANGE_UNMARSHALL(CHAR
, CHAR
, "%u");
6464 TRACE("value: 0x%02x\n", **ppMemory
);
6466 case RPC_FC_WCHAR
: /* FIXME: valid? */
6468 RANGE_UNMARSHALL(USHORT
, USHORT
, "%u");
6469 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6472 RANGE_UNMARSHALL(SHORT
, SHORT
, "%d");
6473 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6477 RANGE_UNMARSHALL(LONG
, LONG
, "%d");
6478 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6481 RANGE_UNMARSHALL(ULONG
, ULONG
, "%u");
6482 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6485 RANGE_UNMARSHALL(UINT
, USHORT
, "%u");
6486 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
6492 ERR("invalid range base type: 0x%02x\n", base_type
);
6493 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6499 /***********************************************************************
6500 * NdrRangeBufferSize [internal]
6502 static void WINAPI
NdrRangeBufferSize(
6503 PMIDL_STUB_MESSAGE pStubMsg
,
6504 unsigned char *pMemory
,
6505 PFORMAT_STRING pFormat
)
6507 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6508 unsigned char base_type
;
6510 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6512 if (pRange
->type
!= RPC_FC_RANGE
)
6514 ERR("invalid format type %x\n", pRange
->type
);
6515 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6517 base_type
= pRange
->flags_type
& 0xf;
6519 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &base_type
);
6522 /***********************************************************************
6523 * NdrRangeMemorySize [internal]
6525 static ULONG WINAPI
NdrRangeMemorySize(
6526 PMIDL_STUB_MESSAGE pStubMsg
,
6527 PFORMAT_STRING pFormat
)
6529 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6530 unsigned char base_type
;
6532 if (pRange
->type
!= RPC_FC_RANGE
)
6534 ERR("invalid format type %x\n", pRange
->type
);
6535 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6538 base_type
= pRange
->flags_type
& 0xf;
6540 return NdrBaseTypeMemorySize(pStubMsg
, &base_type
);
6543 /***********************************************************************
6544 * NdrRangeFree [internal]
6546 static void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6547 unsigned char *pMemory
,
6548 PFORMAT_STRING pFormat
)
6550 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6555 /***********************************************************************
6556 * NdrBaseTypeMarshall [internal]
6558 static unsigned char *WINAPI
NdrBaseTypeMarshall(
6559 PMIDL_STUB_MESSAGE pStubMsg
,
6560 unsigned char *pMemory
,
6561 PFORMAT_STRING pFormat
)
6563 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6571 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(UCHAR
));
6572 TRACE("value: 0x%02x\n", *pMemory
);
6577 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(USHORT
));
6578 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(USHORT
));
6579 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
6583 case RPC_FC_ERROR_STATUS_T
:
6585 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(ULONG
));
6586 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONG
));
6587 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
6590 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(float));
6591 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
6594 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(double));
6595 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
6598 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(ULONGLONG
));
6599 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONGLONG
));
6600 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
6604 USHORT val
= *(UINT
*)pMemory
;
6605 /* only 16-bits on the wire, so do a sanity check */
6606 if (*(UINT
*)pMemory
> SHRT_MAX
)
6607 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
6608 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(USHORT
));
6609 safe_copy_to_buffer(pStubMsg
, &val
, sizeof(val
));
6610 TRACE("value: 0x%04x\n", *(UINT
*)pMemory
);
6613 case RPC_FC_INT3264
:
6614 case RPC_FC_UINT3264
:
6616 UINT val
= *(UINT_PTR
*)pMemory
;
6617 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(UINT
));
6618 safe_copy_to_buffer(pStubMsg
, &val
, sizeof(val
));
6624 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6627 /* FIXME: what is the correct return value? */
6631 /***********************************************************************
6632 * NdrBaseTypeUnmarshall [internal]
6634 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(
6635 PMIDL_STUB_MESSAGE pStubMsg
,
6636 unsigned char **ppMemory
,
6637 PFORMAT_STRING pFormat
,
6638 unsigned char fMustAlloc
)
6640 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6642 #define BASE_TYPE_UNMARSHALL(type) do { \
6643 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
6644 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6646 *ppMemory = pStubMsg->Buffer; \
6647 TRACE("*ppMemory: %p\n", *ppMemory); \
6648 safe_buffer_increment(pStubMsg, sizeof(type)); \
6653 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6654 TRACE("*ppMemory: %p\n", *ppMemory); \
6655 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6665 BASE_TYPE_UNMARSHALL(UCHAR
);
6666 TRACE("value: 0x%02x\n", **ppMemory
);
6671 BASE_TYPE_UNMARSHALL(USHORT
);
6672 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6676 case RPC_FC_ERROR_STATUS_T
:
6678 BASE_TYPE_UNMARSHALL(ULONG
);
6679 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6682 BASE_TYPE_UNMARSHALL(float);
6683 TRACE("value: %f\n", **(float **)ppMemory
);
6686 BASE_TYPE_UNMARSHALL(double);
6687 TRACE("value: %f\n", **(double **)ppMemory
);
6690 BASE_TYPE_UNMARSHALL(ULONGLONG
);
6691 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG
**)ppMemory
));
6696 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6697 if (!fMustAlloc
&& !*ppMemory
)
6700 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT
));
6701 safe_copy_from_buffer(pStubMsg
, &val
, sizeof(USHORT
));
6702 /* 16-bits on the wire, but int in memory */
6703 **(UINT
**)ppMemory
= val
;
6704 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
6707 case RPC_FC_INT3264
:
6708 if (sizeof(INT_PTR
) == sizeof(INT
)) BASE_TYPE_UNMARSHALL(INT
);
6712 align_pointer(&pStubMsg
->Buffer
, sizeof(INT
));
6713 if (!fMustAlloc
&& !*ppMemory
)
6716 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(INT_PTR
));
6717 safe_copy_from_buffer(pStubMsg
, &val
, sizeof(INT
));
6718 **(INT_PTR
**)ppMemory
= val
;
6719 TRACE("value: 0x%08lx\n", **(INT_PTR
**)ppMemory
);
6722 case RPC_FC_UINT3264
:
6723 if (sizeof(UINT_PTR
) == sizeof(UINT
)) BASE_TYPE_UNMARSHALL(UINT
);
6727 align_pointer(&pStubMsg
->Buffer
, sizeof(UINT
));
6728 if (!fMustAlloc
&& !*ppMemory
)
6731 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT_PTR
));
6732 safe_copy_from_buffer(pStubMsg
, &val
, sizeof(UINT
));
6733 **(UINT_PTR
**)ppMemory
= val
;
6734 TRACE("value: 0x%08lx\n", **(UINT_PTR
**)ppMemory
);
6740 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6742 #undef BASE_TYPE_UNMARSHALL
6744 /* FIXME: what is the correct return value? */
6749 /***********************************************************************
6750 * NdrBaseTypeBufferSize [internal]
6752 static void WINAPI
NdrBaseTypeBufferSize(
6753 PMIDL_STUB_MESSAGE pStubMsg
,
6754 unsigned char *pMemory
,
6755 PFORMAT_STRING pFormat
)
6757 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6765 safe_buffer_length_increment(pStubMsg
, sizeof(UCHAR
));
6771 align_length(&pStubMsg
->BufferLength
, sizeof(USHORT
));
6772 safe_buffer_length_increment(pStubMsg
, sizeof(USHORT
));
6777 case RPC_FC_INT3264
:
6778 case RPC_FC_UINT3264
:
6779 align_length(&pStubMsg
->BufferLength
, sizeof(ULONG
));
6780 safe_buffer_length_increment(pStubMsg
, sizeof(ULONG
));
6783 align_length(&pStubMsg
->BufferLength
, sizeof(float));
6784 safe_buffer_length_increment(pStubMsg
, sizeof(float));
6787 align_length(&pStubMsg
->BufferLength
, sizeof(double));
6788 safe_buffer_length_increment(pStubMsg
, sizeof(double));
6791 align_length(&pStubMsg
->BufferLength
, sizeof(ULONGLONG
));
6792 safe_buffer_length_increment(pStubMsg
, sizeof(ULONGLONG
));
6794 case RPC_FC_ERROR_STATUS_T
:
6795 align_length(&pStubMsg
->BufferLength
, sizeof(error_status_t
));
6796 safe_buffer_length_increment(pStubMsg
, sizeof(error_status_t
));
6801 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6805 /***********************************************************************
6806 * NdrBaseTypeMemorySize [internal]
6808 static ULONG WINAPI
NdrBaseTypeMemorySize(
6809 PMIDL_STUB_MESSAGE pStubMsg
,
6810 PFORMAT_STRING pFormat
)
6812 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg
, *pFormat
);
6820 safe_buffer_increment(pStubMsg
, sizeof(UCHAR
));
6821 pStubMsg
->MemorySize
+= sizeof(UCHAR
);
6822 return sizeof(UCHAR
);
6826 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6827 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6828 align_length(&pStubMsg
->MemorySize
, sizeof(USHORT
));
6829 pStubMsg
->MemorySize
+= sizeof(USHORT
);
6830 return sizeof(USHORT
);
6834 align_pointer(&pStubMsg
->Buffer
, sizeof(ULONG
));
6835 safe_buffer_increment(pStubMsg
, sizeof(ULONG
));
6836 align_length(&pStubMsg
->MemorySize
, sizeof(ULONG
));
6837 pStubMsg
->MemorySize
+= sizeof(ULONG
);
6838 return sizeof(ULONG
);
6840 align_pointer(&pStubMsg
->Buffer
, sizeof(float));
6841 safe_buffer_increment(pStubMsg
, sizeof(float));
6842 align_length(&pStubMsg
->MemorySize
, sizeof(float));
6843 pStubMsg
->MemorySize
+= sizeof(float);
6844 return sizeof(float);
6846 align_pointer(&pStubMsg
->Buffer
, sizeof(double));
6847 safe_buffer_increment(pStubMsg
, sizeof(double));
6848 align_length(&pStubMsg
->MemorySize
, sizeof(double));
6849 pStubMsg
->MemorySize
+= sizeof(double);
6850 return sizeof(double);
6852 align_pointer(&pStubMsg
->Buffer
, sizeof(ULONGLONG
));
6853 safe_buffer_increment(pStubMsg
, sizeof(ULONGLONG
));
6854 align_length(&pStubMsg
->MemorySize
, sizeof(ULONGLONG
));
6855 pStubMsg
->MemorySize
+= sizeof(ULONGLONG
);
6856 return sizeof(ULONGLONG
);
6857 case RPC_FC_ERROR_STATUS_T
:
6858 align_pointer(&pStubMsg
->Buffer
, sizeof(error_status_t
));
6859 safe_buffer_increment(pStubMsg
, sizeof(error_status_t
));
6860 align_length(&pStubMsg
->MemorySize
, sizeof(error_status_t
));
6861 pStubMsg
->MemorySize
+= sizeof(error_status_t
);
6862 return sizeof(error_status_t
);
6864 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6865 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6866 align_length(&pStubMsg
->MemorySize
, sizeof(UINT
));
6867 pStubMsg
->MemorySize
+= sizeof(UINT
);
6868 return sizeof(UINT
);
6869 case RPC_FC_INT3264
:
6870 case RPC_FC_UINT3264
:
6871 align_pointer(&pStubMsg
->Buffer
, sizeof(UINT
));
6872 safe_buffer_increment(pStubMsg
, sizeof(UINT
));
6873 align_length(&pStubMsg
->MemorySize
, sizeof(UINT_PTR
));
6874 pStubMsg
->MemorySize
+= sizeof(UINT_PTR
);
6875 return sizeof(UINT_PTR
);
6877 align_length(&pStubMsg
->MemorySize
, sizeof(void *));
6878 pStubMsg
->MemorySize
+= sizeof(void *);
6879 return sizeof(void *);
6881 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6886 /***********************************************************************
6887 * NdrBaseTypeFree [internal]
6889 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6890 unsigned char *pMemory
,
6891 PFORMAT_STRING pFormat
)
6893 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6898 /***********************************************************************
6899 * NdrContextHandleBufferSize [internal]
6901 static void WINAPI
NdrContextHandleBufferSize(
6902 PMIDL_STUB_MESSAGE pStubMsg
,
6903 unsigned char *pMemory
,
6904 PFORMAT_STRING pFormat
)
6906 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6908 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6910 ERR("invalid format type %x\n", *pFormat
);
6911 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6913 align_length(&pStubMsg
->BufferLength
, 4);
6914 safe_buffer_length_increment(pStubMsg
, cbNDRContext
);
6917 /***********************************************************************
6918 * NdrContextHandleMarshall [internal]
6920 static unsigned char *WINAPI
NdrContextHandleMarshall(
6921 PMIDL_STUB_MESSAGE pStubMsg
,
6922 unsigned char *pMemory
,
6923 PFORMAT_STRING pFormat
)
6925 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6927 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6929 ERR("invalid format type %x\n", *pFormat
);
6930 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6932 TRACE("flags: 0x%02x\n", pFormat
[1]);
6934 if (pStubMsg
->IsClient
)
6936 if (pFormat
[1] & HANDLE_PARAM_IS_VIA_PTR
)
6937 NdrClientContextMarshall(pStubMsg
, *(NDR_CCONTEXT
**)pMemory
, FALSE
);
6939 NdrClientContextMarshall(pStubMsg
, pMemory
, FALSE
);
6943 NDR_SCONTEXT ctxt
= NDRSContextFromValue(pMemory
);
6944 NDR_RUNDOWN rundown
= pStubMsg
->StubDesc
->apfnNdrRundownRoutines
[pFormat
[2]];
6945 NdrServerContextNewMarshall(pStubMsg
, ctxt
, rundown
, pFormat
);
6951 /***********************************************************************
6952 * NdrContextHandleUnmarshall [internal]
6954 static unsigned char *WINAPI
NdrContextHandleUnmarshall(
6955 PMIDL_STUB_MESSAGE pStubMsg
,
6956 unsigned char **ppMemory
,
6957 PFORMAT_STRING pFormat
,
6958 unsigned char fMustAlloc
)
6960 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg
,
6961 ppMemory
, pFormat
, fMustAlloc
? "TRUE": "FALSE");
6963 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
6965 ERR("invalid format type %x\n", *pFormat
);
6966 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6968 TRACE("flags: 0x%02x\n", pFormat
[1]);
6970 if (pStubMsg
->IsClient
)
6972 /* [out]-only or [ret] param */
6973 if ((pFormat
[1] & (HANDLE_PARAM_IS_IN
|HANDLE_PARAM_IS_OUT
)) == HANDLE_PARAM_IS_OUT
)
6974 **(NDR_CCONTEXT
**)ppMemory
= NULL
;
6975 NdrClientContextUnmarshall(pStubMsg
, *(NDR_CCONTEXT
**)ppMemory
, pStubMsg
->RpcMsg
->Handle
);
6980 ctxt
= NdrServerContextNewUnmarshall(pStubMsg
, pFormat
);
6981 if (pFormat
[1] & HANDLE_PARAM_IS_VIA_PTR
)
6982 *(void **)ppMemory
= NDRSContextValue(ctxt
);
6984 *(void **)ppMemory
= *NDRSContextValue(ctxt
);
6990 /***********************************************************************
6991 * NdrClientContextMarshall [RPCRT4.@]
6993 void WINAPI
NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6994 NDR_CCONTEXT ContextHandle
,
6997 TRACE("(%p, %p, %d)\n", pStubMsg
, ContextHandle
, fCheck
);
6999 align_pointer_clear(&pStubMsg
->Buffer
, 4);
7001 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7003 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7004 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7005 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7008 /* FIXME: what does fCheck do? */
7009 NDRCContextMarshall(ContextHandle
,
7012 pStubMsg
->Buffer
+= cbNDRContext
;
7015 /***********************************************************************
7016 * NdrClientContextUnmarshall [RPCRT4.@]
7018 void WINAPI
NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7019 NDR_CCONTEXT
* pContextHandle
,
7020 RPC_BINDING_HANDLE BindHandle
)
7022 TRACE("(%p, %p, %p)\n", pStubMsg
, pContextHandle
, BindHandle
);
7024 align_pointer(&pStubMsg
->Buffer
, 4);
7026 if (pStubMsg
->Buffer
+ cbNDRContext
> pStubMsg
->BufferEnd
)
7027 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7029 NDRCContextUnmarshall(pContextHandle
,
7032 pStubMsg
->RpcMsg
->DataRepresentation
);
7034 pStubMsg
->Buffer
+= cbNDRContext
;
7037 void WINAPI
NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7038 NDR_SCONTEXT ContextHandle
,
7039 NDR_RUNDOWN RundownRoutine
)
7041 TRACE("(%p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
);
7043 align_pointer(&pStubMsg
->Buffer
, 4);
7045 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7047 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7048 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7049 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7052 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
7053 pStubMsg
->Buffer
, RundownRoutine
, NULL
,
7054 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
7055 pStubMsg
->Buffer
+= cbNDRContext
;
7058 NDR_SCONTEXT WINAPI
NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
)
7060 NDR_SCONTEXT ContextHandle
;
7062 TRACE("(%p)\n", pStubMsg
);
7064 align_pointer(&pStubMsg
->Buffer
, 4);
7066 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7068 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7069 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7070 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7073 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
7075 pStubMsg
->RpcMsg
->DataRepresentation
,
7076 NULL
, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
7077 pStubMsg
->Buffer
+= cbNDRContext
;
7079 return ContextHandle
;
7082 void WINAPI
NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg
,
7083 unsigned char* pMemory
,
7084 PFORMAT_STRING pFormat
)
7086 FIXME("(%p, %p, %p): stub\n", pStubMsg
, pMemory
, pFormat
);
7089 NDR_SCONTEXT WINAPI
NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg
,
7090 PFORMAT_STRING pFormat
)
7092 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
7093 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
7095 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
7097 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
7098 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
7099 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
7100 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
7101 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
7103 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
7104 if_id
= &sif
->InterfaceId
;
7107 return NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
, NULL
,
7108 pStubMsg
->RpcMsg
->DataRepresentation
, if_id
,
7112 void WINAPI
NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7113 NDR_SCONTEXT ContextHandle
,
7114 NDR_RUNDOWN RundownRoutine
,
7115 PFORMAT_STRING pFormat
)
7117 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
7118 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
7120 TRACE("(%p, %p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
, pFormat
);
7122 align_pointer(&pStubMsg
->Buffer
, 4);
7124 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7126 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7127 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7128 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7131 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
7132 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
7133 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
7134 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
7135 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
7137 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
7138 if_id
= &sif
->InterfaceId
;
7141 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
7142 pStubMsg
->Buffer
, RundownRoutine
, if_id
, flags
);
7143 pStubMsg
->Buffer
+= cbNDRContext
;
7146 NDR_SCONTEXT WINAPI
NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7147 PFORMAT_STRING pFormat
)
7149 NDR_SCONTEXT ContextHandle
;
7150 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
7151 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
7153 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
7155 align_pointer(&pStubMsg
->Buffer
, 4);
7157 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7159 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7160 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7161 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7164 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
7165 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
7166 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE
)
7167 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
7168 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
7170 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
7171 if_id
= &sif
->InterfaceId
;
7174 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
7176 pStubMsg
->RpcMsg
->DataRepresentation
,
7178 pStubMsg
->Buffer
+= cbNDRContext
;
7180 return ContextHandle
;
7183 /***********************************************************************
7184 * NdrCorrelationInitialize [RPCRT4.@]
7186 * Initializes correlation validity checking.
7189 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7190 * pMemory [I] Pointer to memory to use as a cache.
7191 * CacheSize [I] Size of the memory pointed to by pMemory.
7192 * Flags [I] Reserved. Set to zero.
7197 void WINAPI
NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg
, void *pMemory
, ULONG CacheSize
, ULONG Flags
)
7199 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg
, pMemory
, CacheSize
, Flags
);
7200 pStubMsg
->fHasNewCorrDesc
= TRUE
;
7203 /***********************************************************************
7204 * NdrCorrelationPass [RPCRT4.@]
7206 * Performs correlation validity checking.
7209 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7214 void WINAPI
NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg
)
7216 FIXME("(%p): stub\n", pStubMsg
);
7219 /***********************************************************************
7220 * NdrCorrelationFree [RPCRT4.@]
7222 * Frees any resources used while unmarshalling parameters that need
7223 * correlation validity checking.
7226 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7231 void WINAPI
NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg
)
7233 FIXME("(%p): stub\n", pStubMsg
);