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/debug.h"
48 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
51 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
52 (*((UINT32 *)(pchar)) = (uint32))
54 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
55 (*((UINT32 *)(pchar)))
57 /* these would work for i386 too, but less efficient */
58 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
59 (*(pchar) = LOBYTE(LOWORD(uint32)), \
60 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
61 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
62 *((pchar)+3) = HIBYTE(HIWORD(uint32)))
64 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
66 MAKEWORD(*(pchar), *((pchar)+1)), \
67 MAKEWORD(*((pchar)+2), *((pchar)+3))))
70 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
71 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
72 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
73 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
74 *(pchar) = HIBYTE(HIWORD(uint32)))
76 #define BIG_ENDIAN_UINT32_READ(pchar) \
78 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
79 MAKEWORD(*((pchar)+1), *(pchar))))
81 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
82 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
83 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
84 # define NDR_LOCAL_UINT32_READ(pchar) \
85 BIG_ENDIAN_UINT32_READ(pchar)
87 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
88 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
89 # define NDR_LOCAL_UINT32_READ(pchar) \
90 LITTLE_ENDIAN_UINT32_READ(pchar)
93 static inline void align_length( ULONG
*len
, unsigned int align
)
95 *len
= (*len
+ align
- 1) & ~(align
- 1);
98 static inline void align_pointer( unsigned char **ptr
, unsigned int align
)
100 ULONG_PTR mask
= align
- 1;
101 *ptr
= (unsigned char *)(((ULONG_PTR
)*ptr
+ mask
) & ~mask
);
104 static inline void align_pointer_clear( unsigned char **ptr
, unsigned int align
)
106 ULONG_PTR mask
= align
- 1;
107 memset( *ptr
, 0, (align
- (ULONG_PTR
)*ptr
) & mask
);
108 *ptr
= (unsigned char *)(((ULONG_PTR
)*ptr
+ mask
) & ~mask
);
111 static inline void align_pointer_offset( unsigned char **ptr
, unsigned char *base
, unsigned int align
)
113 ULONG_PTR mask
= align
- 1;
114 *ptr
= base
+ (((ULONG_PTR
)(*ptr
- base
) + mask
) & ~mask
);
117 static inline void align_pointer_offset_clear( unsigned char **ptr
, unsigned char *base
, unsigned int align
)
119 ULONG_PTR mask
= align
- 1;
120 memset( *ptr
, 0, (align
- (ULONG_PTR
)(*ptr
- base
)) & mask
);
121 *ptr
= base
+ (((ULONG_PTR
)(*ptr
- base
) + mask
) & ~mask
);
124 #define STD_OVERFLOW_CHECK(_Msg) do { \
125 TRACE("buffer=%d/%d\n", (ULONG)(_Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer), _Msg->BufferLength); \
126 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
127 ERR("buffer overflow %d bytes\n", (ULONG)(_Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength))); \
130 #define NDR_POINTER_ID_BASE 0x20000
131 #define NDR_POINTER_ID(pStubMsg) (NDR_POINTER_ID_BASE + ((pStubMsg)->UniquePtrCount++) * 4)
132 #define NDR_TABLE_SIZE 128
133 #define NDR_TABLE_MASK 127
135 #define NDRSContextFromValue(user_context) (NDR_SCONTEXT)((char *)(user_context) - (char *)NDRSContextValue((NDR_SCONTEXT)NULL))
137 static unsigned char *WINAPI
NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
138 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
139 static void WINAPI
NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
140 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
141 static ULONG WINAPI
NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
143 static unsigned char *WINAPI
NdrContextHandleMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
144 static void WINAPI
NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
145 static unsigned char *WINAPI
NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
147 static unsigned char *WINAPI
NdrRangeMarshall(PMIDL_STUB_MESSAGE
,unsigned char *, PFORMAT_STRING
);
148 static void WINAPI
NdrRangeBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
149 static ULONG WINAPI
NdrRangeMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
150 static void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
152 static ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
154 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
155 unsigned char *pMemory
,
156 PFORMAT_STRING pFormat
,
157 PFORMAT_STRING pPointer
);
158 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
159 unsigned char *pMemory
,
160 PFORMAT_STRING pFormat
,
161 PFORMAT_STRING pPointer
);
162 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
163 unsigned char *pMemory
,
164 PFORMAT_STRING pFormat
,
165 PFORMAT_STRING pPointer
,
166 unsigned char fMustAlloc
);
167 static ULONG
ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
168 PFORMAT_STRING pFormat
,
169 PFORMAT_STRING pPointer
);
170 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
171 unsigned char *pMemory
,
172 PFORMAT_STRING pFormat
,
173 PFORMAT_STRING pPointer
);
175 const NDR_MARSHALL NdrMarshaller
[NDR_TABLE_SIZE
] = {
177 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
178 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
179 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
180 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
184 NdrPointerMarshall
, NdrPointerMarshall
,
185 NdrPointerMarshall
, NdrPointerMarshall
,
187 NdrSimpleStructMarshall
, NdrSimpleStructMarshall
,
188 NdrConformantStructMarshall
, NdrConformantStructMarshall
,
189 NdrConformantVaryingStructMarshall
,
190 NdrComplexStructMarshall
,
192 NdrConformantArrayMarshall
,
193 NdrConformantVaryingArrayMarshall
,
194 NdrFixedArrayMarshall
, NdrFixedArrayMarshall
,
195 NdrVaryingArrayMarshall
, NdrVaryingArrayMarshall
,
196 NdrComplexArrayMarshall
,
198 NdrConformantStringMarshall
, 0, 0,
199 NdrConformantStringMarshall
,
200 NdrNonConformantStringMarshall
, 0, 0, 0,
202 NdrEncapsulatedUnionMarshall
,
203 NdrNonEncapsulatedUnionMarshall
,
204 NdrByteCountPointerMarshall
,
205 NdrXmitOrRepAsMarshall
, NdrXmitOrRepAsMarshall
,
207 NdrInterfacePointerMarshall
,
209 NdrContextHandleMarshall
,
212 NdrUserMarshalMarshall
,
219 const NDR_UNMARSHALL NdrUnmarshaller
[NDR_TABLE_SIZE
] = {
221 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
222 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
223 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
224 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
226 NdrBaseTypeUnmarshall
,
228 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
229 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
231 NdrSimpleStructUnmarshall
, NdrSimpleStructUnmarshall
,
232 NdrConformantStructUnmarshall
, NdrConformantStructUnmarshall
,
233 NdrConformantVaryingStructUnmarshall
,
234 NdrComplexStructUnmarshall
,
236 NdrConformantArrayUnmarshall
,
237 NdrConformantVaryingArrayUnmarshall
,
238 NdrFixedArrayUnmarshall
, NdrFixedArrayUnmarshall
,
239 NdrVaryingArrayUnmarshall
, NdrVaryingArrayUnmarshall
,
240 NdrComplexArrayUnmarshall
,
242 NdrConformantStringUnmarshall
, 0, 0,
243 NdrConformantStringUnmarshall
,
244 NdrNonConformantStringUnmarshall
, 0, 0, 0,
246 NdrEncapsulatedUnionUnmarshall
,
247 NdrNonEncapsulatedUnionUnmarshall
,
248 NdrByteCountPointerUnmarshall
,
249 NdrXmitOrRepAsUnmarshall
, NdrXmitOrRepAsUnmarshall
,
251 NdrInterfacePointerUnmarshall
,
253 NdrContextHandleUnmarshall
,
256 NdrUserMarshalUnmarshall
,
260 NdrBaseTypeUnmarshall
,
261 NdrBaseTypeUnmarshall
263 const NDR_BUFFERSIZE NdrBufferSizer
[NDR_TABLE_SIZE
] = {
265 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
266 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
267 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
268 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
270 NdrBaseTypeBufferSize
,
272 NdrPointerBufferSize
, NdrPointerBufferSize
,
273 NdrPointerBufferSize
, NdrPointerBufferSize
,
275 NdrSimpleStructBufferSize
, NdrSimpleStructBufferSize
,
276 NdrConformantStructBufferSize
, NdrConformantStructBufferSize
,
277 NdrConformantVaryingStructBufferSize
,
278 NdrComplexStructBufferSize
,
280 NdrConformantArrayBufferSize
,
281 NdrConformantVaryingArrayBufferSize
,
282 NdrFixedArrayBufferSize
, NdrFixedArrayBufferSize
,
283 NdrVaryingArrayBufferSize
, NdrVaryingArrayBufferSize
,
284 NdrComplexArrayBufferSize
,
286 NdrConformantStringBufferSize
, 0, 0,
287 NdrConformantStringBufferSize
,
288 NdrNonConformantStringBufferSize
, 0, 0, 0,
290 NdrEncapsulatedUnionBufferSize
,
291 NdrNonEncapsulatedUnionBufferSize
,
292 NdrByteCountPointerBufferSize
,
293 NdrXmitOrRepAsBufferSize
, NdrXmitOrRepAsBufferSize
,
295 NdrInterfacePointerBufferSize
,
297 NdrContextHandleBufferSize
,
300 NdrUserMarshalBufferSize
,
304 NdrBaseTypeBufferSize
,
305 NdrBaseTypeBufferSize
307 const NDR_MEMORYSIZE NdrMemorySizer
[NDR_TABLE_SIZE
] = {
309 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
310 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
311 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
312 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
314 NdrBaseTypeMemorySize
,
316 NdrPointerMemorySize
, NdrPointerMemorySize
,
317 NdrPointerMemorySize
, NdrPointerMemorySize
,
319 NdrSimpleStructMemorySize
, NdrSimpleStructMemorySize
,
320 NdrConformantStructMemorySize
, NdrConformantStructMemorySize
,
321 NdrConformantVaryingStructMemorySize
,
322 NdrComplexStructMemorySize
,
324 NdrConformantArrayMemorySize
,
325 NdrConformantVaryingArrayMemorySize
,
326 NdrFixedArrayMemorySize
, NdrFixedArrayMemorySize
,
327 NdrVaryingArrayMemorySize
, NdrVaryingArrayMemorySize
,
328 NdrComplexArrayMemorySize
,
330 NdrConformantStringMemorySize
, 0, 0,
331 NdrConformantStringMemorySize
,
332 NdrNonConformantStringMemorySize
, 0, 0, 0,
334 NdrEncapsulatedUnionMemorySize
,
335 NdrNonEncapsulatedUnionMemorySize
,
336 NdrByteCountPointerMemorySize
,
337 NdrXmitOrRepAsMemorySize
, NdrXmitOrRepAsMemorySize
,
339 NdrInterfacePointerMemorySize
,
344 NdrUserMarshalMemorySize
,
348 NdrBaseTypeMemorySize
,
349 NdrBaseTypeMemorySize
351 const NDR_FREE NdrFreer
[NDR_TABLE_SIZE
] = {
353 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
354 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
355 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
356 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
360 NdrPointerFree
, NdrPointerFree
,
361 NdrPointerFree
, NdrPointerFree
,
363 NdrSimpleStructFree
, NdrSimpleStructFree
,
364 NdrConformantStructFree
, NdrConformantStructFree
,
365 NdrConformantVaryingStructFree
,
366 NdrComplexStructFree
,
368 NdrConformantArrayFree
,
369 NdrConformantVaryingArrayFree
,
370 NdrFixedArrayFree
, NdrFixedArrayFree
,
371 NdrVaryingArrayFree
, NdrVaryingArrayFree
,
377 NdrEncapsulatedUnionFree
,
378 NdrNonEncapsulatedUnionFree
,
380 NdrXmitOrRepAsFree
, NdrXmitOrRepAsFree
,
382 NdrInterfacePointerFree
,
395 typedef struct _NDR_MEMORY_LIST
400 struct _NDR_MEMORY_LIST
*next
;
403 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
405 /***********************************************************************
406 * NdrAllocate [RPCRT4.@]
408 * Allocates a block of memory using pStubMsg->pfnAllocate.
411 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
412 * len [I] Size of memory block to allocate.
415 * The memory block of size len that was allocated.
418 * The memory block is always 8-byte aligned.
419 * If the function is unable to allocate memory an RPC_X_NO_MEMORY
420 * exception is raised.
422 void * WINAPI
NdrAllocate(MIDL_STUB_MESSAGE
*pStubMsg
, SIZE_T len
)
427 NDR_MEMORY_LIST
*mem_list
;
429 aligned_len
= (len
+ 7) & ~7;
430 adjusted_len
= aligned_len
+ sizeof(NDR_MEMORY_LIST
);
431 /* check for overflow */
432 if (adjusted_len
< len
)
434 ERR("overflow of adjusted_len %ld, len %ld\n", adjusted_len
, len
);
435 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
438 p
= pStubMsg
->pfnAllocate(adjusted_len
);
439 if (!p
) RpcRaiseException(RPC_X_NO_MEMORY
);
441 mem_list
= (NDR_MEMORY_LIST
*)((char *)p
+ aligned_len
);
442 mem_list
->magic
= MEML_MAGIC
;
443 mem_list
->size
= aligned_len
;
444 mem_list
->reserved
= 0;
445 mem_list
->next
= pStubMsg
->pMemoryList
;
446 pStubMsg
->pMemoryList
= mem_list
;
452 static void *NdrAllocateZero(MIDL_STUB_MESSAGE
*stubmsg
, SIZE_T len
)
454 void *mem
= NdrAllocate(stubmsg
, len
);
459 static void NdrFree(MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *Pointer
)
461 TRACE("(%p, %p)\n", pStubMsg
, Pointer
);
463 pStubMsg
->pfnFree(Pointer
);
466 static inline BOOL
IsConformanceOrVariancePresent(PFORMAT_STRING pFormat
)
468 return (*(const ULONG
*)pFormat
!= -1);
471 static inline PFORMAT_STRING
SkipConformance(const PMIDL_STUB_MESSAGE pStubMsg
, const PFORMAT_STRING pFormat
)
473 return pFormat
+ 4 + pStubMsg
->CorrDespIncrement
;
476 static PFORMAT_STRING
ReadConformance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
)
478 align_pointer(&pStubMsg
->Buffer
, 4);
479 if (pStubMsg
->Buffer
+ 4 > pStubMsg
->BufferEnd
)
480 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
481 pStubMsg
->MaxCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
482 pStubMsg
->Buffer
+= 4;
483 TRACE("unmarshalled conformance is %ld\n", pStubMsg
->MaxCount
);
484 return SkipConformance(pStubMsg
, pFormat
);
487 static inline PFORMAT_STRING
ReadVariance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
, ULONG MaxValue
)
489 if (pFormat
&& !IsConformanceOrVariancePresent(pFormat
))
491 pStubMsg
->Offset
= 0;
492 pStubMsg
->ActualCount
= pStubMsg
->MaxCount
;
496 align_pointer(&pStubMsg
->Buffer
, 4);
497 if (pStubMsg
->Buffer
+ 8 > pStubMsg
->BufferEnd
)
498 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
499 pStubMsg
->Offset
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
500 pStubMsg
->Buffer
+= 4;
501 TRACE("offset is %d\n", pStubMsg
->Offset
);
502 pStubMsg
->ActualCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
503 pStubMsg
->Buffer
+= 4;
504 TRACE("variance is %d\n", pStubMsg
->ActualCount
);
506 if ((pStubMsg
->ActualCount
> MaxValue
) ||
507 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> MaxValue
))
509 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
510 pStubMsg
->ActualCount
, pStubMsg
->Offset
, MaxValue
);
511 RpcRaiseException(RPC_S_INVALID_BOUND
);
516 return SkipConformance(pStubMsg
, pFormat
);
519 /* writes the conformance value to the buffer */
520 static inline void WriteConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
522 align_pointer_clear(&pStubMsg
->Buffer
, 4);
523 if (pStubMsg
->Buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
524 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
525 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->MaxCount
);
526 pStubMsg
->Buffer
+= 4;
529 /* writes the variance values to the buffer */
530 static inline void WriteVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
532 align_pointer_clear(&pStubMsg
->Buffer
, 4);
533 if (pStubMsg
->Buffer
+ 8 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
534 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
535 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->Offset
);
536 pStubMsg
->Buffer
+= 4;
537 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->ActualCount
);
538 pStubMsg
->Buffer
+= 4;
541 /* requests buffer space for the conformance value */
542 static inline void SizeConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
544 align_length(&pStubMsg
->BufferLength
, 4);
545 if (pStubMsg
->BufferLength
+ 4 < pStubMsg
->BufferLength
)
546 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
547 pStubMsg
->BufferLength
+= 4;
550 /* requests buffer space for the variance values */
551 static inline void SizeVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
553 align_length(&pStubMsg
->BufferLength
, 4);
554 if (pStubMsg
->BufferLength
+ 8 < pStubMsg
->BufferLength
)
555 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
556 pStubMsg
->BufferLength
+= 8;
559 PFORMAT_STRING
ComputeConformanceOrVariance(
560 MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *pMemory
,
561 PFORMAT_STRING pFormat
, ULONG_PTR def
, ULONG_PTR
*pCount
)
563 BYTE dtype
= pFormat
[0] & 0xf;
564 short ofs
= *(const short *)&pFormat
[2];
568 if (!IsConformanceOrVariancePresent(pFormat
)) {
569 /* null descriptor */
574 switch (pFormat
[0] & 0xf0) {
575 case FC_NORMAL_CONFORMANCE
:
576 TRACE("normal conformance, ofs=%d\n", ofs
);
579 case FC_POINTER_CONFORMANCE
:
580 TRACE("pointer conformance, ofs=%d\n", ofs
);
581 ptr
= pStubMsg
->Memory
;
583 case FC_TOP_LEVEL_CONFORMANCE
:
584 TRACE("toplevel conformance, ofs=%d\n", ofs
);
585 if (pStubMsg
->StackTop
) {
586 ptr
= pStubMsg
->StackTop
;
589 /* -Os mode, *pCount is already set */
593 case FC_CONSTANT_CONFORMANCE
:
594 data
= ofs
| ((DWORD
)pFormat
[1] << 16);
595 TRACE("constant conformance, val=%ld\n", data
);
598 case FC_TOP_LEVEL_MULTID_CONFORMANCE
:
599 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs
);
600 if (pStubMsg
->StackTop
) {
601 ptr
= pStubMsg
->StackTop
;
609 FIXME("unknown conformance type %x, expect crash.\n", pFormat
[0] & 0xf0);
613 switch (pFormat
[1]) {
615 ptr
= *(LPVOID
*)((char *)ptr
+ ofs
);
619 unsigned char *old_stack_top
= pStubMsg
->StackTop
;
620 ULONG_PTR max_count
, old_max_count
= pStubMsg
->MaxCount
;
622 pStubMsg
->StackTop
= ptr
;
624 /* ofs is index into StubDesc->apfnExprEval */
625 TRACE("callback conformance into apfnExprEval[%d]\n", ofs
);
626 pStubMsg
->StubDesc
->apfnExprEval
[ofs
](pStubMsg
);
628 pStubMsg
->StackTop
= old_stack_top
;
630 /* the callback function always stores the computed value in MaxCount */
631 max_count
= pStubMsg
->MaxCount
;
632 pStubMsg
->MaxCount
= old_max_count
;
637 ptr
= (char *)ptr
+ ofs
;
650 data
= *(USHORT
*)ptr
;
661 data
= *(ULONGLONG
*)ptr
;
664 FIXME("unknown conformance data type %x\n", dtype
);
667 TRACE("dereferenced data type %x at %p, got %ld\n", dtype
, ptr
, data
);
670 switch (pFormat
[1]) {
671 case FC_DEREFERENCE
: /* already handled */
688 FIXME("unknown conformance op %d\n", pFormat
[1]);
693 TRACE("resulting conformance is %ld\n", *pCount
);
695 return SkipConformance(pStubMsg
, pFormat
);
698 static inline PFORMAT_STRING
SkipVariance(PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
700 return SkipConformance( pStubMsg
, pFormat
);
703 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
704 * the result overflows 32-bits */
705 static inline ULONG
safe_multiply(ULONG a
, ULONG b
)
707 ULONGLONG ret
= (ULONGLONG
)a
* b
;
708 if (ret
> 0xffffffff)
710 RpcRaiseException(RPC_S_INVALID_BOUND
);
716 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
718 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
719 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
720 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
721 pStubMsg
->Buffer
+= size
;
724 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
726 if (pStubMsg
->BufferLength
+ size
< pStubMsg
->BufferLength
) /* integer overflow of pStubMsg->BufferSize */
728 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
729 pStubMsg
->BufferLength
, size
);
730 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
732 pStubMsg
->BufferLength
+= size
;
735 /* copies data from the buffer, checking that there is enough data in the buffer
737 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, void *p
, ULONG size
)
739 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
740 (pStubMsg
->Buffer
+ size
> pStubMsg
->BufferEnd
))
742 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
743 pStubMsg
->Buffer
, pStubMsg
->BufferEnd
, size
);
744 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
746 if (p
== pStubMsg
->Buffer
)
747 ERR("pointer is the same as the buffer\n");
748 memcpy(p
, pStubMsg
->Buffer
, size
);
749 pStubMsg
->Buffer
+= size
;
752 /* copies data to the buffer, checking that there is enough space to do so */
753 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, const void *p
, ULONG size
)
755 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
756 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
758 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
759 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
,
761 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
763 memcpy(pStubMsg
->Buffer
, p
, size
);
764 pStubMsg
->Buffer
+= size
;
767 /* verify that string data sitting in the buffer is valid and safe to
769 static void validate_string_data(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG bufsize
, ULONG esize
)
773 /* verify the buffer is safe to access */
774 if ((pStubMsg
->Buffer
+ bufsize
< pStubMsg
->Buffer
) ||
775 (pStubMsg
->Buffer
+ bufsize
> pStubMsg
->BufferEnd
))
777 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize
,
778 pStubMsg
->BufferEnd
, pStubMsg
->Buffer
);
779 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
782 /* strings must always have null terminating bytes */
785 ERR("invalid string length of %d\n", bufsize
/ esize
);
786 RpcRaiseException(RPC_S_INVALID_BOUND
);
789 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
790 if (pStubMsg
->Buffer
[i
] != 0)
792 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
793 i
, pStubMsg
->Buffer
[i
]);
794 RpcRaiseException(RPC_S_INVALID_BOUND
);
798 static inline void dump_pointer_attr(unsigned char attr
)
800 if (attr
& FC_ALLOCATE_ALL_NODES
)
801 TRACE(" FC_ALLOCATE_ALL_NODES");
802 if (attr
& FC_DONT_FREE
)
803 TRACE(" FC_DONT_FREE");
804 if (attr
& FC_ALLOCED_ON_STACK
)
805 TRACE(" FC_ALLOCED_ON_STACK");
806 if (attr
& FC_SIMPLE_POINTER
)
807 TRACE(" FC_SIMPLE_POINTER");
808 if (attr
& FC_POINTER_DEREF
)
809 TRACE(" FC_POINTER_DEREF");
813 /***********************************************************************
814 * PointerMarshall [internal]
816 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
817 unsigned char *Buffer
,
818 unsigned char *Pointer
,
819 PFORMAT_STRING pFormat
)
821 unsigned type
= pFormat
[0], attr
= pFormat
[1];
825 BOOL pointer_needs_marshaling
;
827 TRACE("(%p,%p,%p,%p)\n", pStubMsg
, Buffer
, Pointer
, pFormat
);
828 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
830 if (attr
& FC_SIMPLE_POINTER
) desc
= pFormat
;
831 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
834 case FC_RP
: /* ref pointer (always non-null) */
837 ERR("NULL ref pointer is not allowed\n");
838 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
840 pointer_needs_marshaling
= TRUE
;
842 case FC_UP
: /* unique pointer */
843 case FC_OP
: /* object pointer - same as unique here */
845 pointer_needs_marshaling
= TRUE
;
847 pointer_needs_marshaling
= FALSE
;
848 pointer_id
= Pointer
? NDR_POINTER_ID(pStubMsg
) : 0;
849 TRACE("writing 0x%08x to buffer\n", pointer_id
);
850 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
853 pointer_needs_marshaling
= !NdrFullPointerQueryPointer(
854 pStubMsg
->FullPtrXlatTables
, Pointer
, 1, &pointer_id
);
855 TRACE("writing 0x%08x to buffer\n", pointer_id
);
856 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
859 FIXME("unhandled ptr type=%02x\n", type
);
860 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
864 TRACE("calling marshaller for type 0x%x\n", (int)*desc
);
866 if (pointer_needs_marshaling
) {
867 if (attr
& FC_POINTER_DEREF
) {
868 Pointer
= *(unsigned char**)Pointer
;
869 TRACE("deref => %p\n", Pointer
);
871 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
872 if (m
) m(pStubMsg
, Pointer
, desc
);
873 else FIXME("no marshaller for data type=%02x\n", *desc
);
876 STD_OVERFLOW_CHECK(pStubMsg
);
879 /* pPointer is the pointer that we will unmarshal into; pSrcPointer is the
880 * pointer to memory which we may attempt to reuse if non-NULL. Usually these
881 * are the same; for the case when they aren't, see EmbeddedPointerUnmarshall().
883 * fMustAlloc seems to determine whether we can allocate from the buffer (if we
884 * are on the server side). It's ignored here, since we can't allocate a pointer
885 * from the buffer. */
886 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
887 unsigned char *Buffer
,
888 unsigned char **pPointer
,
889 unsigned char *pSrcPointer
,
890 PFORMAT_STRING pFormat
,
891 unsigned char fMustAlloc
)
893 unsigned type
= pFormat
[0], attr
= pFormat
[1];
896 DWORD pointer_id
= 0;
897 BOOL pointer_needs_unmarshaling
, need_alloc
= FALSE
, inner_must_alloc
= FALSE
;
899 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg
, Buffer
, pPointer
, pSrcPointer
, pFormat
, fMustAlloc
);
900 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
902 if (attr
& FC_SIMPLE_POINTER
) desc
= pFormat
;
903 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
906 case FC_RP
: /* ref pointer (always non-null) */
907 pointer_needs_unmarshaling
= TRUE
;
909 case FC_UP
: /* unique pointer */
910 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
911 TRACE("pointer_id is 0x%08x\n", pointer_id
);
913 pointer_needs_unmarshaling
= TRUE
;
916 pointer_needs_unmarshaling
= FALSE
;
919 case FC_OP
: /* object pointer - we must free data before overwriting it */
920 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
921 TRACE("pointer_id is 0x%08x\n", pointer_id
);
923 /* An object pointer always allocates new memory (it cannot point to the
925 inner_must_alloc
= TRUE
;
928 FIXME("free object pointer %p\n", pSrcPointer
);
930 pointer_needs_unmarshaling
= TRUE
;
934 pointer_needs_unmarshaling
= FALSE
;
938 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
939 TRACE("pointer_id is 0x%08x\n", pointer_id
);
940 pointer_needs_unmarshaling
= !NdrFullPointerQueryRefId(
941 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, (void **)pPointer
);
944 FIXME("unhandled ptr type=%02x\n", type
);
945 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
949 if (pointer_needs_unmarshaling
) {
950 unsigned char **current_ptr
= pPointer
;
951 if (pStubMsg
->IsClient
) {
953 /* Try to use the existing (source) pointer to unmarshall the data into
954 * so that [in, out] or [out, ref] parameters behave correctly. If the
955 * source pointer is NULL and we are not dereferencing, we must force the
956 * inner marshalling routine to allocate, since otherwise it will crash. */
959 TRACE("setting *pPointer to %p\n", pSrcPointer
);
960 *pPointer
= pSrcPointer
;
963 need_alloc
= inner_must_alloc
= TRUE
;
966 /* We can use an existing source pointer here only if it is on-stack,
967 * probably since otherwise NdrPointerFree() might later try to free a
968 * pointer we don't know the provenance of. Otherwise we must always
969 * allocate if we are dereferencing. We never need to force the inner
970 * routine to allocate here, since it will either write into an existing
971 * pointer, or use a pointer to the buffer. */
972 if (attr
& FC_POINTER_DEREF
)
974 if (pSrcPointer
&& (attr
& FC_ALLOCED_ON_STACK
))
975 *pPointer
= pSrcPointer
;
983 if (attr
& FC_ALLOCATE_ALL_NODES
)
984 FIXME("FC_ALLOCATE_ALL_NODES not implemented\n");
986 if (attr
& FC_POINTER_DEREF
) {
988 *pPointer
= NdrAllocateZero(pStubMsg
, sizeof(void *));
990 current_ptr
= *(unsigned char***)current_ptr
;
991 TRACE("deref => %p\n", current_ptr
);
993 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
994 if (m
) m(pStubMsg
, current_ptr
, desc
, inner_must_alloc
);
995 else FIXME("no unmarshaller for data type=%02x\n", *desc
);
998 NdrFullPointerInsertRefId(pStubMsg
->FullPtrXlatTables
, pointer_id
,
1002 TRACE("pointer=%p\n", *pPointer
);
1005 /***********************************************************************
1006 * PointerBufferSize [internal]
1008 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1009 unsigned char *Pointer
,
1010 PFORMAT_STRING pFormat
)
1012 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1013 PFORMAT_STRING desc
;
1015 BOOL pointer_needs_sizing
;
1018 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1019 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1021 if (attr
& FC_SIMPLE_POINTER
) desc
= pFormat
;
1022 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1025 case FC_RP
: /* ref pointer (always non-null) */
1028 ERR("NULL ref pointer is not allowed\n");
1029 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
1034 /* NULL pointer has no further representation */
1039 pointer_needs_sizing
= !NdrFullPointerQueryPointer(
1040 pStubMsg
->FullPtrXlatTables
, Pointer
, 0, &pointer_id
);
1041 if (!pointer_needs_sizing
)
1045 FIXME("unhandled ptr type=%02x\n", type
);
1046 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1050 if (attr
& FC_POINTER_DEREF
) {
1051 Pointer
= *(unsigned char**)Pointer
;
1052 TRACE("deref => %p\n", Pointer
);
1055 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
1056 if (m
) m(pStubMsg
, Pointer
, desc
);
1057 else FIXME("no buffersizer for data type=%02x\n", *desc
);
1060 /***********************************************************************
1061 * PointerMemorySize [internal]
1063 static ULONG
PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1064 unsigned char *Buffer
, PFORMAT_STRING pFormat
)
1066 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1067 PFORMAT_STRING desc
;
1069 DWORD pointer_id
= 0;
1070 BOOL pointer_needs_sizing
;
1072 TRACE("(%p,%p,%p)\n", pStubMsg
, Buffer
, pFormat
);
1073 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1075 if (attr
& FC_SIMPLE_POINTER
) desc
= pFormat
;
1076 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1079 case FC_RP
: /* ref pointer (always non-null) */
1080 pointer_needs_sizing
= TRUE
;
1082 case FC_UP
: /* unique pointer */
1083 case FC_OP
: /* object pointer - we must free data before overwriting it */
1084 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1085 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1087 pointer_needs_sizing
= TRUE
;
1089 pointer_needs_sizing
= FALSE
;
1094 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1095 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1096 pointer_needs_sizing
= !NdrFullPointerQueryRefId(
1097 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, &pointer
);
1101 FIXME("unhandled ptr type=%02x\n", type
);
1102 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1106 if (attr
& FC_POINTER_DEREF
) {
1107 align_length(&pStubMsg
->MemorySize
, sizeof(void*));
1108 pStubMsg
->MemorySize
+= sizeof(void*);
1112 if (pointer_needs_sizing
) {
1113 m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
1114 if (m
) m(pStubMsg
, desc
);
1115 else FIXME("no memorysizer for data type=%02x\n", *desc
);
1118 return pStubMsg
->MemorySize
;
1121 /***********************************************************************
1122 * PointerFree [internal]
1124 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1125 unsigned char *Pointer
,
1126 PFORMAT_STRING pFormat
)
1128 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1129 PFORMAT_STRING desc
;
1131 unsigned char *current_pointer
= Pointer
;
1133 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1134 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1135 if (attr
& FC_DONT_FREE
) return;
1137 if (attr
& FC_SIMPLE_POINTER
) desc
= pFormat
;
1138 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1140 if (!Pointer
) return;
1142 if (type
== FC_FP
) {
1143 int pointer_needs_freeing
= NdrFullPointerFree(
1144 pStubMsg
->FullPtrXlatTables
, Pointer
);
1145 if (!pointer_needs_freeing
)
1149 if (attr
& FC_POINTER_DEREF
) {
1150 current_pointer
= *(unsigned char**)Pointer
;
1151 TRACE("deref => %p\n", current_pointer
);
1154 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
1155 if (m
) m(pStubMsg
, current_pointer
, desc
);
1157 /* this check stops us from trying to free buffer memory. we don't have to
1158 * worry about clients, since they won't call this function.
1159 * we don't have to check for the buffer being reallocated because
1160 * BufferStart and BufferEnd won't be reset when allocating memory for
1161 * sending the response. we don't have to check for the new buffer here as
1162 * it won't be used a type memory, only for buffer memory */
1163 if (Pointer
>= pStubMsg
->BufferStart
&& Pointer
<= pStubMsg
->BufferEnd
)
1166 if (attr
& FC_ALLOCED_ON_STACK
) {
1167 TRACE("not freeing stack ptr %p\n", Pointer
);
1170 TRACE("freeing %p\n", Pointer
);
1171 NdrFree(pStubMsg
, Pointer
);
1174 TRACE("not freeing %p\n", Pointer
);
1177 /***********************************************************************
1178 * EmbeddedPointerMarshall
1180 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1181 unsigned char *pMemory
,
1182 PFORMAT_STRING pFormat
)
1184 unsigned char *Mark
= pStubMsg
->BufferMark
;
1185 unsigned rep
, count
, stride
;
1187 unsigned char *saved_buffer
= NULL
;
1189 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1191 if (*pFormat
!= FC_PP
) return NULL
;
1194 if (pStubMsg
->PointerBufferMark
)
1196 saved_buffer
= pStubMsg
->Buffer
;
1197 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1198 pStubMsg
->PointerBufferMark
= NULL
;
1201 while (pFormat
[0] != FC_END
) {
1202 switch (pFormat
[0]) {
1204 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat
[0]);
1212 case FC_FIXED_REPEAT
:
1213 rep
= *(const WORD
*)&pFormat
[2];
1214 stride
= *(const WORD
*)&pFormat
[4];
1215 count
= *(const WORD
*)&pFormat
[8];
1218 case FC_VARIABLE_REPEAT
:
1219 rep
= (pFormat
[1] == FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1220 stride
= *(const WORD
*)&pFormat
[2];
1221 count
= *(const WORD
*)&pFormat
[6];
1225 for (i
= 0; i
< rep
; i
++) {
1226 PFORMAT_STRING info
= pFormat
;
1227 unsigned char *membase
= pMemory
+ (i
* stride
);
1228 unsigned char *bufbase
= Mark
+ (i
* stride
);
1231 for (u
=0; u
<count
; u
++,info
+=8) {
1232 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1233 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1234 unsigned char *saved_memory
= pStubMsg
->Memory
;
1236 pStubMsg
->Memory
= membase
;
1237 PointerMarshall(pStubMsg
, bufptr
, *(unsigned char**)memptr
, info
+4);
1238 pStubMsg
->Memory
= saved_memory
;
1241 pFormat
+= 8 * count
;
1246 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1247 pStubMsg
->Buffer
= saved_buffer
;
1250 STD_OVERFLOW_CHECK(pStubMsg
);
1255 /* rpcrt4 does something bizarre with embedded pointers: instead of copying the
1256 * struct/array/union from the buffer to memory and then unmarshalling pointers
1257 * into it, it unmarshals pointers into the buffer itself and then copies it to
1258 * memory. However, it will still attempt to use a user-supplied pointer where
1259 * appropriate (i.e. one on stack). Therefore we need to pass both pointers to
1260 * this function and to PointerUnmarshall: the pointer (to the buffer) that we
1261 * will actually unmarshal into (pDstBuffer), and the pointer (to memory) that
1262 * we will attempt to use for storage if possible (pSrcMemoryPtrs). */
1263 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1264 unsigned char *pDstBuffer
,
1265 unsigned char *pSrcMemoryPtrs
,
1266 PFORMAT_STRING pFormat
,
1267 unsigned char fMustAlloc
)
1269 unsigned char *Mark
= pStubMsg
->BufferMark
;
1270 unsigned rep
, count
, stride
;
1272 unsigned char *saved_buffer
= NULL
;
1274 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg
, pDstBuffer
, pSrcMemoryPtrs
, pFormat
, fMustAlloc
);
1276 if (*pFormat
!= FC_PP
) return NULL
;
1279 if (pStubMsg
->PointerBufferMark
)
1281 saved_buffer
= pStubMsg
->Buffer
;
1282 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1283 pStubMsg
->PointerBufferMark
= NULL
;
1286 while (pFormat
[0] != FC_END
) {
1287 TRACE("pFormat[0] = 0x%x\n", pFormat
[0]);
1288 switch (pFormat
[0]) {
1290 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat
[0]);
1298 case FC_FIXED_REPEAT
:
1299 rep
= *(const WORD
*)&pFormat
[2];
1300 stride
= *(const WORD
*)&pFormat
[4];
1301 count
= *(const WORD
*)&pFormat
[8];
1304 case FC_VARIABLE_REPEAT
:
1305 rep
= (pFormat
[1] == FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1306 stride
= *(const WORD
*)&pFormat
[2];
1307 count
= *(const WORD
*)&pFormat
[6];
1311 for (i
= 0; i
< rep
; i
++) {
1312 PFORMAT_STRING info
= pFormat
;
1313 unsigned char *bufdstbase
= pDstBuffer
+ (i
* stride
);
1314 unsigned char *memsrcbase
= pSrcMemoryPtrs
+ (i
* stride
);
1315 unsigned char *bufbase
= Mark
+ (i
* stride
);
1318 for (u
=0; u
<count
; u
++,info
+=8) {
1319 unsigned char **bufdstptr
= (unsigned char **)(bufdstbase
+ *(const SHORT
*)&info
[2]);
1320 unsigned char **memsrcptr
= (unsigned char **)(memsrcbase
+ *(const SHORT
*)&info
[0]);
1321 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1322 PointerUnmarshall(pStubMsg
, bufptr
, bufdstptr
, *memsrcptr
, info
+4, fMustAlloc
);
1325 pFormat
+= 8 * count
;
1330 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1331 pStubMsg
->Buffer
= saved_buffer
;
1337 /***********************************************************************
1338 * EmbeddedPointerBufferSize
1340 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1341 unsigned char *pMemory
,
1342 PFORMAT_STRING pFormat
)
1344 unsigned rep
, count
, stride
;
1346 ULONG saved_buffer_length
= 0;
1348 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1350 if (pStubMsg
->IgnoreEmbeddedPointers
) return;
1352 if (*pFormat
!= FC_PP
) return;
1355 if (pStubMsg
->PointerLength
)
1357 saved_buffer_length
= pStubMsg
->BufferLength
;
1358 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
1359 pStubMsg
->PointerLength
= 0;
1362 while (pFormat
[0] != FC_END
) {
1363 switch (pFormat
[0]) {
1365 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat
[0]);
1373 case FC_FIXED_REPEAT
:
1374 rep
= *(const WORD
*)&pFormat
[2];
1375 stride
= *(const WORD
*)&pFormat
[4];
1376 count
= *(const WORD
*)&pFormat
[8];
1379 case FC_VARIABLE_REPEAT
:
1380 rep
= (pFormat
[1] == FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1381 stride
= *(const WORD
*)&pFormat
[2];
1382 count
= *(const WORD
*)&pFormat
[6];
1386 for (i
= 0; i
< rep
; i
++) {
1387 PFORMAT_STRING info
= pFormat
;
1388 unsigned char *membase
= pMemory
+ (i
* stride
);
1391 for (u
=0; u
<count
; u
++,info
+=8) {
1392 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1393 unsigned char *saved_memory
= pStubMsg
->Memory
;
1395 pStubMsg
->Memory
= membase
;
1396 PointerBufferSize(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1397 pStubMsg
->Memory
= saved_memory
;
1400 pFormat
+= 8 * count
;
1403 if (saved_buffer_length
)
1405 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
1406 pStubMsg
->BufferLength
= saved_buffer_length
;
1410 /***********************************************************************
1411 * EmbeddedPointerMemorySize [internal]
1413 static ULONG
EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1414 PFORMAT_STRING pFormat
)
1416 unsigned char *Mark
= pStubMsg
->BufferMark
;
1417 unsigned rep
, count
, stride
;
1419 unsigned char *saved_buffer
= NULL
;
1421 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1423 if (pStubMsg
->IgnoreEmbeddedPointers
) return 0;
1425 if (pStubMsg
->PointerBufferMark
)
1427 saved_buffer
= pStubMsg
->Buffer
;
1428 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1429 pStubMsg
->PointerBufferMark
= NULL
;
1432 if (*pFormat
!= FC_PP
) return 0;
1435 while (pFormat
[0] != FC_END
) {
1436 switch (pFormat
[0]) {
1438 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat
[0]);
1446 case FC_FIXED_REPEAT
:
1447 rep
= *(const WORD
*)&pFormat
[2];
1448 stride
= *(const WORD
*)&pFormat
[4];
1449 count
= *(const WORD
*)&pFormat
[8];
1452 case FC_VARIABLE_REPEAT
:
1453 rep
= (pFormat
[1] == FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1454 stride
= *(const WORD
*)&pFormat
[2];
1455 count
= *(const WORD
*)&pFormat
[6];
1459 for (i
= 0; i
< rep
; i
++) {
1460 PFORMAT_STRING info
= pFormat
;
1461 unsigned char *bufbase
= Mark
+ (i
* stride
);
1463 for (u
=0; u
<count
; u
++,info
+=8) {
1464 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1465 PointerMemorySize(pStubMsg
, bufptr
, info
+4);
1468 pFormat
+= 8 * count
;
1473 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1474 pStubMsg
->Buffer
= saved_buffer
;
1480 /***********************************************************************
1481 * EmbeddedPointerFree [internal]
1483 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1484 unsigned char *pMemory
,
1485 PFORMAT_STRING pFormat
)
1487 unsigned rep
, count
, stride
;
1490 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1491 if (*pFormat
!= FC_PP
) return;
1494 while (pFormat
[0] != FC_END
) {
1495 switch (pFormat
[0]) {
1497 FIXME("unknown repeat type %d; assuming no repeat\n", pFormat
[0]);
1505 case FC_FIXED_REPEAT
:
1506 rep
= *(const WORD
*)&pFormat
[2];
1507 stride
= *(const WORD
*)&pFormat
[4];
1508 count
= *(const WORD
*)&pFormat
[8];
1511 case FC_VARIABLE_REPEAT
:
1512 rep
= (pFormat
[1] == FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1513 stride
= *(const WORD
*)&pFormat
[2];
1514 count
= *(const WORD
*)&pFormat
[6];
1518 for (i
= 0; i
< rep
; i
++) {
1519 PFORMAT_STRING info
= pFormat
;
1520 unsigned char *membase
= pMemory
+ (i
* stride
);
1523 for (u
=0; u
<count
; u
++,info
+=8) {
1524 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1525 unsigned char *saved_memory
= pStubMsg
->Memory
;
1527 pStubMsg
->Memory
= membase
;
1528 PointerFree(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1529 pStubMsg
->Memory
= saved_memory
;
1532 pFormat
+= 8 * count
;
1536 /***********************************************************************
1537 * NdrPointerMarshall [RPCRT4.@]
1539 unsigned char * WINAPI
NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1540 unsigned char *pMemory
,
1541 PFORMAT_STRING pFormat
)
1543 unsigned char *Buffer
;
1545 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1547 /* Increment the buffer here instead of in PointerMarshall,
1548 * as that is used by embedded pointers which already handle the incrementing
1549 * the buffer, and shouldn't write any additional pointer data to the wire */
1550 if (*pFormat
!= FC_RP
)
1552 align_pointer_clear(&pStubMsg
->Buffer
, 4);
1553 Buffer
= pStubMsg
->Buffer
;
1554 safe_buffer_increment(pStubMsg
, 4);
1557 Buffer
= pStubMsg
->Buffer
;
1559 PointerMarshall(pStubMsg
, Buffer
, pMemory
, pFormat
);
1564 /***********************************************************************
1565 * NdrPointerUnmarshall [RPCRT4.@]
1567 unsigned char * WINAPI
NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1568 unsigned char **ppMemory
,
1569 PFORMAT_STRING pFormat
,
1570 unsigned char fMustAlloc
)
1572 unsigned char *Buffer
;
1574 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1576 if (*pFormat
== FC_RP
)
1578 Buffer
= pStubMsg
->Buffer
;
1579 /* Do the NULL ref pointer check here because embedded pointers can be
1580 * NULL if the type the pointer is embedded in was allocated rather than
1581 * being passed in by the client */
1582 if (pStubMsg
->IsClient
&& !*ppMemory
)
1584 ERR("NULL ref pointer is not allowed\n");
1585 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
1590 /* Increment the buffer here instead of in PointerUnmarshall,
1591 * as that is used by embedded pointers which already handle the incrementing
1592 * the buffer, and shouldn't read any additional pointer data from the
1594 align_pointer(&pStubMsg
->Buffer
, 4);
1595 Buffer
= pStubMsg
->Buffer
;
1596 safe_buffer_increment(pStubMsg
, 4);
1599 PointerUnmarshall(pStubMsg
, Buffer
, ppMemory
, *ppMemory
, pFormat
, fMustAlloc
);
1604 /***********************************************************************
1605 * NdrPointerBufferSize [RPCRT4.@]
1607 void WINAPI
NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1608 unsigned char *pMemory
,
1609 PFORMAT_STRING pFormat
)
1611 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1613 /* Increment the buffer length here instead of in PointerBufferSize,
1614 * as that is used by embedded pointers which already handle the buffer
1615 * length, and shouldn't write anything more to the wire */
1616 if (*pFormat
!= FC_RP
)
1618 align_length(&pStubMsg
->BufferLength
, 4);
1619 safe_buffer_length_increment(pStubMsg
, 4);
1622 PointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1625 /***********************************************************************
1626 * NdrPointerMemorySize [RPCRT4.@]
1628 ULONG WINAPI
NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1629 PFORMAT_STRING pFormat
)
1631 unsigned char *Buffer
= pStubMsg
->Buffer
;
1632 if (*pFormat
!= FC_RP
)
1634 align_pointer(&pStubMsg
->Buffer
, 4);
1635 safe_buffer_increment(pStubMsg
, 4);
1637 align_length(&pStubMsg
->MemorySize
, sizeof(void *));
1638 return PointerMemorySize(pStubMsg
, Buffer
, pFormat
);
1641 /***********************************************************************
1642 * NdrPointerFree [RPCRT4.@]
1644 void WINAPI
NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1645 unsigned char *pMemory
,
1646 PFORMAT_STRING pFormat
)
1648 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1649 PointerFree(pStubMsg
, pMemory
, pFormat
);
1652 /***********************************************************************
1653 * NdrSimpleTypeMarshall [RPCRT4.@]
1655 void WINAPI
NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1656 unsigned char FormatChar
)
1658 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &FormatChar
);
1661 /***********************************************************************
1662 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1664 * Unmarshall a base type.
1667 * Doesn't check that the buffer is long enough before copying, so the caller
1670 void WINAPI
NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1671 unsigned char FormatChar
)
1673 #define BASE_TYPE_UNMARSHALL(type) \
1674 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
1675 TRACE("pMemory: %p\n", pMemory); \
1676 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1677 pStubMsg->Buffer += sizeof(type);
1685 BASE_TYPE_UNMARSHALL(UCHAR
);
1686 TRACE("value: 0x%02x\n", *pMemory
);
1691 BASE_TYPE_UNMARSHALL(USHORT
);
1692 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
1696 case FC_ERROR_STATUS_T
:
1698 BASE_TYPE_UNMARSHALL(ULONG
);
1699 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
1702 BASE_TYPE_UNMARSHALL(float);
1703 TRACE("value: %f\n", *(float *)pMemory
);
1706 BASE_TYPE_UNMARSHALL(double);
1707 TRACE("value: %f\n", *(double *)pMemory
);
1710 BASE_TYPE_UNMARSHALL(ULONGLONG
);
1711 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
1714 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
1715 TRACE("pMemory: %p\n", pMemory
);
1716 /* 16-bits on the wire, but int in memory */
1717 *(UINT
*)pMemory
= *(USHORT
*)pStubMsg
->Buffer
;
1718 pStubMsg
->Buffer
+= sizeof(USHORT
);
1719 TRACE("value: 0x%08x\n", *(UINT
*)pMemory
);
1722 align_pointer(&pStubMsg
->Buffer
, sizeof(INT
));
1723 /* 32-bits on the wire, but int_ptr in memory */
1724 *(INT_PTR
*)pMemory
= *(INT
*)pStubMsg
->Buffer
;
1725 pStubMsg
->Buffer
+= sizeof(INT
);
1726 TRACE("value: 0x%08lx\n", *(INT_PTR
*)pMemory
);
1729 align_pointer(&pStubMsg
->Buffer
, sizeof(UINT
));
1730 /* 32-bits on the wire, but int_ptr in memory */
1731 *(UINT_PTR
*)pMemory
= *(UINT
*)pStubMsg
->Buffer
;
1732 pStubMsg
->Buffer
+= sizeof(UINT
);
1733 TRACE("value: 0x%08lx\n", *(UINT_PTR
*)pMemory
);
1738 FIXME("Unhandled base type: 0x%02x\n", FormatChar
);
1740 #undef BASE_TYPE_UNMARSHALL
1743 /***********************************************************************
1744 * NdrSimpleStructMarshall [RPCRT4.@]
1746 unsigned char * WINAPI
NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1747 unsigned char *pMemory
,
1748 PFORMAT_STRING pFormat
)
1750 unsigned size
= *(const WORD
*)(pFormat
+2);
1751 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1753 align_pointer_clear(&pStubMsg
->Buffer
, pFormat
[1] + 1);
1755 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1756 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
1758 if (pFormat
[0] != FC_STRUCT
)
1759 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
+4);
1764 /***********************************************************************
1765 * NdrSimpleStructUnmarshall [RPCRT4.@]
1767 unsigned char * WINAPI
NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1768 unsigned char **ppMemory
,
1769 PFORMAT_STRING pFormat
,
1770 unsigned char fMustAlloc
)
1772 unsigned size
= *(const WORD
*)(pFormat
+2);
1773 unsigned char *saved_buffer
;
1774 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1776 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
1779 *ppMemory
= NdrAllocateZero(pStubMsg
, size
);
1782 if (!pStubMsg
->IsClient
&& !*ppMemory
)
1783 /* for servers, we just point straight into the RPC buffer */
1784 *ppMemory
= pStubMsg
->Buffer
;
1787 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1788 safe_buffer_increment(pStubMsg
, size
);
1789 if (pFormat
[0] == FC_PSTRUCT
)
1790 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
+4, fMustAlloc
);
1792 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
1793 if (*ppMemory
!= saved_buffer
)
1794 memcpy(*ppMemory
, saved_buffer
, size
);
1799 /***********************************************************************
1800 * NdrSimpleStructBufferSize [RPCRT4.@]
1802 void WINAPI
NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1803 unsigned char *pMemory
,
1804 PFORMAT_STRING pFormat
)
1806 unsigned size
= *(const WORD
*)(pFormat
+2);
1807 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1809 align_length(&pStubMsg
->BufferLength
, pFormat
[1] + 1);
1811 safe_buffer_length_increment(pStubMsg
, size
);
1812 if (pFormat
[0] != FC_STRUCT
)
1813 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
+4);
1816 /***********************************************************************
1817 * NdrSimpleStructMemorySize [RPCRT4.@]
1819 ULONG WINAPI
NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1820 PFORMAT_STRING pFormat
)
1822 unsigned short size
= *(const WORD
*)(pFormat
+2);
1824 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1826 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
1827 pStubMsg
->MemorySize
+= size
;
1828 safe_buffer_increment(pStubMsg
, size
);
1830 if (pFormat
[0] != FC_STRUCT
)
1831 EmbeddedPointerMemorySize(pStubMsg
, pFormat
+4);
1832 return pStubMsg
->MemorySize
;
1835 /***********************************************************************
1836 * NdrSimpleStructFree [RPCRT4.@]
1838 void WINAPI
NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
1839 unsigned char *pMemory
,
1840 PFORMAT_STRING pFormat
)
1842 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1843 if (pFormat
[0] != FC_STRUCT
)
1844 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
+4);
1849 static inline void array_compute_and_size_conformance(
1850 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1851 PFORMAT_STRING pFormat
)
1858 ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1859 SizeConformance(pStubMsg
);
1862 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, 0);
1863 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
1864 SizeConformance(pStubMsg
);
1868 if (fc
== FC_C_CSTRING
)
1870 TRACE("string=%s\n", debugstr_a((const char *)pMemory
));
1871 pStubMsg
->ActualCount
= strlen((const char *)pMemory
)+1;
1875 TRACE("string=%s\n", debugstr_w((LPCWSTR
)pMemory
));
1876 pStubMsg
->ActualCount
= strlenW((LPCWSTR
)pMemory
)+1;
1879 if (pFormat
[1] == FC_STRING_SIZED
)
1880 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
1882 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
1884 SizeConformance(pStubMsg
);
1886 case FC_BOGUS_ARRAY
:
1887 count
= *(const WORD
*)(pFormat
+ 2);
1889 if (IsConformanceOrVariancePresent(pFormat
)) SizeConformance(pStubMsg
);
1890 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, count
);
1891 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
1894 ERR("unknown array format 0x%x\n", fc
);
1895 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1899 static inline void array_buffer_size(
1900 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1901 PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
1905 unsigned char alignment
;
1910 esize
= *(const WORD
*)(pFormat
+2);
1911 alignment
= pFormat
[1] + 1;
1913 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1915 align_length(&pStubMsg
->BufferLength
, alignment
);
1917 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
1918 /* conformance value plus array */
1919 safe_buffer_length_increment(pStubMsg
, size
);
1922 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1925 esize
= *(const WORD
*)(pFormat
+2);
1926 alignment
= pFormat
[1] + 1;
1928 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1929 pFormat
= SkipVariance(pStubMsg
, pFormat
);
1931 SizeVariance(pStubMsg
);
1933 align_length(&pStubMsg
->BufferLength
, alignment
);
1935 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1936 safe_buffer_length_increment(pStubMsg
, size
);
1939 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1943 if (fc
== FC_C_CSTRING
)
1948 SizeVariance(pStubMsg
);
1950 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
1951 safe_buffer_length_increment(pStubMsg
, size
);
1953 case FC_BOGUS_ARRAY
:
1954 alignment
= pFormat
[1] + 1;
1955 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
1956 if (IsConformanceOrVariancePresent(pFormat
)) SizeVariance(pStubMsg
);
1957 pFormat
= SkipVariance(pStubMsg
, pFormat
);
1959 align_length(&pStubMsg
->BufferLength
, alignment
);
1961 size
= pStubMsg
->ActualCount
;
1962 for (i
= 0; i
< size
; i
++)
1963 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
1966 ERR("unknown array format 0x%x\n", fc
);
1967 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1971 static inline void array_compute_and_write_conformance(
1972 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
1973 PFORMAT_STRING pFormat
)
1976 BOOL conformance_present
;
1981 ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
1982 WriteConformance(pStubMsg
);
1985 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, 0);
1986 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
1987 WriteConformance(pStubMsg
);
1991 if (fc
== FC_C_CSTRING
)
1993 TRACE("string=%s\n", debugstr_a((const char *)pMemory
));
1994 pStubMsg
->ActualCount
= strlen((const char *)pMemory
)+1;
1998 TRACE("string=%s\n", debugstr_w((LPCWSTR
)pMemory
));
1999 pStubMsg
->ActualCount
= strlenW((LPCWSTR
)pMemory
)+1;
2001 if (pFormat
[1] == FC_STRING_SIZED
)
2002 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
2004 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
2005 pStubMsg
->Offset
= 0;
2006 WriteConformance(pStubMsg
);
2008 case FC_BOGUS_ARRAY
:
2009 def
= *(const WORD
*)(pFormat
+ 2);
2011 conformance_present
= IsConformanceOrVariancePresent(pFormat
);
2012 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
2013 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
2014 if (conformance_present
) WriteConformance(pStubMsg
);
2017 ERR("unknown array format 0x%x\n", fc
);
2018 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2022 static inline void array_write_variance_and_marshall(
2023 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
,
2024 PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
2028 unsigned char alignment
;
2033 esize
= *(const WORD
*)(pFormat
+2);
2034 alignment
= pFormat
[1] + 1;
2036 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2038 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
2040 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2042 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2043 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
2046 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2049 esize
= *(const WORD
*)(pFormat
+2);
2050 alignment
= pFormat
[1] + 1;
2052 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2053 pFormat
= SkipVariance(pStubMsg
, pFormat
);
2055 WriteVariance(pStubMsg
);
2057 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
2059 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2062 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2063 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, size
);
2066 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2070 if (fc
== FC_C_CSTRING
)
2075 WriteVariance(pStubMsg
);
2077 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2078 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
2080 case FC_BOGUS_ARRAY
:
2081 alignment
= pFormat
[1] + 1;
2082 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2083 if (IsConformanceOrVariancePresent(pFormat
)) WriteVariance(pStubMsg
);
2084 pFormat
= SkipVariance(pStubMsg
, pFormat
);
2086 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
2088 size
= pStubMsg
->ActualCount
;
2089 for (i
= 0; i
< size
; i
++)
2090 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
2093 ERR("unknown array format 0x%x\n", fc
);
2094 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2098 static inline ULONG
array_read_conformance(
2099 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
2106 esize
= *(const WORD
*)(pFormat
+2);
2107 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2108 return safe_multiply(esize
, pStubMsg
->MaxCount
);
2110 esize
= *(const WORD
*)(pFormat
+2);
2111 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2112 return safe_multiply(esize
, pStubMsg
->MaxCount
);
2115 if (fc
== FC_C_CSTRING
)
2120 if (pFormat
[1] == FC_STRING_SIZED
)
2121 ReadConformance(pStubMsg
, pFormat
+ 2);
2123 ReadConformance(pStubMsg
, NULL
);
2124 return safe_multiply(esize
, pStubMsg
->MaxCount
);
2125 case FC_BOGUS_ARRAY
:
2126 def
= *(const WORD
*)(pFormat
+ 2);
2128 if (IsConformanceOrVariancePresent(pFormat
)) pFormat
= ReadConformance(pStubMsg
, pFormat
);
2131 pStubMsg
->MaxCount
= def
;
2132 pFormat
= SkipConformance( pStubMsg
, pFormat
);
2134 pFormat
= SkipVariance( pStubMsg
, pFormat
);
2136 esize
= ComplexStructSize(pStubMsg
, pFormat
);
2137 return safe_multiply(pStubMsg
->MaxCount
, esize
);
2139 ERR("unknown array format 0x%x\n", fc
);
2140 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2144 static inline ULONG
array_read_variance_and_unmarshall(
2145 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, unsigned char **ppMemory
,
2146 PFORMAT_STRING pFormat
, unsigned char fMustAlloc
,
2147 unsigned char fUseBufferMemoryServer
, unsigned char fUnmarshall
)
2149 ULONG bufsize
, memsize
;
2151 unsigned char alignment
;
2152 unsigned char *saved_buffer
, *pMemory
;
2153 ULONG i
, offset
, count
;
2158 esize
= *(const WORD
*)(pFormat
+2);
2159 alignment
= pFormat
[1] + 1;
2161 bufsize
= memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2163 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2165 align_pointer(&pStubMsg
->Buffer
, alignment
);
2170 *ppMemory
= NdrAllocateZero(pStubMsg
, memsize
);
2173 if (fUseBufferMemoryServer
&& !pStubMsg
->IsClient
&& !*ppMemory
)
2174 /* for servers, we just point straight into the RPC buffer */
2175 *ppMemory
= pStubMsg
->Buffer
;
2178 saved_buffer
= pStubMsg
->Buffer
;
2179 safe_buffer_increment(pStubMsg
, bufsize
);
2181 pStubMsg
->BufferMark
= saved_buffer
;
2182 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
2184 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
2185 if (*ppMemory
!= saved_buffer
)
2186 memcpy(*ppMemory
, saved_buffer
, bufsize
);
2190 esize
= *(const WORD
*)(pFormat
+2);
2191 alignment
= pFormat
[1] + 1;
2193 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2195 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2197 align_pointer(&pStubMsg
->Buffer
, alignment
);
2199 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2200 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2204 offset
= pStubMsg
->Offset
;
2206 if (!fMustAlloc
&& !*ppMemory
)
2209 *ppMemory
= NdrAllocateZero(pStubMsg
, memsize
);
2210 saved_buffer
= pStubMsg
->Buffer
;
2211 safe_buffer_increment(pStubMsg
, bufsize
);
2213 pStubMsg
->BufferMark
= saved_buffer
;
2214 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
,
2217 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
2222 if (fc
== FC_C_CSTRING
)
2227 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
2229 if (pFormat
[1] != FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
2231 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2232 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
2233 RpcRaiseException(RPC_S_INVALID_BOUND
);
2235 if (pStubMsg
->Offset
)
2237 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2238 RpcRaiseException(RPC_S_INVALID_BOUND
);
2241 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2242 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2244 validate_string_data(pStubMsg
, bufsize
, esize
);
2249 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2252 if (fUseBufferMemoryServer
&& !pStubMsg
->IsClient
&&
2253 !*ppMemory
&& (pStubMsg
->MaxCount
== pStubMsg
->ActualCount
))
2254 /* if the data in the RPC buffer is big enough, we just point
2255 * straight into it */
2256 *ppMemory
= pStubMsg
->Buffer
;
2257 else if (!*ppMemory
)
2258 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2261 if (*ppMemory
== pStubMsg
->Buffer
)
2262 safe_buffer_increment(pStubMsg
, bufsize
);
2264 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
2266 if (*pFormat
== FC_C_CSTRING
)
2267 TRACE("string=%s\n", debugstr_a((char*)*ppMemory
));
2269 TRACE("string=%s\n", debugstr_w((LPWSTR
)*ppMemory
));
2273 case FC_BOGUS_ARRAY
:
2274 alignment
= pFormat
[1] + 1;
2275 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2276 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2278 esize
= ComplexStructSize(pStubMsg
, pFormat
);
2279 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2281 assert( fUnmarshall
);
2283 if (!fMustAlloc
&& !*ppMemory
)
2286 *ppMemory
= NdrAllocateZero(pStubMsg
, memsize
);
2288 align_pointer(&pStubMsg
->Buffer
, alignment
);
2289 saved_buffer
= pStubMsg
->Buffer
;
2291 pMemory
= *ppMemory
;
2292 count
= pStubMsg
->ActualCount
;
2293 for (i
= 0; i
< count
; i
++)
2294 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
, fMustAlloc
);
2295 return pStubMsg
->Buffer
- saved_buffer
;
2298 ERR("unknown array format 0x%x\n", fc
);
2299 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2303 static inline void array_memory_size(
2304 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
,
2305 unsigned char fHasPointers
)
2307 ULONG i
, count
, SavedMemorySize
;
2308 ULONG bufsize
, memsize
;
2310 unsigned char alignment
;
2315 esize
= *(const WORD
*)(pFormat
+2);
2316 alignment
= pFormat
[1] + 1;
2318 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2320 bufsize
= memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2321 pStubMsg
->MemorySize
+= memsize
;
2323 align_pointer(&pStubMsg
->Buffer
, alignment
);
2325 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2326 safe_buffer_increment(pStubMsg
, bufsize
);
2329 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2332 esize
= *(const WORD
*)(pFormat
+2);
2333 alignment
= pFormat
[1] + 1;
2335 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2337 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2339 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2340 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2341 pStubMsg
->MemorySize
+= memsize
;
2343 align_pointer(&pStubMsg
->Buffer
, alignment
);
2345 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2346 safe_buffer_increment(pStubMsg
, bufsize
);
2349 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2353 if (fc
== FC_C_CSTRING
)
2358 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
2360 if (pFormat
[1] != FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
2362 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2363 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
2364 RpcRaiseException(RPC_S_INVALID_BOUND
);
2366 if (pStubMsg
->Offset
)
2368 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2369 RpcRaiseException(RPC_S_INVALID_BOUND
);
2372 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2373 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2375 validate_string_data(pStubMsg
, bufsize
, esize
);
2377 safe_buffer_increment(pStubMsg
, bufsize
);
2378 pStubMsg
->MemorySize
+= memsize
;
2380 case FC_BOGUS_ARRAY
:
2381 alignment
= pFormat
[1] + 1;
2382 pFormat
= SkipConformance(pStubMsg
, pFormat
+ 4);
2383 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2385 align_pointer(&pStubMsg
->Buffer
, alignment
);
2387 SavedMemorySize
= pStubMsg
->MemorySize
;
2389 esize
= ComplexStructSize(pStubMsg
, pFormat
);
2390 memsize
= safe_multiply(pStubMsg
->MaxCount
, esize
);
2392 count
= pStubMsg
->ActualCount
;
2393 for (i
= 0; i
< count
; i
++)
2394 ComplexStructMemorySize(pStubMsg
, pFormat
, NULL
);
2396 pStubMsg
->MemorySize
= SavedMemorySize
+ memsize
;
2399 ERR("unknown array format 0x%x\n", fc
);
2400 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2404 static inline void array_free(
2405 unsigned char fc
, PMIDL_STUB_MESSAGE pStubMsg
,
2406 unsigned char *pMemory
, PFORMAT_STRING pFormat
, unsigned char fHasPointers
)
2413 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2415 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2418 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2419 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2421 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2425 /* No embedded pointers so nothing to do */
2427 case FC_BOGUS_ARRAY
:
2428 count
= *(const WORD
*)(pFormat
+ 2);
2429 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 4, count
);
2430 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
2432 count
= pStubMsg
->ActualCount
;
2433 for (i
= 0; i
< count
; i
++)
2434 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
2437 ERR("unknown array format 0x%x\n", fc
);
2438 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2443 * NdrConformantString:
2445 * What MS calls a ConformantString is, in DCE terminology,
2446 * a Varying-Conformant String.
2448 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2449 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2450 * into unmarshalled string)
2451 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2453 * data: CHARTYPE[maxlen]
2455 * ], where CHARTYPE is the appropriate character type (specified externally)
2459 /***********************************************************************
2460 * NdrConformantStringMarshall [RPCRT4.@]
2462 unsigned char *WINAPI
NdrConformantStringMarshall(MIDL_STUB_MESSAGE
*pStubMsg
,
2463 unsigned char *pszMessage
, PFORMAT_STRING pFormat
)
2465 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg
, pszMessage
, pFormat
);
2467 if (pFormat
[0] != FC_C_CSTRING
&& pFormat
[0] != FC_C_WSTRING
) {
2468 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2469 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2472 /* allow compiler to optimise inline function by passing constant into
2473 * these functions */
2474 if (pFormat
[0] == FC_C_CSTRING
) {
2475 array_compute_and_write_conformance(FC_C_CSTRING
, pStubMsg
, pszMessage
,
2477 array_write_variance_and_marshall(FC_C_CSTRING
, pStubMsg
, pszMessage
,
2478 pFormat
, TRUE
/* fHasPointers */);
2480 array_compute_and_write_conformance(FC_C_WSTRING
, pStubMsg
, pszMessage
,
2482 array_write_variance_and_marshall(FC_C_WSTRING
, pStubMsg
, pszMessage
,
2483 pFormat
, TRUE
/* fHasPointers */);
2489 /***********************************************************************
2490 * NdrConformantStringBufferSize [RPCRT4.@]
2492 void WINAPI
NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2493 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
2495 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2497 if (pFormat
[0] != FC_C_CSTRING
&& pFormat
[0] != FC_C_WSTRING
) {
2498 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2499 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2502 /* allow compiler to optimise inline function by passing constant into
2503 * these functions */
2504 if (pFormat
[0] == FC_C_CSTRING
) {
2505 array_compute_and_size_conformance(FC_C_CSTRING
, pStubMsg
, pMemory
,
2507 array_buffer_size(FC_C_CSTRING
, pStubMsg
, pMemory
, pFormat
,
2508 TRUE
/* fHasPointers */);
2510 array_compute_and_size_conformance(FC_C_WSTRING
, pStubMsg
, pMemory
,
2512 array_buffer_size(FC_C_WSTRING
, pStubMsg
, pMemory
, pFormat
,
2513 TRUE
/* fHasPointers */);
2517 /************************************************************************
2518 * NdrConformantStringMemorySize [RPCRT4.@]
2520 ULONG WINAPI
NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
2521 PFORMAT_STRING pFormat
)
2523 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
2525 if (pFormat
[0] != FC_C_CSTRING
&& pFormat
[0] != FC_C_WSTRING
) {
2526 ERR("Unhandled string type: %#x\n", pFormat
[0]);
2527 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2530 /* allow compiler to optimise inline function by passing constant into
2531 * these functions */
2532 if (pFormat
[0] == FC_C_CSTRING
) {
2533 array_read_conformance(FC_C_CSTRING
, pStubMsg
, pFormat
);
2534 array_memory_size(FC_C_CSTRING
, pStubMsg
, pFormat
,
2535 TRUE
/* fHasPointers */);
2537 array_read_conformance(FC_C_WSTRING
, pStubMsg
, pFormat
);
2538 array_memory_size(FC_C_WSTRING
, pStubMsg
, pFormat
,
2539 TRUE
/* fHasPointers */);
2542 return pStubMsg
->MemorySize
;
2545 /************************************************************************
2546 * NdrConformantStringUnmarshall [RPCRT4.@]
2548 unsigned char *WINAPI
NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2549 unsigned char** ppMemory
, PFORMAT_STRING pFormat
, unsigned char fMustAlloc
)
2551 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2552 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
2554 if (pFormat
[0] != FC_C_CSTRING
&& pFormat
[0] != FC_C_WSTRING
) {
2555 ERR("Unhandled string type: %#x\n", *pFormat
);
2556 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2559 /* allow compiler to optimise inline function by passing constant into
2560 * these functions */
2561 if (pFormat
[0] == FC_C_CSTRING
) {
2562 array_read_conformance(FC_C_CSTRING
, pStubMsg
, pFormat
);
2563 array_read_variance_and_unmarshall(FC_C_CSTRING
, pStubMsg
, ppMemory
,
2564 pFormat
, fMustAlloc
,
2565 TRUE
/* fUseBufferMemoryServer */,
2566 TRUE
/* fUnmarshall */);
2568 array_read_conformance(FC_C_WSTRING
, pStubMsg
, pFormat
);
2569 array_read_variance_and_unmarshall(FC_C_WSTRING
, pStubMsg
, ppMemory
,
2570 pFormat
, fMustAlloc
,
2571 TRUE
/* fUseBufferMemoryServer */,
2572 TRUE
/* fUnmarshall */);
2578 /***********************************************************************
2579 * NdrNonConformantStringMarshall [RPCRT4.@]
2581 unsigned char * WINAPI
NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2582 unsigned char *pMemory
,
2583 PFORMAT_STRING pFormat
)
2585 ULONG esize
, size
, maxsize
;
2587 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2589 maxsize
= *(const USHORT
*)&pFormat
[2];
2591 if (*pFormat
== FC_CSTRING
)
2594 const char *str
= (const char *)pMemory
;
2595 while (i
< maxsize
&& str
[i
]) i
++;
2596 TRACE("string=%s\n", debugstr_an(str
, i
));
2597 pStubMsg
->ActualCount
= i
+ 1;
2600 else if (*pFormat
== FC_WSTRING
)
2603 const WCHAR
*str
= (const WCHAR
*)pMemory
;
2604 while (i
< maxsize
&& str
[i
]) i
++;
2605 TRACE("string=%s\n", debugstr_wn(str
, i
));
2606 pStubMsg
->ActualCount
= i
+ 1;
2611 ERR("Unhandled string type: %#x\n", *pFormat
);
2612 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2615 pStubMsg
->Offset
= 0;
2616 WriteVariance(pStubMsg
);
2618 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2619 safe_copy_to_buffer(pStubMsg
, pMemory
, size
); /* the string itself */
2624 /***********************************************************************
2625 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2627 unsigned char * WINAPI
NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2628 unsigned char **ppMemory
,
2629 PFORMAT_STRING pFormat
,
2630 unsigned char fMustAlloc
)
2632 ULONG bufsize
, memsize
, esize
, maxsize
;
2634 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2635 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
2637 maxsize
= *(const USHORT
*)&pFormat
[2];
2639 ReadVariance(pStubMsg
, NULL
, maxsize
);
2640 if (pStubMsg
->Offset
)
2642 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2643 RpcRaiseException(RPC_S_INVALID_BOUND
);
2646 if (*pFormat
== FC_CSTRING
) esize
= 1;
2647 else if (*pFormat
== FC_WSTRING
) esize
= 2;
2650 ERR("Unhandled string type: %#x\n", *pFormat
);
2651 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2654 memsize
= esize
* maxsize
;
2655 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2657 validate_string_data(pStubMsg
, bufsize
, esize
);
2659 if (!fMustAlloc
&& !*ppMemory
)
2662 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2664 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
2666 if (*pFormat
== FC_CSTRING
) {
2667 TRACE("string=%s\n", debugstr_an((char*)*ppMemory
, pStubMsg
->ActualCount
));
2669 else if (*pFormat
== FC_WSTRING
) {
2670 TRACE("string=%s\n", debugstr_wn((LPWSTR
)*ppMemory
, pStubMsg
->ActualCount
));
2676 /***********************************************************************
2677 * NdrNonConformantStringBufferSize [RPCRT4.@]
2679 void WINAPI
NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2680 unsigned char *pMemory
,
2681 PFORMAT_STRING pFormat
)
2683 ULONG esize
, maxsize
;
2685 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
2687 maxsize
= *(const USHORT
*)&pFormat
[2];
2689 SizeVariance(pStubMsg
);
2691 if (*pFormat
== FC_CSTRING
)
2694 const char *str
= (const char *)pMemory
;
2695 while (i
< maxsize
&& str
[i
]) i
++;
2696 TRACE("string=%s\n", debugstr_an(str
, i
));
2697 pStubMsg
->ActualCount
= i
+ 1;
2700 else if (*pFormat
== FC_WSTRING
)
2703 const WCHAR
*str
= (const WCHAR
*)pMemory
;
2704 while (i
< maxsize
&& str
[i
]) i
++;
2705 TRACE("string=%s\n", debugstr_wn(str
, i
));
2706 pStubMsg
->ActualCount
= i
+ 1;
2711 ERR("Unhandled string type: %#x\n", *pFormat
);
2712 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2715 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
2718 /***********************************************************************
2719 * NdrNonConformantStringMemorySize [RPCRT4.@]
2721 ULONG WINAPI
NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2722 PFORMAT_STRING pFormat
)
2724 ULONG bufsize
, memsize
, esize
, maxsize
;
2726 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
2728 maxsize
= *(const USHORT
*)&pFormat
[2];
2730 ReadVariance(pStubMsg
, NULL
, maxsize
);
2732 if (pStubMsg
->Offset
)
2734 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
2735 RpcRaiseException(RPC_S_INVALID_BOUND
);
2738 if (*pFormat
== FC_CSTRING
) esize
= 1;
2739 else if (*pFormat
== FC_WSTRING
) esize
= 2;
2742 ERR("Unhandled string type: %#x\n", *pFormat
);
2743 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2746 memsize
= esize
* maxsize
;
2747 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2749 validate_string_data(pStubMsg
, bufsize
, esize
);
2751 safe_buffer_increment(pStubMsg
, bufsize
);
2752 pStubMsg
->MemorySize
+= memsize
;
2754 return pStubMsg
->MemorySize
;
2759 #include "pshpack1.h"
2763 unsigned char flags_type
; /* flags in upper nibble, type in lower nibble */
2767 #include "poppack.h"
2769 static ULONG
EmbeddedComplexSize(MIDL_STUB_MESSAGE
*pStubMsg
,
2770 PFORMAT_STRING pFormat
)
2776 case FC_BOGUS_STRUCT
:
2780 return *(const WORD
*)&pFormat
[2];
2783 return *(const ULONG
*)&pFormat
[2];
2784 case FC_USER_MARSHAL
:
2785 return *(const WORD
*)&pFormat
[4];
2787 switch (((const NDR_RANGE
*)pFormat
)->flags_type
& 0xf) {
2792 return sizeof(UCHAR
);
2796 return sizeof(USHORT
);
2800 return sizeof(ULONG
);
2802 return sizeof(float);
2804 return sizeof(double);
2806 return sizeof(ULONGLONG
);
2808 return sizeof(UINT
);
2810 ERR("unknown type 0x%x\n", ((const NDR_RANGE
*)pFormat
)->flags_type
& 0xf);
2811 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2814 case FC_NON_ENCAPSULATED_UNION
:
2816 pFormat
= SkipConformance(pStubMsg
, pFormat
);
2817 pFormat
+= *(const SHORT
*)pFormat
;
2818 return *(const SHORT
*)pFormat
;
2820 return sizeof(void *);
2822 return *(const WORD
*)&pFormat
[2] * 2;
2824 FIXME("unhandled embedded type %02x\n", *pFormat
);
2830 static ULONG
EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2831 PFORMAT_STRING pFormat
)
2833 NDR_MEMORYSIZE m
= NdrMemorySizer
[*pFormat
& NDR_TABLE_MASK
];
2837 FIXME("no memorysizer for data type=%02x\n", *pFormat
);
2841 return m(pStubMsg
, pFormat
);
2845 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2846 unsigned char *pMemory
,
2847 PFORMAT_STRING pFormat
,
2848 PFORMAT_STRING pPointer
)
2850 unsigned char *mem_base
= pMemory
;
2851 PFORMAT_STRING desc
;
2855 while (*pFormat
!= FC_END
) {
2861 TRACE("byte=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2862 safe_copy_to_buffer(pStubMsg
, pMemory
, 1);
2868 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
2869 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
2874 USHORT val
= *(DWORD
*)pMemory
;
2875 TRACE("enum16=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2876 if (32767 < *(DWORD
*)pMemory
)
2877 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
2878 safe_copy_to_buffer(pStubMsg
, &val
, 2);
2885 TRACE("long=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
2886 safe_copy_to_buffer(pStubMsg
, pMemory
, 4);
2892 UINT val
= *(UINT_PTR
*)pMemory
;
2893 TRACE("int3264=%ld <= %p\n", *(UINT_PTR
*)pMemory
, pMemory
);
2894 safe_copy_to_buffer(pStubMsg
, &val
, sizeof(UINT
));
2895 pMemory
+= sizeof(UINT_PTR
);
2899 TRACE("float=%f <= %p\n", *(float*)pMemory
, pMemory
);
2900 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
2901 pMemory
+= sizeof(float);
2904 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2905 safe_copy_to_buffer(pStubMsg
, pMemory
, 8);
2909 TRACE("double=%f <= %p\n", *(double*)pMemory
, pMemory
);
2910 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
2911 pMemory
+= sizeof(double);
2919 unsigned char *saved_buffer
;
2920 BOOL pointer_buffer_mark_set
= FALSE
;
2921 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
2922 TRACE("pStubMsg->Buffer before %p\n", pStubMsg
->Buffer
);
2923 if (*pFormat
!= FC_POINTER
)
2925 if (*pPointer
!= FC_RP
)
2926 align_pointer_clear(&pStubMsg
->Buffer
, 4);
2927 saved_buffer
= pStubMsg
->Buffer
;
2928 if (pStubMsg
->PointerBufferMark
)
2930 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2931 pStubMsg
->PointerBufferMark
= NULL
;
2932 pointer_buffer_mark_set
= TRUE
;
2934 else if (*pPointer
!= FC_RP
)
2935 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2936 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char**)pMemory
, pPointer
);
2937 if (pointer_buffer_mark_set
)
2939 STD_OVERFLOW_CHECK(pStubMsg
);
2940 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2941 pStubMsg
->Buffer
= saved_buffer
;
2942 if (*pPointer
!= FC_RP
)
2943 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2945 TRACE("pStubMsg->Buffer after %p\n", pStubMsg
->Buffer
);
2946 if (*pFormat
== FC_POINTER
)
2950 pMemory
+= sizeof(void *);
2954 align_pointer_offset(&pMemory
, mem_base
, 2);
2957 align_pointer_offset(&pMemory
, mem_base
, 4);
2960 align_pointer_offset(&pMemory
, mem_base
, 8);
2969 pMemory
+= *pFormat
- FC_STRUCTPAD1
+ 1;
2971 case FC_EMBEDDED_COMPLEX
:
2972 pMemory
+= pFormat
[1];
2974 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2975 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2976 TRACE("embedded complex (size=%d) <= %p\n", size
, pMemory
);
2977 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
2980 /* for some reason interface pointers aren't generated as
2981 * FC_POINTER, but instead as FC_EMBEDDED_COMPLEX, yet
2982 * they still need the dereferencing treatment that pointers are
2985 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2987 m(pStubMsg
, pMemory
, desc
);
2989 else FIXME("no marshaller for embedded type %02x\n", *desc
);
2996 FIXME("unhandled format 0x%02x\n", *pFormat
);
3004 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3005 unsigned char *pMemory
,
3006 PFORMAT_STRING pFormat
,
3007 PFORMAT_STRING pPointer
,
3008 unsigned char fMustAlloc
)
3010 unsigned char *mem_base
= pMemory
;
3011 PFORMAT_STRING desc
;
3015 while (*pFormat
!= FC_END
) {
3021 safe_copy_from_buffer(pStubMsg
, pMemory
, 1);
3022 TRACE("byte=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
3028 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
3029 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
3035 safe_copy_from_buffer(pStubMsg
, &val
, 2);
3036 *(DWORD
*)pMemory
= val
;
3037 TRACE("enum16=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
3038 if (32767 < *(DWORD
*)pMemory
)
3039 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
3046 safe_copy_from_buffer(pStubMsg
, pMemory
, 4);
3047 TRACE("long=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
3053 safe_copy_from_buffer(pStubMsg
, &val
, 4);
3054 *(INT_PTR
*)pMemory
= val
;
3055 TRACE("int3264=%ld => %p\n", *(INT_PTR
*)pMemory
, pMemory
);
3056 pMemory
+= sizeof(INT_PTR
);
3062 safe_copy_from_buffer(pStubMsg
, &val
, 4);
3063 *(UINT_PTR
*)pMemory
= val
;
3064 TRACE("uint3264=%ld => %p\n", *(UINT_PTR
*)pMemory
, pMemory
);
3065 pMemory
+= sizeof(UINT_PTR
);
3069 safe_copy_from_buffer(pStubMsg
, pMemory
, sizeof(float));
3070 TRACE("float=%f => %p\n", *(float*)pMemory
, pMemory
);
3071 pMemory
+= sizeof(float);
3074 safe_copy_from_buffer(pStubMsg
, pMemory
, 8);
3075 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
3079 safe_copy_from_buffer(pStubMsg
, pMemory
, sizeof(double));
3080 TRACE("double=%f => %p\n", *(double*)pMemory
, pMemory
);
3081 pMemory
+= sizeof(double);
3089 unsigned char *saved_buffer
;
3090 BOOL pointer_buffer_mark_set
= FALSE
;
3091 TRACE("pointer => %p\n", pMemory
);
3092 if (*pFormat
!= FC_POINTER
)
3094 if (*pPointer
!= FC_RP
)
3095 align_pointer(&pStubMsg
->Buffer
, 4);
3096 saved_buffer
= pStubMsg
->Buffer
;
3097 if (pStubMsg
->PointerBufferMark
)
3099 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3100 pStubMsg
->PointerBufferMark
= NULL
;
3101 pointer_buffer_mark_set
= TRUE
;
3103 else if (*pPointer
!= FC_RP
)
3104 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3106 PointerUnmarshall(pStubMsg
, saved_buffer
, (unsigned char**)pMemory
, *(unsigned char**)pMemory
, pPointer
, fMustAlloc
);
3107 if (pointer_buffer_mark_set
)
3109 STD_OVERFLOW_CHECK(pStubMsg
);
3110 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3111 pStubMsg
->Buffer
= saved_buffer
;
3112 if (*pPointer
!= FC_RP
)
3113 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3115 if (*pFormat
== FC_POINTER
)
3119 pMemory
+= sizeof(void *);
3123 align_pointer_offset_clear(&pMemory
, mem_base
, 2);
3126 align_pointer_offset_clear(&pMemory
, mem_base
, 4);
3129 align_pointer_offset_clear(&pMemory
, mem_base
, 8);
3138 memset(pMemory
, 0, *pFormat
- FC_STRUCTPAD1
+ 1);
3139 pMemory
+= *pFormat
- FC_STRUCTPAD1
+ 1;
3141 case FC_EMBEDDED_COMPLEX
:
3142 pMemory
+= pFormat
[1];
3144 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3145 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3146 TRACE("embedded complex (size=%d) => %p\n", size
, pMemory
);
3148 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
3149 * since the type is part of the memory block that is encompassed by
3150 * the whole complex type. Memory is forced to allocate when pointers
3151 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
3152 * clearing the memory we pass in to the unmarshaller */
3153 memset(pMemory
, 0, size
);
3154 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
3157 /* for some reason interface pointers aren't generated as
3158 * FC_POINTER, but instead as FC_EMBEDDED_COMPLEX, yet
3159 * they still need the dereferencing treatment that pointers are
3162 m(pStubMsg
, (unsigned char **)pMemory
, desc
, FALSE
);
3164 m(pStubMsg
, &pMemory
, desc
, FALSE
);
3166 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
3173 FIXME("unhandled format %d\n", *pFormat
);
3181 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3182 unsigned char *pMemory
,
3183 PFORMAT_STRING pFormat
,
3184 PFORMAT_STRING pPointer
)
3186 unsigned char *mem_base
= pMemory
;
3187 PFORMAT_STRING desc
;
3191 while (*pFormat
!= FC_END
) {
3197 safe_buffer_length_increment(pStubMsg
, 1);
3203 safe_buffer_length_increment(pStubMsg
, 2);
3207 safe_buffer_length_increment(pStubMsg
, 2);
3214 safe_buffer_length_increment(pStubMsg
, 4);
3219 safe_buffer_length_increment(pStubMsg
, 4);
3220 pMemory
+= sizeof(INT_PTR
);
3224 safe_buffer_length_increment(pStubMsg
, 8);
3232 if (*pFormat
!= FC_POINTER
)
3234 if (!pStubMsg
->IgnoreEmbeddedPointers
)
3236 int saved_buffer_length
= pStubMsg
->BufferLength
;
3237 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3238 pStubMsg
->PointerLength
= 0;
3239 if(!pStubMsg
->BufferLength
)
3240 ERR("BufferLength == 0??\n");
3241 PointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
3242 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3243 pStubMsg
->BufferLength
= saved_buffer_length
;
3245 if (*pPointer
!= FC_RP
)
3247 align_length(&pStubMsg
->BufferLength
, 4);
3248 safe_buffer_length_increment(pStubMsg
, 4);
3250 if (*pFormat
== FC_POINTER
)
3254 pMemory
+= sizeof(void*);
3257 align_pointer_offset(&pMemory
, mem_base
, 2);
3260 align_pointer_offset(&pMemory
, mem_base
, 4);
3263 align_pointer_offset(&pMemory
, mem_base
, 8);
3272 pMemory
+= *pFormat
- FC_STRUCTPAD1
+ 1;
3274 case FC_EMBEDDED_COMPLEX
:
3275 pMemory
+= pFormat
[1];
3277 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3278 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3279 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
3282 /* for some reason interface pointers aren't generated as
3283 * FC_POINTER, but instead as FC_EMBEDDED_COMPLEX, yet
3284 * they still need the dereferencing treatment that pointers are
3287 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
3289 m(pStubMsg
, pMemory
, desc
);
3291 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
3298 FIXME("unhandled format 0x%02x\n", *pFormat
);
3306 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
3307 unsigned char *pMemory
,
3308 PFORMAT_STRING pFormat
,
3309 PFORMAT_STRING pPointer
)
3311 unsigned char *mem_base
= pMemory
;
3312 PFORMAT_STRING desc
;
3316 while (*pFormat
!= FC_END
) {
3338 pMemory
+= sizeof(INT_PTR
);
3349 if (*pFormat
!= FC_POINTER
)
3351 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
3352 if (*pFormat
== FC_POINTER
)
3356 pMemory
+= sizeof(void *);
3359 align_pointer_offset(&pMemory
, mem_base
, 2);
3362 align_pointer_offset(&pMemory
, mem_base
, 4);
3365 align_pointer_offset(&pMemory
, mem_base
, 8);
3374 pMemory
+= *pFormat
- FC_STRUCTPAD1
+ 1;
3376 case FC_EMBEDDED_COMPLEX
:
3377 pMemory
+= pFormat
[1];
3379 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3380 size
= EmbeddedComplexSize(pStubMsg
, desc
);
3381 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
3384 /* for some reason interface pointers aren't generated as
3385 * FC_POINTER, but instead as FC_EMBEDDED_COMPLEX, yet
3386 * they still need the dereferencing treatment that pointers are
3389 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
3391 m(pStubMsg
, pMemory
, desc
);
3399 FIXME("unhandled format 0x%02x\n", *pFormat
);
3407 static ULONG
ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3408 PFORMAT_STRING pFormat
,
3409 PFORMAT_STRING pPointer
)
3411 PFORMAT_STRING desc
;
3414 while (*pFormat
!= FC_END
) {
3421 safe_buffer_increment(pStubMsg
, 1);
3427 safe_buffer_increment(pStubMsg
, 2);
3431 safe_buffer_increment(pStubMsg
, 2);
3438 safe_buffer_increment(pStubMsg
, 4);
3442 size
+= sizeof(INT_PTR
);
3443 safe_buffer_increment(pStubMsg
, 4);
3448 safe_buffer_increment(pStubMsg
, 8);
3456 unsigned char *saved_buffer
;
3457 BOOL pointer_buffer_mark_set
= FALSE
;
3458 if (*pFormat
!= FC_POINTER
)
3460 if (*pPointer
!= FC_RP
)
3461 align_pointer(&pStubMsg
->Buffer
, 4);
3462 saved_buffer
= pStubMsg
->Buffer
;
3463 if (pStubMsg
->PointerBufferMark
)
3465 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3466 pStubMsg
->PointerBufferMark
= NULL
;
3467 pointer_buffer_mark_set
= TRUE
;
3469 else if (*pPointer
!= FC_RP
)
3470 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3472 if (!pStubMsg
->IgnoreEmbeddedPointers
)
3473 PointerMemorySize(pStubMsg
, saved_buffer
, pPointer
);
3474 if (pointer_buffer_mark_set
)
3476 STD_OVERFLOW_CHECK(pStubMsg
);
3477 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3478 pStubMsg
->Buffer
= saved_buffer
;
3479 if (*pPointer
!= FC_RP
)
3480 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
3482 if (*pFormat
== FC_POINTER
)
3486 size
+= sizeof(void *);
3490 align_length(&size
, 2);
3493 align_length(&size
, 4);
3496 align_length(&size
, 8);
3505 size
+= *pFormat
- FC_STRUCTPAD1
+ 1;
3507 case FC_EMBEDDED_COMPLEX
:
3510 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3511 size
+= EmbeddedComplexMemorySize(pStubMsg
, desc
);
3517 FIXME("unhandled format 0x%02x\n", *pFormat
);
3525 ULONG
ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
3527 PFORMAT_STRING desc
;
3530 while (*pFormat
!= FC_END
) {
3552 size
+= sizeof(INT_PTR
);
3563 size
+= sizeof(void *);
3564 if (*pFormat
!= FC_POINTER
)
3568 align_length(&size
, 2);
3571 align_length(&size
, 4);
3574 align_length(&size
, 8);
3583 size
+= *pFormat
- FC_STRUCTPAD1
+ 1;
3585 case FC_EMBEDDED_COMPLEX
:
3588 desc
= pFormat
+ *(const SHORT
*)pFormat
;
3589 size
+= EmbeddedComplexSize(pStubMsg
, desc
);
3595 FIXME("unhandled format 0x%02x\n", *pFormat
);
3603 /***********************************************************************
3604 * NdrComplexStructMarshall [RPCRT4.@]
3606 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3607 unsigned char *pMemory
,
3608 PFORMAT_STRING pFormat
)
3610 PFORMAT_STRING conf_array
= NULL
;
3611 PFORMAT_STRING pointer_desc
= NULL
;
3612 unsigned char *OldMemory
= pStubMsg
->Memory
;
3613 BOOL pointer_buffer_mark_set
= FALSE
;
3615 ULONG max_count
= 0;
3618 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3620 if (!pStubMsg
->PointerBufferMark
)
3622 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3623 /* save buffer length */
3624 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
3626 /* get the buffer pointer after complex array data, but before
3628 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
;
3629 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3630 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
3631 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3633 /* save it for use by embedded pointer code later */
3634 pStubMsg
->PointerBufferMark
= (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
;
3635 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->PointerBufferMark
- pStubMsg
->Buffer
));
3636 pointer_buffer_mark_set
= TRUE
;
3638 /* restore the original buffer length */
3639 pStubMsg
->BufferLength
= saved_buffer_length
;
3642 align_pointer_clear(&pStubMsg
->Buffer
, pFormat
[1] + 1);
3645 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3647 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3650 pStubMsg
->Memory
= pMemory
;
3654 ULONG struct_size
= ComplexStructSize(pStubMsg
, pFormat
);
3655 array_compute_and_write_conformance(conf_array
[0], pStubMsg
,
3656 pMemory
+ struct_size
, conf_array
);
3657 /* these could be changed in ComplexMarshall so save them for later */
3658 max_count
= pStubMsg
->MaxCount
;
3659 count
= pStubMsg
->ActualCount
;
3660 offset
= pStubMsg
->Offset
;
3663 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3667 pStubMsg
->MaxCount
= max_count
;
3668 pStubMsg
->ActualCount
= count
;
3669 pStubMsg
->Offset
= offset
;
3670 array_write_variance_and_marshall(conf_array
[0], pStubMsg
, pMemory
,
3671 conf_array
, TRUE
/* fHasPointers */);
3674 pStubMsg
->Memory
= OldMemory
;
3676 if (pointer_buffer_mark_set
)
3678 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3679 pStubMsg
->PointerBufferMark
= NULL
;
3682 STD_OVERFLOW_CHECK(pStubMsg
);
3687 /***********************************************************************
3688 * NdrComplexStructUnmarshall [RPCRT4.@]
3690 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3691 unsigned char **ppMemory
,
3692 PFORMAT_STRING pFormat
,
3693 unsigned char fMustAlloc
)
3695 unsigned size
= *(const WORD
*)(pFormat
+2);
3696 PFORMAT_STRING conf_array
= NULL
;
3697 PFORMAT_STRING pointer_desc
= NULL
;
3698 unsigned char *pMemory
;
3699 BOOL pointer_buffer_mark_set
= FALSE
;
3701 ULONG max_count
= 0;
3703 ULONG array_size
= 0;
3705 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3707 if (!pStubMsg
->PointerBufferMark
)
3709 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3710 /* save buffer pointer */
3711 unsigned char *saved_buffer
= pStubMsg
->Buffer
;
3713 /* get the buffer pointer after complex array data, but before
3715 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3716 NdrComplexStructMemorySize(pStubMsg
, pFormat
);
3717 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3719 /* save it for use by embedded pointer code later */
3720 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3721 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->PointerBufferMark
- saved_buffer
));
3722 pointer_buffer_mark_set
= TRUE
;
3724 /* restore the original buffer */
3725 pStubMsg
->Buffer
= saved_buffer
;
3728 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
3731 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3733 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3738 array_size
= array_read_conformance(conf_array
[0], pStubMsg
, conf_array
);
3741 /* these could be changed in ComplexMarshall so save them for later */
3742 max_count
= pStubMsg
->MaxCount
;
3743 count
= pStubMsg
->ActualCount
;
3744 offset
= pStubMsg
->Offset
;
3747 if (!fMustAlloc
&& !*ppMemory
)
3750 *ppMemory
= NdrAllocateZero(pStubMsg
, size
);
3752 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
, fMustAlloc
);
3756 pStubMsg
->MaxCount
= max_count
;
3757 pStubMsg
->ActualCount
= count
;
3758 pStubMsg
->Offset
= offset
;
3760 memset(pMemory
, 0, array_size
);
3761 array_read_variance_and_unmarshall(conf_array
[0], pStubMsg
, &pMemory
,
3763 FALSE
/* fUseBufferMemoryServer */,
3764 TRUE
/* fUnmarshall */);
3767 if (pointer_buffer_mark_set
)
3769 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3770 pStubMsg
->PointerBufferMark
= NULL
;
3776 /***********************************************************************
3777 * NdrComplexStructBufferSize [RPCRT4.@]
3779 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3780 unsigned char *pMemory
,
3781 PFORMAT_STRING pFormat
)
3783 PFORMAT_STRING conf_array
= NULL
;
3784 PFORMAT_STRING pointer_desc
= NULL
;
3785 unsigned char *OldMemory
= pStubMsg
->Memory
;
3786 int pointer_length_set
= 0;
3788 ULONG max_count
= 0;
3791 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3793 align_length(&pStubMsg
->BufferLength
, pFormat
[1] + 1);
3795 if(!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
3797 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3798 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
3800 /* get the buffer length after complex struct data, but before
3802 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3803 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
3804 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3806 /* save it for use by embedded pointer code later */
3807 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3808 pointer_length_set
= 1;
3809 TRACE("difference = 0x%x\n", pStubMsg
->PointerLength
- saved_buffer_length
);
3811 /* restore the original buffer length */
3812 pStubMsg
->BufferLength
= saved_buffer_length
;
3816 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3818 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3821 pStubMsg
->Memory
= pMemory
;
3825 ULONG struct_size
= ComplexStructSize(pStubMsg
, pFormat
);
3826 array_compute_and_size_conformance(conf_array
[0], pStubMsg
, pMemory
+ struct_size
,
3829 /* these could be changed in ComplexMarshall so save them for later */
3830 max_count
= pStubMsg
->MaxCount
;
3831 count
= pStubMsg
->ActualCount
;
3832 offset
= pStubMsg
->Offset
;
3835 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3839 pStubMsg
->MaxCount
= max_count
;
3840 pStubMsg
->ActualCount
= count
;
3841 pStubMsg
->Offset
= offset
;
3842 array_buffer_size(conf_array
[0], pStubMsg
, pMemory
, conf_array
,
3843 TRUE
/* fHasPointers */);
3846 pStubMsg
->Memory
= OldMemory
;
3848 if(pointer_length_set
)
3850 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3851 pStubMsg
->PointerLength
= 0;
3856 /***********************************************************************
3857 * NdrComplexStructMemorySize [RPCRT4.@]
3859 ULONG WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3860 PFORMAT_STRING pFormat
)
3862 unsigned size
= *(const WORD
*)(pFormat
+2);
3863 PFORMAT_STRING conf_array
= NULL
;
3864 PFORMAT_STRING pointer_desc
= NULL
;
3866 ULONG max_count
= 0;
3869 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3871 align_pointer(&pStubMsg
->Buffer
, pFormat
[1] + 1);
3874 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3876 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3881 array_read_conformance(conf_array
[0], pStubMsg
, conf_array
);
3883 /* these could be changed in ComplexStructMemorySize so save them for
3885 max_count
= pStubMsg
->MaxCount
;
3886 count
= pStubMsg
->ActualCount
;
3887 offset
= pStubMsg
->Offset
;
3890 ComplexStructMemorySize(pStubMsg
, pFormat
, pointer_desc
);
3894 pStubMsg
->MaxCount
= max_count
;
3895 pStubMsg
->ActualCount
= count
;
3896 pStubMsg
->Offset
= offset
;
3897 array_memory_size(conf_array
[0], pStubMsg
, conf_array
,
3898 TRUE
/* fHasPointers */);
3904 /***********************************************************************
3905 * NdrComplexStructFree [RPCRT4.@]
3907 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3908 unsigned char *pMemory
,
3909 PFORMAT_STRING pFormat
)
3911 PFORMAT_STRING conf_array
= NULL
;
3912 PFORMAT_STRING pointer_desc
= NULL
;
3913 unsigned char *OldMemory
= pStubMsg
->Memory
;
3915 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3918 if (*(const SHORT
*)pFormat
) conf_array
= pFormat
+ *(const SHORT
*)pFormat
;
3920 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
3923 pStubMsg
->Memory
= pMemory
;
3925 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
3928 array_free(conf_array
[0], pStubMsg
, pMemory
, conf_array
,
3929 TRUE
/* fHasPointers */);
3931 pStubMsg
->Memory
= OldMemory
;
3934 /***********************************************************************
3935 * NdrConformantArrayMarshall [RPCRT4.@]
3937 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3938 unsigned char *pMemory
,
3939 PFORMAT_STRING pFormat
)
3941 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3942 if (pFormat
[0] != FC_CARRAY
)
3944 ERR("invalid format = 0x%x\n", pFormat
[0]);
3945 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3948 array_compute_and_write_conformance(FC_CARRAY
, pStubMsg
, pMemory
,
3950 array_write_variance_and_marshall(FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3951 TRUE
/* fHasPointers */);
3956 /***********************************************************************
3957 * NdrConformantArrayUnmarshall [RPCRT4.@]
3959 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3960 unsigned char **ppMemory
,
3961 PFORMAT_STRING pFormat
,
3962 unsigned char fMustAlloc
)
3964 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3965 if (pFormat
[0] != FC_CARRAY
)
3967 ERR("invalid format = 0x%x\n", pFormat
[0]);
3968 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3971 array_read_conformance(FC_CARRAY
, pStubMsg
, pFormat
);
3972 array_read_variance_and_unmarshall(FC_CARRAY
, pStubMsg
, ppMemory
, pFormat
,
3974 TRUE
/* fUseBufferMemoryServer */,
3975 TRUE
/* fUnmarshall */);
3980 /***********************************************************************
3981 * NdrConformantArrayBufferSize [RPCRT4.@]
3983 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3984 unsigned char *pMemory
,
3985 PFORMAT_STRING pFormat
)
3987 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3988 if (pFormat
[0] != FC_CARRAY
)
3990 ERR("invalid format = 0x%x\n", pFormat
[0]);
3991 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3994 array_compute_and_size_conformance(FC_CARRAY
, pStubMsg
, pMemory
, pFormat
);
3995 array_buffer_size(FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
3996 TRUE
/* fHasPointers */);
3999 /***********************************************************************
4000 * NdrConformantArrayMemorySize [RPCRT4.@]
4002 ULONG WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4003 PFORMAT_STRING pFormat
)
4005 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
4006 if (pFormat
[0] != FC_CARRAY
)
4008 ERR("invalid format = 0x%x\n", pFormat
[0]);
4009 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4012 array_read_conformance(FC_CARRAY
, pStubMsg
, pFormat
);
4013 array_memory_size(FC_CARRAY
, pStubMsg
, pFormat
, TRUE
/* fHasPointers */);
4015 return pStubMsg
->MemorySize
;
4018 /***********************************************************************
4019 * NdrConformantArrayFree [RPCRT4.@]
4021 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4022 unsigned char *pMemory
,
4023 PFORMAT_STRING pFormat
)
4025 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4026 if (pFormat
[0] != FC_CARRAY
)
4028 ERR("invalid format = 0x%x\n", pFormat
[0]);
4029 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4032 array_free(FC_CARRAY
, pStubMsg
, pMemory
, pFormat
,
4033 TRUE
/* fHasPointers */);
4037 /***********************************************************************
4038 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
4040 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
4041 unsigned char* pMemory
,
4042 PFORMAT_STRING pFormat
)
4044 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4046 if (pFormat
[0] != FC_CVARRAY
)
4048 ERR("invalid format type %x\n", pFormat
[0]);
4049 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4053 array_compute_and_write_conformance(FC_CVARRAY
, pStubMsg
, pMemory
,
4055 array_write_variance_and_marshall(FC_CVARRAY
, pStubMsg
, pMemory
,
4056 pFormat
, TRUE
/* fHasPointers */);
4062 /***********************************************************************
4063 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
4065 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
4066 unsigned char** ppMemory
,
4067 PFORMAT_STRING pFormat
,
4068 unsigned char fMustAlloc
)
4070 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4072 if (pFormat
[0] != FC_CVARRAY
)
4074 ERR("invalid format type %x\n", pFormat
[0]);
4075 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4079 array_read_conformance(FC_CVARRAY
, pStubMsg
, pFormat
);
4080 array_read_variance_and_unmarshall(FC_CVARRAY
, pStubMsg
, ppMemory
,
4081 pFormat
, fMustAlloc
,
4082 TRUE
/* fUseBufferMemoryServer */,
4083 TRUE
/* fUnmarshall */);
4089 /***********************************************************************
4090 * NdrConformantVaryingArrayFree [RPCRT4.@]
4092 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
4093 unsigned char* pMemory
,
4094 PFORMAT_STRING pFormat
)
4096 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4098 if (pFormat
[0] != FC_CVARRAY
)
4100 ERR("invalid format type %x\n", pFormat
[0]);
4101 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4105 array_free(FC_CVARRAY
, pStubMsg
, pMemory
, pFormat
,
4106 TRUE
/* fHasPointers */);
4110 /***********************************************************************
4111 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
4113 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
4114 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
4116 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4118 if (pFormat
[0] != FC_CVARRAY
)
4120 ERR("invalid format type %x\n", pFormat
[0]);
4121 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4125 array_compute_and_size_conformance(FC_CVARRAY
, pStubMsg
, pMemory
,
4127 array_buffer_size(FC_CVARRAY
, pStubMsg
, pMemory
, pFormat
,
4128 TRUE
/* fHasPointers */);
4132 /***********************************************************************
4133 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
4135 ULONG WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
4136 PFORMAT_STRING pFormat
)
4138 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4140 if (pFormat
[0] != FC_CVARRAY
)
4142 ERR("invalid format type %x\n", pFormat
[0]);
4143 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4144 return pStubMsg
->MemorySize
;
4147 array_read_conformance(FC_CVARRAY
, pStubMsg
, pFormat
);
4148 array_memory_size(FC_CVARRAY
, pStubMsg
, pFormat
,
4149 TRUE
/* fHasPointers */);
4151 return pStubMsg
->MemorySize
;
4155 /***********************************************************************
4156 * NdrComplexArrayMarshall [RPCRT4.@]
4158 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4159 unsigned char *pMemory
,
4160 PFORMAT_STRING pFormat
)
4162 BOOL pointer_buffer_mark_set
= FALSE
;
4164 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4166 if (pFormat
[0] != FC_BOGUS_ARRAY
)
4168 ERR("invalid format type %x\n", pFormat
[0]);
4169 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4173 if (!pStubMsg
->PointerBufferMark
)
4175 /* save buffer fields that may be changed by buffer sizer functions
4176 * and that may be needed later on */
4177 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
4178 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
4179 ULONG_PTR saved_max_count
= pStubMsg
->MaxCount
;
4180 ULONG saved_offset
= pStubMsg
->Offset
;
4181 ULONG saved_actual_count
= pStubMsg
->ActualCount
;
4183 /* get the buffer pointer after complex array data, but before
4185 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
;
4186 pStubMsg
->IgnoreEmbeddedPointers
= 1;
4187 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
4188 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
4190 /* save it for use by embedded pointer code later */
4191 pStubMsg
->PointerBufferMark
= (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
;
4192 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->Buffer
- (unsigned char *)pStubMsg
->RpcMsg
->Buffer
));
4193 pointer_buffer_mark_set
= TRUE
;
4195 /* restore fields */
4196 pStubMsg
->ActualCount
= saved_actual_count
;
4197 pStubMsg
->Offset
= saved_offset
;
4198 pStubMsg
->MaxCount
= saved_max_count
;
4199 pStubMsg
->BufferLength
= saved_buffer_length
;
4202 array_compute_and_write_conformance(FC_BOGUS_ARRAY
, pStubMsg
, pMemory
, pFormat
);
4203 array_write_variance_and_marshall(FC_BOGUS_ARRAY
, pStubMsg
,
4204 pMemory
, pFormat
, TRUE
/* fHasPointers */);
4206 STD_OVERFLOW_CHECK(pStubMsg
);
4208 if (pointer_buffer_mark_set
)
4210 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4211 pStubMsg
->PointerBufferMark
= NULL
;
4217 /***********************************************************************
4218 * NdrComplexArrayUnmarshall [RPCRT4.@]
4220 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4221 unsigned char **ppMemory
,
4222 PFORMAT_STRING pFormat
,
4223 unsigned char fMustAlloc
)
4225 unsigned char *saved_buffer
;
4226 BOOL pointer_buffer_mark_set
= FALSE
;
4227 int saved_ignore_embedded
;
4229 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4231 if (pFormat
[0] != FC_BOGUS_ARRAY
)
4233 ERR("invalid format type %x\n", pFormat
[0]);
4234 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4238 saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
4239 /* save buffer pointer */
4240 saved_buffer
= pStubMsg
->Buffer
;
4241 /* get the buffer pointer after complex array data, but before
4243 pStubMsg
->IgnoreEmbeddedPointers
= 1;
4244 pStubMsg
->MemorySize
= 0;
4245 NdrComplexArrayMemorySize(pStubMsg
, pFormat
);
4246 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
4248 TRACE("difference = 0x%x\n", (ULONG
)(pStubMsg
->Buffer
- saved_buffer
));
4249 if (!pStubMsg
->PointerBufferMark
)
4251 /* save it for use by embedded pointer code later */
4252 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4253 pointer_buffer_mark_set
= TRUE
;
4255 /* restore the original buffer */
4256 pStubMsg
->Buffer
= saved_buffer
;
4258 array_read_conformance(FC_BOGUS_ARRAY
, pStubMsg
, pFormat
);
4259 array_read_variance_and_unmarshall(FC_BOGUS_ARRAY
, pStubMsg
, ppMemory
, pFormat
, fMustAlloc
,
4260 TRUE
/* fUseBufferMemoryServer */, TRUE
/* fUnmarshall */);
4262 if (pointer_buffer_mark_set
)
4264 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4265 pStubMsg
->PointerBufferMark
= NULL
;
4271 /***********************************************************************
4272 * NdrComplexArrayBufferSize [RPCRT4.@]
4274 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4275 unsigned char *pMemory
,
4276 PFORMAT_STRING pFormat
)
4278 int pointer_length_set
= 0;
4280 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4282 if (pFormat
[0] != FC_BOGUS_ARRAY
)
4284 ERR("invalid format type %x\n", pFormat
[0]);
4285 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4289 if (!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
4291 /* save buffer fields that may be changed by buffer sizer functions
4292 * and that may be needed later on */
4293 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
4294 ULONG saved_buffer_length
= pStubMsg
->BufferLength
;
4295 ULONG_PTR saved_max_count
= pStubMsg
->MaxCount
;
4296 ULONG saved_offset
= pStubMsg
->Offset
;
4297 ULONG saved_actual_count
= pStubMsg
->ActualCount
;
4299 /* get the buffer pointer after complex array data, but before
4301 pStubMsg
->IgnoreEmbeddedPointers
= 1;
4302 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
4303 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
4305 /* save it for use by embedded pointer code later */
4306 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4307 pointer_length_set
= 1;
4309 /* restore fields */
4310 pStubMsg
->ActualCount
= saved_actual_count
;
4311 pStubMsg
->Offset
= saved_offset
;
4312 pStubMsg
->MaxCount
= saved_max_count
;
4313 pStubMsg
->BufferLength
= saved_buffer_length
;
4316 array_compute_and_size_conformance(FC_BOGUS_ARRAY
, pStubMsg
, pMemory
, pFormat
);
4317 array_buffer_size(FC_BOGUS_ARRAY
, pStubMsg
, pMemory
, pFormat
, TRUE
/* fHasPointers */);
4319 if(pointer_length_set
)
4321 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4322 pStubMsg
->PointerLength
= 0;
4326 /***********************************************************************
4327 * NdrComplexArrayMemorySize [RPCRT4.@]
4329 ULONG WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4330 PFORMAT_STRING pFormat
)
4332 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
4334 if (pFormat
[0] != FC_BOGUS_ARRAY
)
4336 ERR("invalid format type %x\n", pFormat
[0]);
4337 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4341 array_read_conformance(FC_BOGUS_ARRAY
, pStubMsg
, pFormat
);
4342 array_memory_size(FC_BOGUS_ARRAY
, pStubMsg
, pFormat
, TRUE
/* fHasPointers */);
4343 return pStubMsg
->MemorySize
;
4346 /***********************************************************************
4347 * NdrComplexArrayFree [RPCRT4.@]
4349 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4350 unsigned char *pMemory
,
4351 PFORMAT_STRING pFormat
)
4353 ULONG i
, count
, def
;
4355 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4357 if (pFormat
[0] != FC_BOGUS_ARRAY
)
4359 ERR("invalid format type %x\n", pFormat
[0]);
4360 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4364 def
= *(const WORD
*)&pFormat
[2];
4367 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
4368 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
4370 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
4371 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
4373 count
= pStubMsg
->ActualCount
;
4374 for (i
= 0; i
< count
; i
++)
4375 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
4378 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg
,
4379 USER_MARSHAL_CB_TYPE cbtype
, PFORMAT_STRING pFormat
,
4380 USER_MARSHAL_CB
*umcb
)
4382 umcb
->Flags
= MAKELONG(pStubMsg
->dwDestContext
,
4383 pStubMsg
->RpcMsg
->DataRepresentation
);
4384 umcb
->pStubMsg
= pStubMsg
;
4385 umcb
->pReserve
= NULL
;
4386 umcb
->Signature
= USER_MARSHAL_CB_SIGNATURE
;
4387 umcb
->CBType
= cbtype
;
4388 umcb
->pFormat
= pFormat
;
4389 umcb
->pTypeFormat
= NULL
/* FIXME */;
4392 #define USER_MARSHAL_PTR_PREFIX \
4393 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4394 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4396 /***********************************************************************
4397 * NdrUserMarshalMarshall [RPCRT4.@]
4399 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4400 unsigned char *pMemory
,
4401 PFORMAT_STRING pFormat
)
4403 unsigned flags
= pFormat
[1];
4404 unsigned index
= *(const WORD
*)&pFormat
[2];
4405 unsigned char *saved_buffer
= NULL
;
4406 USER_MARSHAL_CB umcb
;
4408 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4409 TRACE("index=%d\n", index
);
4411 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_MARSHALL
, pFormat
, &umcb
);
4413 if (flags
& USER_MARSHAL_POINTER
)
4415 align_pointer_clear(&pStubMsg
->Buffer
, 4);
4416 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, USER_MARSHAL_PTR_PREFIX
);
4417 pStubMsg
->Buffer
+= 4;
4418 if (pStubMsg
->PointerBufferMark
)
4420 saved_buffer
= pStubMsg
->Buffer
;
4421 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4422 pStubMsg
->PointerBufferMark
= NULL
;
4424 align_pointer_clear(&pStubMsg
->Buffer
, 8);
4427 align_pointer_clear(&pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4430 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
4431 &umcb
.Flags
, pStubMsg
->Buffer
, pMemory
);
4435 STD_OVERFLOW_CHECK(pStubMsg
);
4436 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4437 pStubMsg
->Buffer
= saved_buffer
;
4440 STD_OVERFLOW_CHECK(pStubMsg
);
4445 /***********************************************************************
4446 * NdrUserMarshalUnmarshall [RPCRT4.@]
4448 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4449 unsigned char **ppMemory
,
4450 PFORMAT_STRING pFormat
,
4451 unsigned char fMustAlloc
)
4453 unsigned flags
= pFormat
[1];
4454 unsigned index
= *(const WORD
*)&pFormat
[2];
4455 DWORD memsize
= *(const WORD
*)&pFormat
[4];
4456 unsigned char *saved_buffer
= NULL
;
4457 USER_MARSHAL_CB umcb
;
4459 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4460 TRACE("index=%d\n", index
);
4462 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_UNMARSHALL
, pFormat
, &umcb
);
4464 if (flags
& USER_MARSHAL_POINTER
)
4466 align_pointer(&pStubMsg
->Buffer
, 4);
4467 /* skip pointer prefix */
4468 pStubMsg
->Buffer
+= 4;
4469 if (pStubMsg
->PointerBufferMark
)
4471 saved_buffer
= pStubMsg
->Buffer
;
4472 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4473 pStubMsg
->PointerBufferMark
= NULL
;
4475 align_pointer(&pStubMsg
->Buffer
, 8);
4478 align_pointer(&pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4480 if (!fMustAlloc
&& !*ppMemory
)
4484 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
4485 memset(*ppMemory
, 0, memsize
);
4489 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
4490 &umcb
.Flags
, pStubMsg
->Buffer
, *ppMemory
);
4494 STD_OVERFLOW_CHECK(pStubMsg
);
4495 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4496 pStubMsg
->Buffer
= saved_buffer
;
4502 /***********************************************************************
4503 * NdrUserMarshalBufferSize [RPCRT4.@]
4505 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4506 unsigned char *pMemory
,
4507 PFORMAT_STRING pFormat
)
4509 unsigned flags
= pFormat
[1];
4510 unsigned index
= *(const WORD
*)&pFormat
[2];
4511 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
4512 USER_MARSHAL_CB umcb
;
4513 ULONG saved_buffer_length
= 0;
4515 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4516 TRACE("index=%d\n", index
);
4518 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_BUFFER_SIZE
, pFormat
, &umcb
);
4520 if (flags
& USER_MARSHAL_POINTER
)
4522 align_length(&pStubMsg
->BufferLength
, 4);
4523 /* skip pointer prefix */
4524 safe_buffer_length_increment(pStubMsg
, 4);
4525 if (pStubMsg
->IgnoreEmbeddedPointers
)
4527 if (pStubMsg
->PointerLength
)
4529 saved_buffer_length
= pStubMsg
->BufferLength
;
4530 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4531 pStubMsg
->PointerLength
= 0;
4533 align_length(&pStubMsg
->BufferLength
, 8);
4536 align_length(&pStubMsg
->BufferLength
, (flags
& 0xf) + 1);
4539 TRACE("size=%d\n", bufsize
);
4540 safe_buffer_length_increment(pStubMsg
, bufsize
);
4543 pStubMsg
->BufferLength
=
4544 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
4545 &umcb
.Flags
, pStubMsg
->BufferLength
, pMemory
);
4547 if (saved_buffer_length
)
4549 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4550 pStubMsg
->BufferLength
= saved_buffer_length
;
4555 /***********************************************************************
4556 * NdrUserMarshalMemorySize [RPCRT4.@]
4558 ULONG WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4559 PFORMAT_STRING pFormat
)
4561 unsigned flags
= pFormat
[1];
4562 unsigned index
= *(const WORD
*)&pFormat
[2];
4563 DWORD memsize
= *(const WORD
*)&pFormat
[4];
4564 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
4566 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
4567 TRACE("index=%d\n", index
);
4569 pStubMsg
->MemorySize
+= memsize
;
4571 if (flags
& USER_MARSHAL_POINTER
)
4573 align_pointer(&pStubMsg
->Buffer
, 4);
4574 /* skip pointer prefix */
4575 pStubMsg
->Buffer
+= 4;
4576 if (pStubMsg
->IgnoreEmbeddedPointers
)
4577 return pStubMsg
->MemorySize
;
4578 align_pointer(&pStubMsg
->Buffer
, 8);
4581 align_pointer(&pStubMsg
->Buffer
, (flags
& 0xf) + 1);
4584 FIXME("not implemented for varying buffer size\n");
4586 pStubMsg
->Buffer
+= bufsize
;
4588 return pStubMsg
->MemorySize
;
4591 /***********************************************************************
4592 * NdrUserMarshalFree [RPCRT4.@]
4594 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
4595 unsigned char *pMemory
,
4596 PFORMAT_STRING pFormat
)
4598 /* unsigned flags = pFormat[1]; */
4599 unsigned index
= *(const WORD
*)&pFormat
[2];
4600 USER_MARSHAL_CB umcb
;
4602 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
4603 TRACE("index=%d\n", index
);
4605 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_FREE
, pFormat
, &umcb
);
4607 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
4608 &umcb
.Flags
, pMemory
);
4611 /***********************************************************************
4612 * NdrGetUserMarshalInfo [RPCRT4.@]
4614 RPC_STATUS RPC_ENTRY
NdrGetUserMarshalInfo(ULONG
*flags
, ULONG level
, NDR_USER_MARSHAL_INFO
*umi
)
4616 USER_MARSHAL_CB
*umcb
= CONTAINING_RECORD(flags
, USER_MARSHAL_CB
, Flags
);
4618 TRACE("(%p,%u,%p)\n", flags
, level
, umi
);
4621 return RPC_S_INVALID_ARG
;
4623 memset(&umi
->u1
.Level1
, 0, sizeof(umi
->u1
.Level1
));
4624 umi
->InformationLevel
= level
;
4626 if (umcb
->Signature
!= USER_MARSHAL_CB_SIGNATURE
)
4627 return RPC_S_INVALID_ARG
;
4629 umi
->u1
.Level1
.pfnAllocate
= umcb
->pStubMsg
->pfnAllocate
;
4630 umi
->u1
.Level1
.pfnFree
= umcb
->pStubMsg
->pfnFree
;
4631 umi
->u1
.Level1
.pRpcChannelBuffer
= umcb
->pStubMsg
->pRpcChannelBuffer
;
4633 switch (umcb
->CBType
)
4635 case USER_MARSHAL_CB_MARSHALL
:
4636 case USER_MARSHAL_CB_UNMARSHALL
:
4638 RPC_MESSAGE
*msg
= umcb
->pStubMsg
->RpcMsg
;
4639 unsigned char *buffer_start
= msg
->Buffer
;
4640 unsigned char *buffer_end
=
4641 (unsigned char *)msg
->Buffer
+ msg
->BufferLength
;
4643 if (umcb
->pStubMsg
->Buffer
< buffer_start
||
4644 umcb
->pStubMsg
->Buffer
> buffer_end
)
4645 return RPC_X_INVALID_BUFFER
;
4647 umi
->u1
.Level1
.Buffer
= umcb
->pStubMsg
->Buffer
;
4648 umi
->u1
.Level1
.BufferSize
= buffer_end
- umcb
->pStubMsg
->Buffer
;
4651 case USER_MARSHAL_CB_BUFFER_SIZE
:
4652 case USER_MARSHAL_CB_FREE
:
4655 WARN("unrecognised CBType %d\n", umcb
->CBType
);
4661 /***********************************************************************
4662 * NdrClearOutParameters [RPCRT4.@]
4664 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
4665 PFORMAT_STRING pFormat
,
4668 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
4671 /***********************************************************************
4672 * NdrConvert [RPCRT4.@]
4674 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
4676 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
4677 /* FIXME: since this stub doesn't do any converting, the proper behavior
4678 is to raise an exception */
4681 /***********************************************************************
4682 * NdrConvert2 [RPCRT4.@]
4684 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, LONG NumberParams
)
4686 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4687 pStubMsg
, pFormat
, NumberParams
);
4688 /* FIXME: since this stub doesn't do any converting, the proper behavior
4689 is to raise an exception */
4692 #include "pshpack1.h"
4693 typedef struct _NDR_CSTRUCT_FORMAT
4696 unsigned char alignment
;
4697 unsigned short memory_size
;
4698 short offset_to_array_description
;
4699 } NDR_CSTRUCT_FORMAT
, NDR_CVSTRUCT_FORMAT
;
4700 #include "poppack.h"
4702 /***********************************************************************
4703 * NdrConformantStructMarshall [RPCRT4.@]
4705 unsigned char * WINAPI
NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4706 unsigned char *pMemory
,
4707 PFORMAT_STRING pFormat
)
4709 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4710 PFORMAT_STRING pCArrayFormat
;
4711 ULONG esize
, bufsize
;
4713 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4715 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4716 if ((pCStructFormat
->type
!= FC_CPSTRUCT
) && (pCStructFormat
->type
!= FC_CSTRUCT
))
4718 ERR("invalid format type %x\n", pCStructFormat
->type
);
4719 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4723 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4724 pCStructFormat
->offset_to_array_description
;
4725 if (*pCArrayFormat
!= FC_CARRAY
)
4727 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4728 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4731 esize
= *(const WORD
*)(pCArrayFormat
+2);
4733 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4734 pCArrayFormat
+ 4, 0);
4736 WriteConformance(pStubMsg
);
4738 align_pointer_clear(&pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4740 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4742 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4743 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4745 ERR("integer overflow of memory_size %u with bufsize %u\n",
4746 pCStructFormat
->memory_size
, bufsize
);
4747 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4749 /* copy constant sized part of struct */
4750 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4751 safe_copy_to_buffer(pStubMsg
, pMemory
, pCStructFormat
->memory_size
+ bufsize
);
4753 if (pCStructFormat
->type
== FC_CPSTRUCT
)
4754 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4759 /***********************************************************************
4760 * NdrConformantStructUnmarshall [RPCRT4.@]
4762 unsigned char * WINAPI
NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4763 unsigned char **ppMemory
,
4764 PFORMAT_STRING pFormat
,
4765 unsigned char fMustAlloc
)
4767 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4768 PFORMAT_STRING pCArrayFormat
;
4769 ULONG esize
, bufsize
;
4770 unsigned char *saved_buffer
;
4772 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4774 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4775 if ((pCStructFormat
->type
!= FC_CPSTRUCT
) && (pCStructFormat
->type
!= FC_CSTRUCT
))
4777 ERR("invalid format type %x\n", pCStructFormat
->type
);
4778 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4781 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4782 pCStructFormat
->offset_to_array_description
;
4783 if (*pCArrayFormat
!= FC_CARRAY
)
4785 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4786 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4789 esize
= *(const WORD
*)(pCArrayFormat
+2);
4791 pCArrayFormat
= ReadConformance(pStubMsg
, pCArrayFormat
+ 4);
4793 align_pointer(&pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
4795 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4797 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
4798 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
4800 ERR("integer overflow of memory_size %u with bufsize %u\n",
4801 pCStructFormat
->memory_size
, bufsize
);
4802 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4807 SIZE_T size
= pCStructFormat
->memory_size
+ bufsize
;
4808 *ppMemory
= NdrAllocateZero(pStubMsg
, size
);
4812 if (!pStubMsg
->IsClient
&& !*ppMemory
)
4813 /* for servers, we just point straight into the RPC buffer */
4814 *ppMemory
= pStubMsg
->Buffer
;
4817 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4818 safe_buffer_increment(pStubMsg
, pCStructFormat
->memory_size
+ bufsize
);
4819 if (pCStructFormat
->type
== FC_CPSTRUCT
)
4820 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4822 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
4823 if (*ppMemory
!= saved_buffer
)
4824 memcpy(*ppMemory
, saved_buffer
, pCStructFormat
->memory_size
+ bufsize
);
4829 /***********************************************************************
4830 * NdrConformantStructBufferSize [RPCRT4.@]
4832 void WINAPI
NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4833 unsigned char *pMemory
,
4834 PFORMAT_STRING pFormat
)
4836 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4837 PFORMAT_STRING pCArrayFormat
;
4840 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4842 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4843 if ((pCStructFormat
->type
!= FC_CPSTRUCT
) && (pCStructFormat
->type
!= FC_CSTRUCT
))
4845 ERR("invalid format type %x\n", pCStructFormat
->type
);
4846 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4849 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4850 pCStructFormat
->offset_to_array_description
;
4851 if (*pCArrayFormat
!= FC_CARRAY
)
4853 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4854 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4857 esize
= *(const WORD
*)(pCArrayFormat
+2);
4859 pCArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
, pCArrayFormat
+4, 0);
4860 SizeConformance(pStubMsg
);
4862 align_length(&pStubMsg
->BufferLength
, pCStructFormat
->alignment
+ 1);
4864 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4866 safe_buffer_length_increment(pStubMsg
, pCStructFormat
->memory_size
);
4867 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
4869 if (pCStructFormat
->type
== FC_CPSTRUCT
)
4870 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4873 /***********************************************************************
4874 * NdrConformantStructMemorySize [RPCRT4.@]
4876 ULONG WINAPI
NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4877 PFORMAT_STRING pFormat
)
4883 /***********************************************************************
4884 * NdrConformantStructFree [RPCRT4.@]
4886 void WINAPI
NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
4887 unsigned char *pMemory
,
4888 PFORMAT_STRING pFormat
)
4890 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
4891 PFORMAT_STRING pCArrayFormat
;
4893 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4895 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
4896 if ((pCStructFormat
->type
!= FC_CPSTRUCT
) && (pCStructFormat
->type
!= FC_CSTRUCT
))
4898 ERR("invalid format type %x\n", pCStructFormat
->type
);
4899 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4903 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
4904 pCStructFormat
->offset_to_array_description
;
4905 if (*pCArrayFormat
!= FC_CARRAY
)
4907 ERR("invalid array format type %x\n", pCStructFormat
->type
);
4908 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4912 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
4913 pCArrayFormat
+ 4, 0);
4915 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
4917 /* copy constant sized part of struct */
4918 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4920 if (pCStructFormat
->type
== FC_CPSTRUCT
)
4921 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4924 /***********************************************************************
4925 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4927 unsigned char * WINAPI
NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4928 unsigned char *pMemory
,
4929 PFORMAT_STRING pFormat
)
4931 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4932 PFORMAT_STRING pCVArrayFormat
;
4934 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4936 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4937 if (pCVStructFormat
->type
!= FC_CVSTRUCT
)
4939 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4940 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4944 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4945 pCVStructFormat
->offset_to_array_description
;
4947 array_compute_and_write_conformance(*pCVArrayFormat
, pStubMsg
,
4948 pMemory
+ pCVStructFormat
->memory_size
,
4951 align_pointer_clear(&pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4953 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4955 /* write constant sized part */
4956 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4957 safe_copy_to_buffer(pStubMsg
, pMemory
, pCVStructFormat
->memory_size
);
4959 array_write_variance_and_marshall(*pCVArrayFormat
, pStubMsg
,
4960 pMemory
+ pCVStructFormat
->memory_size
,
4961 pCVArrayFormat
, FALSE
/* fHasPointers */);
4963 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4968 /***********************************************************************
4969 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4971 unsigned char * WINAPI
NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4972 unsigned char **ppMemory
,
4973 PFORMAT_STRING pFormat
,
4974 unsigned char fMustAlloc
)
4976 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4977 PFORMAT_STRING pCVArrayFormat
;
4978 ULONG memsize
, bufsize
;
4979 unsigned char *saved_buffer
, *saved_array_buffer
;
4981 unsigned char *array_memory
;
4983 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4985 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4986 if (pCVStructFormat
->type
!= FC_CVSTRUCT
)
4988 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4989 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4993 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4994 pCVStructFormat
->offset_to_array_description
;
4996 memsize
= array_read_conformance(*pCVArrayFormat
, pStubMsg
,
4999 align_pointer(&pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
5001 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
5003 /* work out how much memory to allocate if we need to do so */
5004 if (!fMustAlloc
&& !*ppMemory
)
5008 SIZE_T size
= pCVStructFormat
->memory_size
+ memsize
;
5009 *ppMemory
= NdrAllocateZero(pStubMsg
, size
);
5012 /* mark the start of the constant data */
5013 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5014 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
5016 array_memory
= *ppMemory
+ pCVStructFormat
->memory_size
;
5017 bufsize
= array_read_variance_and_unmarshall(*pCVArrayFormat
, pStubMsg
,
5018 &array_memory
, pCVArrayFormat
,
5019 FALSE
/* fMustAlloc */,
5020 FALSE
/* fUseServerBufferMemory */,
5021 FALSE
/* fUnmarshall */);
5023 /* save offset in case unmarshalling pointers changes it */
5024 offset
= pStubMsg
->Offset
;
5026 /* mark the start of the array data */
5027 saved_array_buffer
= pStubMsg
->Buffer
;
5028 safe_buffer_increment(pStubMsg
, bufsize
);
5030 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
5032 /* copy the constant data */
5033 memcpy(*ppMemory
, saved_buffer
, pCVStructFormat
->memory_size
);
5034 /* copy the array data */
5035 TRACE("copying %p to %p\n", saved_array_buffer
, *ppMemory
+ pCVStructFormat
->memory_size
);
5036 memcpy(*ppMemory
+ pCVStructFormat
->memory_size
+ offset
,
5037 saved_array_buffer
, bufsize
);
5039 if (*pCVArrayFormat
== FC_C_CSTRING
)
5040 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory
+ pCVStructFormat
->memory_size
)));
5041 else if (*pCVArrayFormat
== FC_C_WSTRING
)
5042 TRACE("string=%s\n", debugstr_w((WCHAR
*)(*ppMemory
+ pCVStructFormat
->memory_size
)));
5047 /***********************************************************************
5048 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
5050 void WINAPI
NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5051 unsigned char *pMemory
,
5052 PFORMAT_STRING pFormat
)
5054 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
5055 PFORMAT_STRING pCVArrayFormat
;
5057 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5059 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
5060 if (pCVStructFormat
->type
!= FC_CVSTRUCT
)
5062 ERR("invalid format type %x\n", pCVStructFormat
->type
);
5063 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5067 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
5068 pCVStructFormat
->offset_to_array_description
;
5069 array_compute_and_size_conformance(*pCVArrayFormat
, pStubMsg
,
5070 pMemory
+ pCVStructFormat
->memory_size
,
5073 align_length(&pStubMsg
->BufferLength
, pCVStructFormat
->alignment
+ 1);
5075 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
5077 safe_buffer_length_increment(pStubMsg
, pCVStructFormat
->memory_size
);
5079 array_buffer_size(*pCVArrayFormat
, pStubMsg
,
5080 pMemory
+ pCVStructFormat
->memory_size
, pCVArrayFormat
,
5081 FALSE
/* fHasPointers */);
5083 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5086 /***********************************************************************
5087 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
5089 ULONG WINAPI
NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5090 PFORMAT_STRING pFormat
)
5092 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
5093 PFORMAT_STRING pCVArrayFormat
;
5095 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5097 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
5098 if (pCVStructFormat
->type
!= FC_CVSTRUCT
)
5100 ERR("invalid format type %x\n", pCVStructFormat
->type
);
5101 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5105 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
5106 pCVStructFormat
->offset_to_array_description
;
5107 array_read_conformance(*pCVArrayFormat
, pStubMsg
, pCVArrayFormat
);
5109 align_pointer(&pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
5111 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
5113 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
5114 array_memory_size(*pCVArrayFormat
, pStubMsg
, pCVArrayFormat
,
5115 FALSE
/* fHasPointers */);
5117 pStubMsg
->MemorySize
+= pCVStructFormat
->memory_size
;
5119 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5121 return pStubMsg
->MemorySize
;
5124 /***********************************************************************
5125 * NdrConformantVaryingStructFree [RPCRT4.@]
5127 void WINAPI
NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
5128 unsigned char *pMemory
,
5129 PFORMAT_STRING pFormat
)
5131 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
5132 PFORMAT_STRING pCVArrayFormat
;
5134 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5136 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
5137 if (pCVStructFormat
->type
!= FC_CVSTRUCT
)
5139 ERR("invalid format type %x\n", pCVStructFormat
->type
);
5140 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5144 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
5145 pCVStructFormat
->offset_to_array_description
;
5146 array_free(*pCVArrayFormat
, pStubMsg
,
5147 pMemory
+ pCVStructFormat
->memory_size
, pCVArrayFormat
,
5148 FALSE
/* fHasPointers */);
5150 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
5152 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5155 #include "pshpack1.h"
5159 unsigned char alignment
;
5160 unsigned short total_size
;
5161 } NDR_SMFARRAY_FORMAT
;
5166 unsigned char alignment
;
5168 } NDR_LGFARRAY_FORMAT
;
5169 #include "poppack.h"
5171 /***********************************************************************
5172 * NdrFixedArrayMarshall [RPCRT4.@]
5174 unsigned char * WINAPI
NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5175 unsigned char *pMemory
,
5176 PFORMAT_STRING pFormat
)
5178 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5181 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5183 if ((pSmFArrayFormat
->type
!= FC_SMFARRAY
) &&
5184 (pSmFArrayFormat
->type
!= FC_LGFARRAY
))
5186 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5187 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5191 align_pointer_clear(&pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
5193 if (pSmFArrayFormat
->type
== FC_SMFARRAY
)
5195 total_size
= pSmFArrayFormat
->total_size
;
5196 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5200 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5201 total_size
= pLgFArrayFormat
->total_size
;
5202 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5205 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5206 safe_copy_to_buffer(pStubMsg
, pMemory
, total_size
);
5208 pFormat
= EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
5213 /***********************************************************************
5214 * NdrFixedArrayUnmarshall [RPCRT4.@]
5216 unsigned char * WINAPI
NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5217 unsigned char **ppMemory
,
5218 PFORMAT_STRING pFormat
,
5219 unsigned char fMustAlloc
)
5221 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5223 unsigned char *saved_buffer
;
5225 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5227 if ((pSmFArrayFormat
->type
!= FC_SMFARRAY
) &&
5228 (pSmFArrayFormat
->type
!= FC_LGFARRAY
))
5230 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5231 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5235 align_pointer(&pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
5237 if (pSmFArrayFormat
->type
== FC_SMFARRAY
)
5239 total_size
= pSmFArrayFormat
->total_size
;
5240 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5244 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5245 total_size
= pLgFArrayFormat
->total_size
;
5246 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5250 *ppMemory
= NdrAllocateZero(pStubMsg
, total_size
);
5253 if (!pStubMsg
->IsClient
&& !*ppMemory
)
5254 /* for servers, we just point straight into the RPC buffer */
5255 *ppMemory
= pStubMsg
->Buffer
;
5258 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5259 safe_buffer_increment(pStubMsg
, total_size
);
5260 pFormat
= EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
5262 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
5263 if (*ppMemory
!= saved_buffer
)
5264 memcpy(*ppMemory
, saved_buffer
, total_size
);
5269 /***********************************************************************
5270 * NdrFixedArrayBufferSize [RPCRT4.@]
5272 void WINAPI
NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5273 unsigned char *pMemory
,
5274 PFORMAT_STRING pFormat
)
5276 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5279 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5281 if ((pSmFArrayFormat
->type
!= FC_SMFARRAY
) &&
5282 (pSmFArrayFormat
->type
!= FC_LGFARRAY
))
5284 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5285 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5289 align_length(&pStubMsg
->BufferLength
, pSmFArrayFormat
->alignment
+ 1);
5291 if (pSmFArrayFormat
->type
== FC_SMFARRAY
)
5293 total_size
= pSmFArrayFormat
->total_size
;
5294 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5298 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5299 total_size
= pLgFArrayFormat
->total_size
;
5300 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5302 safe_buffer_length_increment(pStubMsg
, total_size
);
5304 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5307 /***********************************************************************
5308 * NdrFixedArrayMemorySize [RPCRT4.@]
5310 ULONG WINAPI
NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5311 PFORMAT_STRING pFormat
)
5313 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5316 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5318 if ((pSmFArrayFormat
->type
!= FC_SMFARRAY
) &&
5319 (pSmFArrayFormat
->type
!= FC_LGFARRAY
))
5321 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5322 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5326 align_pointer(&pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
5328 if (pSmFArrayFormat
->type
== FC_SMFARRAY
)
5330 total_size
= pSmFArrayFormat
->total_size
;
5331 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5335 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5336 total_size
= pLgFArrayFormat
->total_size
;
5337 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5339 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5340 safe_buffer_increment(pStubMsg
, total_size
);
5341 pStubMsg
->MemorySize
+= total_size
;
5343 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5348 /***********************************************************************
5349 * NdrFixedArrayFree [RPCRT4.@]
5351 void WINAPI
NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
5352 unsigned char *pMemory
,
5353 PFORMAT_STRING pFormat
)
5355 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
5357 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5359 if ((pSmFArrayFormat
->type
!= FC_SMFARRAY
) &&
5360 (pSmFArrayFormat
->type
!= FC_LGFARRAY
))
5362 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
5363 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5367 if (pSmFArrayFormat
->type
== FC_SMFARRAY
)
5368 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
5371 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
5372 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
5375 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5378 /***********************************************************************
5379 * NdrVaryingArrayMarshall [RPCRT4.@]
5381 unsigned char * WINAPI
NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5382 unsigned char *pMemory
,
5383 PFORMAT_STRING pFormat
)
5385 unsigned char alignment
;
5386 DWORD elements
, esize
;
5389 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5391 if ((pFormat
[0] != FC_SMVARRAY
) &&
5392 (pFormat
[0] != FC_LGVARRAY
))
5394 ERR("invalid format type %x\n", pFormat
[0]);
5395 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5399 alignment
= pFormat
[1] + 1;
5401 if (pFormat
[0] == FC_SMVARRAY
)
5404 pFormat
+= sizeof(WORD
);
5405 elements
= *(const WORD
*)pFormat
;
5406 pFormat
+= sizeof(WORD
);
5411 pFormat
+= sizeof(DWORD
);
5412 elements
= *(const DWORD
*)pFormat
;
5413 pFormat
+= sizeof(DWORD
);
5416 esize
= *(const WORD
*)pFormat
;
5417 pFormat
+= sizeof(WORD
);
5419 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5420 if ((pStubMsg
->ActualCount
> elements
) ||
5421 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5423 RpcRaiseException(RPC_S_INVALID_BOUND
);
5427 WriteVariance(pStubMsg
);
5429 align_pointer_clear(&pStubMsg
->Buffer
, alignment
);
5431 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
5432 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5433 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
5435 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
5440 /***********************************************************************
5441 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5443 unsigned char * WINAPI
NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5444 unsigned char **ppMemory
,
5445 PFORMAT_STRING pFormat
,
5446 unsigned char fMustAlloc
)
5448 unsigned char alignment
;
5449 DWORD size
, elements
, esize
;
5451 unsigned char *saved_buffer
;
5454 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5456 if ((pFormat
[0] != FC_SMVARRAY
) &&
5457 (pFormat
[0] != FC_LGVARRAY
))
5459 ERR("invalid format type %x\n", pFormat
[0]);
5460 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5464 alignment
= pFormat
[1] + 1;
5466 if (pFormat
[0] == FC_SMVARRAY
)
5469 size
= *(const WORD
*)pFormat
;
5470 pFormat
+= sizeof(WORD
);
5471 elements
= *(const WORD
*)pFormat
;
5472 pFormat
+= sizeof(WORD
);
5477 size
= *(const DWORD
*)pFormat
;
5478 pFormat
+= sizeof(DWORD
);
5479 elements
= *(const DWORD
*)pFormat
;
5480 pFormat
+= sizeof(DWORD
);
5483 esize
= *(const WORD
*)pFormat
;
5484 pFormat
+= sizeof(WORD
);
5486 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
5488 align_pointer(&pStubMsg
->Buffer
, alignment
);
5490 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
5491 offset
= pStubMsg
->Offset
;
5493 if (!fMustAlloc
&& !*ppMemory
)
5496 *ppMemory
= NdrAllocateZero(pStubMsg
, size
);
5497 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
5498 safe_buffer_increment(pStubMsg
, bufsize
);
5500 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
5502 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
5507 /***********************************************************************
5508 * NdrVaryingArrayBufferSize [RPCRT4.@]
5510 void WINAPI
NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5511 unsigned char *pMemory
,
5512 PFORMAT_STRING pFormat
)
5514 unsigned char alignment
;
5515 DWORD elements
, esize
;
5517 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5519 if ((pFormat
[0] != FC_SMVARRAY
) &&
5520 (pFormat
[0] != FC_LGVARRAY
))
5522 ERR("invalid format type %x\n", pFormat
[0]);
5523 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5527 alignment
= pFormat
[1] + 1;
5529 if (pFormat
[0] == FC_SMVARRAY
)
5532 pFormat
+= sizeof(WORD
);
5533 elements
= *(const WORD
*)pFormat
;
5534 pFormat
+= sizeof(WORD
);
5539 pFormat
+= sizeof(DWORD
);
5540 elements
= *(const DWORD
*)pFormat
;
5541 pFormat
+= sizeof(DWORD
);
5544 esize
= *(const WORD
*)pFormat
;
5545 pFormat
+= sizeof(WORD
);
5547 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5548 if ((pStubMsg
->ActualCount
> elements
) ||
5549 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5551 RpcRaiseException(RPC_S_INVALID_BOUND
);
5555 SizeVariance(pStubMsg
);
5557 align_length(&pStubMsg
->BufferLength
, alignment
);
5559 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
5561 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
5564 /***********************************************************************
5565 * NdrVaryingArrayMemorySize [RPCRT4.@]
5567 ULONG WINAPI
NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5568 PFORMAT_STRING pFormat
)
5570 unsigned char alignment
;
5571 DWORD size
, elements
, esize
;
5573 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
5575 if ((pFormat
[0] != FC_SMVARRAY
) &&
5576 (pFormat
[0] != FC_LGVARRAY
))
5578 ERR("invalid format type %x\n", pFormat
[0]);
5579 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5583 alignment
= pFormat
[1] + 1;
5585 if (pFormat
[0] == FC_SMVARRAY
)
5588 size
= *(const WORD
*)pFormat
;
5589 pFormat
+= sizeof(WORD
);
5590 elements
= *(const WORD
*)pFormat
;
5591 pFormat
+= sizeof(WORD
);
5596 size
= *(const DWORD
*)pFormat
;
5597 pFormat
+= sizeof(DWORD
);
5598 elements
= *(const DWORD
*)pFormat
;
5599 pFormat
+= sizeof(DWORD
);
5602 esize
= *(const WORD
*)pFormat
;
5603 pFormat
+= sizeof(WORD
);
5605 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
5607 align_pointer(&pStubMsg
->Buffer
, alignment
);
5609 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
5610 pStubMsg
->MemorySize
+= size
;
5612 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
5614 return pStubMsg
->MemorySize
;
5617 /***********************************************************************
5618 * NdrVaryingArrayFree [RPCRT4.@]
5620 void WINAPI
NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
5621 unsigned char *pMemory
,
5622 PFORMAT_STRING pFormat
)
5626 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5628 if ((pFormat
[0] != FC_SMVARRAY
) &&
5629 (pFormat
[0] != FC_LGVARRAY
))
5631 ERR("invalid format type %x\n", pFormat
[0]);
5632 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5636 if (pFormat
[0] == FC_SMVARRAY
)
5639 pFormat
+= sizeof(WORD
);
5640 elements
= *(const WORD
*)pFormat
;
5641 pFormat
+= sizeof(WORD
);
5646 pFormat
+= sizeof(DWORD
);
5647 elements
= *(const DWORD
*)pFormat
;
5648 pFormat
+= sizeof(DWORD
);
5651 pFormat
+= sizeof(WORD
);
5653 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
5654 if ((pStubMsg
->ActualCount
> elements
) ||
5655 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
5657 RpcRaiseException(RPC_S_INVALID_BOUND
);
5661 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
5664 static ULONG
get_discriminant(unsigned char fc
, const unsigned char *pMemory
)
5677 return *(const USHORT
*)pMemory
;
5681 return *(const ULONG
*)pMemory
;
5683 FIXME("Unhandled base type: 0x%02x\n", fc
);
5688 static PFORMAT_STRING
get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg
,
5690 PFORMAT_STRING pFormat
)
5692 unsigned short num_arms
, arm
, type
;
5694 num_arms
= *(const SHORT
*)pFormat
& 0x0fff;
5696 for(arm
= 0; arm
< num_arms
; arm
++)
5698 if(discriminant
== *(const ULONG
*)pFormat
)
5706 type
= *(const unsigned short*)pFormat
;
5707 TRACE("type %04x\n", type
);
5708 if(arm
== num_arms
) /* default arm extras */
5712 ERR("no arm for 0x%x and no default case\n", discriminant
);
5713 RpcRaiseException(RPC_S_INVALID_TAG
);
5718 TRACE("falling back to empty default case for 0x%x\n", discriminant
);
5725 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
, ULONG discriminant
, PFORMAT_STRING pFormat
)
5727 unsigned short type
;
5731 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5735 type
= *(const unsigned short*)pFormat
;
5736 if((type
& 0xff00) == 0x8000)
5738 unsigned char basetype
= LOBYTE(type
);
5739 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &basetype
);
5743 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5744 NDR_MARSHALL m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
5747 unsigned char *saved_buffer
= NULL
;
5748 BOOL pointer_buffer_mark_set
= FALSE
;
5755 align_pointer_clear(&pStubMsg
->Buffer
, 4);
5756 saved_buffer
= pStubMsg
->Buffer
;
5757 if (pStubMsg
->PointerBufferMark
)
5759 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5760 pStubMsg
->PointerBufferMark
= NULL
;
5761 pointer_buffer_mark_set
= TRUE
;
5764 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
5766 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char **)pMemory
, desc
);
5767 if (pointer_buffer_mark_set
)
5769 STD_OVERFLOW_CHECK(pStubMsg
);
5770 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5771 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5773 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5774 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
5775 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5777 pStubMsg
->Buffer
= saved_buffer
+ 4;
5781 /* must be dereferenced first */
5782 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5785 m(pStubMsg
, pMemory
, desc
);
5789 FIXME("no marshaller for embedded type %02x\n", *desc
);
5794 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5795 unsigned char **ppMemory
,
5797 PFORMAT_STRING pFormat
,
5798 unsigned char fMustAlloc
)
5800 unsigned short type
;
5804 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5808 type
= *(const unsigned short*)pFormat
;
5809 if((type
& 0xff00) == 0x8000)
5811 unsigned char basetype
= LOBYTE(type
);
5812 return NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &basetype
, FALSE
);
5816 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5817 NDR_UNMARSHALL m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
5820 unsigned char *saved_buffer
= NULL
;
5821 BOOL pointer_buffer_mark_set
= FALSE
;
5828 align_pointer(&pStubMsg
->Buffer
, 4);
5829 saved_buffer
= pStubMsg
->Buffer
;
5830 if (pStubMsg
->PointerBufferMark
)
5832 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
5833 pStubMsg
->PointerBufferMark
= NULL
;
5834 pointer_buffer_mark_set
= TRUE
;
5837 pStubMsg
->Buffer
+= 4; /* for pointer ID */
5839 if (saved_buffer
+ 4 > pStubMsg
->BufferEnd
)
5841 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5842 saved_buffer
, pStubMsg
->BufferEnd
);
5843 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5846 PointerUnmarshall(pStubMsg
, saved_buffer
, *(unsigned char ***)ppMemory
, **(unsigned char ***)ppMemory
, desc
, fMustAlloc
);
5847 if (pointer_buffer_mark_set
)
5849 STD_OVERFLOW_CHECK(pStubMsg
);
5850 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
5851 pStubMsg
->Buffer
= saved_buffer
+ 4;
5855 /* must be dereferenced first */
5856 m(pStubMsg
, *(unsigned char ***)ppMemory
, desc
, fMustAlloc
);
5859 m(pStubMsg
, ppMemory
, desc
, fMustAlloc
);
5863 FIXME("no marshaller for embedded type %02x\n", *desc
);
5868 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg
,
5869 unsigned char *pMemory
,
5871 PFORMAT_STRING pFormat
)
5873 unsigned short type
;
5877 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5881 type
= *(const unsigned short*)pFormat
;
5882 if((type
& 0xff00) == 0x8000)
5884 unsigned char basetype
= LOBYTE(type
);
5885 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &basetype
);
5889 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5890 NDR_BUFFERSIZE m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
5899 align_length(&pStubMsg
->BufferLength
, 4);
5900 safe_buffer_length_increment(pStubMsg
, 4); /* for pointer ID */
5901 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5903 int saved_buffer_length
= pStubMsg
->BufferLength
;
5904 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
5905 pStubMsg
->PointerLength
= 0;
5906 if(!pStubMsg
->BufferLength
)
5907 ERR("BufferLength == 0??\n");
5908 PointerBufferSize(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5909 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
5910 pStubMsg
->BufferLength
= saved_buffer_length
;
5914 /* must be dereferenced first */
5915 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5918 m(pStubMsg
, pMemory
, desc
);
5922 FIXME("no buffersizer for embedded type %02x\n", *desc
);
5926 static ULONG
union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg
,
5928 PFORMAT_STRING pFormat
)
5930 unsigned short type
, size
;
5932 size
= *(const unsigned short*)pFormat
;
5933 pStubMsg
->Memory
+= size
;
5936 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5940 type
= *(const unsigned short*)pFormat
;
5941 if((type
& 0xff00) == 0x8000)
5943 return NdrBaseTypeMemorySize(pStubMsg
, pFormat
);
5947 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5948 NDR_MEMORYSIZE m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
5949 unsigned char *saved_buffer
;
5958 align_pointer(&pStubMsg
->Buffer
, 4);
5959 saved_buffer
= pStubMsg
->Buffer
;
5960 safe_buffer_increment(pStubMsg
, 4);
5961 align_length(&pStubMsg
->MemorySize
, sizeof(void *));
5962 pStubMsg
->MemorySize
+= sizeof(void *);
5963 if (!pStubMsg
->IgnoreEmbeddedPointers
)
5964 PointerMemorySize(pStubMsg
, saved_buffer
, pFormat
);
5967 return m(pStubMsg
, desc
);
5971 FIXME("no marshaller for embedded type %02x\n", *desc
);
5974 TRACE("size %d\n", size
);
5978 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg
,
5979 unsigned char *pMemory
,
5981 PFORMAT_STRING pFormat
)
5983 unsigned short type
;
5987 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5991 type
= *(const unsigned short*)pFormat
;
5992 if((type
& 0xff00) != 0x8000)
5994 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5995 NDR_FREE m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
6004 PointerFree(pStubMsg
, *(unsigned char **)pMemory
, desc
);
6007 /* must be dereferenced first */
6008 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
6011 m(pStubMsg
, pMemory
, desc
);
6017 /***********************************************************************
6018 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
6020 unsigned char * WINAPI
NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6021 unsigned char *pMemory
,
6022 PFORMAT_STRING pFormat
)
6024 unsigned char switch_type
;
6025 unsigned char increment
;
6028 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6031 switch_type
= *pFormat
& 0xf;
6032 increment
= (*pFormat
& 0xf0) >> 4;
6035 align_pointer_clear(&pStubMsg
->Buffer
, increment
);
6037 switch_value
= get_discriminant(switch_type
, pMemory
);
6038 TRACE("got switch value 0x%x\n", switch_value
);
6040 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &switch_type
);
6041 pMemory
+= increment
;
6043 return union_arm_marshall(pStubMsg
, pMemory
, switch_value
, pFormat
);
6046 /***********************************************************************
6047 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
6049 unsigned char * WINAPI
NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6050 unsigned char **ppMemory
,
6051 PFORMAT_STRING pFormat
,
6052 unsigned char fMustAlloc
)
6054 unsigned char switch_type
;
6055 unsigned char increment
;
6057 unsigned short size
;
6058 unsigned char *pMemoryArm
;
6060 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
6063 switch_type
= *pFormat
& 0xf;
6064 increment
= (*pFormat
& 0xf0) >> 4;
6067 align_pointer(&pStubMsg
->Buffer
, increment
);
6068 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
6069 TRACE("got switch value 0x%x\n", switch_value
);
6071 size
= *(const unsigned short*)pFormat
+ increment
;
6072 if (!fMustAlloc
&& !*ppMemory
)
6075 *ppMemory
= NdrAllocate(pStubMsg
, size
);
6077 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6078 * since the arm is part of the memory block that is encompassed by
6079 * the whole union. Memory is forced to allocate when pointers
6080 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6081 * clearing the memory we pass in to the unmarshaller */
6083 memset(*ppMemory
, 0, size
);
6085 NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &switch_type
, FALSE
);
6086 pMemoryArm
= *ppMemory
+ increment
;
6088 return union_arm_unmarshall(pStubMsg
, &pMemoryArm
, switch_value
, pFormat
, FALSE
);
6091 /***********************************************************************
6092 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
6094 void WINAPI
NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6095 unsigned char *pMemory
,
6096 PFORMAT_STRING pFormat
)
6098 unsigned char switch_type
;
6099 unsigned char increment
;
6102 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6105 switch_type
= *pFormat
& 0xf;
6106 increment
= (*pFormat
& 0xf0) >> 4;
6109 align_length(&pStubMsg
->BufferLength
, increment
);
6110 switch_value
= get_discriminant(switch_type
, pMemory
);
6111 TRACE("got switch value 0x%x\n", switch_value
);
6113 /* Add discriminant size */
6114 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&switch_value
, &switch_type
);
6115 pMemory
+= increment
;
6117 union_arm_buffer_size(pStubMsg
, pMemory
, switch_value
, pFormat
);
6120 /***********************************************************************
6121 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
6123 ULONG WINAPI
NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6124 PFORMAT_STRING pFormat
)
6126 unsigned char switch_type
;
6127 unsigned char increment
;
6130 switch_type
= *pFormat
& 0xf;
6131 increment
= (*pFormat
& 0xf0) >> 4;
6134 align_pointer(&pStubMsg
->Buffer
, increment
);
6135 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
6136 TRACE("got switch value 0x%x\n", switch_value
);
6138 pStubMsg
->Memory
+= increment
;
6140 return increment
+ union_arm_memory_size(pStubMsg
, switch_value
, pFormat
+ *(const SHORT
*)pFormat
);
6143 /***********************************************************************
6144 * NdrEncapsulatedUnionFree [RPCRT4.@]
6146 void WINAPI
NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
6147 unsigned char *pMemory
,
6148 PFORMAT_STRING pFormat
)
6150 unsigned char switch_type
;
6151 unsigned char increment
;
6154 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6157 switch_type
= *pFormat
& 0xf;
6158 increment
= (*pFormat
& 0xf0) >> 4;
6161 switch_value
= get_discriminant(switch_type
, pMemory
);
6162 TRACE("got switch value 0x%x\n", switch_value
);
6164 pMemory
+= increment
;
6166 union_arm_free(pStubMsg
, pMemory
, switch_value
, pFormat
);
6169 /***********************************************************************
6170 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
6172 unsigned char * WINAPI
NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6173 unsigned char *pMemory
,
6174 PFORMAT_STRING pFormat
)
6176 unsigned char switch_type
;
6178 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6181 switch_type
= *pFormat
;
6184 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6185 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6186 /* Marshall discriminant */
6187 NdrBaseTypeMarshall(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
6189 return union_arm_marshall(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6192 static LONG
unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg
,
6193 PFORMAT_STRING
*ppFormat
)
6195 LONG discriminant
= 0;
6205 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
6215 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6216 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
6224 align_pointer(&pStubMsg
->Buffer
, sizeof(ULONG
));
6225 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
6230 FIXME("Unhandled base type: 0x%02x\n", **ppFormat
);
6234 *ppFormat
= SkipConformance(pStubMsg
, *ppFormat
);
6235 return discriminant
;
6238 /**********************************************************************
6239 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
6241 unsigned char * WINAPI
NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6242 unsigned char **ppMemory
,
6243 PFORMAT_STRING pFormat
,
6244 unsigned char fMustAlloc
)
6247 unsigned short size
;
6249 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
6252 /* Unmarshall discriminant */
6253 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
6254 TRACE("unmarshalled discriminant %x\n", discriminant
);
6256 pFormat
+= *(const SHORT
*)pFormat
;
6258 size
= *(const unsigned short*)pFormat
;
6260 if (!fMustAlloc
&& !*ppMemory
)
6263 *ppMemory
= NdrAllocate(pStubMsg
, size
);
6265 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
6266 * since the arm is part of the memory block that is encompassed by
6267 * the whole union. Memory is forced to allocate when pointers
6268 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
6269 * clearing the memory we pass in to the unmarshaller */
6271 memset(*ppMemory
, 0, size
);
6273 return union_arm_unmarshall(pStubMsg
, ppMemory
, discriminant
, pFormat
, FALSE
);
6276 /***********************************************************************
6277 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
6279 void WINAPI
NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6280 unsigned char *pMemory
,
6281 PFORMAT_STRING pFormat
)
6283 unsigned char switch_type
;
6285 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6288 switch_type
= *pFormat
;
6291 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6292 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6293 /* Add discriminant size */
6294 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
6296 union_arm_buffer_size(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6299 /***********************************************************************
6300 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
6302 ULONG WINAPI
NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6303 PFORMAT_STRING pFormat
)
6308 /* Unmarshall discriminant */
6309 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
6310 TRACE("unmarshalled discriminant 0x%x\n", discriminant
);
6312 return union_arm_memory_size(pStubMsg
, discriminant
, pFormat
+ *(const SHORT
*)pFormat
);
6315 /***********************************************************************
6316 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6318 void WINAPI
NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
6319 unsigned char *pMemory
,
6320 PFORMAT_STRING pFormat
)
6322 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
6326 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
6327 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
6329 union_arm_free(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
6332 /***********************************************************************
6333 * NdrByteCountPointerMarshall [RPCRT4.@]
6335 unsigned char * WINAPI
NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6336 unsigned char *pMemory
,
6337 PFORMAT_STRING pFormat
)
6343 /***********************************************************************
6344 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6346 unsigned char * WINAPI
NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6347 unsigned char **ppMemory
,
6348 PFORMAT_STRING pFormat
,
6349 unsigned char fMustAlloc
)
6355 /***********************************************************************
6356 * NdrByteCountPointerBufferSize [RPCRT4.@]
6358 void WINAPI
NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6359 unsigned char *pMemory
,
6360 PFORMAT_STRING pFormat
)
6365 /***********************************************************************
6366 * NdrByteCountPointerMemorySize [internal]
6368 static ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6369 PFORMAT_STRING pFormat
)
6375 /***********************************************************************
6376 * NdrByteCountPointerFree [RPCRT4.@]
6378 void WINAPI
NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
6379 unsigned char *pMemory
,
6380 PFORMAT_STRING pFormat
)
6385 /***********************************************************************
6386 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6388 unsigned char * WINAPI
NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6389 unsigned char *pMemory
,
6390 PFORMAT_STRING pFormat
)
6396 /***********************************************************************
6397 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6399 unsigned char * WINAPI
NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6400 unsigned char **ppMemory
,
6401 PFORMAT_STRING pFormat
,
6402 unsigned char fMustAlloc
)
6408 /***********************************************************************
6409 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6411 void WINAPI
NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
6412 unsigned char *pMemory
,
6413 PFORMAT_STRING pFormat
)
6418 /***********************************************************************
6419 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6421 ULONG WINAPI
NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
6422 PFORMAT_STRING pFormat
)
6428 /***********************************************************************
6429 * NdrXmitOrRepAsFree [RPCRT4.@]
6431 void WINAPI
NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg
,
6432 unsigned char *pMemory
,
6433 PFORMAT_STRING pFormat
)
6438 /***********************************************************************
6439 * NdrRangeMarshall [internal]
6441 static unsigned char *WINAPI
NdrRangeMarshall(
6442 PMIDL_STUB_MESSAGE pStubMsg
,
6443 unsigned char *pMemory
,
6444 PFORMAT_STRING pFormat
)
6446 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6447 unsigned char base_type
;
6449 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6451 if (pRange
->type
!= FC_RANGE
)
6453 ERR("invalid format type %x\n", pRange
->type
);
6454 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6458 base_type
= pRange
->flags_type
& 0xf;
6460 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &base_type
);
6463 /***********************************************************************
6464 * NdrRangeUnmarshall [RPCRT4.@]
6466 unsigned char *WINAPI
NdrRangeUnmarshall(
6467 PMIDL_STUB_MESSAGE pStubMsg
,
6468 unsigned char **ppMemory
,
6469 PFORMAT_STRING pFormat
,
6470 unsigned char fMustAlloc
)
6472 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6473 unsigned char base_type
;
6475 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6477 if (pRange
->type
!= FC_RANGE
)
6479 ERR("invalid format type %x\n", pRange
->type
);
6480 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6483 base_type
= pRange
->flags_type
& 0xf;
6485 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6486 base_type
, pRange
->low_value
, pRange
->high_value
);
6488 #define RANGE_UNMARSHALL(mem_type, wire_type, format_spec) \
6491 align_pointer(&pStubMsg->Buffer, sizeof(wire_type)); \
6492 if (!fMustAlloc && !*ppMemory) \
6493 fMustAlloc = TRUE; \
6495 *ppMemory = NdrAllocate(pStubMsg, sizeof(mem_type)); \
6496 if (pStubMsg->Buffer + sizeof(wire_type) > pStubMsg->BufferEnd) \
6498 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6499 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6500 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6502 if ((*(wire_type *)pStubMsg->Buffer < (mem_type)pRange->low_value) || \
6503 (*(wire_type *)pStubMsg->Buffer > (mem_type)pRange->high_value)) \
6505 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6506 *(wire_type *)pStubMsg->Buffer, (mem_type)pRange->low_value, \
6507 (mem_type)pRange->high_value); \
6508 RpcRaiseException(RPC_S_INVALID_BOUND); \
6511 TRACE("*ppMemory: %p\n", *ppMemory); \
6512 **(mem_type **)ppMemory = *(wire_type *)pStubMsg->Buffer; \
6513 pStubMsg->Buffer += sizeof(wire_type); \
6520 RANGE_UNMARSHALL(UCHAR
, UCHAR
, "%d");
6521 TRACE("value: 0x%02x\n", **ppMemory
);
6525 RANGE_UNMARSHALL(CHAR
, CHAR
, "%u");
6526 TRACE("value: 0x%02x\n", **ppMemory
);
6528 case FC_WCHAR
: /* FIXME: valid? */
6530 RANGE_UNMARSHALL(USHORT
, USHORT
, "%u");
6531 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6534 RANGE_UNMARSHALL(SHORT
, SHORT
, "%d");
6535 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6539 RANGE_UNMARSHALL(LONG
, LONG
, "%d");
6540 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6543 RANGE_UNMARSHALL(ULONG
, ULONG
, "%u");
6544 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6547 RANGE_UNMARSHALL(UINT
, USHORT
, "%u");
6548 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
6554 ERR("invalid range base type: 0x%02x\n", base_type
);
6555 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6561 /***********************************************************************
6562 * NdrRangeBufferSize [internal]
6564 static void WINAPI
NdrRangeBufferSize(
6565 PMIDL_STUB_MESSAGE pStubMsg
,
6566 unsigned char *pMemory
,
6567 PFORMAT_STRING pFormat
)
6569 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6570 unsigned char base_type
;
6572 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6574 if (pRange
->type
!= FC_RANGE
)
6576 ERR("invalid format type %x\n", pRange
->type
);
6577 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6579 base_type
= pRange
->flags_type
& 0xf;
6581 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &base_type
);
6584 /***********************************************************************
6585 * NdrRangeMemorySize [internal]
6587 static ULONG WINAPI
NdrRangeMemorySize(
6588 PMIDL_STUB_MESSAGE pStubMsg
,
6589 PFORMAT_STRING pFormat
)
6591 const NDR_RANGE
*pRange
= (const NDR_RANGE
*)pFormat
;
6592 unsigned char base_type
;
6594 if (pRange
->type
!= FC_RANGE
)
6596 ERR("invalid format type %x\n", pRange
->type
);
6597 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6600 base_type
= pRange
->flags_type
& 0xf;
6602 return NdrBaseTypeMemorySize(pStubMsg
, &base_type
);
6605 /***********************************************************************
6606 * NdrRangeFree [internal]
6608 static void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6609 unsigned char *pMemory
,
6610 PFORMAT_STRING pFormat
)
6612 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6617 /***********************************************************************
6618 * NdrBaseTypeMarshall [internal]
6620 static unsigned char *WINAPI
NdrBaseTypeMarshall(
6621 PMIDL_STUB_MESSAGE pStubMsg
,
6622 unsigned char *pMemory
,
6623 PFORMAT_STRING pFormat
)
6625 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6633 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(UCHAR
));
6634 TRACE("value: 0x%02x\n", *pMemory
);
6639 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(USHORT
));
6640 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(USHORT
));
6641 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
6645 case FC_ERROR_STATUS_T
:
6647 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(ULONG
));
6648 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONG
));
6649 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
6652 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(float));
6653 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
6656 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(double));
6657 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
6660 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(ULONGLONG
));
6661 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONGLONG
));
6662 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
6666 USHORT val
= *(UINT
*)pMemory
;
6667 /* only 16-bits on the wire, so do a sanity check */
6668 if (*(UINT
*)pMemory
> SHRT_MAX
)
6669 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
6670 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(USHORT
));
6671 safe_copy_to_buffer(pStubMsg
, &val
, sizeof(val
));
6672 TRACE("value: 0x%04x\n", *(UINT
*)pMemory
);
6678 UINT val
= *(UINT_PTR
*)pMemory
;
6679 align_pointer_clear(&pStubMsg
->Buffer
, sizeof(UINT
));
6680 safe_copy_to_buffer(pStubMsg
, &val
, sizeof(val
));
6686 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6689 /* FIXME: what is the correct return value? */
6693 /***********************************************************************
6694 * NdrBaseTypeUnmarshall [internal]
6696 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(
6697 PMIDL_STUB_MESSAGE pStubMsg
,
6698 unsigned char **ppMemory
,
6699 PFORMAT_STRING pFormat
,
6700 unsigned char fMustAlloc
)
6702 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
6704 #define BASE_TYPE_UNMARSHALL(type) do { \
6705 align_pointer(&pStubMsg->Buffer, sizeof(type)); \
6706 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6708 *ppMemory = pStubMsg->Buffer; \
6709 TRACE("*ppMemory: %p\n", *ppMemory); \
6710 safe_buffer_increment(pStubMsg, sizeof(type)); \
6715 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6716 TRACE("*ppMemory: %p\n", *ppMemory); \
6717 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6727 BASE_TYPE_UNMARSHALL(UCHAR
);
6728 TRACE("value: 0x%02x\n", **ppMemory
);
6733 BASE_TYPE_UNMARSHALL(USHORT
);
6734 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
6738 case FC_ERROR_STATUS_T
:
6740 BASE_TYPE_UNMARSHALL(ULONG
);
6741 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
6744 BASE_TYPE_UNMARSHALL(float);
6745 TRACE("value: %f\n", **(float **)ppMemory
);
6748 BASE_TYPE_UNMARSHALL(double);
6749 TRACE("value: %f\n", **(double **)ppMemory
);
6752 BASE_TYPE_UNMARSHALL(ULONGLONG
);
6753 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG
**)ppMemory
));
6758 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6759 if (!fMustAlloc
&& !*ppMemory
)
6762 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT
));
6763 safe_copy_from_buffer(pStubMsg
, &val
, sizeof(USHORT
));
6764 /* 16-bits on the wire, but int in memory */
6765 **(UINT
**)ppMemory
= val
;
6766 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
6770 if (sizeof(INT_PTR
) == sizeof(INT
)) BASE_TYPE_UNMARSHALL(INT
);
6774 align_pointer(&pStubMsg
->Buffer
, sizeof(INT
));
6775 if (!fMustAlloc
&& !*ppMemory
)
6778 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(INT_PTR
));
6779 safe_copy_from_buffer(pStubMsg
, &val
, sizeof(INT
));
6780 **(INT_PTR
**)ppMemory
= val
;
6781 TRACE("value: 0x%08lx\n", **(INT_PTR
**)ppMemory
);
6785 if (sizeof(UINT_PTR
) == sizeof(UINT
)) BASE_TYPE_UNMARSHALL(UINT
);
6789 align_pointer(&pStubMsg
->Buffer
, sizeof(UINT
));
6790 if (!fMustAlloc
&& !*ppMemory
)
6793 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT_PTR
));
6794 safe_copy_from_buffer(pStubMsg
, &val
, sizeof(UINT
));
6795 **(UINT_PTR
**)ppMemory
= val
;
6796 TRACE("value: 0x%08lx\n", **(UINT_PTR
**)ppMemory
);
6802 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6804 #undef BASE_TYPE_UNMARSHALL
6806 /* FIXME: what is the correct return value? */
6811 /***********************************************************************
6812 * NdrBaseTypeBufferSize [internal]
6814 static void WINAPI
NdrBaseTypeBufferSize(
6815 PMIDL_STUB_MESSAGE pStubMsg
,
6816 unsigned char *pMemory
,
6817 PFORMAT_STRING pFormat
)
6819 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6827 safe_buffer_length_increment(pStubMsg
, sizeof(UCHAR
));
6833 align_length(&pStubMsg
->BufferLength
, sizeof(USHORT
));
6834 safe_buffer_length_increment(pStubMsg
, sizeof(USHORT
));
6841 align_length(&pStubMsg
->BufferLength
, sizeof(ULONG
));
6842 safe_buffer_length_increment(pStubMsg
, sizeof(ULONG
));
6845 align_length(&pStubMsg
->BufferLength
, sizeof(float));
6846 safe_buffer_length_increment(pStubMsg
, sizeof(float));
6849 align_length(&pStubMsg
->BufferLength
, sizeof(double));
6850 safe_buffer_length_increment(pStubMsg
, sizeof(double));
6853 align_length(&pStubMsg
->BufferLength
, sizeof(ULONGLONG
));
6854 safe_buffer_length_increment(pStubMsg
, sizeof(ULONGLONG
));
6856 case FC_ERROR_STATUS_T
:
6857 align_length(&pStubMsg
->BufferLength
, sizeof(error_status_t
));
6858 safe_buffer_length_increment(pStubMsg
, sizeof(error_status_t
));
6863 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6867 /***********************************************************************
6868 * NdrBaseTypeMemorySize [internal]
6870 static ULONG WINAPI
NdrBaseTypeMemorySize(
6871 PMIDL_STUB_MESSAGE pStubMsg
,
6872 PFORMAT_STRING pFormat
)
6874 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg
, *pFormat
);
6882 safe_buffer_increment(pStubMsg
, sizeof(UCHAR
));
6883 pStubMsg
->MemorySize
+= sizeof(UCHAR
);
6884 return sizeof(UCHAR
);
6888 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6889 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6890 align_length(&pStubMsg
->MemorySize
, sizeof(USHORT
));
6891 pStubMsg
->MemorySize
+= sizeof(USHORT
);
6892 return sizeof(USHORT
);
6896 align_pointer(&pStubMsg
->Buffer
, sizeof(ULONG
));
6897 safe_buffer_increment(pStubMsg
, sizeof(ULONG
));
6898 align_length(&pStubMsg
->MemorySize
, sizeof(ULONG
));
6899 pStubMsg
->MemorySize
+= sizeof(ULONG
);
6900 return sizeof(ULONG
);
6902 align_pointer(&pStubMsg
->Buffer
, sizeof(float));
6903 safe_buffer_increment(pStubMsg
, sizeof(float));
6904 align_length(&pStubMsg
->MemorySize
, sizeof(float));
6905 pStubMsg
->MemorySize
+= sizeof(float);
6906 return sizeof(float);
6908 align_pointer(&pStubMsg
->Buffer
, sizeof(double));
6909 safe_buffer_increment(pStubMsg
, sizeof(double));
6910 align_length(&pStubMsg
->MemorySize
, sizeof(double));
6911 pStubMsg
->MemorySize
+= sizeof(double);
6912 return sizeof(double);
6914 align_pointer(&pStubMsg
->Buffer
, sizeof(ULONGLONG
));
6915 safe_buffer_increment(pStubMsg
, sizeof(ULONGLONG
));
6916 align_length(&pStubMsg
->MemorySize
, sizeof(ULONGLONG
));
6917 pStubMsg
->MemorySize
+= sizeof(ULONGLONG
);
6918 return sizeof(ULONGLONG
);
6919 case FC_ERROR_STATUS_T
:
6920 align_pointer(&pStubMsg
->Buffer
, sizeof(error_status_t
));
6921 safe_buffer_increment(pStubMsg
, sizeof(error_status_t
));
6922 align_length(&pStubMsg
->MemorySize
, sizeof(error_status_t
));
6923 pStubMsg
->MemorySize
+= sizeof(error_status_t
);
6924 return sizeof(error_status_t
);
6926 align_pointer(&pStubMsg
->Buffer
, sizeof(USHORT
));
6927 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
6928 align_length(&pStubMsg
->MemorySize
, sizeof(UINT
));
6929 pStubMsg
->MemorySize
+= sizeof(UINT
);
6930 return sizeof(UINT
);
6933 align_pointer(&pStubMsg
->Buffer
, sizeof(UINT
));
6934 safe_buffer_increment(pStubMsg
, sizeof(UINT
));
6935 align_length(&pStubMsg
->MemorySize
, sizeof(UINT_PTR
));
6936 pStubMsg
->MemorySize
+= sizeof(UINT_PTR
);
6937 return sizeof(UINT_PTR
);
6939 align_length(&pStubMsg
->MemorySize
, sizeof(void *));
6940 pStubMsg
->MemorySize
+= sizeof(void *);
6941 return sizeof(void *);
6943 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
6948 /***********************************************************************
6949 * NdrBaseTypeFree [internal]
6951 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg
,
6952 unsigned char *pMemory
,
6953 PFORMAT_STRING pFormat
)
6955 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6960 /***********************************************************************
6961 * NdrContextHandleBufferSize [internal]
6963 static void WINAPI
NdrContextHandleBufferSize(
6964 PMIDL_STUB_MESSAGE pStubMsg
,
6965 unsigned char *pMemory
,
6966 PFORMAT_STRING pFormat
)
6968 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6970 if (*pFormat
!= FC_BIND_CONTEXT
)
6972 ERR("invalid format type %x\n", *pFormat
);
6973 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6975 align_length(&pStubMsg
->BufferLength
, 4);
6976 safe_buffer_length_increment(pStubMsg
, cbNDRContext
);
6979 /***********************************************************************
6980 * NdrContextHandleMarshall [internal]
6982 static unsigned char *WINAPI
NdrContextHandleMarshall(
6983 PMIDL_STUB_MESSAGE pStubMsg
,
6984 unsigned char *pMemory
,
6985 PFORMAT_STRING pFormat
)
6987 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
6989 if (*pFormat
!= FC_BIND_CONTEXT
)
6991 ERR("invalid format type %x\n", *pFormat
);
6992 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
6994 TRACE("flags: 0x%02x\n", pFormat
[1]);
6996 if (pStubMsg
->IsClient
)
6998 if (pFormat
[1] & HANDLE_PARAM_IS_VIA_PTR
)
6999 NdrClientContextMarshall(pStubMsg
, *(NDR_CCONTEXT
**)pMemory
, FALSE
);
7001 NdrClientContextMarshall(pStubMsg
, pMemory
, FALSE
);
7005 NDR_SCONTEXT ctxt
= NDRSContextFromValue(pMemory
);
7006 NDR_RUNDOWN rundown
= pStubMsg
->StubDesc
->apfnNdrRundownRoutines
[pFormat
[2]];
7007 NdrServerContextNewMarshall(pStubMsg
, ctxt
, rundown
, pFormat
);
7013 /***********************************************************************
7014 * NdrContextHandleUnmarshall [internal]
7016 static unsigned char *WINAPI
NdrContextHandleUnmarshall(
7017 PMIDL_STUB_MESSAGE pStubMsg
,
7018 unsigned char **ppMemory
,
7019 PFORMAT_STRING pFormat
,
7020 unsigned char fMustAlloc
)
7022 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg
,
7023 ppMemory
, pFormat
, fMustAlloc
? "TRUE": "FALSE");
7025 if (*pFormat
!= FC_BIND_CONTEXT
)
7027 ERR("invalid format type %x\n", *pFormat
);
7028 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
7030 TRACE("flags: 0x%02x\n", pFormat
[1]);
7032 if (pStubMsg
->IsClient
)
7034 /* [out]-only or [ret] param */
7035 if ((pFormat
[1] & (HANDLE_PARAM_IS_IN
|HANDLE_PARAM_IS_OUT
)) == HANDLE_PARAM_IS_OUT
)
7036 **(NDR_CCONTEXT
**)ppMemory
= NULL
;
7037 NdrClientContextUnmarshall(pStubMsg
, *(NDR_CCONTEXT
**)ppMemory
, pStubMsg
->RpcMsg
->Handle
);
7042 ctxt
= NdrServerContextNewUnmarshall(pStubMsg
, pFormat
);
7043 if (pFormat
[1] & HANDLE_PARAM_IS_VIA_PTR
)
7044 *(void **)ppMemory
= NDRSContextValue(ctxt
);
7046 *(void **)ppMemory
= *NDRSContextValue(ctxt
);
7052 /***********************************************************************
7053 * NdrClientContextMarshall [RPCRT4.@]
7055 void WINAPI
NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7056 NDR_CCONTEXT ContextHandle
,
7059 TRACE("(%p, %p, %d)\n", pStubMsg
, ContextHandle
, fCheck
);
7061 align_pointer_clear(&pStubMsg
->Buffer
, 4);
7063 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7065 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7066 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7067 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7070 /* FIXME: what does fCheck do? */
7071 NDRCContextMarshall(ContextHandle
,
7074 pStubMsg
->Buffer
+= cbNDRContext
;
7077 /***********************************************************************
7078 * NdrClientContextUnmarshall [RPCRT4.@]
7080 void WINAPI
NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7081 NDR_CCONTEXT
* pContextHandle
,
7082 RPC_BINDING_HANDLE BindHandle
)
7084 TRACE("(%p, %p, %p)\n", pStubMsg
, pContextHandle
, BindHandle
);
7086 align_pointer(&pStubMsg
->Buffer
, 4);
7088 if (pStubMsg
->Buffer
+ cbNDRContext
> pStubMsg
->BufferEnd
)
7089 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7091 NDRCContextUnmarshall(pContextHandle
,
7094 pStubMsg
->RpcMsg
->DataRepresentation
);
7096 pStubMsg
->Buffer
+= cbNDRContext
;
7099 void WINAPI
NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7100 NDR_SCONTEXT ContextHandle
,
7101 NDR_RUNDOWN RundownRoutine
)
7103 TRACE("(%p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
);
7105 align_pointer(&pStubMsg
->Buffer
, 4);
7107 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7109 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7110 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7111 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7114 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
7115 pStubMsg
->Buffer
, RundownRoutine
, NULL
,
7116 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
7117 pStubMsg
->Buffer
+= cbNDRContext
;
7120 NDR_SCONTEXT WINAPI
NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
)
7122 NDR_SCONTEXT ContextHandle
;
7124 TRACE("(%p)\n", pStubMsg
);
7126 align_pointer(&pStubMsg
->Buffer
, 4);
7128 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7130 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7131 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7132 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7135 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
7137 pStubMsg
->RpcMsg
->DataRepresentation
,
7138 NULL
, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
);
7139 pStubMsg
->Buffer
+= cbNDRContext
;
7141 return ContextHandle
;
7144 void WINAPI
NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg
,
7145 unsigned char* pMemory
,
7146 PFORMAT_STRING pFormat
)
7148 FIXME("(%p, %p, %p): stub\n", pStubMsg
, pMemory
, pFormat
);
7151 NDR_SCONTEXT WINAPI
NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg
,
7152 PFORMAT_STRING pFormat
)
7154 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
7155 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
7157 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
7159 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
7160 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
7161 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NOSERIALIZE
)
7162 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
7163 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
7165 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
7166 if_id
= &sif
->InterfaceId
;
7169 return NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
, NULL
,
7170 pStubMsg
->RpcMsg
->DataRepresentation
, if_id
,
7174 void WINAPI
NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7175 NDR_SCONTEXT ContextHandle
,
7176 NDR_RUNDOWN RundownRoutine
,
7177 PFORMAT_STRING pFormat
)
7179 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
7180 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
7182 TRACE("(%p, %p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
, pFormat
);
7184 align_pointer(&pStubMsg
->Buffer
, 4);
7186 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7188 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7189 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7190 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7193 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
7194 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
7195 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NOSERIALIZE
)
7196 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
7197 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
7199 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
7200 if_id
= &sif
->InterfaceId
;
7203 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
7204 pStubMsg
->Buffer
, RundownRoutine
, if_id
, flags
);
7205 pStubMsg
->Buffer
+= cbNDRContext
;
7208 NDR_SCONTEXT WINAPI
NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
7209 PFORMAT_STRING pFormat
)
7211 NDR_SCONTEXT ContextHandle
;
7212 RPC_SYNTAX_IDENTIFIER
*if_id
= NULL
;
7213 ULONG flags
= RPC_CONTEXT_HANDLE_DEFAULT_FLAGS
;
7215 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
7217 align_pointer(&pStubMsg
->Buffer
, 4);
7219 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
7221 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
7222 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
7223 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
7226 if (pFormat
[1] & NDR_CONTEXT_HANDLE_SERIALIZE
)
7227 flags
|= RPC_CONTEXT_HANDLE_SERIALIZE
;
7228 if (pFormat
[1] & NDR_CONTEXT_HANDLE_NOSERIALIZE
)
7229 flags
|= RPC_CONTEXT_HANDLE_DONT_SERIALIZE
;
7230 if (pFormat
[1] & NDR_STRICT_CONTEXT_HANDLE
)
7232 RPC_SERVER_INTERFACE
*sif
= pStubMsg
->StubDesc
->RpcInterfaceInformation
;
7233 if_id
= &sif
->InterfaceId
;
7236 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
7238 pStubMsg
->RpcMsg
->DataRepresentation
,
7240 pStubMsg
->Buffer
+= cbNDRContext
;
7242 return ContextHandle
;
7245 /***********************************************************************
7246 * NdrCorrelationInitialize [RPCRT4.@]
7248 * Initializes correlation validity checking.
7251 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7252 * pMemory [I] Pointer to memory to use as a cache.
7253 * CacheSize [I] Size of the memory pointed to by pMemory.
7254 * Flags [I] Reserved. Set to zero.
7259 void WINAPI
NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg
, void *pMemory
, ULONG CacheSize
, ULONG Flags
)
7261 FIXME("(%p, %p, %d, 0x%x): semi-stub\n", pStubMsg
, pMemory
, CacheSize
, Flags
);
7263 if (pStubMsg
->CorrDespIncrement
== 0)
7264 pStubMsg
->CorrDespIncrement
= 2; /* size of the normal (non-range) /robust payload */
7266 pStubMsg
->fHasNewCorrDesc
= TRUE
;
7269 /***********************************************************************
7270 * NdrCorrelationPass [RPCRT4.@]
7272 * Performs correlation validity checking.
7275 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7280 void WINAPI
NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg
)
7282 FIXME("(%p): stub\n", pStubMsg
);
7285 /***********************************************************************
7286 * NdrCorrelationFree [RPCRT4.@]
7288 * Frees any resources used while unmarshalling parameters that need
7289 * correlation validity checking.
7292 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
7297 void WINAPI
NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg
)
7299 FIXME("(%p): stub\n", pStubMsg
);