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
22 * - Non-conformant strings
24 * - Byte count pointers
25 * - transmit_as/represent as
26 * - Multi-dimensional arrays
27 * - Conversion functions (NdrConvert)
28 * - Checks for integer addition overflow in base type and user marshall functions
44 #include "wine/unicode.h"
45 #include "wine/rpcfc.h"
47 #include "wine/debug.h"
49 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
52 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
53 (*((UINT32 *)(pchar)) = (uint32))
55 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
56 (*((UINT32 *)(pchar)))
58 /* these would work for i386 too, but less efficient */
59 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
60 (*(pchar) = LOBYTE(LOWORD(uint32)), \
61 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
62 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
63 *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
64 (uint32)) /* allow as r-value */
66 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
68 MAKEWORD(*(pchar), *((pchar)+1)), \
69 MAKEWORD(*((pchar)+2), *((pchar)+3))))
72 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
73 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
74 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
75 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
76 *(pchar) = HIBYTE(HIWORD(uint32)), \
77 (uint32)) /* allow as r-value */
79 #define BIG_ENDIAN_UINT32_READ(pchar) \
81 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
82 MAKEWORD(*((pchar)+1), *(pchar))))
84 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
85 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
86 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
87 # define NDR_LOCAL_UINT32_READ(pchar) \
88 BIG_ENDIAN_UINT32_READ(pchar)
90 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
91 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
92 # define NDR_LOCAL_UINT32_READ(pchar) \
93 LITTLE_ENDIAN_UINT32_READ(pchar)
96 /* _Align must be the desired alignment,
97 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
98 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
99 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
100 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
101 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
102 #define ALIGN_POINTER_CLEAR(_Ptr, _Align) \
104 memset((_Ptr), 0, ((_Align) - (ULONG_PTR)(_Ptr)) & ((_Align) - 1)); \
105 ALIGN_POINTER(_Ptr, _Align); \
108 #define STD_OVERFLOW_CHECK(_Msg) do { \
109 TRACE("buffer=%d/%d\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
110 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
111 ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
114 #define NDR_TABLE_SIZE 128
115 #define NDR_TABLE_MASK 127
117 static unsigned char *WINAPI
NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
118 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
119 static void WINAPI
NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
120 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
121 static ULONG WINAPI
NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
123 static unsigned char *WINAPI
NdrContextHandleMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
124 static void WINAPI
NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
125 static unsigned char *WINAPI
NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
127 const NDR_MARSHALL NdrMarshaller
[NDR_TABLE_SIZE
] = {
129 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
130 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
131 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
132 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
136 NdrPointerMarshall
, NdrPointerMarshall
,
137 NdrPointerMarshall
, NdrPointerMarshall
,
139 NdrSimpleStructMarshall
, NdrSimpleStructMarshall
,
140 NdrConformantStructMarshall
, NdrConformantStructMarshall
,
141 NdrConformantVaryingStructMarshall
,
142 NdrComplexStructMarshall
,
144 NdrConformantArrayMarshall
,
145 NdrConformantVaryingArrayMarshall
,
146 NdrFixedArrayMarshall
, NdrFixedArrayMarshall
,
147 NdrVaryingArrayMarshall
, NdrVaryingArrayMarshall
,
148 NdrComplexArrayMarshall
,
150 NdrConformantStringMarshall
, 0, 0,
151 NdrConformantStringMarshall
,
152 NdrNonConformantStringMarshall
, 0, 0, 0,
154 NdrEncapsulatedUnionMarshall
,
155 NdrNonEncapsulatedUnionMarshall
,
156 NdrByteCountPointerMarshall
,
157 NdrXmitOrRepAsMarshall
, NdrXmitOrRepAsMarshall
,
159 NdrInterfacePointerMarshall
,
161 NdrContextHandleMarshall
,
164 NdrUserMarshalMarshall
,
169 const NDR_UNMARSHALL NdrUnmarshaller
[NDR_TABLE_SIZE
] = {
171 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
172 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
173 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
174 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
176 NdrBaseTypeUnmarshall
,
178 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
179 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
181 NdrSimpleStructUnmarshall
, NdrSimpleStructUnmarshall
,
182 NdrConformantStructUnmarshall
, NdrConformantStructUnmarshall
,
183 NdrConformantVaryingStructUnmarshall
,
184 NdrComplexStructUnmarshall
,
186 NdrConformantArrayUnmarshall
,
187 NdrConformantVaryingArrayUnmarshall
,
188 NdrFixedArrayUnmarshall
, NdrFixedArrayUnmarshall
,
189 NdrVaryingArrayUnmarshall
, NdrVaryingArrayUnmarshall
,
190 NdrComplexArrayUnmarshall
,
192 NdrConformantStringUnmarshall
, 0, 0,
193 NdrConformantStringUnmarshall
,
194 NdrNonConformantStringUnmarshall
, 0, 0, 0,
196 NdrEncapsulatedUnionUnmarshall
,
197 NdrNonEncapsulatedUnionUnmarshall
,
198 NdrByteCountPointerUnmarshall
,
199 NdrXmitOrRepAsUnmarshall
, NdrXmitOrRepAsUnmarshall
,
201 NdrInterfacePointerUnmarshall
,
203 NdrContextHandleUnmarshall
,
206 NdrUserMarshalUnmarshall
,
211 const NDR_BUFFERSIZE NdrBufferSizer
[NDR_TABLE_SIZE
] = {
213 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
214 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
215 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
216 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
218 NdrBaseTypeBufferSize
,
220 NdrPointerBufferSize
, NdrPointerBufferSize
,
221 NdrPointerBufferSize
, NdrPointerBufferSize
,
223 NdrSimpleStructBufferSize
, NdrSimpleStructBufferSize
,
224 NdrConformantStructBufferSize
, NdrConformantStructBufferSize
,
225 NdrConformantVaryingStructBufferSize
,
226 NdrComplexStructBufferSize
,
228 NdrConformantArrayBufferSize
,
229 NdrConformantVaryingArrayBufferSize
,
230 NdrFixedArrayBufferSize
, NdrFixedArrayBufferSize
,
231 NdrVaryingArrayBufferSize
, NdrVaryingArrayBufferSize
,
232 NdrComplexArrayBufferSize
,
234 NdrConformantStringBufferSize
, 0, 0,
235 NdrConformantStringBufferSize
,
236 NdrNonConformantStringBufferSize
, 0, 0, 0,
238 NdrEncapsulatedUnionBufferSize
,
239 NdrNonEncapsulatedUnionBufferSize
,
240 NdrByteCountPointerBufferSize
,
241 NdrXmitOrRepAsBufferSize
, NdrXmitOrRepAsBufferSize
,
243 NdrInterfacePointerBufferSize
,
245 NdrContextHandleBufferSize
,
248 NdrUserMarshalBufferSize
,
253 const NDR_MEMORYSIZE NdrMemorySizer
[NDR_TABLE_SIZE
] = {
255 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
256 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
257 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
258 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
260 NdrBaseTypeMemorySize
,
262 NdrPointerMemorySize
, NdrPointerMemorySize
,
263 NdrPointerMemorySize
, NdrPointerMemorySize
,
265 NdrSimpleStructMemorySize
, NdrSimpleStructMemorySize
,
266 NdrConformantStructMemorySize
, NdrConformantStructMemorySize
,
267 NdrConformantVaryingStructMemorySize
,
268 NdrComplexStructMemorySize
,
270 NdrConformantArrayMemorySize
,
271 NdrConformantVaryingArrayMemorySize
,
272 NdrFixedArrayMemorySize
, NdrFixedArrayMemorySize
,
273 NdrVaryingArrayMemorySize
, NdrVaryingArrayMemorySize
,
274 NdrComplexArrayMemorySize
,
276 NdrConformantStringMemorySize
, 0, 0,
277 NdrConformantStringMemorySize
,
278 NdrNonConformantStringMemorySize
, 0, 0, 0,
280 NdrEncapsulatedUnionMemorySize
,
281 NdrNonEncapsulatedUnionMemorySize
,
282 NdrByteCountPointerMemorySize
,
283 NdrXmitOrRepAsMemorySize
, NdrXmitOrRepAsMemorySize
,
285 NdrInterfacePointerMemorySize
,
290 NdrUserMarshalMemorySize
,
295 const NDR_FREE NdrFreer
[NDR_TABLE_SIZE
] = {
297 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
298 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
299 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
300 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
304 NdrPointerFree
, NdrPointerFree
,
305 NdrPointerFree
, NdrPointerFree
,
307 NdrSimpleStructFree
, NdrSimpleStructFree
,
308 NdrConformantStructFree
, NdrConformantStructFree
,
309 NdrConformantVaryingStructFree
,
310 NdrComplexStructFree
,
312 NdrConformantArrayFree
,
313 NdrConformantVaryingArrayFree
,
314 NdrFixedArrayFree
, NdrFixedArrayFree
,
315 NdrVaryingArrayFree
, NdrVaryingArrayFree
,
321 NdrEncapsulatedUnionFree
,
322 NdrNonEncapsulatedUnionFree
,
324 NdrXmitOrRepAsFree
, NdrXmitOrRepAsFree
,
326 NdrInterfacePointerFree
,
337 typedef struct _NDR_MEMORY_LIST
342 struct _NDR_MEMORY_LIST
*next
;
345 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
347 /***********************************************************************
348 * NdrAllocate [RPCRT4.@]
350 * Allocates a block of memory using pStubMsg->pfnAllocate.
353 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
354 * len [I] Size of memory block to allocate.
357 * The memory block of size len that was allocated.
360 * The memory block is always 8-byte aligned.
361 * If the function is unable to allocate memory an ERROR_OUTOFMEMORY
362 * exception is raised.
364 void * WINAPI
NdrAllocate(MIDL_STUB_MESSAGE
*pStubMsg
, size_t len
)
369 NDR_MEMORY_LIST
*mem_list
;
371 aligned_len
= ALIGNED_LENGTH(len
, 8);
372 adjusted_len
= aligned_len
+ sizeof(NDR_MEMORY_LIST
);
373 /* check for overflow */
374 if (adjusted_len
< len
)
376 ERR("overflow of adjusted_len %d, len %d\n", adjusted_len
, len
);
377 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
380 p
= pStubMsg
->pfnAllocate(adjusted_len
);
381 if (!p
) RpcRaiseException(ERROR_OUTOFMEMORY
);
383 mem_list
= (NDR_MEMORY_LIST
*)((char *)p
+ aligned_len
);
384 mem_list
->magic
= MEML_MAGIC
;
385 mem_list
->size
= aligned_len
;
386 mem_list
->reserved
= 0;
387 mem_list
->next
= pStubMsg
->pMemoryList
;
388 pStubMsg
->pMemoryList
= mem_list
;
394 static void WINAPI
NdrFree(MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *Pointer
)
396 TRACE("(%p, %p)\n", pStubMsg
, Pointer
);
398 pStubMsg
->pfnFree(Pointer
);
401 static inline BOOL
IsConformanceOrVariancePresent(PFORMAT_STRING pFormat
)
403 return (*(const ULONG
*)pFormat
!= -1);
406 static PFORMAT_STRING
ReadConformance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
)
408 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
409 if (pStubMsg
->Buffer
+ 4 > pStubMsg
->BufferEnd
)
410 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
411 pStubMsg
->MaxCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
412 pStubMsg
->Buffer
+= 4;
413 TRACE("unmarshalled conformance is %ld\n", pStubMsg
->MaxCount
);
414 if (pStubMsg
->fHasNewCorrDesc
)
420 static inline PFORMAT_STRING
ReadVariance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
, ULONG MaxValue
)
422 if (pFormat
&& !IsConformanceOrVariancePresent(pFormat
))
424 pStubMsg
->Offset
= 0;
425 pStubMsg
->ActualCount
= pStubMsg
->MaxCount
;
429 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
430 if (pStubMsg
->Buffer
+ 8 > pStubMsg
->BufferEnd
)
431 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
432 pStubMsg
->Offset
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
433 pStubMsg
->Buffer
+= 4;
434 TRACE("offset is %d\n", pStubMsg
->Offset
);
435 pStubMsg
->ActualCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
436 pStubMsg
->Buffer
+= 4;
437 TRACE("variance is %d\n", pStubMsg
->ActualCount
);
439 if ((pStubMsg
->ActualCount
> MaxValue
) ||
440 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> MaxValue
))
442 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
443 pStubMsg
->ActualCount
, pStubMsg
->Offset
, MaxValue
);
444 RpcRaiseException(RPC_S_INVALID_BOUND
);
449 if (pStubMsg
->fHasNewCorrDesc
)
455 /* writes the conformance value to the buffer */
456 static inline void WriteConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
458 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
459 if (pStubMsg
->Buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
460 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
461 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->MaxCount
);
462 pStubMsg
->Buffer
+= 4;
465 /* writes the variance values to the buffer */
466 static inline void WriteVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
468 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
469 if (pStubMsg
->Buffer
+ 8 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
470 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
471 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->Offset
);
472 pStubMsg
->Buffer
+= 4;
473 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->ActualCount
);
474 pStubMsg
->Buffer
+= 4;
477 /* requests buffer space for the conformance value */
478 static inline void SizeConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
480 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
481 if (pStubMsg
->BufferLength
+ 4 < pStubMsg
->BufferLength
)
482 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
483 pStubMsg
->BufferLength
+= 4;
486 /* requests buffer space for the variance values */
487 static inline void SizeVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
489 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
490 if (pStubMsg
->BufferLength
+ 8 < pStubMsg
->BufferLength
)
491 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
492 pStubMsg
->BufferLength
+= 8;
495 PFORMAT_STRING
ComputeConformanceOrVariance(
496 MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *pMemory
,
497 PFORMAT_STRING pFormat
, ULONG_PTR def
, ULONG_PTR
*pCount
)
499 BYTE dtype
= pFormat
[0] & 0xf;
500 short ofs
= *(const short *)&pFormat
[2];
504 if (!IsConformanceOrVariancePresent(pFormat
)) {
505 /* null descriptor */
510 switch (pFormat
[0] & 0xf0) {
511 case RPC_FC_NORMAL_CONFORMANCE
:
512 TRACE("normal conformance, ofs=%d\n", ofs
);
515 case RPC_FC_POINTER_CONFORMANCE
:
516 TRACE("pointer conformance, ofs=%d\n", ofs
);
517 ptr
= pStubMsg
->Memory
;
519 case RPC_FC_TOP_LEVEL_CONFORMANCE
:
520 TRACE("toplevel conformance, ofs=%d\n", ofs
);
521 if (pStubMsg
->StackTop
) {
522 ptr
= pStubMsg
->StackTop
;
525 /* -Os mode, *pCount is already set */
529 case RPC_FC_CONSTANT_CONFORMANCE
:
530 data
= ofs
| ((DWORD
)pFormat
[1] << 16);
531 TRACE("constant conformance, val=%d\n", data
);
534 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE
:
535 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs
);
536 if (pStubMsg
->StackTop
) {
537 ptr
= pStubMsg
->StackTop
;
545 FIXME("unknown conformance type %x\n", pFormat
[0] & 0xf0);
548 switch (pFormat
[1]) {
549 case RPC_FC_DEREFERENCE
:
550 ptr
= *(LPVOID
*)((char *)ptr
+ ofs
);
552 case RPC_FC_CALLBACK
:
554 unsigned char *old_stack_top
= pStubMsg
->StackTop
;
555 pStubMsg
->StackTop
= ptr
;
557 /* ofs is index into StubDesc->apfnExprEval */
558 TRACE("callback conformance into apfnExprEval[%d]\n", ofs
);
559 pStubMsg
->StubDesc
->apfnExprEval
[ofs
](pStubMsg
);
561 pStubMsg
->StackTop
= old_stack_top
;
563 /* the callback function always stores the computed value in MaxCount */
564 *pCount
= pStubMsg
->MaxCount
;
568 ptr
= (char *)ptr
+ ofs
;
581 data
= *(USHORT
*)ptr
;
592 FIXME("unknown conformance data type %x\n", dtype
);
595 TRACE("dereferenced data type %x at %p, got %d\n", dtype
, ptr
, data
);
598 switch (pFormat
[1]) {
599 case RPC_FC_DEREFERENCE
: /* already handled */
616 FIXME("unknown conformance op %d\n", pFormat
[1]);
621 TRACE("resulting conformance is %ld\n", *pCount
);
622 if (pStubMsg
->fHasNewCorrDesc
)
628 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
629 * the result overflows 32-bits */
630 static inline ULONG
safe_multiply(ULONG a
, ULONG b
)
632 ULONGLONG ret
= (ULONGLONG
)a
* b
;
633 if (ret
> 0xffffffff)
635 RpcRaiseException(RPC_S_INVALID_BOUND
);
641 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
643 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
644 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
645 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
646 pStubMsg
->Buffer
+= size
;
649 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
651 if (pStubMsg
->BufferLength
+ size
< pStubMsg
->BufferLength
) /* integer overflow of pStubMsg->BufferSize */
653 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
654 pStubMsg
->BufferLength
, size
);
655 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
657 pStubMsg
->BufferLength
+= size
;
660 /* copies data from the buffer, checking that there is enough data in the buffer
662 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, void *p
, ULONG size
)
664 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
665 (pStubMsg
->Buffer
+ size
> pStubMsg
->BufferEnd
))
667 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
668 pStubMsg
->Buffer
, pStubMsg
->BufferEnd
, size
);
669 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
671 if (p
== pStubMsg
->Buffer
)
672 ERR("pointer is the same as the buffer\n");
673 memcpy(p
, pStubMsg
->Buffer
, size
);
674 pStubMsg
->Buffer
+= size
;
677 /* copies data to the buffer, checking that there is enough space to do so */
678 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, const void *p
, ULONG size
)
680 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
681 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
683 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
684 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
,
686 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
688 memcpy(pStubMsg
->Buffer
, p
, size
);
689 pStubMsg
->Buffer
+= size
;
693 * NdrConformantString:
695 * What MS calls a ConformantString is, in DCE terminology,
696 * a Varying-Conformant String.
698 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
699 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
700 * into unmarshalled string)
701 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
703 * data: CHARTYPE[maxlen]
705 * ], where CHARTYPE is the appropriate character type (specified externally)
709 /***********************************************************************
710 * NdrConformantStringMarshall [RPCRT4.@]
712 unsigned char *WINAPI
NdrConformantStringMarshall(MIDL_STUB_MESSAGE
*pStubMsg
,
713 unsigned char *pszMessage
, PFORMAT_STRING pFormat
)
717 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg
, pszMessage
, pFormat
);
719 if (*pFormat
== RPC_FC_C_CSTRING
) {
720 TRACE("string=%s\n", debugstr_a((char*)pszMessage
));
721 pStubMsg
->ActualCount
= strlen((char*)pszMessage
)+1;
724 else if (*pFormat
== RPC_FC_C_WSTRING
) {
725 TRACE("string=%s\n", debugstr_w((LPWSTR
)pszMessage
));
726 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pszMessage
)+1;
730 ERR("Unhandled string type: %#x\n", *pFormat
);
731 /* FIXME: raise an exception. */
735 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
736 pFormat
= ComputeConformance(pStubMsg
, pszMessage
, pFormat
+ 2, 0);
738 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
739 pStubMsg
->Offset
= 0;
740 WriteConformance(pStubMsg
);
741 WriteVariance(pStubMsg
);
743 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
744 safe_copy_to_buffer(pStubMsg
, pszMessage
, size
); /* the string itself */
747 return NULL
; /* is this always right? */
750 /***********************************************************************
751 * NdrConformantStringBufferSize [RPCRT4.@]
753 void WINAPI
NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
754 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
758 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
760 SizeConformance(pStubMsg
);
761 SizeVariance(pStubMsg
);
763 if (*pFormat
== RPC_FC_C_CSTRING
) {
764 TRACE("string=%s\n", debugstr_a((char*)pMemory
));
765 pStubMsg
->ActualCount
= strlen((char*)pMemory
)+1;
768 else if (*pFormat
== RPC_FC_C_WSTRING
) {
769 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
));
770 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
)+1;
774 ERR("Unhandled string type: %#x\n", *pFormat
);
775 /* FIXME: raise an exception */
779 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
780 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
782 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
784 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
787 /************************************************************************
788 * NdrConformantStringMemorySize [RPCRT4.@]
790 ULONG WINAPI
NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
791 PFORMAT_STRING pFormat
)
795 FIXME("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
797 assert(pStubMsg
&& pFormat
);
799 if (*pFormat
== RPC_FC_C_CSTRING
) {
800 rslt
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
); /* maxlen */
802 else if (*pFormat
== RPC_FC_C_WSTRING
) {
803 rslt
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
)*2; /* maxlen */
806 ERR("Unhandled string type: %#x\n", *pFormat
);
807 /* FIXME: raise an exception */
810 if (pFormat
[1] != RPC_FC_PAD
) {
811 FIXME("sized string format=%d\n", pFormat
[1]);
814 TRACE(" --> %u\n", rslt
);
818 /************************************************************************
819 * NdrConformantStringUnmarshall [RPCRT4.@]
821 unsigned char *WINAPI
NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
822 unsigned char** ppMemory
, PFORMAT_STRING pFormat
, unsigned char fMustAlloc
)
824 ULONG bufsize
, memsize
, esize
, i
;
826 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
827 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
829 assert(pFormat
&& ppMemory
&& pStubMsg
);
831 ReadConformance(pStubMsg
, NULL
);
832 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
834 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
836 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
837 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
838 RpcRaiseException(RPC_S_INVALID_BOUND
);
841 if (pStubMsg
->Offset
)
843 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
844 RpcRaiseException(RPC_S_INVALID_BOUND
);
848 if (*pFormat
== RPC_FC_C_CSTRING
) esize
= 1;
849 else if (*pFormat
== RPC_FC_C_WSTRING
) esize
= 2;
851 ERR("Unhandled string type: %#x\n", *pFormat
);
852 /* FIXME: raise an exception */
856 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
857 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
859 /* strings must always have null terminating bytes */
862 ERR("invalid string length of %d\n", pStubMsg
->ActualCount
);
863 RpcRaiseException(RPC_S_INVALID_BOUND
);
867 /* verify the buffer is safe to access */
868 if ((pStubMsg
->Buffer
+ bufsize
< pStubMsg
->Buffer
) ||
869 (pStubMsg
->Buffer
+ bufsize
> pStubMsg
->BufferEnd
))
871 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize
,
872 pStubMsg
->BufferEnd
, pStubMsg
->Buffer
);
873 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
877 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
878 if (pStubMsg
->Buffer
[i
] != 0)
880 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
881 i
, pStubMsg
->Buffer
[i
]);
882 RpcRaiseException(RPC_S_INVALID_BOUND
);
887 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
890 if (!pStubMsg
->IsClient
&& !*ppMemory
&& (pStubMsg
->MaxCount
== pStubMsg
->ActualCount
))
891 /* if the data in the RPC buffer is big enough, we just point straight
893 *ppMemory
= pStubMsg
->Buffer
;
895 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
898 if (*ppMemory
== pStubMsg
->Buffer
)
899 safe_buffer_increment(pStubMsg
, bufsize
);
901 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
903 if (*pFormat
== RPC_FC_C_CSTRING
) {
904 TRACE("string=%s\n", debugstr_a((char*)*ppMemory
));
906 else if (*pFormat
== RPC_FC_C_WSTRING
) {
907 TRACE("string=%s\n", debugstr_w((LPWSTR
)*ppMemory
));
910 return NULL
; /* FIXME: is this always right? */
913 /***********************************************************************
914 * NdrNonConformantStringMarshall [RPCRT4.@]
916 unsigned char * WINAPI
NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
917 unsigned char *pMemory
,
918 PFORMAT_STRING pFormat
)
924 /***********************************************************************
925 * NdrNonConformantStringUnmarshall [RPCRT4.@]
927 unsigned char * WINAPI
NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
928 unsigned char **ppMemory
,
929 PFORMAT_STRING pFormat
,
930 unsigned char fMustAlloc
)
936 /***********************************************************************
937 * NdrNonConformantStringBufferSize [RPCRT4.@]
939 void WINAPI
NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
940 unsigned char *pMemory
,
941 PFORMAT_STRING pFormat
)
946 /***********************************************************************
947 * NdrNonConformantStringMemorySize [RPCRT4.@]
949 ULONG WINAPI
NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
950 PFORMAT_STRING pFormat
)
956 static inline void dump_pointer_attr(unsigned char attr
)
958 if (attr
& RPC_FC_P_ALLOCALLNODES
)
959 TRACE(" RPC_FC_P_ALLOCALLNODES");
960 if (attr
& RPC_FC_P_DONTFREE
)
961 TRACE(" RPC_FC_P_DONTFREE");
962 if (attr
& RPC_FC_P_ONSTACK
)
963 TRACE(" RPC_FC_P_ONSTACK");
964 if (attr
& RPC_FC_P_SIMPLEPOINTER
)
965 TRACE(" RPC_FC_P_SIMPLEPOINTER");
966 if (attr
& RPC_FC_P_DEREF
)
967 TRACE(" RPC_FC_P_DEREF");
971 /***********************************************************************
972 * PointerMarshall [internal]
974 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
975 unsigned char *Buffer
,
976 unsigned char *Pointer
,
977 PFORMAT_STRING pFormat
)
979 unsigned type
= pFormat
[0], attr
= pFormat
[1];
983 int pointer_needs_marshaling
;
985 TRACE("(%p,%p,%p,%p)\n", pStubMsg
, Buffer
, Pointer
, pFormat
);
986 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
988 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
989 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
992 case RPC_FC_RP
: /* ref pointer (always non-null) */
995 ERR("NULL ref pointer is not allowed\n");
996 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
998 pointer_needs_marshaling
= 1;
1000 case RPC_FC_UP
: /* unique pointer */
1001 case RPC_FC_OP
: /* object pointer - same as unique here */
1003 pointer_needs_marshaling
= 1;
1005 pointer_needs_marshaling
= 0;
1006 pointer_id
= (ULONG
)Pointer
;
1007 TRACE("writing 0x%08x to buffer\n", pointer_id
);
1008 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
1011 pointer_needs_marshaling
= !NdrFullPointerQueryPointer(
1012 pStubMsg
->FullPtrXlatTables
, Pointer
, 1, &pointer_id
);
1013 TRACE("writing 0x%08x to buffer\n", pointer_id
);
1014 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
1017 FIXME("unhandled ptr type=%02x\n", type
);
1018 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1022 TRACE("calling marshaller for type 0x%x\n", (int)*desc
);
1024 if (pointer_needs_marshaling
) {
1025 if (attr
& RPC_FC_P_DEREF
) {
1026 Pointer
= *(unsigned char**)Pointer
;
1027 TRACE("deref => %p\n", Pointer
);
1029 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
1030 if (m
) m(pStubMsg
, Pointer
, desc
);
1031 else FIXME("no marshaller for data type=%02x\n", *desc
);
1034 STD_OVERFLOW_CHECK(pStubMsg
);
1037 /***********************************************************************
1038 * PointerUnmarshall [internal]
1040 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1041 unsigned char *Buffer
,
1042 unsigned char **pPointer
,
1043 unsigned char *pSrcPointer
,
1044 PFORMAT_STRING pFormat
,
1045 unsigned char fMustAlloc
)
1047 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1048 PFORMAT_STRING desc
;
1050 DWORD pointer_id
= 0;
1051 int pointer_needs_unmarshaling
;
1053 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg
, Buffer
, pPointer
, pSrcPointer
, pFormat
, fMustAlloc
);
1054 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1056 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1057 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1060 case RPC_FC_RP
: /* ref pointer (always non-null) */
1061 pointer_needs_unmarshaling
= 1;
1063 case RPC_FC_UP
: /* unique pointer */
1064 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1065 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1067 pointer_needs_unmarshaling
= 1;
1070 pointer_needs_unmarshaling
= 0;
1073 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
1074 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1075 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1076 if (!fMustAlloc
&& pSrcPointer
)
1078 FIXME("free object pointer %p\n", pSrcPointer
);
1082 pointer_needs_unmarshaling
= 1;
1084 pointer_needs_unmarshaling
= 0;
1087 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1088 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1089 pointer_needs_unmarshaling
= !NdrFullPointerQueryRefId(
1090 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, (void **)pPointer
);
1093 FIXME("unhandled ptr type=%02x\n", type
);
1094 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1098 if (pointer_needs_unmarshaling
) {
1099 unsigned char *base_ptr_val
= *pPointer
;
1100 unsigned char **current_ptr
= pPointer
;
1101 if (pStubMsg
->IsClient
) {
1103 /* if we aren't forcing allocation of memory then try to use the existing
1104 * (source) pointer to unmarshall the data into so that [in,out]
1105 * parameters behave correctly. it doesn't matter if the parameter is
1106 * [out] only since in that case the pointer will be NULL. we force
1107 * allocation when the source pointer is NULL here instead of in the type
1108 * unmarshalling routine for the benefit of the deref code below */
1111 TRACE("setting *pPointer to %p\n", pSrcPointer
);
1112 *pPointer
= base_ptr_val
= pSrcPointer
;
1118 /* the memory in a stub is never initialised, so we have to work out here
1119 * whether we have to initialise it so we can use the optimisation of
1120 * setting the pointer to the buffer, if possible, or set fMustAlloc to
1122 if (attr
& RPC_FC_P_DEREF
) {
1125 base_ptr_val
= NULL
;
1126 *current_ptr
= NULL
;
1130 if (attr
& RPC_FC_P_ALLOCALLNODES
)
1131 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
1133 if (attr
& RPC_FC_P_DEREF
) {
1135 base_ptr_val
= NdrAllocate(pStubMsg
, sizeof(void *));
1136 *pPointer
= base_ptr_val
;
1137 current_ptr
= (unsigned char **)base_ptr_val
;
1139 current_ptr
= *(unsigned char***)current_ptr
;
1140 TRACE("deref => %p\n", current_ptr
);
1141 if (!fMustAlloc
&& !*current_ptr
) fMustAlloc
= TRUE
;
1143 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
1144 if (m
) m(pStubMsg
, current_ptr
, desc
, fMustAlloc
);
1145 else FIXME("no unmarshaller for data type=%02x\n", *desc
);
1147 if (type
== RPC_FC_FP
)
1148 NdrFullPointerInsertRefId(pStubMsg
->FullPtrXlatTables
, pointer_id
,
1152 TRACE("pointer=%p\n", *pPointer
);
1155 /***********************************************************************
1156 * PointerBufferSize [internal]
1158 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1159 unsigned char *Pointer
,
1160 PFORMAT_STRING pFormat
)
1162 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1163 PFORMAT_STRING desc
;
1165 int pointer_needs_sizing
;
1168 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1169 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1171 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1172 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1175 case RPC_FC_RP
: /* ref pointer (always non-null) */
1178 ERR("NULL ref pointer is not allowed\n");
1179 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
1184 /* NULL pointer has no further representation */
1189 pointer_needs_sizing
= !NdrFullPointerQueryPointer(
1190 pStubMsg
->FullPtrXlatTables
, Pointer
, 0, &pointer_id
);
1191 if (!pointer_needs_sizing
)
1195 FIXME("unhandled ptr type=%02x\n", type
);
1196 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1200 if (attr
& RPC_FC_P_DEREF
) {
1201 Pointer
= *(unsigned char**)Pointer
;
1202 TRACE("deref => %p\n", Pointer
);
1205 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
1206 if (m
) m(pStubMsg
, Pointer
, desc
);
1207 else FIXME("no buffersizer for data type=%02x\n", *desc
);
1210 /***********************************************************************
1211 * PointerMemorySize [internal]
1213 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1214 unsigned char *Buffer
,
1215 PFORMAT_STRING pFormat
)
1217 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1218 PFORMAT_STRING desc
;
1220 DWORD pointer_id
= 0;
1221 int pointer_needs_sizing
;
1223 TRACE("(%p,%p,%p)\n", pStubMsg
, Buffer
, pFormat
);
1224 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1226 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1227 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1230 case RPC_FC_RP
: /* ref pointer (always non-null) */
1231 pointer_needs_sizing
= 1;
1233 case RPC_FC_UP
: /* unique pointer */
1234 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
1235 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1236 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1238 pointer_needs_sizing
= 1;
1240 pointer_needs_sizing
= 0;
1245 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1246 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1247 pointer_needs_sizing
= !NdrFullPointerQueryRefId(
1248 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, &pointer
);
1252 FIXME("unhandled ptr type=%02x\n", type
);
1253 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1257 if (attr
& RPC_FC_P_DEREF
) {
1261 if (pointer_needs_sizing
) {
1262 m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
1263 if (m
) m(pStubMsg
, desc
);
1264 else FIXME("no memorysizer for data type=%02x\n", *desc
);
1267 return pStubMsg
->MemorySize
;
1270 /***********************************************************************
1271 * PointerFree [internal]
1273 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1274 unsigned char *Pointer
,
1275 PFORMAT_STRING pFormat
)
1277 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1278 PFORMAT_STRING desc
;
1280 unsigned char *current_pointer
= Pointer
;
1282 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1283 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1284 if (attr
& RPC_FC_P_DONTFREE
) return;
1286 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1287 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1289 if (!Pointer
) return;
1291 if (type
== RPC_FC_FP
) {
1292 int pointer_needs_freeing
= NdrFullPointerFree(
1293 pStubMsg
->FullPtrXlatTables
, Pointer
);
1294 if (!pointer_needs_freeing
)
1298 if (attr
& RPC_FC_P_DEREF
) {
1299 current_pointer
= *(unsigned char**)Pointer
;
1300 TRACE("deref => %p\n", current_pointer
);
1303 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
1304 if (m
) m(pStubMsg
, current_pointer
, desc
);
1306 /* this check stops us from trying to free buffer memory. we don't have to
1307 * worry about clients, since they won't call this function.
1308 * we don't have to check for the buffer being reallocated because
1309 * BufferStart and BufferEnd won't be reset when allocating memory for
1310 * sending the response. we don't have to check for the new buffer here as
1311 * it won't be used a type memory, only for buffer memory */
1312 if (Pointer
>= (unsigned char *)pStubMsg
->BufferStart
&&
1313 Pointer
< (unsigned char *)pStubMsg
->BufferEnd
)
1316 if (attr
& RPC_FC_P_ONSTACK
) {
1317 TRACE("not freeing stack ptr %p\n", Pointer
);
1320 TRACE("freeing %p\n", Pointer
);
1321 NdrFree(pStubMsg
, Pointer
);
1324 TRACE("not freeing %p\n", Pointer
);
1327 /***********************************************************************
1328 * EmbeddedPointerMarshall
1330 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1331 unsigned char *pMemory
,
1332 PFORMAT_STRING pFormat
)
1334 unsigned char *Mark
= pStubMsg
->BufferMark
;
1335 unsigned rep
, count
, stride
;
1337 unsigned char *saved_buffer
= NULL
;
1339 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1341 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1344 if (pStubMsg
->PointerBufferMark
)
1346 saved_buffer
= pStubMsg
->Buffer
;
1347 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1348 pStubMsg
->PointerBufferMark
= NULL
;
1351 while (pFormat
[0] != RPC_FC_END
) {
1352 switch (pFormat
[0]) {
1354 FIXME("unknown repeat type %d\n", pFormat
[0]);
1355 case RPC_FC_NO_REPEAT
:
1361 case RPC_FC_FIXED_REPEAT
:
1362 rep
= *(const WORD
*)&pFormat
[2];
1363 stride
= *(const WORD
*)&pFormat
[4];
1364 count
= *(const WORD
*)&pFormat
[8];
1367 case RPC_FC_VARIABLE_REPEAT
:
1368 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1369 stride
= *(const WORD
*)&pFormat
[2];
1370 count
= *(const WORD
*)&pFormat
[6];
1374 for (i
= 0; i
< rep
; i
++) {
1375 PFORMAT_STRING info
= pFormat
;
1376 unsigned char *membase
= pMemory
+ (i
* stride
);
1377 unsigned char *bufbase
= Mark
+ (i
* stride
);
1380 for (u
=0; u
<count
; u
++,info
+=8) {
1381 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1382 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1383 unsigned char *saved_memory
= pStubMsg
->Memory
;
1385 pStubMsg
->Memory
= pMemory
;
1386 PointerMarshall(pStubMsg
, bufptr
, *(unsigned char**)memptr
, info
+4);
1387 pStubMsg
->Memory
= saved_memory
;
1390 pFormat
+= 8 * count
;
1395 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1396 pStubMsg
->Buffer
= saved_buffer
;
1399 STD_OVERFLOW_CHECK(pStubMsg
);
1404 /***********************************************************************
1405 * EmbeddedPointerUnmarshall
1407 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1408 unsigned char *pDstMemoryPtrs
,
1409 unsigned char *pSrcMemoryPtrs
,
1410 PFORMAT_STRING pFormat
,
1411 unsigned char fMustAlloc
)
1413 unsigned char *Mark
= pStubMsg
->BufferMark
;
1414 unsigned rep
, count
, stride
;
1416 unsigned char *saved_buffer
= NULL
;
1418 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg
, pDstMemoryPtrs
, pSrcMemoryPtrs
, pFormat
, fMustAlloc
);
1420 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1423 if (pStubMsg
->PointerBufferMark
)
1425 saved_buffer
= pStubMsg
->Buffer
;
1426 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1427 pStubMsg
->PointerBufferMark
= NULL
;
1430 while (pFormat
[0] != RPC_FC_END
) {
1431 TRACE("pFormat[0] = 0x%x\n", pFormat
[0]);
1432 switch (pFormat
[0]) {
1434 FIXME("unknown repeat type %d\n", pFormat
[0]);
1435 case RPC_FC_NO_REPEAT
:
1441 case RPC_FC_FIXED_REPEAT
:
1442 rep
= *(const WORD
*)&pFormat
[2];
1443 stride
= *(const WORD
*)&pFormat
[4];
1444 count
= *(const WORD
*)&pFormat
[8];
1447 case RPC_FC_VARIABLE_REPEAT
:
1448 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1449 stride
= *(const WORD
*)&pFormat
[2];
1450 count
= *(const WORD
*)&pFormat
[6];
1454 for (i
= 0; i
< rep
; i
++) {
1455 PFORMAT_STRING info
= pFormat
;
1456 unsigned char *memdstbase
= pDstMemoryPtrs
+ (i
* stride
);
1457 unsigned char *memsrcbase
= pSrcMemoryPtrs
+ (i
* stride
);
1458 unsigned char *bufbase
= Mark
+ (i
* stride
);
1461 for (u
=0; u
<count
; u
++,info
+=8) {
1462 unsigned char **memdstptr
= (unsigned char **)(memdstbase
+ *(const SHORT
*)&info
[0]);
1463 unsigned char **memsrcptr
= (unsigned char **)(memsrcbase
+ *(const SHORT
*)&info
[0]);
1464 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1465 PointerUnmarshall(pStubMsg
, bufptr
, memdstptr
, *memsrcptr
, info
+4, fMustAlloc
);
1468 pFormat
+= 8 * count
;
1473 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1474 pStubMsg
->Buffer
= saved_buffer
;
1480 /***********************************************************************
1481 * EmbeddedPointerBufferSize
1483 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1484 unsigned char *pMemory
,
1485 PFORMAT_STRING pFormat
)
1487 unsigned rep
, count
, stride
;
1489 ULONG saved_buffer_length
= 0;
1491 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1493 if (pStubMsg
->IgnoreEmbeddedPointers
) return;
1495 if (*pFormat
!= RPC_FC_PP
) return;
1498 if (pStubMsg
->PointerLength
)
1500 saved_buffer_length
= pStubMsg
->BufferLength
;
1501 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
1502 pStubMsg
->PointerLength
= 0;
1505 while (pFormat
[0] != RPC_FC_END
) {
1506 switch (pFormat
[0]) {
1508 FIXME("unknown repeat type %d\n", pFormat
[0]);
1509 case RPC_FC_NO_REPEAT
:
1515 case RPC_FC_FIXED_REPEAT
:
1516 rep
= *(const WORD
*)&pFormat
[2];
1517 stride
= *(const WORD
*)&pFormat
[4];
1518 count
= *(const WORD
*)&pFormat
[8];
1521 case RPC_FC_VARIABLE_REPEAT
:
1522 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1523 stride
= *(const WORD
*)&pFormat
[2];
1524 count
= *(const WORD
*)&pFormat
[6];
1528 for (i
= 0; i
< rep
; i
++) {
1529 PFORMAT_STRING info
= pFormat
;
1530 unsigned char *membase
= pMemory
+ (i
* stride
);
1533 for (u
=0; u
<count
; u
++,info
+=8) {
1534 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1535 unsigned char *saved_memory
= pStubMsg
->Memory
;
1537 pStubMsg
->Memory
= pMemory
;
1538 PointerBufferSize(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1539 pStubMsg
->Memory
= saved_memory
;
1542 pFormat
+= 8 * count
;
1545 if (saved_buffer_length
)
1547 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
1548 pStubMsg
->BufferLength
= saved_buffer_length
;
1552 /***********************************************************************
1553 * EmbeddedPointerMemorySize [internal]
1555 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1556 PFORMAT_STRING pFormat
)
1558 unsigned char *Mark
= pStubMsg
->BufferMark
;
1559 unsigned rep
, count
, stride
;
1561 unsigned char *saved_buffer
= NULL
;
1563 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1565 if (pStubMsg
->IgnoreEmbeddedPointers
) return 0;
1567 if (pStubMsg
->PointerBufferMark
)
1569 saved_buffer
= pStubMsg
->Buffer
;
1570 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1571 pStubMsg
->PointerBufferMark
= NULL
;
1574 if (*pFormat
!= RPC_FC_PP
) return 0;
1577 while (pFormat
[0] != RPC_FC_END
) {
1578 switch (pFormat
[0]) {
1580 FIXME("unknown repeat type %d\n", pFormat
[0]);
1581 case RPC_FC_NO_REPEAT
:
1587 case RPC_FC_FIXED_REPEAT
:
1588 rep
= *(const WORD
*)&pFormat
[2];
1589 stride
= *(const WORD
*)&pFormat
[4];
1590 count
= *(const WORD
*)&pFormat
[8];
1593 case RPC_FC_VARIABLE_REPEAT
:
1594 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1595 stride
= *(const WORD
*)&pFormat
[2];
1596 count
= *(const WORD
*)&pFormat
[6];
1600 for (i
= 0; i
< rep
; i
++) {
1601 PFORMAT_STRING info
= pFormat
;
1602 unsigned char *bufbase
= Mark
+ (i
* stride
);
1604 for (u
=0; u
<count
; u
++,info
+=8) {
1605 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1606 PointerMemorySize(pStubMsg
, bufptr
, info
+4);
1609 pFormat
+= 8 * count
;
1614 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1615 pStubMsg
->Buffer
= saved_buffer
;
1621 /***********************************************************************
1622 * EmbeddedPointerFree [internal]
1624 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1625 unsigned char *pMemory
,
1626 PFORMAT_STRING pFormat
)
1628 unsigned rep
, count
, stride
;
1631 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1632 if (*pFormat
!= RPC_FC_PP
) return;
1635 while (pFormat
[0] != RPC_FC_END
) {
1636 switch (pFormat
[0]) {
1638 FIXME("unknown repeat type %d\n", pFormat
[0]);
1639 case RPC_FC_NO_REPEAT
:
1645 case RPC_FC_FIXED_REPEAT
:
1646 rep
= *(const WORD
*)&pFormat
[2];
1647 stride
= *(const WORD
*)&pFormat
[4];
1648 count
= *(const WORD
*)&pFormat
[8];
1651 case RPC_FC_VARIABLE_REPEAT
:
1652 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1653 stride
= *(const WORD
*)&pFormat
[2];
1654 count
= *(const WORD
*)&pFormat
[6];
1658 for (i
= 0; i
< rep
; i
++) {
1659 PFORMAT_STRING info
= pFormat
;
1660 unsigned char *membase
= pMemory
+ (i
* stride
);
1663 for (u
=0; u
<count
; u
++,info
+=8) {
1664 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1665 unsigned char *saved_memory
= pStubMsg
->Memory
;
1667 pStubMsg
->Memory
= pMemory
;
1668 PointerFree(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1669 pStubMsg
->Memory
= saved_memory
;
1672 pFormat
+= 8 * count
;
1676 /***********************************************************************
1677 * NdrPointerMarshall [RPCRT4.@]
1679 unsigned char * WINAPI
NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1680 unsigned char *pMemory
,
1681 PFORMAT_STRING pFormat
)
1683 unsigned char *Buffer
;
1685 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1687 /* incremement the buffer here instead of in PointerMarshall,
1688 * as that is used by embedded pointers which already handle the incrementing
1689 * the buffer, and shouldn't write any additional pointer data to the wire */
1690 if (*pFormat
!= RPC_FC_RP
)
1692 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
1693 Buffer
= pStubMsg
->Buffer
;
1694 safe_buffer_increment(pStubMsg
, 4);
1697 Buffer
= pStubMsg
->Buffer
;
1699 PointerMarshall(pStubMsg
, Buffer
, pMemory
, pFormat
);
1704 /***********************************************************************
1705 * NdrPointerUnmarshall [RPCRT4.@]
1707 unsigned char * WINAPI
NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1708 unsigned char **ppMemory
,
1709 PFORMAT_STRING pFormat
,
1710 unsigned char fMustAlloc
)
1712 unsigned char *Buffer
;
1714 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1716 /* incremement the buffer here instead of in PointerUnmarshall,
1717 * as that is used by embedded pointers which already handle the incrementing
1718 * the buffer, and shouldn't read any additional pointer data from the
1720 if (*pFormat
!= RPC_FC_RP
)
1722 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1723 Buffer
= pStubMsg
->Buffer
;
1724 safe_buffer_increment(pStubMsg
, 4);
1727 Buffer
= pStubMsg
->Buffer
;
1729 PointerUnmarshall(pStubMsg
, Buffer
, ppMemory
, *ppMemory
, pFormat
, fMustAlloc
);
1734 /***********************************************************************
1735 * NdrPointerBufferSize [RPCRT4.@]
1737 void WINAPI
NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1738 unsigned char *pMemory
,
1739 PFORMAT_STRING pFormat
)
1741 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1743 /* incremement the buffer length here instead of in PointerBufferSize,
1744 * as that is used by embedded pointers which already handle the buffer
1745 * length, and shouldn't write anything more to the wire */
1746 if (*pFormat
!= RPC_FC_RP
)
1748 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
1749 safe_buffer_length_increment(pStubMsg
, 4);
1752 PointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1755 /***********************************************************************
1756 * NdrPointerMemorySize [RPCRT4.@]
1758 ULONG WINAPI
NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1759 PFORMAT_STRING pFormat
)
1761 /* unsigned size = *(LPWORD)(pFormat+2); */
1762 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1763 PointerMemorySize(pStubMsg
, pStubMsg
->Buffer
, pFormat
);
1767 /***********************************************************************
1768 * NdrPointerFree [RPCRT4.@]
1770 void WINAPI
NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1771 unsigned char *pMemory
,
1772 PFORMAT_STRING pFormat
)
1774 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1775 PointerFree(pStubMsg
, pMemory
, pFormat
);
1778 /***********************************************************************
1779 * NdrSimpleTypeMarshall [RPCRT4.@]
1781 void WINAPI
NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1782 unsigned char FormatChar
)
1784 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &FormatChar
);
1787 /***********************************************************************
1788 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1790 void WINAPI
NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1791 unsigned char FormatChar
)
1793 NdrBaseTypeUnmarshall(pStubMsg
, &pMemory
, &FormatChar
, 0);
1796 /***********************************************************************
1797 * NdrSimpleStructMarshall [RPCRT4.@]
1799 unsigned char * WINAPI
NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1800 unsigned char *pMemory
,
1801 PFORMAT_STRING pFormat
)
1803 unsigned size
= *(const WORD
*)(pFormat
+2);
1804 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1806 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pFormat
[1] + 1);
1808 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1809 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
1811 if (pFormat
[0] != RPC_FC_STRUCT
)
1812 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
+4);
1817 /***********************************************************************
1818 * NdrSimpleStructUnmarshall [RPCRT4.@]
1820 unsigned char * WINAPI
NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1821 unsigned char **ppMemory
,
1822 PFORMAT_STRING pFormat
,
1823 unsigned char fMustAlloc
)
1825 unsigned size
= *(const WORD
*)(pFormat
+2);
1826 unsigned char *saved_buffer
;
1827 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1829 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1832 *ppMemory
= NdrAllocate(pStubMsg
, size
);
1835 if (!pStubMsg
->IsClient
&& !*ppMemory
)
1836 /* for servers, we just point straight into the RPC buffer */
1837 *ppMemory
= pStubMsg
->Buffer
;
1840 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1841 safe_buffer_increment(pStubMsg
, size
);
1842 if (pFormat
[0] == RPC_FC_PSTRUCT
)
1843 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
+4, fMustAlloc
);
1845 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
1846 if (*ppMemory
!= saved_buffer
)
1847 memcpy(*ppMemory
, saved_buffer
, size
);
1852 /***********************************************************************
1853 * NdrSimpleStructBufferSize [RPCRT4.@]
1855 void WINAPI
NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1856 unsigned char *pMemory
,
1857 PFORMAT_STRING pFormat
)
1859 unsigned size
= *(const WORD
*)(pFormat
+2);
1860 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1862 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
1864 safe_buffer_length_increment(pStubMsg
, size
);
1865 if (pFormat
[0] != RPC_FC_STRUCT
)
1866 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
+4);
1869 /***********************************************************************
1870 * NdrSimpleStructMemorySize [RPCRT4.@]
1872 ULONG WINAPI
NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1873 PFORMAT_STRING pFormat
)
1875 unsigned short size
= *(const WORD
*)(pFormat
+2);
1877 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1879 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1880 pStubMsg
->MemorySize
+= size
;
1881 safe_buffer_increment(pStubMsg
, size
);
1883 if (pFormat
[0] != RPC_FC_STRUCT
)
1884 EmbeddedPointerMemorySize(pStubMsg
, pFormat
+4);
1885 return pStubMsg
->MemorySize
;
1888 /***********************************************************************
1889 * NdrSimpleStructFree [RPCRT4.@]
1891 void WINAPI
NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
1892 unsigned char *pMemory
,
1893 PFORMAT_STRING pFormat
)
1895 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1896 if (pFormat
[0] != RPC_FC_STRUCT
)
1897 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
+4);
1901 static unsigned long EmbeddedComplexSize(const MIDL_STUB_MESSAGE
*pStubMsg
,
1902 PFORMAT_STRING pFormat
)
1906 case RPC_FC_PSTRUCT
:
1907 case RPC_FC_CSTRUCT
:
1908 case RPC_FC_BOGUS_STRUCT
:
1909 case RPC_FC_SMFARRAY
:
1910 case RPC_FC_SMVARRAY
:
1911 return *(const WORD
*)&pFormat
[2];
1912 case RPC_FC_USER_MARSHAL
:
1913 return *(const WORD
*)&pFormat
[4];
1914 case RPC_FC_NON_ENCAPSULATED_UNION
:
1916 if (pStubMsg
->fHasNewCorrDesc
)
1921 pFormat
+= *(const SHORT
*)pFormat
;
1922 return *(const SHORT
*)pFormat
;
1924 return sizeof(void *);
1926 FIXME("unhandled embedded type %02x\n", *pFormat
);
1932 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1933 PFORMAT_STRING pFormat
)
1935 NDR_MEMORYSIZE m
= NdrMemorySizer
[*pFormat
& NDR_TABLE_MASK
];
1939 FIXME("no memorysizer for data type=%02x\n", *pFormat
);
1943 return m(pStubMsg
, pFormat
);
1947 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1948 unsigned char *pMemory
,
1949 PFORMAT_STRING pFormat
,
1950 PFORMAT_STRING pPointer
)
1952 PFORMAT_STRING desc
;
1956 while (*pFormat
!= RPC_FC_END
) {
1962 TRACE("byte=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
1963 safe_copy_to_buffer(pStubMsg
, pMemory
, 1);
1969 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
1970 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
1976 TRACE("long=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
1977 safe_copy_to_buffer(pStubMsg
, pMemory
, 4);
1981 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
1982 safe_copy_to_buffer(pStubMsg
, pMemory
, 8);
1985 case RPC_FC_POINTER
:
1987 unsigned char *saved_buffer
;
1988 int pointer_buffer_mark_set
= 0;
1989 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
1990 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
1991 saved_buffer
= pStubMsg
->Buffer
;
1992 if (pStubMsg
->PointerBufferMark
)
1994 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1995 pStubMsg
->PointerBufferMark
= NULL
;
1996 pointer_buffer_mark_set
= 1;
1999 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2000 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char**)pMemory
, pPointer
);
2001 if (pointer_buffer_mark_set
)
2003 STD_OVERFLOW_CHECK(pStubMsg
);
2004 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2005 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
2007 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2008 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
2009 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2011 pStubMsg
->Buffer
= saved_buffer
+ 4;
2017 case RPC_FC_ALIGNM4
:
2018 ALIGN_POINTER(pMemory
, 4);
2020 case RPC_FC_ALIGNM8
:
2021 ALIGN_POINTER(pMemory
, 8);
2023 case RPC_FC_STRUCTPAD1
:
2024 case RPC_FC_STRUCTPAD2
:
2025 case RPC_FC_STRUCTPAD3
:
2026 case RPC_FC_STRUCTPAD4
:
2027 case RPC_FC_STRUCTPAD5
:
2028 case RPC_FC_STRUCTPAD6
:
2029 case RPC_FC_STRUCTPAD7
:
2030 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2032 case RPC_FC_EMBEDDED_COMPLEX
:
2033 pMemory
+= pFormat
[1];
2035 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2036 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2037 TRACE("embedded complex (size=%ld) <= %p\n", size
, pMemory
);
2038 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
2041 /* for some reason interface pointers aren't generated as
2042 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2043 * they still need the derefencing treatment that pointers are
2045 if (*desc
== RPC_FC_IP
)
2046 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2048 m(pStubMsg
, pMemory
, desc
);
2050 else FIXME("no marshaller for embedded type %02x\n", *desc
);
2057 FIXME("unhandled format 0x%02x\n", *pFormat
);
2065 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2066 unsigned char *pMemory
,
2067 PFORMAT_STRING pFormat
,
2068 PFORMAT_STRING pPointer
)
2070 PFORMAT_STRING desc
;
2074 while (*pFormat
!= RPC_FC_END
) {
2080 safe_copy_from_buffer(pStubMsg
, pMemory
, 1);
2081 TRACE("byte=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2087 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
2088 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2094 safe_copy_from_buffer(pStubMsg
, pMemory
, 4);
2095 TRACE("long=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
2099 safe_copy_from_buffer(pStubMsg
, pMemory
, 8);
2100 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2103 case RPC_FC_POINTER
:
2105 unsigned char *saved_buffer
;
2106 int pointer_buffer_mark_set
= 0;
2107 TRACE("pointer => %p\n", pMemory
);
2108 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2109 saved_buffer
= pStubMsg
->Buffer
;
2110 if (pStubMsg
->PointerBufferMark
)
2112 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2113 pStubMsg
->PointerBufferMark
= NULL
;
2114 pointer_buffer_mark_set
= 1;
2117 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2119 PointerUnmarshall(pStubMsg
, saved_buffer
, (unsigned char**)pMemory
, *(unsigned char**)pMemory
, pPointer
, TRUE
);
2120 if (pointer_buffer_mark_set
)
2122 STD_OVERFLOW_CHECK(pStubMsg
);
2123 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2124 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
2126 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2127 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
2128 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2130 pStubMsg
->Buffer
= saved_buffer
+ 4;
2136 case RPC_FC_ALIGNM4
:
2137 ALIGN_POINTER_CLEAR(pMemory
, 4);
2139 case RPC_FC_ALIGNM8
:
2140 ALIGN_POINTER_CLEAR(pMemory
, 8);
2142 case RPC_FC_STRUCTPAD1
:
2143 case RPC_FC_STRUCTPAD2
:
2144 case RPC_FC_STRUCTPAD3
:
2145 case RPC_FC_STRUCTPAD4
:
2146 case RPC_FC_STRUCTPAD5
:
2147 case RPC_FC_STRUCTPAD6
:
2148 case RPC_FC_STRUCTPAD7
:
2149 memset(pMemory
, 0, *pFormat
- RPC_FC_STRUCTPAD1
+ 1);
2150 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2152 case RPC_FC_EMBEDDED_COMPLEX
:
2153 pMemory
+= pFormat
[1];
2155 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2156 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2157 TRACE("embedded complex (size=%ld) => %p\n", size
, pMemory
);
2158 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
2159 memset(pMemory
, 0, size
); /* just in case */
2162 /* for some reason interface pointers aren't generated as
2163 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2164 * they still need the derefencing treatment that pointers are
2166 if (*desc
== RPC_FC_IP
)
2167 m(pStubMsg
, (unsigned char **)pMemory
, desc
, FALSE
);
2169 m(pStubMsg
, &pMemory
, desc
, FALSE
);
2171 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
2178 FIXME("unhandled format %d\n", *pFormat
);
2186 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2187 unsigned char *pMemory
,
2188 PFORMAT_STRING pFormat
,
2189 PFORMAT_STRING pPointer
)
2191 PFORMAT_STRING desc
;
2195 while (*pFormat
!= RPC_FC_END
) {
2201 safe_buffer_length_increment(pStubMsg
, 1);
2207 safe_buffer_length_increment(pStubMsg
, 2);
2213 safe_buffer_length_increment(pStubMsg
, 4);
2217 safe_buffer_length_increment(pStubMsg
, 8);
2220 case RPC_FC_POINTER
:
2221 if (!pStubMsg
->IgnoreEmbeddedPointers
)
2223 int saved_buffer_length
= pStubMsg
->BufferLength
;
2224 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2225 pStubMsg
->PointerLength
= 0;
2226 if(!pStubMsg
->BufferLength
)
2227 ERR("BufferLength == 0??\n");
2228 PointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
2229 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2230 pStubMsg
->BufferLength
= saved_buffer_length
;
2232 safe_buffer_length_increment(pStubMsg
, 4);
2236 case RPC_FC_ALIGNM4
:
2237 ALIGN_POINTER(pMemory
, 4);
2239 case RPC_FC_ALIGNM8
:
2240 ALIGN_POINTER(pMemory
, 8);
2242 case RPC_FC_STRUCTPAD1
:
2243 case RPC_FC_STRUCTPAD2
:
2244 case RPC_FC_STRUCTPAD3
:
2245 case RPC_FC_STRUCTPAD4
:
2246 case RPC_FC_STRUCTPAD5
:
2247 case RPC_FC_STRUCTPAD6
:
2248 case RPC_FC_STRUCTPAD7
:
2249 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2251 case RPC_FC_EMBEDDED_COMPLEX
:
2252 pMemory
+= pFormat
[1];
2254 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2255 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2256 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
2259 /* for some reason interface pointers aren't generated as
2260 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2261 * they still need the derefencing treatment that pointers are
2263 if (*desc
== RPC_FC_IP
)
2264 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2266 m(pStubMsg
, pMemory
, desc
);
2268 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
2275 FIXME("unhandled format 0x%02x\n", *pFormat
);
2283 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
2284 unsigned char *pMemory
,
2285 PFORMAT_STRING pFormat
,
2286 PFORMAT_STRING pPointer
)
2288 PFORMAT_STRING desc
;
2292 while (*pFormat
!= RPC_FC_END
) {
2313 case RPC_FC_POINTER
:
2314 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
2318 case RPC_FC_ALIGNM4
:
2319 ALIGN_POINTER(pMemory
, 4);
2321 case RPC_FC_ALIGNM8
:
2322 ALIGN_POINTER(pMemory
, 8);
2324 case RPC_FC_STRUCTPAD1
:
2325 case RPC_FC_STRUCTPAD2
:
2326 case RPC_FC_STRUCTPAD3
:
2327 case RPC_FC_STRUCTPAD4
:
2328 case RPC_FC_STRUCTPAD5
:
2329 case RPC_FC_STRUCTPAD6
:
2330 case RPC_FC_STRUCTPAD7
:
2331 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2333 case RPC_FC_EMBEDDED_COMPLEX
:
2334 pMemory
+= pFormat
[1];
2336 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2337 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2338 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
2341 /* for some reason interface pointers aren't generated as
2342 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2343 * they still need the derefencing treatment that pointers are
2345 if (*desc
== RPC_FC_IP
)
2346 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2348 m(pStubMsg
, pMemory
, desc
);
2350 else FIXME("no freer for embedded type %02x\n", *desc
);
2357 FIXME("unhandled format 0x%02x\n", *pFormat
);
2365 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2366 PFORMAT_STRING pFormat
)
2368 PFORMAT_STRING desc
;
2369 unsigned long size
= 0;
2371 while (*pFormat
!= RPC_FC_END
) {
2378 safe_buffer_increment(pStubMsg
, 1);
2384 safe_buffer_increment(pStubMsg
, 2);
2390 safe_buffer_increment(pStubMsg
, 4);
2394 safe_buffer_increment(pStubMsg
, 8);
2396 case RPC_FC_POINTER
:
2398 safe_buffer_increment(pStubMsg
, 4);
2399 if (!pStubMsg
->IgnoreEmbeddedPointers
)
2400 FIXME("embedded pointers\n");
2402 case RPC_FC_ALIGNM4
:
2403 ALIGN_LENGTH(size
, 4);
2404 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2406 case RPC_FC_ALIGNM8
:
2407 ALIGN_LENGTH(size
, 8);
2408 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
2410 case RPC_FC_STRUCTPAD1
:
2411 case RPC_FC_STRUCTPAD2
:
2412 case RPC_FC_STRUCTPAD3
:
2413 case RPC_FC_STRUCTPAD4
:
2414 case RPC_FC_STRUCTPAD5
:
2415 case RPC_FC_STRUCTPAD6
:
2416 case RPC_FC_STRUCTPAD7
:
2417 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2419 case RPC_FC_EMBEDDED_COMPLEX
:
2422 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2423 size
+= EmbeddedComplexMemorySize(pStubMsg
, desc
);
2429 FIXME("unhandled format 0x%02x\n", *pFormat
);
2437 /***********************************************************************
2438 * NdrComplexStructMarshall [RPCRT4.@]
2440 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2441 unsigned char *pMemory
,
2442 PFORMAT_STRING pFormat
)
2444 PFORMAT_STRING conf_array
= NULL
;
2445 PFORMAT_STRING pointer_desc
= NULL
;
2446 unsigned char *OldMemory
= pStubMsg
->Memory
;
2447 int pointer_buffer_mark_set
= 0;
2449 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2451 if (!pStubMsg
->PointerBufferMark
)
2453 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2454 /* save buffer length */
2455 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2457 /* get the buffer pointer after complex array data, but before
2459 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- pStubMsg
->BufferStart
;
2460 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2461 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
2462 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2464 /* save it for use by embedded pointer code later */
2465 pStubMsg
->PointerBufferMark
= pStubMsg
->BufferStart
+ pStubMsg
->BufferLength
;
2466 TRACE("difference = 0x%x\n", pStubMsg
->PointerBufferMark
- pStubMsg
->Buffer
);
2467 pointer_buffer_mark_set
= 1;
2469 /* restore the original buffer length */
2470 pStubMsg
->BufferLength
= saved_buffer_length
;
2473 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pFormat
[1] + 1);
2476 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2478 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2481 pStubMsg
->Memory
= pMemory
;
2483 ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2486 NdrConformantArrayMarshall(pStubMsg
, pMemory
, conf_array
);
2488 pStubMsg
->Memory
= OldMemory
;
2490 if (pointer_buffer_mark_set
)
2492 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2493 pStubMsg
->PointerBufferMark
= NULL
;
2496 STD_OVERFLOW_CHECK(pStubMsg
);
2501 /***********************************************************************
2502 * NdrComplexStructUnmarshall [RPCRT4.@]
2504 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2505 unsigned char **ppMemory
,
2506 PFORMAT_STRING pFormat
,
2507 unsigned char fMustAlloc
)
2509 unsigned size
= *(const WORD
*)(pFormat
+2);
2510 PFORMAT_STRING conf_array
= NULL
;
2511 PFORMAT_STRING pointer_desc
= NULL
;
2512 unsigned char *pMemory
;
2513 int pointer_buffer_mark_set
= 0;
2515 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2517 if (!pStubMsg
->PointerBufferMark
)
2519 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2520 /* save buffer pointer */
2521 unsigned char *saved_buffer
= pStubMsg
->Buffer
;
2523 /* get the buffer pointer after complex array data, but before
2525 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2526 NdrComplexStructMemorySize(pStubMsg
, pFormat
);
2527 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2529 /* save it for use by embedded pointer code later */
2530 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2531 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->PointerBufferMark
- saved_buffer
));
2532 pointer_buffer_mark_set
= 1;
2534 /* restore the original buffer */
2535 pStubMsg
->Buffer
= saved_buffer
;
2538 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2540 if (fMustAlloc
|| !*ppMemory
)
2542 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2543 memset(*ppMemory
, 0, size
);
2547 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2549 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2552 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
);
2555 NdrConformantArrayUnmarshall(pStubMsg
, &pMemory
, conf_array
, fMustAlloc
);
2557 if (pointer_buffer_mark_set
)
2559 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2560 pStubMsg
->PointerBufferMark
= NULL
;
2566 /***********************************************************************
2567 * NdrComplexStructBufferSize [RPCRT4.@]
2569 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2570 unsigned char *pMemory
,
2571 PFORMAT_STRING pFormat
)
2573 PFORMAT_STRING conf_array
= NULL
;
2574 PFORMAT_STRING pointer_desc
= NULL
;
2575 unsigned char *OldMemory
= pStubMsg
->Memory
;
2576 int pointer_length_set
= 0;
2578 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2580 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
2582 if(!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
2584 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2585 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2587 /* get the buffer length after complex struct data, but before
2589 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2590 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
2591 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2593 /* save it for use by embedded pointer code later */
2594 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2595 pointer_length_set
= 1;
2596 TRACE("difference = 0x%lx\n", pStubMsg
->PointerLength
- saved_buffer_length
);
2598 /* restore the original buffer length */
2599 pStubMsg
->BufferLength
= saved_buffer_length
;
2603 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2605 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2608 pStubMsg
->Memory
= pMemory
;
2610 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2613 NdrConformantArrayBufferSize(pStubMsg
, pMemory
, conf_array
);
2615 pStubMsg
->Memory
= OldMemory
;
2617 if(pointer_length_set
)
2619 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2620 pStubMsg
->PointerLength
= 0;
2625 /***********************************************************************
2626 * NdrComplexStructMemorySize [RPCRT4.@]
2628 ULONG WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2629 PFORMAT_STRING pFormat
)
2631 unsigned size
= *(const WORD
*)(pFormat
+2);
2632 PFORMAT_STRING conf_array
= NULL
;
2633 PFORMAT_STRING pointer_desc
= NULL
;
2635 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2637 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2640 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2642 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2645 ComplexStructMemorySize(pStubMsg
, pFormat
);
2648 NdrConformantArrayMemorySize(pStubMsg
, conf_array
);
2653 /***********************************************************************
2654 * NdrComplexStructFree [RPCRT4.@]
2656 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
2657 unsigned char *pMemory
,
2658 PFORMAT_STRING pFormat
)
2660 PFORMAT_STRING conf_array
= NULL
;
2661 PFORMAT_STRING pointer_desc
= NULL
;
2662 unsigned char *OldMemory
= pStubMsg
->Memory
;
2664 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2667 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2669 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2672 pStubMsg
->Memory
= pMemory
;
2674 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2677 NdrConformantArrayFree(pStubMsg
, pMemory
, conf_array
);
2679 pStubMsg
->Memory
= OldMemory
;
2682 /***********************************************************************
2683 * NdrConformantArrayMarshall [RPCRT4.@]
2685 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2686 unsigned char *pMemory
,
2687 PFORMAT_STRING pFormat
)
2689 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
2690 unsigned char alignment
= pFormat
[1] + 1;
2692 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2693 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2695 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2697 WriteConformance(pStubMsg
);
2699 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
2701 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2702 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2703 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
2705 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2710 /***********************************************************************
2711 * NdrConformantArrayUnmarshall [RPCRT4.@]
2713 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2714 unsigned char **ppMemory
,
2715 PFORMAT_STRING pFormat
,
2716 unsigned char fMustAlloc
)
2718 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
2719 unsigned char alignment
= pFormat
[1] + 1;
2720 unsigned char *saved_buffer
;
2722 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2723 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2725 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2727 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2728 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2731 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2734 if (!pStubMsg
->IsClient
&& !*ppMemory
)
2735 /* for servers, we just point straight into the RPC buffer */
2736 *ppMemory
= pStubMsg
->Buffer
;
2739 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2740 safe_buffer_increment(pStubMsg
, size
);
2741 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
2743 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
2744 if (*ppMemory
!= saved_buffer
)
2745 memcpy(*ppMemory
, saved_buffer
, size
);
2750 /***********************************************************************
2751 * NdrConformantArrayBufferSize [RPCRT4.@]
2753 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2754 unsigned char *pMemory
,
2755 PFORMAT_STRING pFormat
)
2757 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
2758 unsigned char alignment
= pFormat
[1] + 1;
2760 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2761 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2763 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2765 SizeConformance(pStubMsg
);
2767 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
2769 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2770 /* conformance value plus array */
2771 safe_buffer_length_increment(pStubMsg
, size
);
2773 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
2776 /***********************************************************************
2777 * NdrConformantArrayMemorySize [RPCRT4.@]
2779 ULONG WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2780 PFORMAT_STRING pFormat
)
2782 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
2783 unsigned char alignment
= pFormat
[1] + 1;
2785 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2786 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2788 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2789 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2790 pStubMsg
->MemorySize
+= size
;
2792 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2793 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2794 safe_buffer_increment(pStubMsg
, size
);
2796 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2798 return pStubMsg
->MemorySize
;
2801 /***********************************************************************
2802 * NdrConformantArrayFree [RPCRT4.@]
2804 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
2805 unsigned char *pMemory
,
2806 PFORMAT_STRING pFormat
)
2808 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2809 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2811 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2813 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2817 /***********************************************************************
2818 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2820 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2821 unsigned char* pMemory
,
2822 PFORMAT_STRING pFormat
)
2825 unsigned char alignment
= pFormat
[1] + 1;
2826 DWORD esize
= *(const WORD
*)(pFormat
+2);
2828 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
2830 if (pFormat
[0] != RPC_FC_CVARRAY
)
2832 ERR("invalid format type %x\n", pFormat
[0]);
2833 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2837 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2838 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2840 WriteConformance(pStubMsg
);
2841 WriteVariance(pStubMsg
);
2843 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
2845 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2847 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2848 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
2850 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2856 /***********************************************************************
2857 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2859 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2860 unsigned char** ppMemory
,
2861 PFORMAT_STRING pFormat
,
2862 unsigned char fMustAlloc
)
2864 ULONG bufsize
, memsize
;
2865 unsigned char alignment
= pFormat
[1] + 1;
2866 DWORD esize
= *(const WORD
*)(pFormat
+2);
2867 unsigned char *saved_buffer
;
2870 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2872 if (pFormat
[0] != RPC_FC_CVARRAY
)
2874 ERR("invalid format type %x\n", pFormat
[0]);
2875 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2879 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2880 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2882 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2884 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2885 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2886 offset
= pStubMsg
->Offset
;
2888 if (!*ppMemory
|| fMustAlloc
)
2889 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2890 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2891 safe_buffer_increment(pStubMsg
, bufsize
);
2893 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
2895 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
2901 /***********************************************************************
2902 * NdrConformantVaryingArrayFree [RPCRT4.@]
2904 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
2905 unsigned char* pMemory
,
2906 PFORMAT_STRING pFormat
)
2908 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2910 if (pFormat
[0] != RPC_FC_CVARRAY
)
2912 ERR("invalid format type %x\n", pFormat
[0]);
2913 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2917 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2918 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2920 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2924 /***********************************************************************
2925 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2927 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
2928 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
2930 unsigned char alignment
= pFormat
[1] + 1;
2931 DWORD esize
= *(const WORD
*)(pFormat
+2);
2933 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
2935 if (pFormat
[0] != RPC_FC_CVARRAY
)
2937 ERR("invalid format type %x\n", pFormat
[0]);
2938 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2943 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2944 /* compute length */
2945 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2947 SizeConformance(pStubMsg
);
2948 SizeVariance(pStubMsg
);
2950 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
2952 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
2954 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
2958 /***********************************************************************
2959 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2961 ULONG WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
2962 PFORMAT_STRING pFormat
)
2964 ULONG bufsize
, memsize
;
2965 unsigned char alignment
= pFormat
[1] + 1;
2966 DWORD esize
= *(const WORD
*)(pFormat
+2);
2968 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
2970 if (pFormat
[0] != RPC_FC_CVARRAY
)
2972 ERR("invalid format type %x\n", pFormat
[0]);
2973 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2974 return pStubMsg
->MemorySize
;
2977 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2978 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2980 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2982 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2983 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2985 safe_buffer_increment(pStubMsg
, bufsize
);
2986 pStubMsg
->MemorySize
+= memsize
;
2988 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2990 return pStubMsg
->MemorySize
;
2994 /***********************************************************************
2995 * NdrComplexArrayMarshall [RPCRT4.@]
2997 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2998 unsigned char *pMemory
,
2999 PFORMAT_STRING pFormat
)
3001 ULONG i
, count
, def
;
3002 BOOL variance_present
;
3003 unsigned char alignment
;
3004 int pointer_buffer_mark_set
= 0;
3006 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3008 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3010 ERR("invalid format type %x\n", pFormat
[0]);
3011 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3015 alignment
= pFormat
[1] + 1;
3017 if (!pStubMsg
->PointerBufferMark
)
3019 /* save buffer fields that may be changed by buffer sizer functions
3020 * and that may be needed later on */
3021 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3022 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
3023 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
3024 unsigned long saved_offset
= pStubMsg
->Offset
;
3025 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
3027 /* get the buffer pointer after complex array data, but before
3029 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- pStubMsg
->BufferStart
;
3030 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3031 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
3032 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3034 /* save it for use by embedded pointer code later */
3035 pStubMsg
->PointerBufferMark
= pStubMsg
->BufferStart
+ pStubMsg
->BufferLength
;
3036 TRACE("difference = 0x%x\n", pStubMsg
->Buffer
- pStubMsg
->BufferStart
);
3037 pointer_buffer_mark_set
= 1;
3039 /* restore fields */
3040 pStubMsg
->ActualCount
= saved_actual_count
;
3041 pStubMsg
->Offset
= saved_offset
;
3042 pStubMsg
->MaxCount
= saved_max_count
;
3043 pStubMsg
->BufferLength
= saved_buffer_length
;
3046 def
= *(const WORD
*)&pFormat
[2];
3049 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3050 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3052 variance_present
= IsConformanceOrVariancePresent(pFormat
);
3053 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3054 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3056 WriteConformance(pStubMsg
);
3057 if (variance_present
)
3058 WriteVariance(pStubMsg
);
3060 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
3062 count
= pStubMsg
->ActualCount
;
3063 for (i
= 0; i
< count
; i
++)
3064 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
3066 STD_OVERFLOW_CHECK(pStubMsg
);
3068 if (pointer_buffer_mark_set
)
3070 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3071 pStubMsg
->PointerBufferMark
= NULL
;
3077 /***********************************************************************
3078 * NdrComplexArrayUnmarshall [RPCRT4.@]
3080 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3081 unsigned char **ppMemory
,
3082 PFORMAT_STRING pFormat
,
3083 unsigned char fMustAlloc
)
3085 ULONG i
, count
, size
;
3086 unsigned char alignment
;
3087 unsigned char *pMemory
;
3088 unsigned char *saved_buffer
;
3089 int pointer_buffer_mark_set
= 0;
3090 int saved_ignore_embedded
;
3092 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3094 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3096 ERR("invalid format type %x\n", pFormat
[0]);
3097 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3101 alignment
= pFormat
[1] + 1;
3103 saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3104 /* save buffer pointer */
3105 saved_buffer
= pStubMsg
->Buffer
;
3106 /* get the buffer pointer after complex array data, but before
3108 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3109 pStubMsg
->MemorySize
= 0;
3110 NdrComplexArrayMemorySize(pStubMsg
, pFormat
);
3111 size
= pStubMsg
->MemorySize
;
3112 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3114 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->Buffer
- saved_buffer
));
3115 if (!pStubMsg
->PointerBufferMark
)
3117 /* save it for use by embedded pointer code later */
3118 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3119 pointer_buffer_mark_set
= 1;
3121 /* restore the original buffer */
3122 pStubMsg
->Buffer
= saved_buffer
;
3126 pFormat
= ReadConformance(pStubMsg
, pFormat
);
3127 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3129 if (fMustAlloc
|| !*ppMemory
)
3131 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3132 memset(*ppMemory
, 0, size
);
3135 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3137 pMemory
= *ppMemory
;
3138 count
= pStubMsg
->ActualCount
;
3139 for (i
= 0; i
< count
; i
++)
3140 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
3142 if (pointer_buffer_mark_set
)
3144 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3145 pStubMsg
->PointerBufferMark
= NULL
;
3151 /***********************************************************************
3152 * NdrComplexArrayBufferSize [RPCRT4.@]
3154 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3155 unsigned char *pMemory
,
3156 PFORMAT_STRING pFormat
)
3158 ULONG i
, count
, def
;
3159 unsigned char alignment
;
3160 BOOL variance_present
;
3161 int pointer_length_set
= 0;
3163 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3165 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3167 ERR("invalid format type %x\n", pFormat
[0]);
3168 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3172 alignment
= pFormat
[1] + 1;
3174 if (!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
3176 /* save buffer fields that may be changed by buffer sizer functions
3177 * and that may be needed later on */
3178 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3179 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
3180 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
3181 unsigned long saved_offset
= pStubMsg
->Offset
;
3182 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
3184 /* get the buffer pointer after complex array data, but before
3186 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3187 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
3188 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3190 /* save it for use by embedded pointer code later */
3191 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3192 pointer_length_set
= 1;
3194 /* restore fields */
3195 pStubMsg
->ActualCount
= saved_actual_count
;
3196 pStubMsg
->Offset
= saved_offset
;
3197 pStubMsg
->MaxCount
= saved_max_count
;
3198 pStubMsg
->BufferLength
= saved_buffer_length
;
3200 def
= *(const WORD
*)&pFormat
[2];
3203 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3204 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3205 SizeConformance(pStubMsg
);
3207 variance_present
= IsConformanceOrVariancePresent(pFormat
);
3208 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3209 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3211 if (variance_present
)
3212 SizeVariance(pStubMsg
);
3214 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
3216 count
= pStubMsg
->ActualCount
;
3217 for (i
= 0; i
< count
; i
++)
3218 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
3220 if(pointer_length_set
)
3222 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3223 pStubMsg
->PointerLength
= 0;
3227 /***********************************************************************
3228 * NdrComplexArrayMemorySize [RPCRT4.@]
3230 ULONG WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3231 PFORMAT_STRING pFormat
)
3233 ULONG i
, count
, esize
, SavedMemorySize
, MemorySize
;
3234 unsigned char alignment
;
3235 unsigned char *Buffer
;
3237 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3239 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3241 ERR("invalid format type %x\n", pFormat
[0]);
3242 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3246 alignment
= pFormat
[1] + 1;
3250 pFormat
= ReadConformance(pStubMsg
, pFormat
);
3251 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3253 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3255 SavedMemorySize
= pStubMsg
->MemorySize
;
3257 Buffer
= pStubMsg
->Buffer
;
3258 pStubMsg
->MemorySize
= 0;
3259 esize
= ComplexStructMemorySize(pStubMsg
, pFormat
);
3260 pStubMsg
->Buffer
= Buffer
;
3262 MemorySize
= safe_multiply(pStubMsg
->MaxCount
, esize
);
3264 count
= pStubMsg
->ActualCount
;
3265 for (i
= 0; i
< count
; i
++)
3266 ComplexStructMemorySize(pStubMsg
, pFormat
);
3268 pStubMsg
->MemorySize
= SavedMemorySize
;
3270 pStubMsg
->MemorySize
+= MemorySize
;
3274 /***********************************************************************
3275 * NdrComplexArrayFree [RPCRT4.@]
3277 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3278 unsigned char *pMemory
,
3279 PFORMAT_STRING pFormat
)
3281 ULONG i
, count
, def
;
3283 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3285 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3287 ERR("invalid format type %x\n", pFormat
[0]);
3288 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3292 def
= *(const WORD
*)&pFormat
[2];
3295 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3296 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3298 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3299 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3301 count
= pStubMsg
->ActualCount
;
3302 for (i
= 0; i
< count
; i
++)
3303 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
3306 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg
,
3307 USER_MARSHAL_CB_TYPE cbtype
, PFORMAT_STRING pFormat
,
3308 USER_MARSHAL_CB
*umcb
)
3310 umcb
->Flags
= MAKELONG(pStubMsg
->dwDestContext
,
3311 pStubMsg
->RpcMsg
->DataRepresentation
);
3312 umcb
->pStubMsg
= pStubMsg
;
3313 umcb
->pReserve
= NULL
;
3314 umcb
->Signature
= USER_MARSHAL_CB_SIGNATURE
;
3315 umcb
->CBType
= cbtype
;
3316 umcb
->pFormat
= pFormat
;
3317 umcb
->pTypeFormat
= NULL
/* FIXME */;
3320 #define USER_MARSHAL_PTR_PREFIX \
3321 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3322 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3324 /***********************************************************************
3325 * NdrUserMarshalMarshall [RPCRT4.@]
3327 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3328 unsigned char *pMemory
,
3329 PFORMAT_STRING pFormat
)
3331 unsigned flags
= pFormat
[1];
3332 unsigned index
= *(const WORD
*)&pFormat
[2];
3333 unsigned char *saved_buffer
= NULL
;
3334 USER_MARSHAL_CB umcb
;
3336 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3337 TRACE("index=%d\n", index
);
3339 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_MARSHALL
, pFormat
, &umcb
);
3341 if (flags
& USER_MARSHAL_POINTER
)
3343 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
3344 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, USER_MARSHAL_PTR_PREFIX
);
3345 pStubMsg
->Buffer
+= 4;
3346 if (pStubMsg
->PointerBufferMark
)
3348 saved_buffer
= pStubMsg
->Buffer
;
3349 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3350 pStubMsg
->PointerBufferMark
= NULL
;
3352 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 8);
3355 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3358 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
3359 &umcb
.Flags
, pStubMsg
->Buffer
, pMemory
);
3363 STD_OVERFLOW_CHECK(pStubMsg
);
3364 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3365 pStubMsg
->Buffer
= saved_buffer
;
3368 STD_OVERFLOW_CHECK(pStubMsg
);
3373 /***********************************************************************
3374 * NdrUserMarshalUnmarshall [RPCRT4.@]
3376 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3377 unsigned char **ppMemory
,
3378 PFORMAT_STRING pFormat
,
3379 unsigned char fMustAlloc
)
3381 unsigned flags
= pFormat
[1];
3382 unsigned index
= *(const WORD
*)&pFormat
[2];
3383 DWORD memsize
= *(const WORD
*)&pFormat
[4];
3384 unsigned char *saved_buffer
= NULL
;
3385 USER_MARSHAL_CB umcb
;
3387 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3388 TRACE("index=%d\n", index
);
3390 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_UNMARSHALL
, pFormat
, &umcb
);
3392 if (flags
& USER_MARSHAL_POINTER
)
3394 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3395 /* skip pointer prefix */
3396 pStubMsg
->Buffer
+= 4;
3397 if (pStubMsg
->PointerBufferMark
)
3399 saved_buffer
= pStubMsg
->Buffer
;
3400 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3401 pStubMsg
->PointerBufferMark
= NULL
;
3403 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3406 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3408 if (fMustAlloc
|| !*ppMemory
)
3409 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
3412 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
3413 &umcb
.Flags
, pStubMsg
->Buffer
, *ppMemory
);
3417 STD_OVERFLOW_CHECK(pStubMsg
);
3418 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3419 pStubMsg
->Buffer
= saved_buffer
;
3425 /***********************************************************************
3426 * NdrUserMarshalBufferSize [RPCRT4.@]
3428 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3429 unsigned char *pMemory
,
3430 PFORMAT_STRING pFormat
)
3432 unsigned flags
= pFormat
[1];
3433 unsigned index
= *(const WORD
*)&pFormat
[2];
3434 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
3435 USER_MARSHAL_CB umcb
;
3436 unsigned long saved_buffer_length
= 0;
3438 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3439 TRACE("index=%d\n", index
);
3441 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_BUFFER_SIZE
, pFormat
, &umcb
);
3443 if (flags
& USER_MARSHAL_POINTER
)
3445 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
3446 /* skip pointer prefix */
3447 safe_buffer_length_increment(pStubMsg
, 4);
3448 if (pStubMsg
->IgnoreEmbeddedPointers
)
3450 if (pStubMsg
->PointerLength
)
3452 saved_buffer_length
= pStubMsg
->BufferLength
;
3453 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3454 pStubMsg
->PointerLength
= 0;
3456 ALIGN_LENGTH(pStubMsg
->BufferLength
, 8);
3459 ALIGN_LENGTH(pStubMsg
->BufferLength
, (flags
& 0xf) + 1);
3462 TRACE("size=%d\n", bufsize
);
3463 safe_buffer_length_increment(pStubMsg
, bufsize
);
3466 pStubMsg
->BufferLength
=
3467 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
3468 &umcb
.Flags
, pStubMsg
->BufferLength
, pMemory
);
3470 if (saved_buffer_length
)
3472 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3473 pStubMsg
->BufferLength
= saved_buffer_length
;
3478 /***********************************************************************
3479 * NdrUserMarshalMemorySize [RPCRT4.@]
3481 ULONG WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3482 PFORMAT_STRING pFormat
)
3484 unsigned flags
= pFormat
[1];
3485 unsigned index
= *(const WORD
*)&pFormat
[2];
3486 DWORD memsize
= *(const WORD
*)&pFormat
[4];
3487 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
3489 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3490 TRACE("index=%d\n", index
);
3492 pStubMsg
->MemorySize
+= memsize
;
3494 if (flags
& USER_MARSHAL_POINTER
)
3496 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3497 /* skip pointer prefix */
3498 pStubMsg
->Buffer
+= 4;
3499 if (pStubMsg
->IgnoreEmbeddedPointers
)
3500 return pStubMsg
->MemorySize
;
3501 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3504 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3507 FIXME("not implemented for varying buffer size\n");
3509 pStubMsg
->Buffer
+= bufsize
;
3511 return pStubMsg
->MemorySize
;
3514 /***********************************************************************
3515 * NdrUserMarshalFree [RPCRT4.@]
3517 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
3518 unsigned char *pMemory
,
3519 PFORMAT_STRING pFormat
)
3521 /* unsigned flags = pFormat[1]; */
3522 unsigned index
= *(const WORD
*)&pFormat
[2];
3523 USER_MARSHAL_CB umcb
;
3525 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3526 TRACE("index=%d\n", index
);
3528 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_FREE
, pFormat
, &umcb
);
3530 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
3531 &umcb
.Flags
, pMemory
);
3534 /***********************************************************************
3535 * NdrClearOutParameters [RPCRT4.@]
3537 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
3538 PFORMAT_STRING pFormat
,
3541 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
3544 /***********************************************************************
3545 * NdrConvert [RPCRT4.@]
3547 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
3549 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
3550 /* FIXME: since this stub doesn't do any converting, the proper behavior
3551 is to raise an exception */
3554 /***********************************************************************
3555 * NdrConvert2 [RPCRT4.@]
3557 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, LONG NumberParams
)
3559 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3560 pStubMsg
, pFormat
, NumberParams
);
3561 /* FIXME: since this stub doesn't do any converting, the proper behavior
3562 is to raise an exception */
3565 #include "pshpack1.h"
3566 typedef struct _NDR_CSTRUCT_FORMAT
3569 unsigned char alignment
;
3570 unsigned short memory_size
;
3571 short offset_to_array_description
;
3572 } NDR_CSTRUCT_FORMAT
, NDR_CVSTRUCT_FORMAT
;
3573 #include "poppack.h"
3575 /***********************************************************************
3576 * NdrConformantStructMarshall [RPCRT4.@]
3578 unsigned char * WINAPI
NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3579 unsigned char *pMemory
,
3580 PFORMAT_STRING pFormat
)
3582 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3583 PFORMAT_STRING pCArrayFormat
;
3584 ULONG esize
, bufsize
;
3586 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3588 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3589 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3591 ERR("invalid format type %x\n", pCStructFormat
->type
);
3592 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3596 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3597 pCStructFormat
->offset_to_array_description
;
3598 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3600 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3601 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3604 esize
= *(const WORD
*)(pCArrayFormat
+2);
3606 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
3607 pCArrayFormat
+ 4, 0);
3609 WriteConformance(pStubMsg
);
3611 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
3613 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3615 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3616 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
3618 ERR("integer overflow of memory_size %u with bufsize %u\n",
3619 pCStructFormat
->memory_size
, bufsize
);
3620 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3622 /* copy constant sized part of struct */
3623 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3624 safe_copy_to_buffer(pStubMsg
, pMemory
, pCStructFormat
->memory_size
+ bufsize
);
3626 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3627 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3632 /***********************************************************************
3633 * NdrConformantStructUnmarshall [RPCRT4.@]
3635 unsigned char * WINAPI
NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3636 unsigned char **ppMemory
,
3637 PFORMAT_STRING pFormat
,
3638 unsigned char fMustAlloc
)
3640 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3641 PFORMAT_STRING pCArrayFormat
;
3642 ULONG esize
, bufsize
;
3643 unsigned char *saved_buffer
;
3645 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3647 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3648 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3650 ERR("invalid format type %x\n", pCStructFormat
->type
);
3651 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3654 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3655 pCStructFormat
->offset_to_array_description
;
3656 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3658 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3659 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3662 esize
= *(const WORD
*)(pCArrayFormat
+2);
3664 pCArrayFormat
= ReadConformance(pStubMsg
, pCArrayFormat
+ 4);
3666 ALIGN_POINTER(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
3668 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3670 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3671 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
3673 ERR("integer overflow of memory_size %u with bufsize %u\n",
3674 pCStructFormat
->memory_size
, bufsize
);
3675 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3680 SIZE_T size
= pCStructFormat
->memory_size
+ bufsize
;
3681 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3685 if (!pStubMsg
->IsClient
&& !*ppMemory
)
3686 /* for servers, we just point straight into the RPC buffer */
3687 *ppMemory
= pStubMsg
->Buffer
;
3690 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3691 safe_buffer_increment(pStubMsg
, pCStructFormat
->memory_size
+ bufsize
);
3692 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3693 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
3695 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
3696 if (*ppMemory
!= saved_buffer
)
3697 memcpy(*ppMemory
, saved_buffer
, pCStructFormat
->memory_size
+ bufsize
);
3702 /***********************************************************************
3703 * NdrConformantStructBufferSize [RPCRT4.@]
3705 void WINAPI
NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3706 unsigned char *pMemory
,
3707 PFORMAT_STRING pFormat
)
3709 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3710 PFORMAT_STRING pCArrayFormat
;
3713 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3715 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3716 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3718 ERR("invalid format type %x\n", pCStructFormat
->type
);
3719 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3722 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3723 pCStructFormat
->offset_to_array_description
;
3724 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3726 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3727 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3730 esize
= *(const WORD
*)(pCArrayFormat
+2);
3732 pCArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
, pCArrayFormat
+4, 0);
3733 SizeConformance(pStubMsg
);
3735 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCStructFormat
->alignment
+ 1);
3737 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3739 safe_buffer_length_increment(pStubMsg
, pCStructFormat
->memory_size
);
3740 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
3742 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3743 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3746 /***********************************************************************
3747 * NdrConformantStructMemorySize [RPCRT4.@]
3749 ULONG WINAPI
NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3750 PFORMAT_STRING pFormat
)
3756 /***********************************************************************
3757 * NdrConformantStructFree [RPCRT4.@]
3759 void WINAPI
NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3760 unsigned char *pMemory
,
3761 PFORMAT_STRING pFormat
)
3763 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3764 PFORMAT_STRING pCArrayFormat
;
3767 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3769 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3770 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3772 ERR("invalid format type %x\n", pCStructFormat
->type
);
3773 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3777 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3778 pCStructFormat
->offset_to_array_description
;
3779 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3781 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3782 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3785 esize
= *(const WORD
*)(pCArrayFormat
+2);
3787 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
3788 pCArrayFormat
+ 4, 0);
3790 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3792 /* copy constant sized part of struct */
3793 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3795 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3796 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
3799 /***********************************************************************
3800 * NdrConformantVaryingStructMarshall [RPCRT4.@]
3802 unsigned char * WINAPI
NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3803 unsigned char *pMemory
,
3804 PFORMAT_STRING pFormat
)
3806 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3807 PFORMAT_STRING pCVArrayFormat
;
3808 ULONG esize
, bufsize
;
3810 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3812 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3813 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3815 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3816 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3820 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3821 pCVStructFormat
->offset_to_array_description
;
3822 switch (*pCVArrayFormat
)
3824 case RPC_FC_CVARRAY
:
3825 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3827 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3828 pCVArrayFormat
+ 4, 0);
3829 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3832 case RPC_FC_C_CSTRING
:
3833 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
3834 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
3835 esize
= sizeof(char);
3836 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3837 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3838 pCVArrayFormat
+ 2, 0);
3840 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3842 case RPC_FC_C_WSTRING
:
3843 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
3844 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
3845 esize
= sizeof(WCHAR
);
3846 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3847 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3848 pCVArrayFormat
+ 2, 0);
3850 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3853 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3854 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3858 WriteConformance(pStubMsg
);
3860 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
3862 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3864 /* write constant sized part */
3865 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3866 safe_copy_to_buffer(pStubMsg
, pMemory
, pCVStructFormat
->memory_size
);
3868 WriteVariance(pStubMsg
);
3870 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3872 /* write array part */
3873 safe_copy_to_buffer(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
, bufsize
);
3875 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3880 /***********************************************************************
3881 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3883 unsigned char * WINAPI
NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3884 unsigned char **ppMemory
,
3885 PFORMAT_STRING pFormat
,
3886 unsigned char fMustAlloc
)
3888 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3889 PFORMAT_STRING pCVArrayFormat
;
3890 ULONG esize
, bufsize
;
3891 unsigned char cvarray_type
;
3893 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3895 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3896 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3898 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3899 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3903 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3904 pCVStructFormat
->offset_to_array_description
;
3905 cvarray_type
= *pCVArrayFormat
;
3906 switch (cvarray_type
)
3908 case RPC_FC_CVARRAY
:
3909 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3910 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 4);
3912 case RPC_FC_C_CSTRING
:
3913 esize
= sizeof(char);
3914 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3915 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3917 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3919 case RPC_FC_C_WSTRING
:
3920 esize
= sizeof(WCHAR
);
3921 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3922 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3924 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3927 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3928 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3932 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
3934 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3936 /* work out how much memory to allocate if we need to do so */
3937 if (!*ppMemory
|| fMustAlloc
)
3939 SIZE_T size
= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->MaxCount
);
3940 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3943 /* copy the constant data */
3944 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3945 safe_copy_from_buffer(pStubMsg
, *ppMemory
, pCVStructFormat
->memory_size
);
3947 pCVArrayFormat
= ReadVariance(pStubMsg
, pCVArrayFormat
, pStubMsg
->MaxCount
);
3949 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3951 if ((cvarray_type
== RPC_FC_C_CSTRING
) ||
3952 (cvarray_type
== RPC_FC_C_WSTRING
))
3955 /* strings must always have null terminating bytes */
3956 if (bufsize
< esize
)
3958 ERR("invalid string length of %d\n", pStubMsg
->ActualCount
);
3959 RpcRaiseException(RPC_S_INVALID_BOUND
);
3962 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
3963 if (pStubMsg
->Buffer
[i
] != 0)
3965 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
3966 i
, pStubMsg
->Buffer
[i
]);
3967 RpcRaiseException(RPC_S_INVALID_BOUND
);
3972 /* copy the array data */
3973 safe_copy_from_buffer(pStubMsg
, *ppMemory
+ pCVStructFormat
->memory_size
, bufsize
);
3975 if (cvarray_type
== RPC_FC_C_CSTRING
)
3976 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory
+ pCVStructFormat
->memory_size
)));
3977 else if (cvarray_type
== RPC_FC_C_WSTRING
)
3978 TRACE("string=%s\n", debugstr_w((WCHAR
*)(*ppMemory
+ pCVStructFormat
->memory_size
)));
3980 EmbeddedPointerUnmarshall(pStubMsg
, *ppMemory
, *ppMemory
, pFormat
, TRUE
/* FIXME */);
3985 /***********************************************************************
3986 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3988 void WINAPI
NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3989 unsigned char *pMemory
,
3990 PFORMAT_STRING pFormat
)
3992 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3993 PFORMAT_STRING pCVArrayFormat
;
3996 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3998 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3999 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4001 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4002 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4006 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4007 pCVStructFormat
->offset_to_array_description
;
4008 switch (*pCVArrayFormat
)
4010 case RPC_FC_CVARRAY
:
4011 esize
= *(const WORD
*)(pCVArrayFormat
+2);
4013 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4014 pCVArrayFormat
+ 4, 0);
4015 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4018 case RPC_FC_C_CSTRING
:
4019 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
4020 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
4021 esize
= sizeof(char);
4022 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4023 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4024 pCVArrayFormat
+ 2, 0);
4026 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4028 case RPC_FC_C_WSTRING
:
4029 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
4030 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
4031 esize
= sizeof(WCHAR
);
4032 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4033 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4034 pCVArrayFormat
+ 2, 0);
4036 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4039 ERR("invalid array format type %x\n", *pCVArrayFormat
);
4040 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4044 SizeConformance(pStubMsg
);
4046 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCVStructFormat
->alignment
+ 1);
4048 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4050 safe_buffer_length_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4051 SizeVariance(pStubMsg
);
4052 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
4054 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4057 /***********************************************************************
4058 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4060 ULONG WINAPI
NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4061 PFORMAT_STRING pFormat
)
4063 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4064 PFORMAT_STRING pCVArrayFormat
;
4066 unsigned char cvarray_type
;
4068 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4070 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4071 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4073 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4074 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4078 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4079 pCVStructFormat
->offset_to_array_description
;
4080 cvarray_type
= *pCVArrayFormat
;
4081 switch (cvarray_type
)
4083 case RPC_FC_CVARRAY
:
4084 esize
= *(const WORD
*)(pCVArrayFormat
+2);
4085 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 4);
4087 case RPC_FC_C_CSTRING
:
4088 esize
= sizeof(char);
4089 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4090 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
4092 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
4094 case RPC_FC_C_WSTRING
:
4095 esize
= sizeof(WCHAR
);
4096 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4097 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
4099 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
4102 ERR("invalid array format type %x\n", *pCVArrayFormat
);
4103 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4107 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4109 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4111 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4112 pCVArrayFormat
= ReadVariance(pStubMsg
, pCVArrayFormat
, pStubMsg
->MaxCount
);
4113 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
4115 pStubMsg
->MemorySize
+= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->MaxCount
);
4117 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4119 return pCVStructFormat
->memory_size
+ pStubMsg
->MaxCount
* esize
;
4122 /***********************************************************************
4123 * NdrConformantVaryingStructFree [RPCRT4.@]
4125 void WINAPI
NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
4126 unsigned char *pMemory
,
4127 PFORMAT_STRING pFormat
)
4129 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4130 PFORMAT_STRING pCVArrayFormat
;
4133 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4135 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4136 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4138 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4139 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4143 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4144 pCVStructFormat
->offset_to_array_description
;
4145 switch (*pCVArrayFormat
)
4147 case RPC_FC_CVARRAY
:
4148 esize
= *(const WORD
*)(pCVArrayFormat
+2);
4150 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4151 pCVArrayFormat
+ 4, 0);
4152 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4155 case RPC_FC_C_CSTRING
:
4156 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
4157 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
4158 esize
= sizeof(char);
4159 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4160 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4161 pCVArrayFormat
+ 2, 0);
4163 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4165 case RPC_FC_C_WSTRING
:
4166 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
4167 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
4168 esize
= sizeof(WCHAR
);
4169 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4170 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4171 pCVArrayFormat
+ 2, 0);
4173 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4176 ERR("invalid array format type %x\n", *pCVArrayFormat
);
4177 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4181 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4183 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4186 #include "pshpack1.h"
4190 unsigned char alignment
;
4191 unsigned short total_size
;
4192 } NDR_SMFARRAY_FORMAT
;
4197 unsigned char alignment
;
4198 unsigned long total_size
;
4199 } NDR_LGFARRAY_FORMAT
;
4200 #include "poppack.h"
4202 /***********************************************************************
4203 * NdrFixedArrayMarshall [RPCRT4.@]
4205 unsigned char * WINAPI
NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4206 unsigned char *pMemory
,
4207 PFORMAT_STRING pFormat
)
4209 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4210 unsigned long total_size
;
4212 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4214 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4215 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4217 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4218 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4222 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4224 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4226 total_size
= pSmFArrayFormat
->total_size
;
4227 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4231 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4232 total_size
= pLgFArrayFormat
->total_size
;
4233 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4236 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4237 safe_copy_to_buffer(pStubMsg
, pMemory
, total_size
);
4239 pFormat
= EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4244 /***********************************************************************
4245 * NdrFixedArrayUnmarshall [RPCRT4.@]
4247 unsigned char * WINAPI
NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4248 unsigned char **ppMemory
,
4249 PFORMAT_STRING pFormat
,
4250 unsigned char fMustAlloc
)
4252 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4253 unsigned long total_size
;
4254 unsigned char *saved_buffer
;
4256 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4258 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4259 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4261 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4262 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4266 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4268 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4270 total_size
= pSmFArrayFormat
->total_size
;
4271 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4275 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4276 total_size
= pLgFArrayFormat
->total_size
;
4277 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4281 *ppMemory
= NdrAllocate(pStubMsg
, total_size
);
4284 if (!pStubMsg
->IsClient
&& !*ppMemory
)
4285 /* for servers, we just point straight into the RPC buffer */
4286 *ppMemory
= pStubMsg
->Buffer
;
4289 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4290 safe_buffer_increment(pStubMsg
, total_size
);
4291 pFormat
= EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4293 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
4294 if (*ppMemory
!= saved_buffer
)
4295 memcpy(*ppMemory
, saved_buffer
, total_size
);
4300 /***********************************************************************
4301 * NdrFixedArrayBufferSize [RPCRT4.@]
4303 void WINAPI
NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4304 unsigned char *pMemory
,
4305 PFORMAT_STRING pFormat
)
4307 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4308 unsigned long total_size
;
4310 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4312 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4313 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4315 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4316 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4320 ALIGN_LENGTH(pStubMsg
->BufferLength
, pSmFArrayFormat
->alignment
+ 1);
4322 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4324 total_size
= pSmFArrayFormat
->total_size
;
4325 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4329 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4330 total_size
= pLgFArrayFormat
->total_size
;
4331 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4333 safe_buffer_length_increment(pStubMsg
, total_size
);
4335 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4338 /***********************************************************************
4339 * NdrFixedArrayMemorySize [RPCRT4.@]
4341 ULONG WINAPI
NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4342 PFORMAT_STRING pFormat
)
4344 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4347 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4349 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4350 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4352 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4353 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4357 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4359 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4361 total_size
= pSmFArrayFormat
->total_size
;
4362 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4366 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4367 total_size
= pLgFArrayFormat
->total_size
;
4368 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4370 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4371 safe_buffer_increment(pStubMsg
, total_size
);
4372 pStubMsg
->MemorySize
+= total_size
;
4374 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4379 /***********************************************************************
4380 * NdrFixedArrayFree [RPCRT4.@]
4382 void WINAPI
NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4383 unsigned char *pMemory
,
4384 PFORMAT_STRING pFormat
)
4386 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4388 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4390 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4391 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4393 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4394 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4398 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4399 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4402 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4403 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4406 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4409 /***********************************************************************
4410 * NdrVaryingArrayMarshall [RPCRT4.@]
4412 unsigned char * WINAPI
NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4413 unsigned char *pMemory
,
4414 PFORMAT_STRING pFormat
)
4416 unsigned char alignment
;
4417 DWORD elements
, esize
;
4420 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4422 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4423 (pFormat
[0] != RPC_FC_LGVARRAY
))
4425 ERR("invalid format type %x\n", pFormat
[0]);
4426 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4430 alignment
= pFormat
[1] + 1;
4432 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4435 pFormat
+= sizeof(WORD
);
4436 elements
= *(const WORD
*)pFormat
;
4437 pFormat
+= sizeof(WORD
);
4442 pFormat
+= sizeof(DWORD
);
4443 elements
= *(const DWORD
*)pFormat
;
4444 pFormat
+= sizeof(DWORD
);
4447 esize
= *(const WORD
*)pFormat
;
4448 pFormat
+= sizeof(WORD
);
4450 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4451 if ((pStubMsg
->ActualCount
> elements
) ||
4452 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4454 RpcRaiseException(RPC_S_INVALID_BOUND
);
4458 WriteVariance(pStubMsg
);
4460 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
4462 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4463 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4464 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
4466 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4471 /***********************************************************************
4472 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4474 unsigned char * WINAPI
NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4475 unsigned char **ppMemory
,
4476 PFORMAT_STRING pFormat
,
4477 unsigned char fMustAlloc
)
4479 unsigned char alignment
;
4480 DWORD size
, elements
, esize
;
4482 unsigned char *saved_buffer
;
4485 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4487 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4488 (pFormat
[0] != RPC_FC_LGVARRAY
))
4490 ERR("invalid format type %x\n", pFormat
[0]);
4491 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4495 alignment
= pFormat
[1] + 1;
4497 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4500 size
= *(const WORD
*)pFormat
;
4501 pFormat
+= sizeof(WORD
);
4502 elements
= *(const WORD
*)pFormat
;
4503 pFormat
+= sizeof(WORD
);
4508 size
= *(const DWORD
*)pFormat
;
4509 pFormat
+= sizeof(DWORD
);
4510 elements
= *(const DWORD
*)pFormat
;
4511 pFormat
+= sizeof(DWORD
);
4514 esize
= *(const WORD
*)pFormat
;
4515 pFormat
+= sizeof(WORD
);
4517 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
4519 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4521 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4522 offset
= pStubMsg
->Offset
;
4524 if (!*ppMemory
|| fMustAlloc
)
4525 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4526 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4527 safe_buffer_increment(pStubMsg
, bufsize
);
4529 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4531 memcpy(*ppMemory
+ offset
, saved_buffer
, bufsize
);
4536 /***********************************************************************
4537 * NdrVaryingArrayBufferSize [RPCRT4.@]
4539 void WINAPI
NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4540 unsigned char *pMemory
,
4541 PFORMAT_STRING pFormat
)
4543 unsigned char alignment
;
4544 DWORD elements
, esize
;
4546 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4548 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4549 (pFormat
[0] != RPC_FC_LGVARRAY
))
4551 ERR("invalid format type %x\n", pFormat
[0]);
4552 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4556 alignment
= pFormat
[1] + 1;
4558 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4561 pFormat
+= sizeof(WORD
);
4562 elements
= *(const WORD
*)pFormat
;
4563 pFormat
+= sizeof(WORD
);
4568 pFormat
+= sizeof(DWORD
);
4569 elements
= *(const DWORD
*)pFormat
;
4570 pFormat
+= sizeof(DWORD
);
4573 esize
= *(const WORD
*)pFormat
;
4574 pFormat
+= sizeof(WORD
);
4576 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4577 if ((pStubMsg
->ActualCount
> elements
) ||
4578 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4580 RpcRaiseException(RPC_S_INVALID_BOUND
);
4584 SizeVariance(pStubMsg
);
4586 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
4588 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
4590 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4593 /***********************************************************************
4594 * NdrVaryingArrayMemorySize [RPCRT4.@]
4596 ULONG WINAPI
NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4597 PFORMAT_STRING pFormat
)
4599 unsigned char alignment
;
4600 DWORD size
, elements
, esize
;
4602 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4604 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4605 (pFormat
[0] != RPC_FC_LGVARRAY
))
4607 ERR("invalid format type %x\n", pFormat
[0]);
4608 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4612 alignment
= pFormat
[1] + 1;
4614 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4617 size
= *(const WORD
*)pFormat
;
4618 pFormat
+= sizeof(WORD
);
4619 elements
= *(const WORD
*)pFormat
;
4620 pFormat
+= sizeof(WORD
);
4625 size
= *(const DWORD
*)pFormat
;
4626 pFormat
+= sizeof(DWORD
);
4627 elements
= *(const DWORD
*)pFormat
;
4628 pFormat
+= sizeof(DWORD
);
4631 esize
= *(const WORD
*)pFormat
;
4632 pFormat
+= sizeof(WORD
);
4634 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
4636 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4638 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
4639 pStubMsg
->MemorySize
+= size
;
4641 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4643 return pStubMsg
->MemorySize
;
4646 /***********************************************************************
4647 * NdrVaryingArrayFree [RPCRT4.@]
4649 void WINAPI
NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4650 unsigned char *pMemory
,
4651 PFORMAT_STRING pFormat
)
4653 unsigned char alignment
;
4656 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4658 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4659 (pFormat
[0] != RPC_FC_LGVARRAY
))
4661 ERR("invalid format type %x\n", pFormat
[0]);
4662 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4666 alignment
= pFormat
[1] + 1;
4668 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4671 pFormat
+= sizeof(WORD
);
4672 elements
= *(const WORD
*)pFormat
;
4673 pFormat
+= sizeof(WORD
);
4678 pFormat
+= sizeof(DWORD
);
4679 elements
= *(const DWORD
*)pFormat
;
4680 pFormat
+= sizeof(DWORD
);
4683 pFormat
+= sizeof(WORD
);
4685 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4686 if ((pStubMsg
->ActualCount
> elements
) ||
4687 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4689 RpcRaiseException(RPC_S_INVALID_BOUND
);
4693 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4696 static ULONG
get_discriminant(unsigned char fc
, const unsigned char *pMemory
)
4704 return *(const UCHAR
*)pMemory
;
4709 return *(const USHORT
*)pMemory
;
4713 return *(const ULONG
*)pMemory
;
4715 FIXME("Unhandled base type: 0x%02x\n", fc
);
4720 static PFORMAT_STRING
get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg
,
4721 unsigned long discriminant
,
4722 PFORMAT_STRING pFormat
)
4724 unsigned short num_arms
, arm
, type
;
4726 num_arms
= *(const SHORT
*)pFormat
& 0x0fff;
4728 for(arm
= 0; arm
< num_arms
; arm
++)
4730 if(discriminant
== *(const ULONG
*)pFormat
)
4738 type
= *(const unsigned short*)pFormat
;
4739 TRACE("type %04x\n", type
);
4740 if(arm
== num_arms
) /* default arm extras */
4744 ERR("no arm for 0x%lx and no default case\n", discriminant
);
4745 RpcRaiseException(RPC_S_INVALID_TAG
);
4750 TRACE("falling back to empty default case for 0x%lx\n", discriminant
);
4757 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
, ULONG discriminant
, PFORMAT_STRING pFormat
)
4759 unsigned short type
;
4763 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4767 type
= *(const unsigned short*)pFormat
;
4768 if((type
& 0xff00) == 0x8000)
4770 unsigned char basetype
= LOBYTE(type
);
4771 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &basetype
);
4775 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4776 NDR_MARSHALL m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
4779 unsigned char *saved_buffer
= NULL
;
4780 int pointer_buffer_mark_set
= 0;
4787 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
4788 saved_buffer
= pStubMsg
->Buffer
;
4789 if (pStubMsg
->PointerBufferMark
)
4791 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4792 pStubMsg
->PointerBufferMark
= NULL
;
4793 pointer_buffer_mark_set
= 1;
4796 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
4798 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char **)pMemory
, desc
);
4799 if (pointer_buffer_mark_set
)
4801 STD_OVERFLOW_CHECK(pStubMsg
);
4802 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4803 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
4805 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
4806 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
4807 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4809 pStubMsg
->Buffer
= saved_buffer
+ 4;
4813 m(pStubMsg
, pMemory
, desc
);
4816 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4821 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4822 unsigned char **ppMemory
,
4824 PFORMAT_STRING pFormat
,
4825 unsigned char fMustAlloc
)
4827 unsigned short type
;
4831 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4835 type
= *(const unsigned short*)pFormat
;
4836 if((type
& 0xff00) == 0x8000)
4838 unsigned char basetype
= LOBYTE(type
);
4839 return NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &basetype
, FALSE
);
4843 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4844 NDR_UNMARSHALL m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
4847 unsigned char *saved_buffer
= NULL
;
4848 int pointer_buffer_mark_set
= 0;
4855 **(void***)ppMemory
= NULL
;
4856 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4857 saved_buffer
= pStubMsg
->Buffer
;
4858 if (pStubMsg
->PointerBufferMark
)
4860 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4861 pStubMsg
->PointerBufferMark
= NULL
;
4862 pointer_buffer_mark_set
= 1;
4865 pStubMsg
->Buffer
+= 4; /* for pointer ID */
4867 if (saved_buffer
+ 4 > pStubMsg
->BufferEnd
)
4869 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
4870 saved_buffer
, pStubMsg
->BufferEnd
);
4871 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4874 PointerUnmarshall(pStubMsg
, saved_buffer
, *(unsigned char ***)ppMemory
, **(unsigned char ***)ppMemory
, desc
, fMustAlloc
);
4875 if (pointer_buffer_mark_set
)
4877 STD_OVERFLOW_CHECK(pStubMsg
);
4878 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4879 pStubMsg
->Buffer
= saved_buffer
+ 4;
4883 m(pStubMsg
, ppMemory
, desc
, fMustAlloc
);
4886 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4891 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg
,
4892 unsigned char *pMemory
,
4894 PFORMAT_STRING pFormat
)
4896 unsigned short type
;
4900 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4904 type
= *(const unsigned short*)pFormat
;
4905 if((type
& 0xff00) == 0x8000)
4907 unsigned char basetype
= LOBYTE(type
);
4908 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &basetype
);
4912 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4913 NDR_BUFFERSIZE m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
4922 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
4923 safe_buffer_length_increment(pStubMsg
, 4); /* for pointer ID */
4924 if (!pStubMsg
->IgnoreEmbeddedPointers
)
4926 int saved_buffer_length
= pStubMsg
->BufferLength
;
4927 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4928 pStubMsg
->PointerLength
= 0;
4929 if(!pStubMsg
->BufferLength
)
4930 ERR("BufferLength == 0??\n");
4931 PointerBufferSize(pStubMsg
, *(unsigned char **)pMemory
, desc
);
4932 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4933 pStubMsg
->BufferLength
= saved_buffer_length
;
4937 m(pStubMsg
, pMemory
, desc
);
4940 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
4944 static ULONG
union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg
,
4946 PFORMAT_STRING pFormat
)
4948 unsigned short type
, size
;
4950 size
= *(const unsigned short*)pFormat
;
4951 pStubMsg
->Memory
+= size
;
4954 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4958 type
= *(const unsigned short*)pFormat
;
4959 if((type
& 0xff00) == 0x8000)
4961 return NdrBaseTypeMemorySize(pStubMsg
, pFormat
);
4965 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4966 NDR_MEMORYSIZE m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
4967 unsigned char *saved_buffer
;
4976 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4977 saved_buffer
= pStubMsg
->Buffer
;
4978 safe_buffer_increment(pStubMsg
, 4);
4979 ALIGN_LENGTH(pStubMsg
->MemorySize
, 4);
4980 pStubMsg
->MemorySize
+= 4;
4981 if (!pStubMsg
->IgnoreEmbeddedPointers
)
4982 PointerMemorySize(pStubMsg
, saved_buffer
, pFormat
);
4985 return m(pStubMsg
, desc
);
4988 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4991 TRACE("size %d\n", size
);
4995 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg
,
4996 unsigned char *pMemory
,
4998 PFORMAT_STRING pFormat
)
5000 unsigned short type
;
5004 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
5008 type
= *(const unsigned short*)pFormat
;
5009 if((type
& 0xff00) != 0x8000)
5011 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
5012 NDR_FREE m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
5021 PointerFree(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5024 m(pStubMsg
, pMemory
, desc
);
5027 else FIXME("no freer for embedded type %02x\n", *desc
);
5031 /***********************************************************************
5032 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5034 unsigned char * WINAPI
NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5035 unsigned char *pMemory
,
5036 PFORMAT_STRING pFormat
)
5038 unsigned char switch_type
;
5039 unsigned char increment
;
5042 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5045 switch_type
= *pFormat
& 0xf;
5046 increment
= (*pFormat
& 0xf0) >> 4;
5049 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, increment
);
5051 switch_value
= get_discriminant(switch_type
, pMemory
);
5052 TRACE("got switch value 0x%x\n", switch_value
);
5054 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &switch_type
);
5055 pMemory
+= increment
;
5057 return union_arm_marshall(pStubMsg
, pMemory
, switch_value
, pFormat
);
5060 /***********************************************************************
5061 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5063 unsigned char * WINAPI
NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5064 unsigned char **ppMemory
,
5065 PFORMAT_STRING pFormat
,
5066 unsigned char fMustAlloc
)
5068 unsigned char switch_type
;
5069 unsigned char increment
;
5071 unsigned short size
;
5072 unsigned char *pMemoryArm
;
5074 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5077 switch_type
= *pFormat
& 0xf;
5078 increment
= (*pFormat
& 0xf0) >> 4;
5081 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
5082 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
5083 TRACE("got switch value 0x%x\n", switch_value
);
5085 size
= *(const unsigned short*)pFormat
+ increment
;
5086 if(!*ppMemory
|| fMustAlloc
)
5087 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5089 NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &switch_type
, FALSE
);
5090 pMemoryArm
= *ppMemory
+ increment
;
5092 return union_arm_unmarshall(pStubMsg
, &pMemoryArm
, switch_value
, pFormat
, fMustAlloc
);
5095 /***********************************************************************
5096 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5098 void WINAPI
NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5099 unsigned char *pMemory
,
5100 PFORMAT_STRING pFormat
)
5102 unsigned char switch_type
;
5103 unsigned char increment
;
5106 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5109 switch_type
= *pFormat
& 0xf;
5110 increment
= (*pFormat
& 0xf0) >> 4;
5113 ALIGN_LENGTH(pStubMsg
->BufferLength
, increment
);
5114 switch_value
= get_discriminant(switch_type
, pMemory
);
5115 TRACE("got switch value 0x%x\n", switch_value
);
5117 /* Add discriminant size */
5118 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&switch_value
, &switch_type
);
5119 pMemory
+= increment
;
5121 union_arm_buffer_size(pStubMsg
, pMemory
, switch_value
, pFormat
);
5124 /***********************************************************************
5125 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5127 ULONG WINAPI
NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5128 PFORMAT_STRING pFormat
)
5130 unsigned char switch_type
;
5131 unsigned char increment
;
5134 switch_type
= *pFormat
& 0xf;
5135 increment
= (*pFormat
& 0xf0) >> 4;
5138 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
5139 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
5140 TRACE("got switch value 0x%x\n", switch_value
);
5142 pStubMsg
->Memory
+= increment
;
5144 return increment
+ union_arm_memory_size(pStubMsg
, switch_value
, pFormat
+ *(const SHORT
*)pFormat
);
5147 /***********************************************************************
5148 * NdrEncapsulatedUnionFree [RPCRT4.@]
5150 void WINAPI
NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
5151 unsigned char *pMemory
,
5152 PFORMAT_STRING pFormat
)
5154 unsigned char switch_type
;
5155 unsigned char increment
;
5158 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5161 switch_type
= *pFormat
& 0xf;
5162 increment
= (*pFormat
& 0xf0) >> 4;
5165 switch_value
= get_discriminant(switch_type
, pMemory
);
5166 TRACE("got switch value 0x%x\n", switch_value
);
5168 pMemory
+= increment
;
5170 return union_arm_free(pStubMsg
, pMemory
, switch_value
, pFormat
);
5173 /***********************************************************************
5174 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5176 unsigned char * WINAPI
NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5177 unsigned char *pMemory
,
5178 PFORMAT_STRING pFormat
)
5180 unsigned char switch_type
;
5182 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5185 switch_type
= *pFormat
;
5188 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5189 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5190 /* Marshall discriminant */
5191 NdrBaseTypeMarshall(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
5193 return union_arm_marshall(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5196 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg
,
5197 PFORMAT_STRING
*ppFormat
)
5199 long discriminant
= 0;
5209 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5218 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5219 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5227 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
5228 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5233 FIXME("Unhandled base type: 0x%02x\n", **ppFormat
);
5237 if (pStubMsg
->fHasNewCorrDesc
)
5241 return discriminant
;
5244 /**********************************************************************
5245 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5247 unsigned char * WINAPI
NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5248 unsigned char **ppMemory
,
5249 PFORMAT_STRING pFormat
,
5250 unsigned char fMustAlloc
)
5253 unsigned short size
;
5255 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5258 /* Unmarshall discriminant */
5259 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
5260 TRACE("unmarshalled discriminant %lx\n", discriminant
);
5262 pFormat
+= *(const SHORT
*)pFormat
;
5264 size
= *(const unsigned short*)pFormat
;
5266 if(!*ppMemory
|| fMustAlloc
)
5267 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5269 return union_arm_unmarshall(pStubMsg
, ppMemory
, discriminant
, pFormat
, fMustAlloc
);
5272 /***********************************************************************
5273 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5275 void WINAPI
NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5276 unsigned char *pMemory
,
5277 PFORMAT_STRING pFormat
)
5279 unsigned char switch_type
;
5281 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5284 switch_type
= *pFormat
;
5287 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5288 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5289 /* Add discriminant size */
5290 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
5292 union_arm_buffer_size(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5295 /***********************************************************************
5296 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5298 ULONG WINAPI
NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5299 PFORMAT_STRING pFormat
)
5304 /* Unmarshall discriminant */
5305 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
5306 TRACE("unmarshalled discriminant 0x%x\n", discriminant
);
5308 return union_arm_memory_size(pStubMsg
, discriminant
, pFormat
+ *(const SHORT
*)pFormat
);
5311 /***********************************************************************
5312 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5314 void WINAPI
NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
5315 unsigned char *pMemory
,
5316 PFORMAT_STRING pFormat
)
5318 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5322 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5323 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5325 return union_arm_free(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5328 /***********************************************************************
5329 * NdrByteCountPointerMarshall [RPCRT4.@]
5331 unsigned char * WINAPI
NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5332 unsigned char *pMemory
,
5333 PFORMAT_STRING pFormat
)
5339 /***********************************************************************
5340 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5342 unsigned char * WINAPI
NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5343 unsigned char **ppMemory
,
5344 PFORMAT_STRING pFormat
,
5345 unsigned char fMustAlloc
)
5351 /***********************************************************************
5352 * NdrByteCountPointerBufferSize [RPCRT4.@]
5354 void WINAPI
NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5355 unsigned char *pMemory
,
5356 PFORMAT_STRING pFormat
)
5361 /***********************************************************************
5362 * NdrByteCountPointerMemorySize [RPCRT4.@]
5364 ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5365 PFORMAT_STRING pFormat
)
5371 /***********************************************************************
5372 * NdrByteCountPointerFree [RPCRT4.@]
5374 void WINAPI
NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
5375 unsigned char *pMemory
,
5376 PFORMAT_STRING pFormat
)
5381 /***********************************************************************
5382 * NdrXmitOrRepAsMarshall [RPCRT4.@]
5384 unsigned char * WINAPI
NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5385 unsigned char *pMemory
,
5386 PFORMAT_STRING pFormat
)
5392 /***********************************************************************
5393 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
5395 unsigned char * WINAPI
NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5396 unsigned char **ppMemory
,
5397 PFORMAT_STRING pFormat
,
5398 unsigned char fMustAlloc
)
5404 /***********************************************************************
5405 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
5407 void WINAPI
NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5408 unsigned char *pMemory
,
5409 PFORMAT_STRING pFormat
)
5414 /***********************************************************************
5415 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
5417 ULONG WINAPI
NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5418 PFORMAT_STRING pFormat
)
5424 /***********************************************************************
5425 * NdrXmitOrRepAsFree [RPCRT4.@]
5427 void WINAPI
NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg
,
5428 unsigned char *pMemory
,
5429 PFORMAT_STRING pFormat
)
5434 #include "pshpack1.h"
5438 unsigned char flags_type
; /* flags in upper nibble, type in lower nibble */
5442 #include "poppack.h"
5444 /***********************************************************************
5445 * NdrRangeMarshall [internal]
5447 unsigned char *WINAPI
NdrRangeMarshall(
5448 PMIDL_STUB_MESSAGE pStubMsg
,
5449 unsigned char *pMemory
,
5450 PFORMAT_STRING pFormat
)
5452 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5453 unsigned char base_type
;
5455 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5457 if (pRange
->type
!= RPC_FC_RANGE
)
5459 ERR("invalid format type %x\n", pRange
->type
);
5460 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5464 base_type
= pRange
->flags_type
& 0xf;
5466 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &base_type
);
5469 /***********************************************************************
5470 * NdrRangeUnmarshall
5472 unsigned char *WINAPI
NdrRangeUnmarshall(
5473 PMIDL_STUB_MESSAGE pStubMsg
,
5474 unsigned char **ppMemory
,
5475 PFORMAT_STRING pFormat
,
5476 unsigned char fMustAlloc
)
5478 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5479 unsigned char base_type
;
5481 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
5483 if (pRange
->type
!= RPC_FC_RANGE
)
5485 ERR("invalid format type %x\n", pRange
->type
);
5486 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5489 base_type
= pRange
->flags_type
& 0xf;
5491 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5492 base_type
, pRange
->low_value
, pRange
->high_value
);
5494 #define RANGE_UNMARSHALL(type, format_spec) \
5497 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5498 if (fMustAlloc || !*ppMemory) \
5499 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5500 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
5502 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
5503 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
5504 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
5506 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5507 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5509 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5510 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5511 (type)pRange->high_value); \
5512 RpcRaiseException(RPC_S_INVALID_BOUND); \
5515 TRACE("*ppMemory: %p\n", *ppMemory); \
5516 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5517 pStubMsg->Buffer += sizeof(type); \
5524 RANGE_UNMARSHALL(UCHAR
, "%d");
5525 TRACE("value: 0x%02x\n", **(UCHAR
**)ppMemory
);
5529 RANGE_UNMARSHALL(CHAR
, "%u");
5530 TRACE("value: 0x%02x\n", **(UCHAR
**)ppMemory
);
5532 case RPC_FC_WCHAR
: /* FIXME: valid? */
5534 RANGE_UNMARSHALL(USHORT
, "%u");
5535 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5538 RANGE_UNMARSHALL(SHORT
, "%d");
5539 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5542 RANGE_UNMARSHALL(LONG
, "%d");
5543 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5546 RANGE_UNMARSHALL(ULONG
, "%u");
5547 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5551 FIXME("Unhandled enum type\n");
5553 case RPC_FC_ERROR_STATUS_T
: /* FIXME: valid? */
5558 ERR("invalid range base type: 0x%02x\n", base_type
);
5559 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5565 /***********************************************************************
5566 * NdrRangeBufferSize [internal]
5568 void WINAPI
NdrRangeBufferSize(
5569 PMIDL_STUB_MESSAGE pStubMsg
,
5570 unsigned char *pMemory
,
5571 PFORMAT_STRING pFormat
)
5573 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5574 unsigned char base_type
;
5576 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5578 if (pRange
->type
!= RPC_FC_RANGE
)
5580 ERR("invalid format type %x\n", pRange
->type
);
5581 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5583 base_type
= pRange
->flags_type
& 0xf;
5585 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &base_type
);
5588 /***********************************************************************
5589 * NdrRangeMemorySize [internal]
5591 ULONG WINAPI
NdrRangeMemorySize(
5592 PMIDL_STUB_MESSAGE pStubMsg
,
5593 PFORMAT_STRING pFormat
)
5595 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5596 unsigned char base_type
;
5598 if (pRange
->type
!= RPC_FC_RANGE
)
5600 ERR("invalid format type %x\n", pRange
->type
);
5601 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5604 base_type
= pRange
->flags_type
& 0xf;
5606 return NdrBaseTypeMemorySize(pStubMsg
, &base_type
);
5609 /***********************************************************************
5610 * NdrRangeFree [internal]
5612 void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg
,
5613 unsigned char *pMemory
,
5614 PFORMAT_STRING pFormat
)
5616 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5621 /***********************************************************************
5622 * NdrBaseTypeMarshall [internal]
5624 static unsigned char *WINAPI
NdrBaseTypeMarshall(
5625 PMIDL_STUB_MESSAGE pStubMsg
,
5626 unsigned char *pMemory
,
5627 PFORMAT_STRING pFormat
)
5629 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5637 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(UCHAR
));
5638 TRACE("value: 0x%02x\n", *(UCHAR
*)pMemory
);
5643 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(USHORT
));
5644 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(USHORT
));
5645 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
5649 case RPC_FC_ERROR_STATUS_T
:
5651 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(ULONG
));
5652 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONG
));
5653 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
5656 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(float));
5657 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
5660 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(double));
5661 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
5664 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(ULONGLONG
));
5665 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONGLONG
));
5666 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
5669 /* only 16-bits on the wire, so do a sanity check */
5670 if (*(UINT
*)pMemory
> SHRT_MAX
)
5671 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
5672 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(USHORT
));
5673 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5674 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5675 *(USHORT
*)pStubMsg
->Buffer
= *(UINT
*)pMemory
;
5676 pStubMsg
->Buffer
+= sizeof(USHORT
);
5677 TRACE("value: 0x%04x\n", *(UINT
*)pMemory
);
5682 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5685 /* FIXME: what is the correct return value? */
5689 /***********************************************************************
5690 * NdrBaseTypeUnmarshall [internal]
5692 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(
5693 PMIDL_STUB_MESSAGE pStubMsg
,
5694 unsigned char **ppMemory
,
5695 PFORMAT_STRING pFormat
,
5696 unsigned char fMustAlloc
)
5698 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
5700 #define BASE_TYPE_UNMARSHALL(type) \
5701 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5702 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
5704 *ppMemory = pStubMsg->Buffer; \
5705 TRACE("*ppMemory: %p\n", *ppMemory); \
5710 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5711 TRACE("*ppMemory: %p\n", *ppMemory); \
5712 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5714 pStubMsg->Buffer += sizeof(type);
5722 BASE_TYPE_UNMARSHALL(UCHAR
);
5723 TRACE("value: 0x%02x\n", **(UCHAR
**)ppMemory
);
5728 BASE_TYPE_UNMARSHALL(USHORT
);
5729 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5733 case RPC_FC_ERROR_STATUS_T
:
5735 BASE_TYPE_UNMARSHALL(ULONG
);
5736 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5739 BASE_TYPE_UNMARSHALL(float);
5740 TRACE("value: %f\n", **(float **)ppMemory
);
5743 BASE_TYPE_UNMARSHALL(double);
5744 TRACE("value: %f\n", **(double **)ppMemory
);
5747 BASE_TYPE_UNMARSHALL(ULONGLONG
);
5748 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG
**)ppMemory
));
5751 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5752 if (fMustAlloc
|| !*ppMemory
)
5753 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT
));
5754 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > pStubMsg
->BufferEnd
)
5755 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5756 TRACE("*ppMemory: %p\n", *ppMemory
);
5757 /* 16-bits on the wire, but int in memory */
5758 **(UINT
**)ppMemory
= *(USHORT
*)pStubMsg
->Buffer
;
5759 pStubMsg
->Buffer
+= sizeof(USHORT
);
5760 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
5765 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5767 #undef BASE_TYPE_UNMARSHALL
5769 /* FIXME: what is the correct return value? */
5774 /***********************************************************************
5775 * NdrBaseTypeBufferSize [internal]
5777 static void WINAPI
NdrBaseTypeBufferSize(
5778 PMIDL_STUB_MESSAGE pStubMsg
,
5779 unsigned char *pMemory
,
5780 PFORMAT_STRING pFormat
)
5782 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5790 safe_buffer_length_increment(pStubMsg
, sizeof(UCHAR
));
5796 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(USHORT
));
5797 safe_buffer_length_increment(pStubMsg
, sizeof(USHORT
));
5802 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONG
));
5803 safe_buffer_length_increment(pStubMsg
, sizeof(ULONG
));
5806 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(float));
5807 safe_buffer_length_increment(pStubMsg
, sizeof(float));
5810 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(double));
5811 safe_buffer_length_increment(pStubMsg
, sizeof(double));
5814 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONGLONG
));
5815 safe_buffer_length_increment(pStubMsg
, sizeof(ULONGLONG
));
5817 case RPC_FC_ERROR_STATUS_T
:
5818 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(error_status_t
));
5819 safe_buffer_length_increment(pStubMsg
, sizeof(error_status_t
));
5824 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5828 /***********************************************************************
5829 * NdrBaseTypeMemorySize [internal]
5831 static ULONG WINAPI
NdrBaseTypeMemorySize(
5832 PMIDL_STUB_MESSAGE pStubMsg
,
5833 PFORMAT_STRING pFormat
)
5835 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg
, *pFormat
);
5843 safe_buffer_increment(pStubMsg
, sizeof(UCHAR
));
5844 pStubMsg
->MemorySize
+= sizeof(UCHAR
);
5845 return sizeof(UCHAR
);
5849 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
5850 pStubMsg
->MemorySize
+= sizeof(USHORT
);
5851 return sizeof(USHORT
);
5855 safe_buffer_increment(pStubMsg
, sizeof(ULONG
));
5856 pStubMsg
->MemorySize
+= sizeof(ULONG
);
5857 return sizeof(ULONG
);
5859 safe_buffer_increment(pStubMsg
, sizeof(float));
5860 pStubMsg
->MemorySize
+= sizeof(float);
5861 return sizeof(float);
5863 safe_buffer_increment(pStubMsg
, sizeof(double));
5864 pStubMsg
->MemorySize
+= sizeof(double);
5865 return sizeof(double);
5867 safe_buffer_increment(pStubMsg
, sizeof(ULONGLONG
));
5868 pStubMsg
->MemorySize
+= sizeof(ULONGLONG
);
5869 return sizeof(ULONGLONG
);
5870 case RPC_FC_ERROR_STATUS_T
:
5871 safe_buffer_increment(pStubMsg
, sizeof(error_status_t
));
5872 pStubMsg
->MemorySize
+= sizeof(error_status_t
);
5873 return sizeof(error_status_t
);
5875 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
5876 pStubMsg
->MemorySize
+= sizeof(UINT
);
5877 return sizeof(UINT
);
5879 pStubMsg
->MemorySize
+= sizeof(void *);
5880 return sizeof(void *);
5882 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5887 /***********************************************************************
5888 * NdrBaseTypeFree [internal]
5890 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg
,
5891 unsigned char *pMemory
,
5892 PFORMAT_STRING pFormat
)
5894 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5899 /***********************************************************************
5900 * NdrContextHandleBufferSize [internal]
5902 static void WINAPI
NdrContextHandleBufferSize(
5903 PMIDL_STUB_MESSAGE pStubMsg
,
5904 unsigned char *pMemory
,
5905 PFORMAT_STRING pFormat
)
5907 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5909 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
5911 ERR("invalid format type %x\n", *pFormat
);
5912 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5914 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
5915 safe_buffer_length_increment(pStubMsg
, cbNDRContext
);
5918 /***********************************************************************
5919 * NdrContextHandleMarshall [internal]
5921 static unsigned char *WINAPI
NdrContextHandleMarshall(
5922 PMIDL_STUB_MESSAGE pStubMsg
,
5923 unsigned char *pMemory
,
5924 PFORMAT_STRING pFormat
)
5926 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5928 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
5930 ERR("invalid format type %x\n", *pFormat
);
5931 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5934 if (pFormat
[1] & 0x80)
5935 NdrClientContextMarshall(pStubMsg
, *(NDR_CCONTEXT
**)pMemory
, FALSE
);
5937 NdrClientContextMarshall(pStubMsg
, (NDR_CCONTEXT
*)pMemory
, FALSE
);
5942 /***********************************************************************
5943 * NdrContextHandleUnmarshall [internal]
5945 static unsigned char *WINAPI
NdrContextHandleUnmarshall(
5946 PMIDL_STUB_MESSAGE pStubMsg
,
5947 unsigned char **ppMemory
,
5948 PFORMAT_STRING pFormat
,
5949 unsigned char fMustAlloc
)
5951 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
5953 ERR("invalid format type %x\n", *pFormat
);
5954 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5957 **(NDR_CCONTEXT
**)ppMemory
= NULL
;
5958 NdrClientContextUnmarshall(pStubMsg
, *(NDR_CCONTEXT
**)ppMemory
, pStubMsg
->RpcMsg
->Handle
);
5963 /***********************************************************************
5964 * NdrClientContextMarshall [RPCRT4.@]
5966 void WINAPI
NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5967 NDR_CCONTEXT ContextHandle
,
5970 TRACE("(%p, %p, %d)\n", pStubMsg
, ContextHandle
, fCheck
);
5972 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
5974 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5976 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
5977 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
5978 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5981 /* FIXME: what does fCheck do? */
5982 NDRCContextMarshall(ContextHandle
,
5985 pStubMsg
->Buffer
+= cbNDRContext
;
5988 /***********************************************************************
5989 * NdrClientContextUnmarshall [RPCRT4.@]
5991 void WINAPI
NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5992 NDR_CCONTEXT
* pContextHandle
,
5993 RPC_BINDING_HANDLE BindHandle
)
5995 TRACE("(%p, %p, %p)\n", pStubMsg
, pContextHandle
, BindHandle
);
5997 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5999 if (pStubMsg
->Buffer
+ cbNDRContext
> pStubMsg
->BufferEnd
)
6000 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6002 NDRCContextUnmarshall(pContextHandle
,
6005 pStubMsg
->RpcMsg
->DataRepresentation
);
6007 pStubMsg
->Buffer
+= cbNDRContext
;
6010 void WINAPI
NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6011 NDR_SCONTEXT ContextHandle
,
6012 NDR_RUNDOWN RundownRoutine
)
6014 TRACE("(%p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
);
6016 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6018 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6020 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6021 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6022 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6025 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
6026 pStubMsg
->Buffer
, RundownRoutine
, NULL
, 0);
6027 pStubMsg
->Buffer
+= cbNDRContext
;
6030 NDR_SCONTEXT WINAPI
NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
)
6032 NDR_SCONTEXT ContextHandle
;
6034 TRACE("(%p)\n", pStubMsg
);
6036 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6038 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6040 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6041 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6042 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6045 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
6047 pStubMsg
->RpcMsg
->DataRepresentation
,
6049 pStubMsg
->Buffer
+= cbNDRContext
;
6051 return ContextHandle
;
6054 void WINAPI
NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg
,
6055 unsigned char* pMemory
,
6056 PFORMAT_STRING pFormat
)
6058 FIXME("(%p, %p, %p): stub\n", pStubMsg
, pMemory
, pFormat
);
6061 NDR_SCONTEXT WINAPI
NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg
,
6062 PFORMAT_STRING pFormat
)
6064 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
6065 return NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
, NULL
,
6066 pStubMsg
->RpcMsg
->DataRepresentation
, NULL
, 0);
6069 void WINAPI
NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6070 NDR_SCONTEXT ContextHandle
,
6071 NDR_RUNDOWN RundownRoutine
,
6072 PFORMAT_STRING pFormat
)
6074 TRACE("(%p, %p, %p, %p)\n", pStubMsg
, ContextHandle
, RundownRoutine
, pFormat
);
6076 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6078 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6080 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6081 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6082 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6085 /* FIXME: do something with pFormat */
6086 NDRSContextMarshall2(pStubMsg
->RpcMsg
->Handle
, ContextHandle
,
6087 pStubMsg
->Buffer
, RundownRoutine
, NULL
, 0);
6088 pStubMsg
->Buffer
+= cbNDRContext
;
6091 NDR_SCONTEXT WINAPI
NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6092 PFORMAT_STRING pFormat
)
6094 NDR_SCONTEXT ContextHandle
;
6096 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
6098 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
6100 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
6102 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6103 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
6104 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
6107 /* FIXME: do something with pFormat */
6108 ContextHandle
= NDRSContextUnmarshall2(pStubMsg
->RpcMsg
->Handle
,
6110 pStubMsg
->RpcMsg
->DataRepresentation
,
6112 pStubMsg
->Buffer
+= cbNDRContext
;
6114 return ContextHandle
;