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
29 * - Checks for out-of-memory conditions
45 #include "wine/unicode.h"
46 #include "wine/rpcfc.h"
48 #include "wine/debug.h"
49 #include "wine/list.h"
51 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
54 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
55 (*((UINT32 *)(pchar)) = (uint32))
57 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
58 (*((UINT32 *)(pchar)))
60 /* these would work for i386 too, but less efficient */
61 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
62 (*(pchar) = LOBYTE(LOWORD(uint32)), \
63 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
64 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
65 *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
66 (uint32)) /* allow as r-value */
68 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
70 MAKEWORD(*(pchar), *((pchar)+1)), \
71 MAKEWORD(*((pchar)+2), *((pchar)+3))))
74 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
75 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
76 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
77 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
78 *(pchar) = HIBYTE(HIWORD(uint32)), \
79 (uint32)) /* allow as r-value */
81 #define BIG_ENDIAN_UINT32_READ(pchar) \
83 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
84 MAKEWORD(*((pchar)+1), *(pchar))))
86 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
87 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
88 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
89 # define NDR_LOCAL_UINT32_READ(pchar) \
90 BIG_ENDIAN_UINT32_READ(pchar)
92 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
93 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
94 # define NDR_LOCAL_UINT32_READ(pchar) \
95 LITTLE_ENDIAN_UINT32_READ(pchar)
98 /* _Align must be the desired alignment,
99 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
100 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
101 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
102 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
103 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
105 #define STD_OVERFLOW_CHECK(_Msg) do { \
106 TRACE("buffer=%d/%d\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
107 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
108 ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
111 #define NDR_TABLE_SIZE 128
112 #define NDR_TABLE_MASK 127
114 static unsigned char *WINAPI
NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
115 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
116 static void WINAPI
NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
117 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
118 static ULONG WINAPI
NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
120 static unsigned char *WINAPI
NdrContextHandleMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
121 static void WINAPI
NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
122 static unsigned char *WINAPI
NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
124 const NDR_MARSHALL NdrMarshaller
[NDR_TABLE_SIZE
] = {
126 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
127 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
128 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
129 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
133 NdrPointerMarshall
, NdrPointerMarshall
,
134 NdrPointerMarshall
, NdrPointerMarshall
,
136 NdrSimpleStructMarshall
, NdrSimpleStructMarshall
,
137 NdrConformantStructMarshall
, NdrConformantStructMarshall
,
138 NdrConformantVaryingStructMarshall
,
139 NdrComplexStructMarshall
,
141 NdrConformantArrayMarshall
,
142 NdrConformantVaryingArrayMarshall
,
143 NdrFixedArrayMarshall
, NdrFixedArrayMarshall
,
144 NdrVaryingArrayMarshall
, NdrVaryingArrayMarshall
,
145 NdrComplexArrayMarshall
,
147 NdrConformantStringMarshall
, 0, 0,
148 NdrConformantStringMarshall
,
149 NdrNonConformantStringMarshall
, 0, 0, 0,
151 NdrEncapsulatedUnionMarshall
,
152 NdrNonEncapsulatedUnionMarshall
,
153 NdrByteCountPointerMarshall
,
154 NdrXmitOrRepAsMarshall
, NdrXmitOrRepAsMarshall
,
156 NdrInterfacePointerMarshall
,
158 NdrContextHandleMarshall
,
161 NdrUserMarshalMarshall
,
166 const NDR_UNMARSHALL NdrUnmarshaller
[NDR_TABLE_SIZE
] = {
168 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
169 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
170 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
171 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
173 NdrBaseTypeUnmarshall
,
175 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
176 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
178 NdrSimpleStructUnmarshall
, NdrSimpleStructUnmarshall
,
179 NdrConformantStructUnmarshall
, NdrConformantStructUnmarshall
,
180 NdrConformantVaryingStructUnmarshall
,
181 NdrComplexStructUnmarshall
,
183 NdrConformantArrayUnmarshall
,
184 NdrConformantVaryingArrayUnmarshall
,
185 NdrFixedArrayUnmarshall
, NdrFixedArrayUnmarshall
,
186 NdrVaryingArrayUnmarshall
, NdrVaryingArrayUnmarshall
,
187 NdrComplexArrayUnmarshall
,
189 NdrConformantStringUnmarshall
, 0, 0,
190 NdrConformantStringUnmarshall
,
191 NdrNonConformantStringUnmarshall
, 0, 0, 0,
193 NdrEncapsulatedUnionUnmarshall
,
194 NdrNonEncapsulatedUnionUnmarshall
,
195 NdrByteCountPointerUnmarshall
,
196 NdrXmitOrRepAsUnmarshall
, NdrXmitOrRepAsUnmarshall
,
198 NdrInterfacePointerUnmarshall
,
200 NdrContextHandleUnmarshall
,
203 NdrUserMarshalUnmarshall
,
208 const NDR_BUFFERSIZE NdrBufferSizer
[NDR_TABLE_SIZE
] = {
210 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
211 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
212 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
213 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
215 NdrBaseTypeBufferSize
,
217 NdrPointerBufferSize
, NdrPointerBufferSize
,
218 NdrPointerBufferSize
, NdrPointerBufferSize
,
220 NdrSimpleStructBufferSize
, NdrSimpleStructBufferSize
,
221 NdrConformantStructBufferSize
, NdrConformantStructBufferSize
,
222 NdrConformantVaryingStructBufferSize
,
223 NdrComplexStructBufferSize
,
225 NdrConformantArrayBufferSize
,
226 NdrConformantVaryingArrayBufferSize
,
227 NdrFixedArrayBufferSize
, NdrFixedArrayBufferSize
,
228 NdrVaryingArrayBufferSize
, NdrVaryingArrayBufferSize
,
229 NdrComplexArrayBufferSize
,
231 NdrConformantStringBufferSize
, 0, 0,
232 NdrConformantStringBufferSize
,
233 NdrNonConformantStringBufferSize
, 0, 0, 0,
235 NdrEncapsulatedUnionBufferSize
,
236 NdrNonEncapsulatedUnionBufferSize
,
237 NdrByteCountPointerBufferSize
,
238 NdrXmitOrRepAsBufferSize
, NdrXmitOrRepAsBufferSize
,
240 NdrInterfacePointerBufferSize
,
242 NdrContextHandleBufferSize
,
245 NdrUserMarshalBufferSize
,
250 const NDR_MEMORYSIZE NdrMemorySizer
[NDR_TABLE_SIZE
] = {
252 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
253 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
254 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
255 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
257 NdrBaseTypeMemorySize
,
259 NdrPointerMemorySize
, NdrPointerMemorySize
,
260 NdrPointerMemorySize
, NdrPointerMemorySize
,
262 NdrSimpleStructMemorySize
, NdrSimpleStructMemorySize
,
263 NdrConformantStructMemorySize
, NdrConformantStructMemorySize
,
264 NdrConformantVaryingStructMemorySize
,
265 NdrComplexStructMemorySize
,
267 NdrConformantArrayMemorySize
,
268 NdrConformantVaryingArrayMemorySize
,
269 NdrFixedArrayMemorySize
, NdrFixedArrayMemorySize
,
270 NdrVaryingArrayMemorySize
, NdrVaryingArrayMemorySize
,
271 NdrComplexArrayMemorySize
,
273 NdrConformantStringMemorySize
, 0, 0,
274 NdrConformantStringMemorySize
,
275 NdrNonConformantStringMemorySize
, 0, 0, 0,
277 NdrEncapsulatedUnionMemorySize
,
278 NdrNonEncapsulatedUnionMemorySize
,
279 NdrByteCountPointerMemorySize
,
280 NdrXmitOrRepAsMemorySize
, NdrXmitOrRepAsMemorySize
,
282 NdrInterfacePointerMemorySize
,
287 NdrUserMarshalMemorySize
,
292 const NDR_FREE NdrFreer
[NDR_TABLE_SIZE
] = {
294 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
295 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
296 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
297 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
301 NdrPointerFree
, NdrPointerFree
,
302 NdrPointerFree
, NdrPointerFree
,
304 NdrSimpleStructFree
, NdrSimpleStructFree
,
305 NdrConformantStructFree
, NdrConformantStructFree
,
306 NdrConformantVaryingStructFree
,
307 NdrComplexStructFree
,
309 NdrConformantArrayFree
,
310 NdrConformantVaryingArrayFree
,
311 NdrFixedArrayFree
, NdrFixedArrayFree
,
312 NdrVaryingArrayFree
, NdrVaryingArrayFree
,
318 NdrEncapsulatedUnionFree
,
319 NdrNonEncapsulatedUnionFree
,
321 NdrXmitOrRepAsFree
, NdrXmitOrRepAsFree
,
323 NdrInterfacePointerFree
,
334 typedef struct _NDR_MEMORY_LIST
339 struct _NDR_MEMORY_LIST
*next
;
342 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
344 /***********************************************************************
345 * NdrAllocate [RPCRT4.@]
347 * Allocates a block of memory using pStubMsg->pfnAllocate.
350 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
351 * len [I] Size of memory block to allocate.
354 * The memory block of size len that was allocated.
357 * The memory block is always 8-byte aligned.
358 * If the function is unable to allocate memory an ERROR_OUTOFMEMORY
359 * exception is raised.
361 void * WINAPI
NdrAllocate(MIDL_STUB_MESSAGE
*pStubMsg
, size_t len
)
366 NDR_MEMORY_LIST
*mem_list
;
368 aligned_len
= ALIGNED_LENGTH(len
, 8);
369 adjusted_len
= aligned_len
+ sizeof(NDR_MEMORY_LIST
);
370 /* check for overflow */
371 if (adjusted_len
< len
)
373 ERR("overflow of adjusted_len %d, len %d\n", adjusted_len
, len
);
374 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
377 p
= pStubMsg
->pfnAllocate(adjusted_len
);
378 if (!p
) RpcRaiseException(ERROR_OUTOFMEMORY
);
380 mem_list
= (NDR_MEMORY_LIST
*)((char *)p
+ aligned_len
);
381 mem_list
->magic
= MEML_MAGIC
;
382 mem_list
->size
= aligned_len
;
383 mem_list
->reserved
= 0;
384 mem_list
->next
= pStubMsg
->pMemoryList
;
385 pStubMsg
->pMemoryList
= mem_list
;
391 static void WINAPI
NdrFree(MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *Pointer
)
393 TRACE("(%p, %p)\n", pStubMsg
, Pointer
);
395 pStubMsg
->pfnFree(Pointer
);
398 static inline BOOL
IsConformanceOrVariancePresent(PFORMAT_STRING pFormat
)
400 return (*(const ULONG
*)pFormat
!= -1);
403 static PFORMAT_STRING
ReadConformance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
)
405 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
406 if (pStubMsg
->Buffer
+ 4 > pStubMsg
->BufferEnd
)
407 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
408 pStubMsg
->MaxCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
409 pStubMsg
->Buffer
+= 4;
410 TRACE("unmarshalled conformance is %ld\n", pStubMsg
->MaxCount
);
411 if (pStubMsg
->fHasNewCorrDesc
)
417 static inline PFORMAT_STRING
ReadVariance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
, ULONG MaxValue
)
419 if (pFormat
&& !IsConformanceOrVariancePresent(pFormat
))
421 pStubMsg
->Offset
= 0;
422 pStubMsg
->ActualCount
= pStubMsg
->MaxCount
;
426 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
427 if (pStubMsg
->Buffer
+ 8 > pStubMsg
->BufferEnd
)
428 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
429 pStubMsg
->Offset
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
430 pStubMsg
->Buffer
+= 4;
431 TRACE("offset is %d\n", pStubMsg
->Offset
);
432 pStubMsg
->ActualCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
433 pStubMsg
->Buffer
+= 4;
434 TRACE("variance is %d\n", pStubMsg
->ActualCount
);
436 if ((pStubMsg
->ActualCount
> MaxValue
) ||
437 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> MaxValue
))
439 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
440 pStubMsg
->ActualCount
, pStubMsg
->Offset
, MaxValue
);
441 RpcRaiseException(RPC_S_INVALID_BOUND
);
446 if (pStubMsg
->fHasNewCorrDesc
)
452 /* writes the conformance value to the buffer */
453 static inline void WriteConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
455 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
456 if (pStubMsg
->Buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
457 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
458 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->MaxCount
);
459 pStubMsg
->Buffer
+= 4;
462 /* writes the variance values to the buffer */
463 static inline void WriteVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
465 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
466 if (pStubMsg
->Buffer
+ 8 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
467 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
468 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->Offset
);
469 pStubMsg
->Buffer
+= 4;
470 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->ActualCount
);
471 pStubMsg
->Buffer
+= 4;
474 /* requests buffer space for the conformance value */
475 static inline void SizeConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
477 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
478 if (pStubMsg
->BufferLength
+ 4 < pStubMsg
->BufferLength
)
479 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
480 pStubMsg
->BufferLength
+= 4;
483 /* requests buffer space for the variance values */
484 static inline void SizeVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
486 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
487 if (pStubMsg
->BufferLength
+ 8 < pStubMsg
->BufferLength
)
488 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
489 pStubMsg
->BufferLength
+= 8;
492 PFORMAT_STRING
ComputeConformanceOrVariance(
493 MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *pMemory
,
494 PFORMAT_STRING pFormat
, ULONG_PTR def
, ULONG_PTR
*pCount
)
496 BYTE dtype
= pFormat
[0] & 0xf;
497 short ofs
= *(const short *)&pFormat
[2];
501 if (!IsConformanceOrVariancePresent(pFormat
)) {
502 /* null descriptor */
507 switch (pFormat
[0] & 0xf0) {
508 case RPC_FC_NORMAL_CONFORMANCE
:
509 TRACE("normal conformance, ofs=%d\n", ofs
);
512 case RPC_FC_POINTER_CONFORMANCE
:
513 TRACE("pointer conformance, ofs=%d\n", ofs
);
514 ptr
= pStubMsg
->Memory
;
516 case RPC_FC_TOP_LEVEL_CONFORMANCE
:
517 TRACE("toplevel conformance, ofs=%d\n", ofs
);
518 if (pStubMsg
->StackTop
) {
519 ptr
= pStubMsg
->StackTop
;
522 /* -Os mode, *pCount is already set */
526 case RPC_FC_CONSTANT_CONFORMANCE
:
527 data
= ofs
| ((DWORD
)pFormat
[1] << 16);
528 TRACE("constant conformance, val=%d\n", data
);
531 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE
:
532 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs
);
533 if (pStubMsg
->StackTop
) {
534 ptr
= pStubMsg
->StackTop
;
542 FIXME("unknown conformance type %x\n", pFormat
[0] & 0xf0);
545 switch (pFormat
[1]) {
546 case RPC_FC_DEREFERENCE
:
547 ptr
= *(LPVOID
*)((char *)ptr
+ ofs
);
549 case RPC_FC_CALLBACK
:
551 unsigned char *old_stack_top
= pStubMsg
->StackTop
;
552 pStubMsg
->StackTop
= ptr
;
554 /* ofs is index into StubDesc->apfnExprEval */
555 TRACE("callback conformance into apfnExprEval[%d]\n", ofs
);
556 pStubMsg
->StubDesc
->apfnExprEval
[ofs
](pStubMsg
);
558 pStubMsg
->StackTop
= old_stack_top
;
560 /* the callback function always stores the computed value in MaxCount */
561 *pCount
= pStubMsg
->MaxCount
;
565 ptr
= (char *)ptr
+ ofs
;
578 data
= *(USHORT
*)ptr
;
589 FIXME("unknown conformance data type %x\n", dtype
);
592 TRACE("dereferenced data type %x at %p, got %d\n", dtype
, ptr
, data
);
595 switch (pFormat
[1]) {
596 case RPC_FC_DEREFERENCE
: /* already handled */
613 FIXME("unknown conformance op %d\n", pFormat
[1]);
618 TRACE("resulting conformance is %ld\n", *pCount
);
619 if (pStubMsg
->fHasNewCorrDesc
)
625 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
626 * the result overflows 32-bits */
627 static inline ULONG
safe_multiply(ULONG a
, ULONG b
)
629 ULONGLONG ret
= (ULONGLONG
)a
* b
;
630 if (ret
> 0xffffffff)
632 RpcRaiseException(RPC_S_INVALID_BOUND
);
638 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
640 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
641 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
642 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
643 pStubMsg
->Buffer
+= size
;
646 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
648 if (pStubMsg
->BufferLength
+ size
< pStubMsg
->BufferLength
) /* integer overflow of pStubMsg->BufferSize */
650 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
651 pStubMsg
->BufferLength
, size
);
652 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
654 pStubMsg
->BufferLength
+= size
;
657 /* copies data from the buffer, checking that there is enough data in the buffer
659 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, void *p
, ULONG size
)
661 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
662 (pStubMsg
->Buffer
+ size
> pStubMsg
->BufferEnd
))
663 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
664 memcpy(p
, pStubMsg
->Buffer
, size
);
665 pStubMsg
->Buffer
+= size
;
668 /* copies data to the buffer, checking that there is enough space to do so */
669 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, const void *p
, ULONG size
)
671 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
672 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
674 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
675 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
,
677 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
679 memcpy(pStubMsg
->Buffer
, p
, size
);
680 pStubMsg
->Buffer
+= size
;
684 * NdrConformantString:
686 * What MS calls a ConformantString is, in DCE terminology,
687 * a Varying-Conformant String.
689 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
690 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
691 * into unmarshalled string)
692 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
694 * data: CHARTYPE[maxlen]
696 * ], where CHARTYPE is the appropriate character type (specified externally)
700 /***********************************************************************
701 * NdrConformantStringMarshall [RPCRT4.@]
703 unsigned char *WINAPI
NdrConformantStringMarshall(MIDL_STUB_MESSAGE
*pStubMsg
,
704 unsigned char *pszMessage
, PFORMAT_STRING pFormat
)
708 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg
, pszMessage
, pFormat
);
710 if (*pFormat
== RPC_FC_C_CSTRING
) {
711 TRACE("string=%s\n", debugstr_a((char*)pszMessage
));
712 pStubMsg
->ActualCount
= strlen((char*)pszMessage
)+1;
715 else if (*pFormat
== RPC_FC_C_WSTRING
) {
716 TRACE("string=%s\n", debugstr_w((LPWSTR
)pszMessage
));
717 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pszMessage
)+1;
721 ERR("Unhandled string type: %#x\n", *pFormat
);
722 /* FIXME: raise an exception. */
726 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
727 pFormat
= ComputeConformance(pStubMsg
, pszMessage
, pFormat
+ 2, 0);
729 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
730 pStubMsg
->Offset
= 0;
731 WriteConformance(pStubMsg
);
732 WriteVariance(pStubMsg
);
734 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
735 safe_copy_to_buffer(pStubMsg
, pszMessage
, size
); /* the string itself */
738 return NULL
; /* is this always right? */
741 /***********************************************************************
742 * NdrConformantStringBufferSize [RPCRT4.@]
744 void WINAPI
NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
745 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
749 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
751 SizeConformance(pStubMsg
);
752 SizeVariance(pStubMsg
);
754 if (*pFormat
== RPC_FC_C_CSTRING
) {
755 TRACE("string=%s\n", debugstr_a((char*)pMemory
));
756 pStubMsg
->ActualCount
= strlen((char*)pMemory
)+1;
759 else if (*pFormat
== RPC_FC_C_WSTRING
) {
760 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
));
761 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
)+1;
765 ERR("Unhandled string type: %#x\n", *pFormat
);
766 /* FIXME: raise an exception */
770 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
771 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
773 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
775 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
778 /************************************************************************
779 * NdrConformantStringMemorySize [RPCRT4.@]
781 ULONG WINAPI
NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
782 PFORMAT_STRING pFormat
)
786 FIXME("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
788 assert(pStubMsg
&& pFormat
);
790 if (*pFormat
== RPC_FC_C_CSTRING
) {
791 rslt
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
); /* maxlen */
793 else if (*pFormat
== RPC_FC_C_WSTRING
) {
794 rslt
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
)*2; /* maxlen */
797 ERR("Unhandled string type: %#x\n", *pFormat
);
798 /* FIXME: raise an exception */
801 if (pFormat
[1] != RPC_FC_PAD
) {
802 FIXME("sized string format=%d\n", pFormat
[1]);
805 TRACE(" --> %u\n", rslt
);
809 /************************************************************************
810 * NdrConformantStringUnmarshall [RPCRT4.@]
812 unsigned char *WINAPI
NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
813 unsigned char** ppMemory
, PFORMAT_STRING pFormat
, unsigned char fMustAlloc
)
815 ULONG bufsize
, memsize
, esize
, i
;
817 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
818 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
820 assert(pFormat
&& ppMemory
&& pStubMsg
);
822 ReadConformance(pStubMsg
, NULL
);
823 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
825 if (*pFormat
== RPC_FC_C_CSTRING
) esize
= 1;
826 else if (*pFormat
== RPC_FC_C_WSTRING
) esize
= 2;
828 ERR("Unhandled string type: %#x\n", *pFormat
);
829 /* FIXME: raise an exception */
833 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
834 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
836 /* strings must always have null terminating bytes */
839 ERR("invalid string length of %d\n", pStubMsg
->ActualCount
);
840 RpcRaiseException(RPC_S_INVALID_BOUND
);
844 /* verify the buffer is safe to access */
845 if ((pStubMsg
->Buffer
+ bufsize
< pStubMsg
->Buffer
) ||
846 (pStubMsg
->Buffer
+ bufsize
> pStubMsg
->BufferEnd
))
848 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize
,
849 pStubMsg
->BufferEnd
, pStubMsg
->Buffer
);
850 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
854 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
855 if (pStubMsg
->Buffer
[i
] != 0)
857 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
858 i
, pStubMsg
->Buffer
[i
]);
859 RpcRaiseException(RPC_S_INVALID_BOUND
);
863 if (fMustAlloc
|| !*ppMemory
)
864 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
866 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
868 if (*pFormat
== RPC_FC_C_CSTRING
) {
869 TRACE("string=%s\n", debugstr_a((char*)*ppMemory
));
871 else if (*pFormat
== RPC_FC_C_WSTRING
) {
872 TRACE("string=%s\n", debugstr_w((LPWSTR
)*ppMemory
));
875 return NULL
; /* FIXME: is this always right? */
878 /***********************************************************************
879 * NdrNonConformantStringMarshall [RPCRT4.@]
881 unsigned char * WINAPI
NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
882 unsigned char *pMemory
,
883 PFORMAT_STRING pFormat
)
889 /***********************************************************************
890 * NdrNonConformantStringUnmarshall [RPCRT4.@]
892 unsigned char * WINAPI
NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
893 unsigned char **ppMemory
,
894 PFORMAT_STRING pFormat
,
895 unsigned char fMustAlloc
)
901 /***********************************************************************
902 * NdrNonConformantStringBufferSize [RPCRT4.@]
904 void WINAPI
NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
905 unsigned char *pMemory
,
906 PFORMAT_STRING pFormat
)
911 /***********************************************************************
912 * NdrNonConformantStringMemorySize [RPCRT4.@]
914 ULONG WINAPI
NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
915 PFORMAT_STRING pFormat
)
921 static inline void dump_pointer_attr(unsigned char attr
)
923 if (attr
& RPC_FC_P_ALLOCALLNODES
)
924 TRACE(" RPC_FC_P_ALLOCALLNODES");
925 if (attr
& RPC_FC_P_DONTFREE
)
926 TRACE(" RPC_FC_P_DONTFREE");
927 if (attr
& RPC_FC_P_ONSTACK
)
928 TRACE(" RPC_FC_P_ONSTACK");
929 if (attr
& RPC_FC_P_SIMPLEPOINTER
)
930 TRACE(" RPC_FC_P_SIMPLEPOINTER");
931 if (attr
& RPC_FC_P_DEREF
)
932 TRACE(" RPC_FC_P_DEREF");
936 /***********************************************************************
937 * PointerMarshall [internal]
939 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
940 unsigned char *Buffer
,
941 unsigned char *Pointer
,
942 PFORMAT_STRING pFormat
)
944 unsigned type
= pFormat
[0], attr
= pFormat
[1];
948 int pointer_needs_marshaling
;
950 TRACE("(%p,%p,%p,%p)\n", pStubMsg
, Buffer
, Pointer
, pFormat
);
951 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
953 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
954 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
957 case RPC_FC_RP
: /* ref pointer (always non-null) */
960 ERR("NULL ref pointer is not allowed\n");
961 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
963 pointer_needs_marshaling
= 1;
965 case RPC_FC_UP
: /* unique pointer */
966 case RPC_FC_OP
: /* object pointer - same as unique here */
968 pointer_needs_marshaling
= 1;
970 pointer_needs_marshaling
= 0;
971 pointer_id
= (ULONG
)Pointer
;
972 TRACE("writing 0x%08x to buffer\n", pointer_id
);
973 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
976 pointer_needs_marshaling
= !NdrFullPointerQueryPointer(
977 pStubMsg
->FullPtrXlatTables
, Pointer
, 1, &pointer_id
);
978 TRACE("writing 0x%08x to buffer\n", pointer_id
);
979 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
982 FIXME("unhandled ptr type=%02x\n", type
);
983 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
987 TRACE("calling marshaller for type 0x%x\n", (int)*desc
);
989 if (pointer_needs_marshaling
) {
990 if (attr
& RPC_FC_P_DEREF
) {
991 Pointer
= *(unsigned char**)Pointer
;
992 TRACE("deref => %p\n", Pointer
);
994 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
995 if (m
) m(pStubMsg
, Pointer
, desc
);
996 else FIXME("no marshaller for data type=%02x\n", *desc
);
999 STD_OVERFLOW_CHECK(pStubMsg
);
1002 /***********************************************************************
1003 * PointerUnmarshall [internal]
1005 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1006 unsigned char *Buffer
,
1007 unsigned char **pPointer
,
1008 unsigned char *pSrcPointer
,
1009 PFORMAT_STRING pFormat
,
1010 unsigned char fMustAlloc
)
1012 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1013 PFORMAT_STRING desc
;
1015 DWORD pointer_id
= 0;
1016 int pointer_needs_unmarshaling
;
1018 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg
, Buffer
, pPointer
, pSrcPointer
, pFormat
, fMustAlloc
);
1019 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1021 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1022 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1025 case RPC_FC_RP
: /* ref pointer (always non-null) */
1026 pointer_needs_unmarshaling
= 1;
1028 case RPC_FC_UP
: /* unique pointer */
1029 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1030 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1032 pointer_needs_unmarshaling
= 1;
1035 pointer_needs_unmarshaling
= 0;
1038 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
1039 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1040 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1041 if (!fMustAlloc
&& pSrcPointer
)
1043 FIXME("free object pointer %p\n", pSrcPointer
);
1047 pointer_needs_unmarshaling
= 1;
1049 pointer_needs_unmarshaling
= 0;
1052 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1053 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1054 pointer_needs_unmarshaling
= !NdrFullPointerQueryRefId(
1055 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, (void **)pPointer
);
1058 FIXME("unhandled ptr type=%02x\n", type
);
1059 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1063 if (pointer_needs_unmarshaling
) {
1064 unsigned char *base_ptr_val
= *pPointer
;
1065 unsigned char **current_ptr
= pPointer
;
1066 if (pStubMsg
->IsClient
) {
1068 /* if we aren't forcing allocation of memory then try to use the existing
1069 * (source) pointer to unmarshall the data into so that [in,out]
1070 * parameters behave correctly. it doesn't matter if the parameter is
1071 * [out] only since in that case the pointer will be NULL. we force
1072 * allocation when the source pointer is NULL here instead of in the type
1073 * unmarshalling routine for the benefit of the deref code below */
1076 TRACE("setting *pPointer to %p\n", pSrcPointer
);
1077 *pPointer
= base_ptr_val
= pSrcPointer
;
1083 /* the memory in a stub is never initialised, so we have to work out here
1084 * whether we have to initialise it so we can use the optimisation of
1085 * setting the pointer to the buffer, if possible, or set fMustAlloc to
1087 if (attr
& RPC_FC_P_DEREF
) {
1090 base_ptr_val
= NULL
;
1091 *current_ptr
= NULL
;
1095 if (attr
& RPC_FC_P_DEREF
) {
1097 base_ptr_val
= NdrAllocate(pStubMsg
, sizeof(void *));
1098 *pPointer
= base_ptr_val
;
1099 current_ptr
= (unsigned char **)base_ptr_val
;
1101 current_ptr
= *(unsigned char***)current_ptr
;
1102 TRACE("deref => %p\n", current_ptr
);
1103 if (!fMustAlloc
&& !*current_ptr
) fMustAlloc
= TRUE
;
1105 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
1106 if (m
) m(pStubMsg
, current_ptr
, desc
, fMustAlloc
);
1107 else FIXME("no unmarshaller for data type=%02x\n", *desc
);
1109 if (type
== RPC_FC_FP
)
1110 NdrFullPointerInsertRefId(pStubMsg
->FullPtrXlatTables
, pointer_id
,
1114 TRACE("pointer=%p\n", *pPointer
);
1117 /***********************************************************************
1118 * PointerBufferSize [internal]
1120 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1121 unsigned char *Pointer
,
1122 PFORMAT_STRING pFormat
)
1124 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1125 PFORMAT_STRING desc
;
1127 int pointer_needs_sizing
;
1130 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1131 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1133 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1134 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1137 case RPC_FC_RP
: /* ref pointer (always non-null) */
1140 ERR("NULL ref pointer is not allowed\n");
1141 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
1146 /* NULL pointer has no further representation */
1151 pointer_needs_sizing
= !NdrFullPointerQueryPointer(
1152 pStubMsg
->FullPtrXlatTables
, Pointer
, 0, &pointer_id
);
1153 if (!pointer_needs_sizing
)
1157 FIXME("unhandled ptr type=%02x\n", type
);
1158 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1162 if (attr
& RPC_FC_P_DEREF
) {
1163 Pointer
= *(unsigned char**)Pointer
;
1164 TRACE("deref => %p\n", Pointer
);
1167 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
1168 if (m
) m(pStubMsg
, Pointer
, desc
);
1169 else FIXME("no buffersizer for data type=%02x\n", *desc
);
1172 /***********************************************************************
1173 * PointerMemorySize [internal]
1175 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1176 unsigned char *Buffer
,
1177 PFORMAT_STRING pFormat
)
1179 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1180 PFORMAT_STRING desc
;
1182 DWORD pointer_id
= 0;
1183 int pointer_needs_sizing
;
1185 TRACE("(%p,%p,%p)\n", pStubMsg
, Buffer
, pFormat
);
1186 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1188 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1189 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1192 case RPC_FC_RP
: /* ref pointer (always non-null) */
1193 pointer_needs_sizing
= 1;
1195 case RPC_FC_UP
: /* unique pointer */
1196 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
1197 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1198 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1200 pointer_needs_sizing
= 1;
1202 pointer_needs_sizing
= 0;
1207 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1208 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1209 pointer_needs_sizing
= !NdrFullPointerQueryRefId(
1210 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, &pointer
);
1214 FIXME("unhandled ptr type=%02x\n", type
);
1215 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1219 if (attr
& RPC_FC_P_DEREF
) {
1223 if (pointer_needs_sizing
) {
1224 m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
1225 if (m
) m(pStubMsg
, desc
);
1226 else FIXME("no memorysizer for data type=%02x\n", *desc
);
1229 return pStubMsg
->MemorySize
;
1232 /***********************************************************************
1233 * PointerFree [internal]
1235 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1236 unsigned char *Pointer
,
1237 PFORMAT_STRING pFormat
)
1239 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1240 PFORMAT_STRING desc
;
1242 unsigned char *current_pointer
= Pointer
;
1244 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1245 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1246 if (attr
& RPC_FC_P_DONTFREE
) return;
1248 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1249 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1251 if (!Pointer
) return;
1253 if (type
== RPC_FC_FP
) {
1254 int pointer_needs_freeing
= NdrFullPointerFree(
1255 pStubMsg
->FullPtrXlatTables
, Pointer
);
1256 if (!pointer_needs_freeing
)
1260 if (attr
& RPC_FC_P_DEREF
) {
1261 current_pointer
= *(unsigned char**)Pointer
;
1262 TRACE("deref => %p\n", current_pointer
);
1265 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
1266 if (m
) m(pStubMsg
, current_pointer
, desc
);
1268 /* this check stops us from trying to free buffer memory. we don't have to
1269 * worry about clients, since they won't call this function.
1270 * we don't have to check for the buffer being reallocated because
1271 * BufferStart and BufferEnd won't be reset when allocating memory for
1272 * sending the response. we don't have to check for the new buffer here as
1273 * it won't be used a type memory, only for buffer memory */
1274 if (Pointer
>= (unsigned char *)pStubMsg
->BufferStart
&&
1275 Pointer
< (unsigned char *)pStubMsg
->BufferEnd
)
1278 if (attr
& RPC_FC_P_ONSTACK
) {
1279 TRACE("not freeing stack ptr %p\n", Pointer
);
1282 TRACE("freeing %p\n", Pointer
);
1283 NdrFree(pStubMsg
, Pointer
);
1286 TRACE("not freeing %p\n", Pointer
);
1289 /***********************************************************************
1290 * EmbeddedPointerMarshall
1292 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1293 unsigned char *pMemory
,
1294 PFORMAT_STRING pFormat
)
1296 unsigned char *Mark
= pStubMsg
->BufferMark
;
1297 unsigned rep
, count
, stride
;
1299 unsigned char *saved_buffer
= NULL
;
1301 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1303 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1306 if (pStubMsg
->PointerBufferMark
)
1308 saved_buffer
= pStubMsg
->Buffer
;
1309 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1310 pStubMsg
->PointerBufferMark
= NULL
;
1313 while (pFormat
[0] != RPC_FC_END
) {
1314 switch (pFormat
[0]) {
1316 FIXME("unknown repeat type %d\n", pFormat
[0]);
1317 case RPC_FC_NO_REPEAT
:
1323 case RPC_FC_FIXED_REPEAT
:
1324 rep
= *(const WORD
*)&pFormat
[2];
1325 stride
= *(const WORD
*)&pFormat
[4];
1326 count
= *(const WORD
*)&pFormat
[8];
1329 case RPC_FC_VARIABLE_REPEAT
:
1330 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1331 stride
= *(const WORD
*)&pFormat
[2];
1332 count
= *(const WORD
*)&pFormat
[6];
1336 for (i
= 0; i
< rep
; i
++) {
1337 PFORMAT_STRING info
= pFormat
;
1338 unsigned char *membase
= pMemory
+ (i
* stride
);
1339 unsigned char *bufbase
= Mark
+ (i
* stride
);
1342 for (u
=0; u
<count
; u
++,info
+=8) {
1343 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1344 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1345 unsigned char *saved_memory
= pStubMsg
->Memory
;
1347 pStubMsg
->Memory
= pMemory
;
1348 PointerMarshall(pStubMsg
, bufptr
, *(unsigned char**)memptr
, info
+4);
1349 pStubMsg
->Memory
= saved_memory
;
1352 pFormat
+= 8 * count
;
1357 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1358 pStubMsg
->Buffer
= saved_buffer
;
1361 STD_OVERFLOW_CHECK(pStubMsg
);
1366 /***********************************************************************
1367 * EmbeddedPointerUnmarshall
1369 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1370 unsigned char *pDstMemoryPtrs
,
1371 unsigned char *pSrcMemoryPtrs
,
1372 PFORMAT_STRING pFormat
,
1373 unsigned char fMustAlloc
)
1375 unsigned char *Mark
= pStubMsg
->BufferMark
;
1376 unsigned rep
, count
, stride
;
1378 unsigned char *saved_buffer
= NULL
;
1380 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg
, pDstMemoryPtrs
, pSrcMemoryPtrs
, pFormat
, fMustAlloc
);
1382 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1385 if (pStubMsg
->PointerBufferMark
)
1387 saved_buffer
= pStubMsg
->Buffer
;
1388 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1389 pStubMsg
->PointerBufferMark
= NULL
;
1392 while (pFormat
[0] != RPC_FC_END
) {
1393 TRACE("pFormat[0] = 0x%x\n", pFormat
[0]);
1394 switch (pFormat
[0]) {
1396 FIXME("unknown repeat type %d\n", pFormat
[0]);
1397 case RPC_FC_NO_REPEAT
:
1403 case RPC_FC_FIXED_REPEAT
:
1404 rep
= *(const WORD
*)&pFormat
[2];
1405 stride
= *(const WORD
*)&pFormat
[4];
1406 count
= *(const WORD
*)&pFormat
[8];
1409 case RPC_FC_VARIABLE_REPEAT
:
1410 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1411 stride
= *(const WORD
*)&pFormat
[2];
1412 count
= *(const WORD
*)&pFormat
[6];
1416 for (i
= 0; i
< rep
; i
++) {
1417 PFORMAT_STRING info
= pFormat
;
1418 unsigned char *memdstbase
= pDstMemoryPtrs
+ (i
* stride
);
1419 unsigned char *memsrcbase
= pSrcMemoryPtrs
+ (i
* stride
);
1420 unsigned char *bufbase
= Mark
+ (i
* stride
);
1423 for (u
=0; u
<count
; u
++,info
+=8) {
1424 unsigned char **memdstptr
= (unsigned char **)(memdstbase
+ *(const SHORT
*)&info
[0]);
1425 unsigned char **memsrcptr
= (unsigned char **)(memsrcbase
+ *(const SHORT
*)&info
[0]);
1426 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1427 PointerUnmarshall(pStubMsg
, bufptr
, memdstptr
, *memsrcptr
, info
+4, fMustAlloc
);
1430 pFormat
+= 8 * count
;
1435 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1436 pStubMsg
->Buffer
= saved_buffer
;
1442 /***********************************************************************
1443 * EmbeddedPointerBufferSize
1445 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1446 unsigned char *pMemory
,
1447 PFORMAT_STRING pFormat
)
1449 unsigned rep
, count
, stride
;
1451 ULONG saved_buffer_length
= 0;
1453 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1455 if (pStubMsg
->IgnoreEmbeddedPointers
) return;
1457 if (*pFormat
!= RPC_FC_PP
) return;
1460 if (pStubMsg
->PointerLength
)
1462 saved_buffer_length
= pStubMsg
->BufferLength
;
1463 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
1464 pStubMsg
->PointerLength
= 0;
1467 while (pFormat
[0] != RPC_FC_END
) {
1468 switch (pFormat
[0]) {
1470 FIXME("unknown repeat type %d\n", pFormat
[0]);
1471 case RPC_FC_NO_REPEAT
:
1477 case RPC_FC_FIXED_REPEAT
:
1478 rep
= *(const WORD
*)&pFormat
[2];
1479 stride
= *(const WORD
*)&pFormat
[4];
1480 count
= *(const WORD
*)&pFormat
[8];
1483 case RPC_FC_VARIABLE_REPEAT
:
1484 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1485 stride
= *(const WORD
*)&pFormat
[2];
1486 count
= *(const WORD
*)&pFormat
[6];
1490 for (i
= 0; i
< rep
; i
++) {
1491 PFORMAT_STRING info
= pFormat
;
1492 unsigned char *membase
= pMemory
+ (i
* stride
);
1495 for (u
=0; u
<count
; u
++,info
+=8) {
1496 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1497 unsigned char *saved_memory
= pStubMsg
->Memory
;
1499 pStubMsg
->Memory
= pMemory
;
1500 PointerBufferSize(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1501 pStubMsg
->Memory
= saved_memory
;
1504 pFormat
+= 8 * count
;
1507 if (saved_buffer_length
)
1509 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
1510 pStubMsg
->BufferLength
= saved_buffer_length
;
1514 /***********************************************************************
1515 * EmbeddedPointerMemorySize [internal]
1517 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1518 PFORMAT_STRING pFormat
)
1520 unsigned char *Mark
= pStubMsg
->BufferMark
;
1521 unsigned rep
, count
, stride
;
1523 unsigned char *saved_buffer
= NULL
;
1525 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1527 if (pStubMsg
->IgnoreEmbeddedPointers
) return 0;
1529 if (pStubMsg
->PointerBufferMark
)
1531 saved_buffer
= pStubMsg
->Buffer
;
1532 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1533 pStubMsg
->PointerBufferMark
= NULL
;
1536 if (*pFormat
!= RPC_FC_PP
) return 0;
1539 while (pFormat
[0] != RPC_FC_END
) {
1540 switch (pFormat
[0]) {
1542 FIXME("unknown repeat type %d\n", pFormat
[0]);
1543 case RPC_FC_NO_REPEAT
:
1549 case RPC_FC_FIXED_REPEAT
:
1550 rep
= *(const WORD
*)&pFormat
[2];
1551 stride
= *(const WORD
*)&pFormat
[4];
1552 count
= *(const WORD
*)&pFormat
[8];
1555 case RPC_FC_VARIABLE_REPEAT
:
1556 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1557 stride
= *(const WORD
*)&pFormat
[2];
1558 count
= *(const WORD
*)&pFormat
[6];
1562 for (i
= 0; i
< rep
; i
++) {
1563 PFORMAT_STRING info
= pFormat
;
1564 unsigned char *bufbase
= Mark
+ (i
* stride
);
1566 for (u
=0; u
<count
; u
++,info
+=8) {
1567 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1568 PointerMemorySize(pStubMsg
, bufptr
, info
+4);
1571 pFormat
+= 8 * count
;
1576 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1577 pStubMsg
->Buffer
= saved_buffer
;
1583 /***********************************************************************
1584 * EmbeddedPointerFree [internal]
1586 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1587 unsigned char *pMemory
,
1588 PFORMAT_STRING pFormat
)
1590 unsigned rep
, count
, stride
;
1593 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1594 if (*pFormat
!= RPC_FC_PP
) return;
1597 while (pFormat
[0] != RPC_FC_END
) {
1598 switch (pFormat
[0]) {
1600 FIXME("unknown repeat type %d\n", pFormat
[0]);
1601 case RPC_FC_NO_REPEAT
:
1607 case RPC_FC_FIXED_REPEAT
:
1608 rep
= *(const WORD
*)&pFormat
[2];
1609 stride
= *(const WORD
*)&pFormat
[4];
1610 count
= *(const WORD
*)&pFormat
[8];
1613 case RPC_FC_VARIABLE_REPEAT
:
1614 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1615 stride
= *(const WORD
*)&pFormat
[2];
1616 count
= *(const WORD
*)&pFormat
[6];
1620 for (i
= 0; i
< rep
; i
++) {
1621 PFORMAT_STRING info
= pFormat
;
1622 unsigned char *membase
= pMemory
+ (i
* stride
);
1625 for (u
=0; u
<count
; u
++,info
+=8) {
1626 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1627 unsigned char *saved_memory
= pStubMsg
->Memory
;
1629 pStubMsg
->Memory
= pMemory
;
1630 PointerFree(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1631 pStubMsg
->Memory
= saved_memory
;
1634 pFormat
+= 8 * count
;
1638 /***********************************************************************
1639 * NdrPointerMarshall [RPCRT4.@]
1641 unsigned char * WINAPI
NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1642 unsigned char *pMemory
,
1643 PFORMAT_STRING pFormat
)
1645 unsigned char *Buffer
;
1647 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1649 /* incremement the buffer here instead of in PointerMarshall,
1650 * as that is used by embedded pointers which already handle the incrementing
1651 * the buffer, and shouldn't write any additional pointer data to the wire */
1652 if (*pFormat
!= RPC_FC_RP
)
1654 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1655 Buffer
= pStubMsg
->Buffer
;
1656 safe_buffer_increment(pStubMsg
, 4);
1659 Buffer
= pStubMsg
->Buffer
;
1661 PointerMarshall(pStubMsg
, Buffer
, pMemory
, pFormat
);
1666 /***********************************************************************
1667 * NdrPointerUnmarshall [RPCRT4.@]
1669 unsigned char * WINAPI
NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1670 unsigned char **ppMemory
,
1671 PFORMAT_STRING pFormat
,
1672 unsigned char fMustAlloc
)
1674 unsigned char *Buffer
;
1676 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1678 /* incremement the buffer here instead of in PointerUnmarshall,
1679 * as that is used by embedded pointers which already handle the incrementing
1680 * the buffer, and shouldn't read any additional pointer data from the
1682 if (*pFormat
!= RPC_FC_RP
)
1684 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1685 Buffer
= pStubMsg
->Buffer
;
1686 safe_buffer_increment(pStubMsg
, 4);
1689 Buffer
= pStubMsg
->Buffer
;
1691 PointerUnmarshall(pStubMsg
, Buffer
, ppMemory
, *ppMemory
, pFormat
, fMustAlloc
);
1696 /***********************************************************************
1697 * NdrPointerBufferSize [RPCRT4.@]
1699 void WINAPI
NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1700 unsigned char *pMemory
,
1701 PFORMAT_STRING pFormat
)
1703 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1705 /* incremement the buffer length here instead of in PointerBufferSize,
1706 * as that is used by embedded pointers which already handle the buffer
1707 * length, and shouldn't write anything more to the wire */
1708 if (*pFormat
!= RPC_FC_RP
)
1710 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
1711 safe_buffer_length_increment(pStubMsg
, 4);
1714 PointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1717 /***********************************************************************
1718 * NdrPointerMemorySize [RPCRT4.@]
1720 ULONG WINAPI
NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1721 PFORMAT_STRING pFormat
)
1723 /* unsigned size = *(LPWORD)(pFormat+2); */
1724 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1725 PointerMemorySize(pStubMsg
, pStubMsg
->Buffer
, pFormat
);
1729 /***********************************************************************
1730 * NdrPointerFree [RPCRT4.@]
1732 void WINAPI
NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1733 unsigned char *pMemory
,
1734 PFORMAT_STRING pFormat
)
1736 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1737 PointerFree(pStubMsg
, pMemory
, pFormat
);
1740 /***********************************************************************
1741 * NdrSimpleTypeMarshall [RPCRT4.@]
1743 void WINAPI
NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1744 unsigned char FormatChar
)
1746 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &FormatChar
);
1749 /***********************************************************************
1750 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1752 void WINAPI
NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1753 unsigned char FormatChar
)
1755 NdrBaseTypeUnmarshall(pStubMsg
, &pMemory
, &FormatChar
, 0);
1758 /***********************************************************************
1759 * NdrSimpleStructMarshall [RPCRT4.@]
1761 unsigned char * WINAPI
NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1762 unsigned char *pMemory
,
1763 PFORMAT_STRING pFormat
)
1765 unsigned size
= *(const WORD
*)(pFormat
+2);
1766 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1768 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1770 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1771 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
1773 if (pFormat
[0] != RPC_FC_STRUCT
)
1774 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
+4);
1779 /***********************************************************************
1780 * NdrSimpleStructUnmarshall [RPCRT4.@]
1782 unsigned char * WINAPI
NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1783 unsigned char **ppMemory
,
1784 PFORMAT_STRING pFormat
,
1785 unsigned char fMustAlloc
)
1787 unsigned size
= *(const WORD
*)(pFormat
+2);
1788 unsigned char *saved_buffer
;
1789 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1791 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1794 *ppMemory
= NdrAllocate(pStubMsg
, size
);
1797 if (!pStubMsg
->IsClient
&& !*ppMemory
)
1798 /* for servers, we just point straight into the RPC buffer */
1799 *ppMemory
= pStubMsg
->Buffer
;
1802 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1803 safe_buffer_increment(pStubMsg
, size
);
1804 if (pFormat
[0] == RPC_FC_PSTRUCT
)
1805 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
+4, fMustAlloc
);
1807 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
1808 if (*ppMemory
!= saved_buffer
)
1809 memcpy(*ppMemory
, saved_buffer
, size
);
1814 /***********************************************************************
1815 * NdrSimpleStructBufferSize [RPCRT4.@]
1817 void WINAPI
NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1818 unsigned char *pMemory
,
1819 PFORMAT_STRING pFormat
)
1821 unsigned size
= *(const WORD
*)(pFormat
+2);
1822 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1824 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
1826 safe_buffer_length_increment(pStubMsg
, size
);
1827 if (pFormat
[0] != RPC_FC_STRUCT
)
1828 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
+4);
1831 /***********************************************************************
1832 * NdrSimpleStructMemorySize [RPCRT4.@]
1834 ULONG WINAPI
NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1835 PFORMAT_STRING pFormat
)
1837 unsigned short size
= *(const WORD
*)(pFormat
+2);
1839 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1841 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1842 pStubMsg
->MemorySize
+= size
;
1843 safe_buffer_increment(pStubMsg
, size
);
1845 if (pFormat
[0] != RPC_FC_STRUCT
)
1846 EmbeddedPointerMemorySize(pStubMsg
, pFormat
+4);
1847 return pStubMsg
->MemorySize
;
1850 /***********************************************************************
1851 * NdrSimpleStructFree [RPCRT4.@]
1853 void WINAPI
NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
1854 unsigned char *pMemory
,
1855 PFORMAT_STRING pFormat
)
1857 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1858 if (pFormat
[0] != RPC_FC_STRUCT
)
1859 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
+4);
1863 static unsigned long EmbeddedComplexSize(const MIDL_STUB_MESSAGE
*pStubMsg
,
1864 PFORMAT_STRING pFormat
)
1868 case RPC_FC_PSTRUCT
:
1869 case RPC_FC_CSTRUCT
:
1870 case RPC_FC_BOGUS_STRUCT
:
1871 case RPC_FC_SMFARRAY
:
1872 case RPC_FC_SMVARRAY
:
1873 return *(const WORD
*)&pFormat
[2];
1874 case RPC_FC_USER_MARSHAL
:
1875 return *(const WORD
*)&pFormat
[4];
1876 case RPC_FC_NON_ENCAPSULATED_UNION
:
1878 if (pStubMsg
->fHasNewCorrDesc
)
1883 pFormat
+= *(const SHORT
*)pFormat
;
1884 return *(const SHORT
*)pFormat
;
1886 return sizeof(void *);
1888 FIXME("unhandled embedded type %02x\n", *pFormat
);
1894 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1895 PFORMAT_STRING pFormat
)
1897 NDR_MEMORYSIZE m
= NdrMemorySizer
[*pFormat
& NDR_TABLE_MASK
];
1901 FIXME("no memorysizer for data type=%02x\n", *pFormat
);
1905 return m(pStubMsg
, pFormat
);
1909 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1910 unsigned char *pMemory
,
1911 PFORMAT_STRING pFormat
,
1912 PFORMAT_STRING pPointer
)
1914 PFORMAT_STRING desc
;
1918 while (*pFormat
!= RPC_FC_END
) {
1924 TRACE("byte=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
1925 safe_copy_to_buffer(pStubMsg
, pMemory
, 1);
1931 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
1932 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
1938 TRACE("long=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
1939 safe_copy_to_buffer(pStubMsg
, pMemory
, 4);
1943 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
1944 safe_copy_to_buffer(pStubMsg
, pMemory
, 8);
1947 case RPC_FC_POINTER
:
1949 unsigned char *saved_buffer
;
1950 int pointer_buffer_mark_set
= 0;
1951 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
1952 saved_buffer
= pStubMsg
->Buffer
;
1953 if (pStubMsg
->PointerBufferMark
)
1955 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1956 pStubMsg
->PointerBufferMark
= NULL
;
1957 pointer_buffer_mark_set
= 1;
1960 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
1961 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char**)pMemory
, pPointer
);
1962 if (pointer_buffer_mark_set
)
1964 STD_OVERFLOW_CHECK(pStubMsg
);
1965 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1966 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
1968 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
1969 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
1970 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1972 pStubMsg
->Buffer
= saved_buffer
+ 4;
1978 case RPC_FC_ALIGNM4
:
1979 ALIGN_POINTER(pMemory
, 4);
1981 case RPC_FC_ALIGNM8
:
1982 ALIGN_POINTER(pMemory
, 8);
1984 case RPC_FC_STRUCTPAD1
:
1985 case RPC_FC_STRUCTPAD2
:
1986 case RPC_FC_STRUCTPAD3
:
1987 case RPC_FC_STRUCTPAD4
:
1988 case RPC_FC_STRUCTPAD5
:
1989 case RPC_FC_STRUCTPAD6
:
1990 case RPC_FC_STRUCTPAD7
:
1991 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
1993 case RPC_FC_EMBEDDED_COMPLEX
:
1994 pMemory
+= pFormat
[1];
1996 desc
= pFormat
+ *(const SHORT
*)pFormat
;
1997 size
= EmbeddedComplexSize(pStubMsg
, desc
);
1998 TRACE("embedded complex (size=%ld) <= %p\n", size
, pMemory
);
1999 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
2002 /* for some reason interface pointers aren't generated as
2003 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2004 * they still need the derefencing treatment that pointers are
2006 if (*desc
== RPC_FC_IP
)
2007 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2009 m(pStubMsg
, pMemory
, desc
);
2011 else FIXME("no marshaller for embedded type %02x\n", *desc
);
2018 FIXME("unhandled format 0x%02x\n", *pFormat
);
2026 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2027 unsigned char *pMemory
,
2028 PFORMAT_STRING pFormat
,
2029 PFORMAT_STRING pPointer
)
2031 PFORMAT_STRING desc
;
2035 while (*pFormat
!= RPC_FC_END
) {
2041 safe_copy_from_buffer(pStubMsg
, pMemory
, 1);
2042 TRACE("byte=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2048 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
2049 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2055 safe_copy_from_buffer(pStubMsg
, pMemory
, 4);
2056 TRACE("long=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
2060 safe_copy_from_buffer(pStubMsg
, pMemory
, 8);
2061 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2064 case RPC_FC_POINTER
:
2066 unsigned char *saved_buffer
;
2067 int pointer_buffer_mark_set
= 0;
2068 TRACE("pointer => %p\n", pMemory
);
2069 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2070 saved_buffer
= pStubMsg
->Buffer
;
2071 if (pStubMsg
->PointerBufferMark
)
2073 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2074 pStubMsg
->PointerBufferMark
= NULL
;
2075 pointer_buffer_mark_set
= 1;
2078 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2080 PointerUnmarshall(pStubMsg
, saved_buffer
, (unsigned char**)pMemory
, *(unsigned char**)pMemory
, pPointer
, TRUE
);
2081 if (pointer_buffer_mark_set
)
2083 STD_OVERFLOW_CHECK(pStubMsg
);
2084 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2085 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
2087 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2088 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
2089 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2091 pStubMsg
->Buffer
= saved_buffer
+ 4;
2097 case RPC_FC_ALIGNM4
:
2098 ALIGN_POINTER(pMemory
, 4);
2100 case RPC_FC_ALIGNM8
:
2101 ALIGN_POINTER(pMemory
, 8);
2103 case RPC_FC_STRUCTPAD1
:
2104 case RPC_FC_STRUCTPAD2
:
2105 case RPC_FC_STRUCTPAD3
:
2106 case RPC_FC_STRUCTPAD4
:
2107 case RPC_FC_STRUCTPAD5
:
2108 case RPC_FC_STRUCTPAD6
:
2109 case RPC_FC_STRUCTPAD7
:
2110 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2112 case RPC_FC_EMBEDDED_COMPLEX
:
2113 pMemory
+= pFormat
[1];
2115 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2116 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2117 TRACE("embedded complex (size=%ld) => %p\n", size
, pMemory
);
2118 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
2119 memset(pMemory
, 0, size
); /* just in case */
2122 /* for some reason interface pointers aren't generated as
2123 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2124 * they still need the derefencing treatment that pointers are
2126 if (*desc
== RPC_FC_IP
)
2127 m(pStubMsg
, (unsigned char **)pMemory
, desc
, FALSE
);
2129 m(pStubMsg
, &pMemory
, desc
, FALSE
);
2131 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
2138 FIXME("unhandled format %d\n", *pFormat
);
2146 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2147 unsigned char *pMemory
,
2148 PFORMAT_STRING pFormat
,
2149 PFORMAT_STRING pPointer
)
2151 PFORMAT_STRING desc
;
2155 while (*pFormat
!= RPC_FC_END
) {
2161 safe_buffer_length_increment(pStubMsg
, 1);
2167 safe_buffer_length_increment(pStubMsg
, 2);
2173 safe_buffer_length_increment(pStubMsg
, 4);
2177 safe_buffer_length_increment(pStubMsg
, 8);
2180 case RPC_FC_POINTER
:
2181 if (!pStubMsg
->IgnoreEmbeddedPointers
)
2183 int saved_buffer_length
= pStubMsg
->BufferLength
;
2184 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2185 pStubMsg
->PointerLength
= 0;
2186 if(!pStubMsg
->BufferLength
)
2187 ERR("BufferLength == 0??\n");
2188 PointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
2189 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2190 pStubMsg
->BufferLength
= saved_buffer_length
;
2192 safe_buffer_length_increment(pStubMsg
, 4);
2196 case RPC_FC_ALIGNM4
:
2197 ALIGN_POINTER(pMemory
, 4);
2199 case RPC_FC_ALIGNM8
:
2200 ALIGN_POINTER(pMemory
, 8);
2202 case RPC_FC_STRUCTPAD1
:
2203 case RPC_FC_STRUCTPAD2
:
2204 case RPC_FC_STRUCTPAD3
:
2205 case RPC_FC_STRUCTPAD4
:
2206 case RPC_FC_STRUCTPAD5
:
2207 case RPC_FC_STRUCTPAD6
:
2208 case RPC_FC_STRUCTPAD7
:
2209 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2211 case RPC_FC_EMBEDDED_COMPLEX
:
2212 pMemory
+= pFormat
[1];
2214 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2215 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2216 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
2219 /* for some reason interface pointers aren't generated as
2220 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2221 * they still need the derefencing treatment that pointers are
2223 if (*desc
== RPC_FC_IP
)
2224 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2226 m(pStubMsg
, pMemory
, desc
);
2228 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
2235 FIXME("unhandled format 0x%02x\n", *pFormat
);
2243 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
2244 unsigned char *pMemory
,
2245 PFORMAT_STRING pFormat
,
2246 PFORMAT_STRING pPointer
)
2248 PFORMAT_STRING desc
;
2252 while (*pFormat
!= RPC_FC_END
) {
2273 case RPC_FC_POINTER
:
2274 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
2278 case RPC_FC_ALIGNM4
:
2279 ALIGN_POINTER(pMemory
, 4);
2281 case RPC_FC_ALIGNM8
:
2282 ALIGN_POINTER(pMemory
, 8);
2284 case RPC_FC_STRUCTPAD1
:
2285 case RPC_FC_STRUCTPAD2
:
2286 case RPC_FC_STRUCTPAD3
:
2287 case RPC_FC_STRUCTPAD4
:
2288 case RPC_FC_STRUCTPAD5
:
2289 case RPC_FC_STRUCTPAD6
:
2290 case RPC_FC_STRUCTPAD7
:
2291 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2293 case RPC_FC_EMBEDDED_COMPLEX
:
2294 pMemory
+= pFormat
[1];
2296 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2297 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2298 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
2301 /* for some reason interface pointers aren't generated as
2302 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2303 * they still need the derefencing treatment that pointers are
2305 if (*desc
== RPC_FC_IP
)
2306 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2308 m(pStubMsg
, pMemory
, desc
);
2310 else FIXME("no freer for embedded type %02x\n", *desc
);
2317 FIXME("unhandled format 0x%02x\n", *pFormat
);
2325 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2326 PFORMAT_STRING pFormat
)
2328 PFORMAT_STRING desc
;
2329 unsigned long size
= 0;
2331 while (*pFormat
!= RPC_FC_END
) {
2338 safe_buffer_increment(pStubMsg
, 1);
2344 safe_buffer_increment(pStubMsg
, 2);
2350 safe_buffer_increment(pStubMsg
, 4);
2354 safe_buffer_increment(pStubMsg
, 8);
2356 case RPC_FC_POINTER
:
2358 safe_buffer_increment(pStubMsg
, 4);
2359 if (!pStubMsg
->IgnoreEmbeddedPointers
)
2360 FIXME("embedded pointers\n");
2362 case RPC_FC_ALIGNM4
:
2363 ALIGN_LENGTH(size
, 4);
2364 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2366 case RPC_FC_ALIGNM8
:
2367 ALIGN_LENGTH(size
, 8);
2368 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
2370 case RPC_FC_STRUCTPAD1
:
2371 case RPC_FC_STRUCTPAD2
:
2372 case RPC_FC_STRUCTPAD3
:
2373 case RPC_FC_STRUCTPAD4
:
2374 case RPC_FC_STRUCTPAD5
:
2375 case RPC_FC_STRUCTPAD6
:
2376 case RPC_FC_STRUCTPAD7
:
2377 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2379 case RPC_FC_EMBEDDED_COMPLEX
:
2382 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2383 size
+= EmbeddedComplexMemorySize(pStubMsg
, desc
);
2389 FIXME("unhandled format 0x%02x\n", *pFormat
);
2397 /***********************************************************************
2398 * NdrComplexStructMarshall [RPCRT4.@]
2400 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2401 unsigned char *pMemory
,
2402 PFORMAT_STRING pFormat
)
2404 PFORMAT_STRING conf_array
= NULL
;
2405 PFORMAT_STRING pointer_desc
= NULL
;
2406 unsigned char *OldMemory
= pStubMsg
->Memory
;
2407 int pointer_buffer_mark_set
= 0;
2409 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2411 if (!pStubMsg
->PointerBufferMark
)
2413 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2414 /* save buffer length */
2415 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2417 /* get the buffer pointer after complex array data, but before
2419 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- pStubMsg
->BufferStart
;
2420 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2421 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
2422 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2424 /* save it for use by embedded pointer code later */
2425 pStubMsg
->PointerBufferMark
= pStubMsg
->BufferStart
+ pStubMsg
->BufferLength
;
2426 TRACE("difference = 0x%x\n", pStubMsg
->PointerBufferMark
- pStubMsg
->Buffer
);
2427 pointer_buffer_mark_set
= 1;
2429 /* restore the original buffer length */
2430 pStubMsg
->BufferLength
= saved_buffer_length
;
2433 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2436 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2438 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2441 pStubMsg
->Memory
= pMemory
;
2443 ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2446 NdrConformantArrayMarshall(pStubMsg
, pMemory
, conf_array
);
2448 pStubMsg
->Memory
= OldMemory
;
2450 if (pointer_buffer_mark_set
)
2452 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2453 pStubMsg
->PointerBufferMark
= NULL
;
2456 STD_OVERFLOW_CHECK(pStubMsg
);
2461 /***********************************************************************
2462 * NdrComplexStructUnmarshall [RPCRT4.@]
2464 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2465 unsigned char **ppMemory
,
2466 PFORMAT_STRING pFormat
,
2467 unsigned char fMustAlloc
)
2469 unsigned size
= *(const WORD
*)(pFormat
+2);
2470 PFORMAT_STRING conf_array
= NULL
;
2471 PFORMAT_STRING pointer_desc
= NULL
;
2472 unsigned char *pMemory
;
2473 int pointer_buffer_mark_set
= 0;
2475 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2477 if (!pStubMsg
->PointerBufferMark
)
2479 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2480 /* save buffer pointer */
2481 unsigned char *saved_buffer
= pStubMsg
->Buffer
;
2483 /* get the buffer pointer after complex array data, but before
2485 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2486 NdrComplexStructMemorySize(pStubMsg
, pFormat
);
2487 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2489 /* save it for use by embedded pointer code later */
2490 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2491 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->PointerBufferMark
- saved_buffer
));
2492 pointer_buffer_mark_set
= 1;
2494 /* restore the original buffer */
2495 pStubMsg
->Buffer
= saved_buffer
;
2498 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2500 if (fMustAlloc
|| !*ppMemory
)
2502 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2503 memset(*ppMemory
, 0, size
);
2507 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2509 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2512 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
);
2515 NdrConformantArrayUnmarshall(pStubMsg
, &pMemory
, conf_array
, fMustAlloc
);
2517 if (pointer_buffer_mark_set
)
2519 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2520 pStubMsg
->PointerBufferMark
= NULL
;
2526 /***********************************************************************
2527 * NdrComplexStructBufferSize [RPCRT4.@]
2529 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2530 unsigned char *pMemory
,
2531 PFORMAT_STRING pFormat
)
2533 PFORMAT_STRING conf_array
= NULL
;
2534 PFORMAT_STRING pointer_desc
= NULL
;
2535 unsigned char *OldMemory
= pStubMsg
->Memory
;
2536 int pointer_length_set
= 0;
2538 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2540 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
2542 if(!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
2544 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2545 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2547 /* get the buffer length after complex struct data, but before
2549 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2550 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
2551 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2553 /* save it for use by embedded pointer code later */
2554 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2555 pointer_length_set
= 1;
2556 TRACE("difference = 0x%lx\n", pStubMsg
->PointerLength
- saved_buffer_length
);
2558 /* restore the original buffer length */
2559 pStubMsg
->BufferLength
= saved_buffer_length
;
2563 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2565 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2568 pStubMsg
->Memory
= pMemory
;
2570 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2573 NdrConformantArrayBufferSize(pStubMsg
, pMemory
, conf_array
);
2575 pStubMsg
->Memory
= OldMemory
;
2577 if(pointer_length_set
)
2579 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2580 pStubMsg
->PointerLength
= 0;
2585 /***********************************************************************
2586 * NdrComplexStructMemorySize [RPCRT4.@]
2588 ULONG WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2589 PFORMAT_STRING pFormat
)
2591 unsigned size
= *(const WORD
*)(pFormat
+2);
2592 PFORMAT_STRING conf_array
= NULL
;
2593 PFORMAT_STRING pointer_desc
= NULL
;
2595 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2597 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2600 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2602 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2605 ComplexStructMemorySize(pStubMsg
, pFormat
);
2608 NdrConformantArrayMemorySize(pStubMsg
, conf_array
);
2613 /***********************************************************************
2614 * NdrComplexStructFree [RPCRT4.@]
2616 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
2617 unsigned char *pMemory
,
2618 PFORMAT_STRING pFormat
)
2620 PFORMAT_STRING conf_array
= NULL
;
2621 PFORMAT_STRING pointer_desc
= NULL
;
2622 unsigned char *OldMemory
= pStubMsg
->Memory
;
2624 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2627 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2629 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2632 pStubMsg
->Memory
= pMemory
;
2634 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2637 NdrConformantArrayFree(pStubMsg
, pMemory
, conf_array
);
2639 pStubMsg
->Memory
= OldMemory
;
2642 /***********************************************************************
2643 * NdrConformantArrayMarshall [RPCRT4.@]
2645 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2646 unsigned char *pMemory
,
2647 PFORMAT_STRING pFormat
)
2649 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
2650 unsigned char alignment
= pFormat
[1] + 1;
2652 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2653 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2655 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2657 WriteConformance(pStubMsg
);
2659 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2661 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2662 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2663 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
2665 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2670 /***********************************************************************
2671 * NdrConformantArrayUnmarshall [RPCRT4.@]
2673 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2674 unsigned char **ppMemory
,
2675 PFORMAT_STRING pFormat
,
2676 unsigned char fMustAlloc
)
2678 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
2679 unsigned char alignment
= pFormat
[1] + 1;
2680 unsigned char *saved_buffer
;
2682 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2683 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2685 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2687 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2688 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2691 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2694 if (!pStubMsg
->IsClient
&& !*ppMemory
)
2695 /* for servers, we just point straight into the RPC buffer */
2696 *ppMemory
= pStubMsg
->Buffer
;
2699 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2700 safe_buffer_increment(pStubMsg
, size
);
2701 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
2703 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
2704 if (*ppMemory
!= saved_buffer
)
2705 memcpy(*ppMemory
, saved_buffer
, size
);
2710 /***********************************************************************
2711 * NdrConformantArrayBufferSize [RPCRT4.@]
2713 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2714 unsigned char *pMemory
,
2715 PFORMAT_STRING pFormat
)
2717 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
2718 unsigned char alignment
= pFormat
[1] + 1;
2720 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2721 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2723 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2725 SizeConformance(pStubMsg
);
2727 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
2729 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2730 /* conformance value plus array */
2731 safe_buffer_length_increment(pStubMsg
, size
);
2733 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
2736 /***********************************************************************
2737 * NdrConformantArrayMemorySize [RPCRT4.@]
2739 ULONG WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2740 PFORMAT_STRING pFormat
)
2742 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
2743 unsigned char alignment
= pFormat
[1] + 1;
2745 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2746 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2748 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2749 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2750 pStubMsg
->MemorySize
+= size
;
2752 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2753 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2754 safe_buffer_increment(pStubMsg
, size
);
2756 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2758 return pStubMsg
->MemorySize
;
2761 /***********************************************************************
2762 * NdrConformantArrayFree [RPCRT4.@]
2764 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
2765 unsigned char *pMemory
,
2766 PFORMAT_STRING pFormat
)
2768 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2769 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2771 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2773 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2777 /***********************************************************************
2778 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2780 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2781 unsigned char* pMemory
,
2782 PFORMAT_STRING pFormat
)
2785 unsigned char alignment
= pFormat
[1] + 1;
2786 DWORD esize
= *(const WORD
*)(pFormat
+2);
2788 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
2790 if (pFormat
[0] != RPC_FC_CVARRAY
)
2792 ERR("invalid format type %x\n", pFormat
[0]);
2793 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2797 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2798 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2800 WriteConformance(pStubMsg
);
2801 WriteVariance(pStubMsg
);
2803 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2805 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2807 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2808 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
2810 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2816 /***********************************************************************
2817 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2819 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2820 unsigned char** ppMemory
,
2821 PFORMAT_STRING pFormat
,
2822 unsigned char fMustAlloc
)
2824 ULONG bufsize
, memsize
;
2825 unsigned char alignment
= pFormat
[1] + 1;
2826 DWORD esize
= *(const WORD
*)(pFormat
+2);
2828 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2830 if (pFormat
[0] != RPC_FC_CVARRAY
)
2832 ERR("invalid format type %x\n", pFormat
[0]);
2833 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2837 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2838 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2840 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2842 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2843 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2845 if (!*ppMemory
|| fMustAlloc
)
2846 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2847 safe_copy_from_buffer(pStubMsg
, *ppMemory
+ pStubMsg
->Offset
, bufsize
);
2849 EmbeddedPointerUnmarshall(pStubMsg
, *ppMemory
, *ppMemory
, pFormat
, TRUE
/* FIXME */);
2855 /***********************************************************************
2856 * NdrConformantVaryingArrayFree [RPCRT4.@]
2858 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
2859 unsigned char* pMemory
,
2860 PFORMAT_STRING pFormat
)
2862 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2864 if (pFormat
[0] != RPC_FC_CVARRAY
)
2866 ERR("invalid format type %x\n", pFormat
[0]);
2867 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2871 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2872 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2874 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2878 /***********************************************************************
2879 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2881 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
2882 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
2884 unsigned char alignment
= pFormat
[1] + 1;
2885 DWORD esize
= *(const WORD
*)(pFormat
+2);
2887 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
2889 if (pFormat
[0] != RPC_FC_CVARRAY
)
2891 ERR("invalid format type %x\n", pFormat
[0]);
2892 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2897 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2898 /* compute length */
2899 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2901 SizeConformance(pStubMsg
);
2902 SizeVariance(pStubMsg
);
2904 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
2906 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
2908 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
2912 /***********************************************************************
2913 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2915 ULONG WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
2916 PFORMAT_STRING pFormat
)
2918 ULONG bufsize
, memsize
;
2919 unsigned char alignment
= pFormat
[1] + 1;
2920 DWORD esize
= *(const WORD
*)(pFormat
+2);
2922 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
2924 if (pFormat
[0] != RPC_FC_CVARRAY
)
2926 ERR("invalid format type %x\n", pFormat
[0]);
2927 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2928 return pStubMsg
->MemorySize
;
2931 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2932 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2934 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2936 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2937 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2939 safe_buffer_increment(pStubMsg
, bufsize
);
2940 pStubMsg
->MemorySize
+= memsize
;
2942 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2944 return pStubMsg
->MemorySize
;
2948 /***********************************************************************
2949 * NdrComplexArrayMarshall [RPCRT4.@]
2951 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2952 unsigned char *pMemory
,
2953 PFORMAT_STRING pFormat
)
2955 ULONG i
, count
, def
;
2956 BOOL variance_present
;
2957 unsigned char alignment
;
2958 int pointer_buffer_mark_set
= 0;
2960 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2962 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
2964 ERR("invalid format type %x\n", pFormat
[0]);
2965 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2969 alignment
= pFormat
[1] + 1;
2971 if (!pStubMsg
->PointerBufferMark
)
2973 /* save buffer fields that may be changed by buffer sizer functions
2974 * and that may be needed later on */
2975 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2976 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2977 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
2978 unsigned long saved_offset
= pStubMsg
->Offset
;
2979 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
2981 /* get the buffer pointer after complex array data, but before
2983 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- pStubMsg
->BufferStart
;
2984 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2985 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
2986 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2988 /* save it for use by embedded pointer code later */
2989 pStubMsg
->PointerBufferMark
= pStubMsg
->BufferStart
+ pStubMsg
->BufferLength
;
2990 TRACE("difference = 0x%x\n", pStubMsg
->Buffer
- pStubMsg
->BufferStart
);
2991 pointer_buffer_mark_set
= 1;
2993 /* restore fields */
2994 pStubMsg
->ActualCount
= saved_actual_count
;
2995 pStubMsg
->Offset
= saved_offset
;
2996 pStubMsg
->MaxCount
= saved_max_count
;
2997 pStubMsg
->BufferLength
= saved_buffer_length
;
3000 def
= *(const WORD
*)&pFormat
[2];
3003 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3004 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3006 variance_present
= IsConformanceOrVariancePresent(pFormat
);
3007 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3008 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3010 WriteConformance(pStubMsg
);
3011 if (variance_present
)
3012 WriteVariance(pStubMsg
);
3014 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3016 count
= pStubMsg
->ActualCount
;
3017 for (i
= 0; i
< count
; i
++)
3018 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
3020 STD_OVERFLOW_CHECK(pStubMsg
);
3022 if (pointer_buffer_mark_set
)
3024 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3025 pStubMsg
->PointerBufferMark
= NULL
;
3031 /***********************************************************************
3032 * NdrComplexArrayUnmarshall [RPCRT4.@]
3034 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3035 unsigned char **ppMemory
,
3036 PFORMAT_STRING pFormat
,
3037 unsigned char fMustAlloc
)
3039 ULONG i
, count
, size
;
3040 unsigned char alignment
;
3041 unsigned char *pMemory
;
3042 unsigned char *saved_buffer
;
3043 int pointer_buffer_mark_set
= 0;
3044 int saved_ignore_embedded
;
3046 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3048 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3050 ERR("invalid format type %x\n", pFormat
[0]);
3051 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3055 alignment
= pFormat
[1] + 1;
3057 saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3058 /* save buffer pointer */
3059 saved_buffer
= pStubMsg
->Buffer
;
3060 /* get the buffer pointer after complex array data, but before
3062 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3063 pStubMsg
->MemorySize
= 0;
3064 NdrComplexArrayMemorySize(pStubMsg
, pFormat
);
3065 size
= pStubMsg
->MemorySize
;
3066 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3068 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->Buffer
- saved_buffer
));
3069 if (!pStubMsg
->PointerBufferMark
)
3071 /* save it for use by embedded pointer code later */
3072 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3073 pointer_buffer_mark_set
= 1;
3075 /* restore the original buffer */
3076 pStubMsg
->Buffer
= saved_buffer
;
3080 pFormat
= ReadConformance(pStubMsg
, pFormat
);
3081 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3083 if (fMustAlloc
|| !*ppMemory
)
3085 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3086 memset(*ppMemory
, 0, size
);
3089 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3091 pMemory
= *ppMemory
;
3092 count
= pStubMsg
->ActualCount
;
3093 for (i
= 0; i
< count
; i
++)
3094 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
3096 if (pointer_buffer_mark_set
)
3098 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3099 pStubMsg
->PointerBufferMark
= NULL
;
3105 /***********************************************************************
3106 * NdrComplexArrayBufferSize [RPCRT4.@]
3108 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3109 unsigned char *pMemory
,
3110 PFORMAT_STRING pFormat
)
3112 ULONG i
, count
, def
;
3113 unsigned char alignment
;
3114 BOOL variance_present
;
3115 int pointer_length_set
= 0;
3117 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3119 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3121 ERR("invalid format type %x\n", pFormat
[0]);
3122 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3126 alignment
= pFormat
[1] + 1;
3128 if (!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
3130 /* save buffer fields that may be changed by buffer sizer functions
3131 * and that may be needed later on */
3132 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3133 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
3134 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
3135 unsigned long saved_offset
= pStubMsg
->Offset
;
3136 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
3138 /* get the buffer pointer after complex array data, but before
3140 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3141 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
3142 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3144 /* save it for use by embedded pointer code later */
3145 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3146 pointer_length_set
= 1;
3148 /* restore fields */
3149 pStubMsg
->ActualCount
= saved_actual_count
;
3150 pStubMsg
->Offset
= saved_offset
;
3151 pStubMsg
->MaxCount
= saved_max_count
;
3152 pStubMsg
->BufferLength
= saved_buffer_length
;
3154 def
= *(const WORD
*)&pFormat
[2];
3157 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3158 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3159 SizeConformance(pStubMsg
);
3161 variance_present
= IsConformanceOrVariancePresent(pFormat
);
3162 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3163 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3165 if (variance_present
)
3166 SizeVariance(pStubMsg
);
3168 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
3170 count
= pStubMsg
->ActualCount
;
3171 for (i
= 0; i
< count
; i
++)
3172 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
3174 if(pointer_length_set
)
3176 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3177 pStubMsg
->PointerLength
= 0;
3181 /***********************************************************************
3182 * NdrComplexArrayMemorySize [RPCRT4.@]
3184 ULONG WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3185 PFORMAT_STRING pFormat
)
3187 ULONG i
, count
, esize
, SavedMemorySize
, MemorySize
;
3188 unsigned char alignment
;
3189 unsigned char *Buffer
;
3191 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3193 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3195 ERR("invalid format type %x\n", pFormat
[0]);
3196 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3200 alignment
= pFormat
[1] + 1;
3204 pFormat
= ReadConformance(pStubMsg
, pFormat
);
3205 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3207 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3209 SavedMemorySize
= pStubMsg
->MemorySize
;
3211 Buffer
= pStubMsg
->Buffer
;
3212 pStubMsg
->MemorySize
= 0;
3213 esize
= ComplexStructMemorySize(pStubMsg
, pFormat
);
3214 pStubMsg
->Buffer
= Buffer
;
3216 MemorySize
= safe_multiply(pStubMsg
->MaxCount
, esize
);
3218 count
= pStubMsg
->ActualCount
;
3219 for (i
= 0; i
< count
; i
++)
3220 ComplexStructMemorySize(pStubMsg
, pFormat
);
3222 pStubMsg
->MemorySize
= SavedMemorySize
;
3224 pStubMsg
->MemorySize
+= MemorySize
;
3228 /***********************************************************************
3229 * NdrComplexArrayFree [RPCRT4.@]
3231 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3232 unsigned char *pMemory
,
3233 PFORMAT_STRING pFormat
)
3235 ULONG i
, count
, def
;
3237 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, 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 def
= *(const WORD
*)&pFormat
[2];
3249 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3250 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3252 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3253 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3255 count
= pStubMsg
->ActualCount
;
3256 for (i
= 0; i
< count
; i
++)
3257 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
3260 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg
,
3261 USER_MARSHAL_CB_TYPE cbtype
, PFORMAT_STRING pFormat
,
3262 USER_MARSHAL_CB
*umcb
)
3264 umcb
->Flags
= MAKELONG(pStubMsg
->dwDestContext
,
3265 pStubMsg
->RpcMsg
->DataRepresentation
);
3266 umcb
->pStubMsg
= pStubMsg
;
3267 umcb
->pReserve
= NULL
;
3268 umcb
->Signature
= USER_MARSHAL_CB_SIGNATURE
;
3269 umcb
->CBType
= cbtype
;
3270 umcb
->pFormat
= pFormat
;
3271 umcb
->pTypeFormat
= NULL
/* FIXME */;
3274 #define USER_MARSHAL_PTR_PREFIX \
3275 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3276 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3278 /***********************************************************************
3279 * NdrUserMarshalMarshall [RPCRT4.@]
3281 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3282 unsigned char *pMemory
,
3283 PFORMAT_STRING pFormat
)
3285 unsigned flags
= pFormat
[1];
3286 unsigned index
= *(const WORD
*)&pFormat
[2];
3287 unsigned char *saved_buffer
= NULL
;
3288 USER_MARSHAL_CB umcb
;
3290 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3291 TRACE("index=%d\n", index
);
3293 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_MARSHALL
, pFormat
, &umcb
);
3295 if (flags
& USER_MARSHAL_POINTER
)
3297 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3298 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, USER_MARSHAL_PTR_PREFIX
);
3299 pStubMsg
->Buffer
+= 4;
3300 if (pStubMsg
->PointerBufferMark
)
3302 saved_buffer
= pStubMsg
->Buffer
;
3303 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3304 pStubMsg
->PointerBufferMark
= NULL
;
3306 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3309 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3312 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
3313 &umcb
.Flags
, pStubMsg
->Buffer
, pMemory
);
3317 STD_OVERFLOW_CHECK(pStubMsg
);
3318 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3319 pStubMsg
->Buffer
= saved_buffer
;
3322 STD_OVERFLOW_CHECK(pStubMsg
);
3327 /***********************************************************************
3328 * NdrUserMarshalUnmarshall [RPCRT4.@]
3330 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3331 unsigned char **ppMemory
,
3332 PFORMAT_STRING pFormat
,
3333 unsigned char fMustAlloc
)
3335 unsigned flags
= pFormat
[1];
3336 unsigned index
= *(const WORD
*)&pFormat
[2];
3337 DWORD memsize
= *(const WORD
*)&pFormat
[4];
3338 unsigned char *saved_buffer
= NULL
;
3339 USER_MARSHAL_CB umcb
;
3341 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3342 TRACE("index=%d\n", index
);
3344 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_UNMARSHALL
, pFormat
, &umcb
);
3346 if (flags
& USER_MARSHAL_POINTER
)
3348 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3349 /* skip pointer prefix */
3350 pStubMsg
->Buffer
+= 4;
3351 if (pStubMsg
->PointerBufferMark
)
3353 saved_buffer
= pStubMsg
->Buffer
;
3354 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3355 pStubMsg
->PointerBufferMark
= NULL
;
3357 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3360 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3362 if (fMustAlloc
|| !*ppMemory
)
3363 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
3366 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
3367 &umcb
.Flags
, pStubMsg
->Buffer
, *ppMemory
);
3371 STD_OVERFLOW_CHECK(pStubMsg
);
3372 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3373 pStubMsg
->Buffer
= saved_buffer
;
3379 /***********************************************************************
3380 * NdrUserMarshalBufferSize [RPCRT4.@]
3382 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3383 unsigned char *pMemory
,
3384 PFORMAT_STRING pFormat
)
3386 unsigned flags
= pFormat
[1];
3387 unsigned index
= *(const WORD
*)&pFormat
[2];
3388 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
3389 USER_MARSHAL_CB umcb
;
3390 unsigned long saved_buffer_length
= 0;
3392 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3393 TRACE("index=%d\n", index
);
3395 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_BUFFER_SIZE
, pFormat
, &umcb
);
3397 if (flags
& USER_MARSHAL_POINTER
)
3399 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
3400 /* skip pointer prefix */
3401 safe_buffer_length_increment(pStubMsg
, 4);
3402 if (pStubMsg
->IgnoreEmbeddedPointers
)
3404 if (pStubMsg
->PointerLength
)
3406 saved_buffer_length
= pStubMsg
->BufferLength
;
3407 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3408 pStubMsg
->PointerLength
= 0;
3410 ALIGN_LENGTH(pStubMsg
->BufferLength
, 8);
3413 ALIGN_LENGTH(pStubMsg
->BufferLength
, (flags
& 0xf) + 1);
3416 TRACE("size=%d\n", bufsize
);
3417 safe_buffer_length_increment(pStubMsg
, bufsize
);
3420 pStubMsg
->BufferLength
=
3421 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
3422 &umcb
.Flags
, pStubMsg
->BufferLength
, pMemory
);
3424 if (saved_buffer_length
)
3426 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3427 pStubMsg
->BufferLength
= saved_buffer_length
;
3432 /***********************************************************************
3433 * NdrUserMarshalMemorySize [RPCRT4.@]
3435 ULONG WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3436 PFORMAT_STRING pFormat
)
3438 unsigned flags
= pFormat
[1];
3439 unsigned index
= *(const WORD
*)&pFormat
[2];
3440 DWORD memsize
= *(const WORD
*)&pFormat
[4];
3441 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
3443 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3444 TRACE("index=%d\n", index
);
3446 pStubMsg
->MemorySize
+= memsize
;
3448 if (flags
& USER_MARSHAL_POINTER
)
3450 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3451 /* skip pointer prefix */
3452 pStubMsg
->Buffer
+= 4;
3453 if (pStubMsg
->IgnoreEmbeddedPointers
)
3454 return pStubMsg
->MemorySize
;
3455 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3458 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3461 FIXME("not implemented for varying buffer size\n");
3463 pStubMsg
->Buffer
+= bufsize
;
3465 return pStubMsg
->MemorySize
;
3468 /***********************************************************************
3469 * NdrUserMarshalFree [RPCRT4.@]
3471 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
3472 unsigned char *pMemory
,
3473 PFORMAT_STRING pFormat
)
3475 /* unsigned flags = pFormat[1]; */
3476 unsigned index
= *(const WORD
*)&pFormat
[2];
3477 USER_MARSHAL_CB umcb
;
3479 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3480 TRACE("index=%d\n", index
);
3482 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_FREE
, pFormat
, &umcb
);
3484 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
3485 &umcb
.Flags
, pMemory
);
3488 /***********************************************************************
3489 * NdrClearOutParameters [RPCRT4.@]
3491 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
3492 PFORMAT_STRING pFormat
,
3495 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
3498 /***********************************************************************
3499 * NdrConvert [RPCRT4.@]
3501 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
3503 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
3504 /* FIXME: since this stub doesn't do any converting, the proper behavior
3505 is to raise an exception */
3508 /***********************************************************************
3509 * NdrConvert2 [RPCRT4.@]
3511 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, LONG NumberParams
)
3513 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3514 pStubMsg
, pFormat
, NumberParams
);
3515 /* FIXME: since this stub doesn't do any converting, the proper behavior
3516 is to raise an exception */
3519 #include "pshpack1.h"
3520 typedef struct _NDR_CSTRUCT_FORMAT
3523 unsigned char alignment
;
3524 unsigned short memory_size
;
3525 short offset_to_array_description
;
3526 } NDR_CSTRUCT_FORMAT
, NDR_CVSTRUCT_FORMAT
;
3527 #include "poppack.h"
3529 /***********************************************************************
3530 * NdrConformantStructMarshall [RPCRT4.@]
3532 unsigned char * WINAPI
NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3533 unsigned char *pMemory
,
3534 PFORMAT_STRING pFormat
)
3536 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3537 PFORMAT_STRING pCArrayFormat
;
3538 ULONG esize
, bufsize
;
3540 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3542 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3543 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3545 ERR("invalid format type %x\n", pCStructFormat
->type
);
3546 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3550 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3551 pCStructFormat
->offset_to_array_description
;
3552 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3554 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3555 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3558 esize
= *(const WORD
*)(pCArrayFormat
+2);
3560 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
3561 pCArrayFormat
+ 4, 0);
3563 WriteConformance(pStubMsg
);
3565 ALIGN_POINTER(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
3567 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3569 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3570 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
3572 ERR("integer overflow of memory_size %u with bufsize %u\n",
3573 pCStructFormat
->memory_size
, bufsize
);
3574 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3576 /* copy constant sized part of struct */
3577 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3578 safe_copy_to_buffer(pStubMsg
, pMemory
, pCStructFormat
->memory_size
+ bufsize
);
3580 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3581 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3586 /***********************************************************************
3587 * NdrConformantStructUnmarshall [RPCRT4.@]
3589 unsigned char * WINAPI
NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3590 unsigned char **ppMemory
,
3591 PFORMAT_STRING pFormat
,
3592 unsigned char fMustAlloc
)
3594 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3595 PFORMAT_STRING pCArrayFormat
;
3596 ULONG esize
, bufsize
;
3597 unsigned char *saved_buffer
;
3599 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3601 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3602 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3604 ERR("invalid format type %x\n", pCStructFormat
->type
);
3605 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3608 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3609 pCStructFormat
->offset_to_array_description
;
3610 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3612 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3613 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3616 esize
= *(const WORD
*)(pCArrayFormat
+2);
3618 pCArrayFormat
= ReadConformance(pStubMsg
, pCArrayFormat
+ 4);
3620 ALIGN_POINTER(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
3622 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3624 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3625 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
3627 ERR("integer overflow of memory_size %u with bufsize %u\n",
3628 pCStructFormat
->memory_size
, bufsize
);
3629 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3634 SIZE_T size
= pCStructFormat
->memory_size
+ bufsize
;
3635 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3639 if (!pStubMsg
->IsClient
&& !*ppMemory
)
3640 /* for servers, we just point straight into the RPC buffer */
3641 *ppMemory
= pStubMsg
->Buffer
;
3644 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3645 safe_buffer_increment(pStubMsg
, pCStructFormat
->memory_size
+ bufsize
);
3646 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3647 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
3649 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
3650 if (*ppMemory
!= saved_buffer
)
3651 memcpy(*ppMemory
, saved_buffer
, pCStructFormat
->memory_size
+ bufsize
);
3656 /***********************************************************************
3657 * NdrConformantStructBufferSize [RPCRT4.@]
3659 void WINAPI
NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3660 unsigned char *pMemory
,
3661 PFORMAT_STRING pFormat
)
3663 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3664 PFORMAT_STRING pCArrayFormat
;
3667 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3669 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3670 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3672 ERR("invalid format type %x\n", pCStructFormat
->type
);
3673 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3676 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3677 pCStructFormat
->offset_to_array_description
;
3678 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3680 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3681 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3684 esize
= *(const WORD
*)(pCArrayFormat
+2);
3686 pCArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
, pCArrayFormat
+4, 0);
3687 SizeConformance(pStubMsg
);
3689 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCStructFormat
->alignment
+ 1);
3691 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3693 safe_buffer_length_increment(pStubMsg
, pCStructFormat
->memory_size
);
3694 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
3696 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3697 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3700 /***********************************************************************
3701 * NdrConformantStructMemorySize [RPCRT4.@]
3703 ULONG WINAPI
NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3704 PFORMAT_STRING pFormat
)
3710 /***********************************************************************
3711 * NdrConformantStructFree [RPCRT4.@]
3713 void WINAPI
NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3714 unsigned char *pMemory
,
3715 PFORMAT_STRING pFormat
)
3717 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3718 PFORMAT_STRING pCArrayFormat
;
3721 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3723 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3724 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3726 ERR("invalid format type %x\n", pCStructFormat
->type
);
3727 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3731 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3732 pCStructFormat
->offset_to_array_description
;
3733 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3735 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3736 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3739 esize
= *(const WORD
*)(pCArrayFormat
+2);
3741 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
3742 pCArrayFormat
+ 4, 0);
3744 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3746 /* copy constant sized part of struct */
3747 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3749 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3750 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
3753 /***********************************************************************
3754 * NdrConformantVaryingStructMarshall [RPCRT4.@]
3756 unsigned char * WINAPI
NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3757 unsigned char *pMemory
,
3758 PFORMAT_STRING pFormat
)
3760 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3761 PFORMAT_STRING pCVArrayFormat
;
3762 ULONG esize
, bufsize
;
3764 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3766 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3767 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3769 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3770 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3774 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3775 pCVStructFormat
->offset_to_array_description
;
3776 switch (*pCVArrayFormat
)
3778 case RPC_FC_CVARRAY
:
3779 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3781 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3782 pCVArrayFormat
+ 4, 0);
3783 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3786 case RPC_FC_C_CSTRING
:
3787 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
3788 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
3789 esize
= sizeof(char);
3790 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3791 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3792 pCVArrayFormat
+ 2, 0);
3794 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3796 case RPC_FC_C_WSTRING
:
3797 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
3798 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
3799 esize
= sizeof(WCHAR
);
3800 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3801 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3802 pCVArrayFormat
+ 2, 0);
3804 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3807 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3808 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3812 WriteConformance(pStubMsg
);
3814 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
3816 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3818 /* write constant sized part */
3819 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3820 safe_copy_to_buffer(pStubMsg
, pMemory
, pCVStructFormat
->memory_size
);
3822 WriteVariance(pStubMsg
);
3824 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3826 /* write array part */
3827 safe_copy_to_buffer(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
, bufsize
);
3829 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3834 /***********************************************************************
3835 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3837 unsigned char * WINAPI
NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3838 unsigned char **ppMemory
,
3839 PFORMAT_STRING pFormat
,
3840 unsigned char fMustAlloc
)
3842 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3843 PFORMAT_STRING pCVArrayFormat
;
3844 ULONG esize
, bufsize
;
3845 unsigned char cvarray_type
;
3847 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3849 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3850 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3852 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3853 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3857 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3858 pCVStructFormat
->offset_to_array_description
;
3859 cvarray_type
= *pCVArrayFormat
;
3860 switch (cvarray_type
)
3862 case RPC_FC_CVARRAY
:
3863 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3864 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 4);
3866 case RPC_FC_C_CSTRING
:
3867 esize
= sizeof(char);
3868 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3869 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3871 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3873 case RPC_FC_C_WSTRING
:
3874 esize
= sizeof(WCHAR
);
3875 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3876 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3878 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3881 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3882 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3886 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
3888 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3890 /* work out how much memory to allocate if we need to do so */
3891 if (!*ppMemory
|| fMustAlloc
)
3893 SIZE_T size
= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->MaxCount
);
3894 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3897 /* copy the constant data */
3898 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3899 safe_copy_from_buffer(pStubMsg
, *ppMemory
, pCVStructFormat
->memory_size
);
3901 pCVArrayFormat
= ReadVariance(pStubMsg
, pCVArrayFormat
, pStubMsg
->MaxCount
);
3903 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3905 if ((cvarray_type
== RPC_FC_C_CSTRING
) ||
3906 (cvarray_type
== RPC_FC_C_WSTRING
))
3909 /* strings must always have null terminating bytes */
3910 if (bufsize
< esize
)
3912 ERR("invalid string length of %d\n", pStubMsg
->ActualCount
);
3913 RpcRaiseException(RPC_S_INVALID_BOUND
);
3916 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
3917 if (pStubMsg
->Buffer
[i
] != 0)
3919 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
3920 i
, pStubMsg
->Buffer
[i
]);
3921 RpcRaiseException(RPC_S_INVALID_BOUND
);
3926 /* copy the array data */
3927 safe_copy_from_buffer(pStubMsg
, *ppMemory
+ pCVStructFormat
->memory_size
, bufsize
);
3929 if (cvarray_type
== RPC_FC_C_CSTRING
)
3930 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory
+ pCVStructFormat
->memory_size
)));
3931 else if (cvarray_type
== RPC_FC_C_WSTRING
)
3932 TRACE("string=%s\n", debugstr_w((WCHAR
*)(*ppMemory
+ pCVStructFormat
->memory_size
)));
3934 EmbeddedPointerUnmarshall(pStubMsg
, *ppMemory
, *ppMemory
, pFormat
, TRUE
/* FIXME */);
3939 /***********************************************************************
3940 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3942 void WINAPI
NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3943 unsigned char *pMemory
,
3944 PFORMAT_STRING pFormat
)
3946 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3947 PFORMAT_STRING pCVArrayFormat
;
3950 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3952 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3953 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3955 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3956 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3960 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3961 pCVStructFormat
->offset_to_array_description
;
3962 switch (*pCVArrayFormat
)
3964 case RPC_FC_CVARRAY
:
3965 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3967 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3968 pCVArrayFormat
+ 4, 0);
3969 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3972 case RPC_FC_C_CSTRING
:
3973 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
3974 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
3975 esize
= sizeof(char);
3976 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3977 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3978 pCVArrayFormat
+ 2, 0);
3980 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3982 case RPC_FC_C_WSTRING
:
3983 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
3984 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
3985 esize
= sizeof(WCHAR
);
3986 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3987 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3988 pCVArrayFormat
+ 2, 0);
3990 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3993 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3994 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3998 SizeConformance(pStubMsg
);
4000 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCVStructFormat
->alignment
+ 1);
4002 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4004 safe_buffer_length_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4005 SizeVariance(pStubMsg
);
4006 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
4008 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4011 /***********************************************************************
4012 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4014 ULONG WINAPI
NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4015 PFORMAT_STRING pFormat
)
4017 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4018 PFORMAT_STRING pCVArrayFormat
;
4020 unsigned char cvarray_type
;
4022 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4024 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4025 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4027 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4028 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4032 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4033 pCVStructFormat
->offset_to_array_description
;
4034 cvarray_type
= *pCVArrayFormat
;
4035 switch (cvarray_type
)
4037 case RPC_FC_CVARRAY
:
4038 esize
= *(const WORD
*)(pCVArrayFormat
+2);
4039 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 4);
4041 case RPC_FC_C_CSTRING
:
4042 esize
= sizeof(char);
4043 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4044 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
4046 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
4048 case RPC_FC_C_WSTRING
:
4049 esize
= sizeof(WCHAR
);
4050 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4051 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
4053 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
4056 ERR("invalid array format type %x\n", *pCVArrayFormat
);
4057 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4061 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4063 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4065 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4066 pCVArrayFormat
= ReadVariance(pStubMsg
, pCVArrayFormat
, pStubMsg
->MaxCount
);
4067 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
4069 pStubMsg
->MemorySize
+= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->MaxCount
);
4071 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4073 return pCVStructFormat
->memory_size
+ pStubMsg
->MaxCount
* esize
;
4076 /***********************************************************************
4077 * NdrConformantVaryingStructFree [RPCRT4.@]
4079 void WINAPI
NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
4080 unsigned char *pMemory
,
4081 PFORMAT_STRING pFormat
)
4083 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4084 PFORMAT_STRING pCVArrayFormat
;
4087 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4089 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4090 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4092 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4093 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4097 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4098 pCVStructFormat
->offset_to_array_description
;
4099 switch (*pCVArrayFormat
)
4101 case RPC_FC_CVARRAY
:
4102 esize
= *(const WORD
*)(pCVArrayFormat
+2);
4104 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4105 pCVArrayFormat
+ 4, 0);
4106 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4109 case RPC_FC_C_CSTRING
:
4110 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
4111 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
4112 esize
= sizeof(char);
4113 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4114 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4115 pCVArrayFormat
+ 2, 0);
4117 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4119 case RPC_FC_C_WSTRING
:
4120 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
4121 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
4122 esize
= sizeof(WCHAR
);
4123 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4124 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4125 pCVArrayFormat
+ 2, 0);
4127 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4130 ERR("invalid array format type %x\n", *pCVArrayFormat
);
4131 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4135 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4137 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4140 #include "pshpack1.h"
4144 unsigned char alignment
;
4145 unsigned short total_size
;
4146 } NDR_SMFARRAY_FORMAT
;
4151 unsigned char alignment
;
4152 unsigned long total_size
;
4153 } NDR_LGFARRAY_FORMAT
;
4154 #include "poppack.h"
4156 /***********************************************************************
4157 * NdrFixedArrayMarshall [RPCRT4.@]
4159 unsigned char * WINAPI
NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4160 unsigned char *pMemory
,
4161 PFORMAT_STRING pFormat
)
4163 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4164 unsigned long total_size
;
4166 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4168 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4169 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4171 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4172 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4176 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4178 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4180 total_size
= pSmFArrayFormat
->total_size
;
4181 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4185 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4186 total_size
= pLgFArrayFormat
->total_size
;
4187 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4190 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4191 safe_copy_to_buffer(pStubMsg
, pMemory
, total_size
);
4193 pFormat
= EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4198 /***********************************************************************
4199 * NdrFixedArrayUnmarshall [RPCRT4.@]
4201 unsigned char * WINAPI
NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4202 unsigned char **ppMemory
,
4203 PFORMAT_STRING pFormat
,
4204 unsigned char fMustAlloc
)
4206 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4207 unsigned long total_size
;
4208 unsigned char *saved_buffer
;
4210 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4212 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4213 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4215 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4216 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4220 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4222 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4224 total_size
= pSmFArrayFormat
->total_size
;
4225 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4229 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4230 total_size
= pLgFArrayFormat
->total_size
;
4231 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4235 *ppMemory
= NdrAllocate(pStubMsg
, total_size
);
4238 if (!pStubMsg
->IsClient
&& !*ppMemory
)
4239 /* for servers, we just point straight into the RPC buffer */
4240 *ppMemory
= pStubMsg
->Buffer
;
4243 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4244 safe_buffer_increment(pStubMsg
, total_size
);
4245 pFormat
= EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4247 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
4248 if (*ppMemory
!= saved_buffer
)
4249 memcpy(*ppMemory
, saved_buffer
, total_size
);
4254 /***********************************************************************
4255 * NdrFixedArrayBufferSize [RPCRT4.@]
4257 void WINAPI
NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4258 unsigned char *pMemory
,
4259 PFORMAT_STRING pFormat
)
4261 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4262 unsigned long total_size
;
4264 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4266 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4267 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4269 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4270 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4274 ALIGN_LENGTH(pStubMsg
->BufferLength
, pSmFArrayFormat
->alignment
+ 1);
4276 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4278 total_size
= pSmFArrayFormat
->total_size
;
4279 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4283 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4284 total_size
= pLgFArrayFormat
->total_size
;
4285 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4287 safe_buffer_length_increment(pStubMsg
, total_size
);
4289 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4292 /***********************************************************************
4293 * NdrFixedArrayMemorySize [RPCRT4.@]
4295 ULONG WINAPI
NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4296 PFORMAT_STRING pFormat
)
4298 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4301 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4303 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4304 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4306 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4307 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4311 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4313 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4315 total_size
= pSmFArrayFormat
->total_size
;
4316 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4320 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4321 total_size
= pLgFArrayFormat
->total_size
;
4322 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4324 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4325 safe_buffer_increment(pStubMsg
, total_size
);
4326 pStubMsg
->MemorySize
+= total_size
;
4328 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4333 /***********************************************************************
4334 * NdrFixedArrayFree [RPCRT4.@]
4336 void WINAPI
NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4337 unsigned char *pMemory
,
4338 PFORMAT_STRING pFormat
)
4340 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4342 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4344 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4345 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4347 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4348 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4352 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4353 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4356 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4357 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4360 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4363 /***********************************************************************
4364 * NdrVaryingArrayMarshall [RPCRT4.@]
4366 unsigned char * WINAPI
NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4367 unsigned char *pMemory
,
4368 PFORMAT_STRING pFormat
)
4370 unsigned char alignment
;
4371 DWORD elements
, esize
;
4374 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4376 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4377 (pFormat
[0] != RPC_FC_LGVARRAY
))
4379 ERR("invalid format type %x\n", pFormat
[0]);
4380 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4384 alignment
= pFormat
[1] + 1;
4386 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4389 pFormat
+= sizeof(WORD
);
4390 elements
= *(const WORD
*)pFormat
;
4391 pFormat
+= sizeof(WORD
);
4396 pFormat
+= sizeof(DWORD
);
4397 elements
= *(const DWORD
*)pFormat
;
4398 pFormat
+= sizeof(DWORD
);
4401 esize
= *(const WORD
*)pFormat
;
4402 pFormat
+= sizeof(WORD
);
4404 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4405 if ((pStubMsg
->ActualCount
> elements
) ||
4406 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4408 RpcRaiseException(RPC_S_INVALID_BOUND
);
4412 WriteVariance(pStubMsg
);
4414 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4416 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4417 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4418 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
4420 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4425 /***********************************************************************
4426 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4428 unsigned char * WINAPI
NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4429 unsigned char **ppMemory
,
4430 PFORMAT_STRING pFormat
,
4431 unsigned char fMustAlloc
)
4433 unsigned char alignment
;
4434 DWORD size
, elements
, esize
;
4437 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4439 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4440 (pFormat
[0] != RPC_FC_LGVARRAY
))
4442 ERR("invalid format type %x\n", pFormat
[0]);
4443 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4447 alignment
= pFormat
[1] + 1;
4449 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4452 size
= *(const WORD
*)pFormat
;
4453 pFormat
+= sizeof(WORD
);
4454 elements
= *(const WORD
*)pFormat
;
4455 pFormat
+= sizeof(WORD
);
4460 size
= *(const DWORD
*)pFormat
;
4461 pFormat
+= sizeof(DWORD
);
4462 elements
= *(const DWORD
*)pFormat
;
4463 pFormat
+= sizeof(DWORD
);
4466 esize
= *(const WORD
*)pFormat
;
4467 pFormat
+= sizeof(WORD
);
4469 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
4471 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4473 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4475 if (!*ppMemory
|| fMustAlloc
)
4476 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4477 safe_copy_from_buffer(pStubMsg
, *ppMemory
+ pStubMsg
->Offset
, bufsize
);
4479 EmbeddedPointerUnmarshall(pStubMsg
, *ppMemory
, *ppMemory
, pFormat
, TRUE
/* FIXME */);
4484 /***********************************************************************
4485 * NdrVaryingArrayBufferSize [RPCRT4.@]
4487 void WINAPI
NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4488 unsigned char *pMemory
,
4489 PFORMAT_STRING pFormat
)
4491 unsigned char alignment
;
4492 DWORD elements
, esize
;
4494 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4496 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4497 (pFormat
[0] != RPC_FC_LGVARRAY
))
4499 ERR("invalid format type %x\n", pFormat
[0]);
4500 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4504 alignment
= pFormat
[1] + 1;
4506 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4509 pFormat
+= sizeof(WORD
);
4510 elements
= *(const WORD
*)pFormat
;
4511 pFormat
+= sizeof(WORD
);
4516 pFormat
+= sizeof(DWORD
);
4517 elements
= *(const DWORD
*)pFormat
;
4518 pFormat
+= sizeof(DWORD
);
4521 esize
= *(const WORD
*)pFormat
;
4522 pFormat
+= sizeof(WORD
);
4524 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4525 if ((pStubMsg
->ActualCount
> elements
) ||
4526 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4528 RpcRaiseException(RPC_S_INVALID_BOUND
);
4532 SizeVariance(pStubMsg
);
4534 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
4536 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
4538 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4541 /***********************************************************************
4542 * NdrVaryingArrayMemorySize [RPCRT4.@]
4544 ULONG WINAPI
NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4545 PFORMAT_STRING pFormat
)
4547 unsigned char alignment
;
4548 DWORD size
, elements
, esize
;
4550 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4552 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4553 (pFormat
[0] != RPC_FC_LGVARRAY
))
4555 ERR("invalid format type %x\n", pFormat
[0]);
4556 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4560 alignment
= pFormat
[1] + 1;
4562 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4565 size
= *(const WORD
*)pFormat
;
4566 pFormat
+= sizeof(WORD
);
4567 elements
= *(const WORD
*)pFormat
;
4568 pFormat
+= sizeof(WORD
);
4573 size
= *(const DWORD
*)pFormat
;
4574 pFormat
+= sizeof(DWORD
);
4575 elements
= *(const DWORD
*)pFormat
;
4576 pFormat
+= sizeof(DWORD
);
4579 esize
= *(const WORD
*)pFormat
;
4580 pFormat
+= sizeof(WORD
);
4582 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
4584 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4586 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
4587 pStubMsg
->MemorySize
+= size
;
4589 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4591 return pStubMsg
->MemorySize
;
4594 /***********************************************************************
4595 * NdrVaryingArrayFree [RPCRT4.@]
4597 void WINAPI
NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4598 unsigned char *pMemory
,
4599 PFORMAT_STRING pFormat
)
4601 unsigned char alignment
;
4604 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4606 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4607 (pFormat
[0] != RPC_FC_LGVARRAY
))
4609 ERR("invalid format type %x\n", pFormat
[0]);
4610 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4614 alignment
= pFormat
[1] + 1;
4616 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4619 pFormat
+= sizeof(WORD
);
4620 elements
= *(const WORD
*)pFormat
;
4621 pFormat
+= sizeof(WORD
);
4626 pFormat
+= sizeof(DWORD
);
4627 elements
= *(const DWORD
*)pFormat
;
4628 pFormat
+= sizeof(DWORD
);
4631 pFormat
+= sizeof(WORD
);
4633 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4634 if ((pStubMsg
->ActualCount
> elements
) ||
4635 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4637 RpcRaiseException(RPC_S_INVALID_BOUND
);
4641 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4644 static ULONG
get_discriminant(unsigned char fc
, const unsigned char *pMemory
)
4652 return *(const UCHAR
*)pMemory
;
4657 return *(const USHORT
*)pMemory
;
4661 return *(const ULONG
*)pMemory
;
4663 FIXME("Unhandled base type: 0x%02x\n", fc
);
4668 static PFORMAT_STRING
get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg
,
4669 unsigned long discriminant
,
4670 PFORMAT_STRING pFormat
)
4672 unsigned short num_arms
, arm
, type
;
4674 num_arms
= *(const SHORT
*)pFormat
& 0x0fff;
4676 for(arm
= 0; arm
< num_arms
; arm
++)
4678 if(discriminant
== *(const ULONG
*)pFormat
)
4686 type
= *(const unsigned short*)pFormat
;
4687 TRACE("type %04x\n", type
);
4688 if(arm
== num_arms
) /* default arm extras */
4692 ERR("no arm for 0x%lx and no default case\n", discriminant
);
4693 RpcRaiseException(RPC_S_INVALID_TAG
);
4698 TRACE("falling back to empty default case for 0x%lx\n", discriminant
);
4705 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
, ULONG discriminant
, PFORMAT_STRING pFormat
)
4707 unsigned short type
;
4711 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4715 type
= *(const unsigned short*)pFormat
;
4716 if((type
& 0xff00) == 0x8000)
4718 unsigned char basetype
= LOBYTE(type
);
4719 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &basetype
);
4723 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4724 NDR_MARSHALL m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
4727 unsigned char *saved_buffer
= NULL
;
4728 int pointer_buffer_mark_set
= 0;
4735 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4736 saved_buffer
= pStubMsg
->Buffer
;
4737 if (pStubMsg
->PointerBufferMark
)
4739 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4740 pStubMsg
->PointerBufferMark
= NULL
;
4741 pointer_buffer_mark_set
= 1;
4744 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
4746 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char **)pMemory
, desc
);
4747 if (pointer_buffer_mark_set
)
4749 STD_OVERFLOW_CHECK(pStubMsg
);
4750 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4751 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
4753 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
4754 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
4755 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4757 pStubMsg
->Buffer
= saved_buffer
+ 4;
4761 m(pStubMsg
, pMemory
, desc
);
4764 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4769 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4770 unsigned char **ppMemory
,
4772 PFORMAT_STRING pFormat
,
4773 unsigned char fMustAlloc
)
4775 unsigned short type
;
4779 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4783 type
= *(const unsigned short*)pFormat
;
4784 if((type
& 0xff00) == 0x8000)
4786 unsigned char basetype
= LOBYTE(type
);
4787 return NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &basetype
, FALSE
);
4791 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4792 NDR_UNMARSHALL m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
4795 unsigned char *saved_buffer
= NULL
;
4796 int pointer_buffer_mark_set
= 0;
4803 **(void***)ppMemory
= NULL
;
4804 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4805 saved_buffer
= pStubMsg
->Buffer
;
4806 if (pStubMsg
->PointerBufferMark
)
4808 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4809 pStubMsg
->PointerBufferMark
= NULL
;
4810 pointer_buffer_mark_set
= 1;
4813 pStubMsg
->Buffer
+= 4; /* for pointer ID */
4815 if (saved_buffer
+ 4 > pStubMsg
->BufferEnd
)
4817 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
4818 saved_buffer
, pStubMsg
->BufferEnd
);
4819 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4822 PointerUnmarshall(pStubMsg
, saved_buffer
, *(unsigned char ***)ppMemory
, **(unsigned char ***)ppMemory
, desc
, fMustAlloc
);
4823 if (pointer_buffer_mark_set
)
4825 STD_OVERFLOW_CHECK(pStubMsg
);
4826 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4827 pStubMsg
->Buffer
= saved_buffer
+ 4;
4831 m(pStubMsg
, ppMemory
, desc
, fMustAlloc
);
4834 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4839 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg
,
4840 unsigned char *pMemory
,
4842 PFORMAT_STRING pFormat
)
4844 unsigned short type
;
4848 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4852 type
= *(const unsigned short*)pFormat
;
4853 if((type
& 0xff00) == 0x8000)
4855 unsigned char basetype
= LOBYTE(type
);
4856 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &basetype
);
4860 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4861 NDR_BUFFERSIZE m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
4870 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
4871 safe_buffer_length_increment(pStubMsg
, 4); /* for pointer ID */
4872 if (!pStubMsg
->IgnoreEmbeddedPointers
)
4874 int saved_buffer_length
= pStubMsg
->BufferLength
;
4875 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4876 pStubMsg
->PointerLength
= 0;
4877 if(!pStubMsg
->BufferLength
)
4878 ERR("BufferLength == 0??\n");
4879 PointerBufferSize(pStubMsg
, *(unsigned char **)pMemory
, desc
);
4880 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4881 pStubMsg
->BufferLength
= saved_buffer_length
;
4885 m(pStubMsg
, pMemory
, desc
);
4888 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
4892 static ULONG
union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg
,
4894 PFORMAT_STRING pFormat
)
4896 unsigned short type
, size
;
4898 size
= *(const unsigned short*)pFormat
;
4899 pStubMsg
->Memory
+= size
;
4902 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4906 type
= *(const unsigned short*)pFormat
;
4907 if((type
& 0xff00) == 0x8000)
4909 return NdrBaseTypeMemorySize(pStubMsg
, pFormat
);
4913 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4914 NDR_MEMORYSIZE m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
4915 unsigned char *saved_buffer
;
4924 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4925 saved_buffer
= pStubMsg
->Buffer
;
4926 safe_buffer_increment(pStubMsg
, 4);
4927 ALIGN_LENGTH(pStubMsg
->MemorySize
, 4);
4928 pStubMsg
->MemorySize
+= 4;
4929 if (!pStubMsg
->IgnoreEmbeddedPointers
)
4930 PointerMemorySize(pStubMsg
, saved_buffer
, pFormat
);
4933 return m(pStubMsg
, desc
);
4936 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4939 TRACE("size %d\n", size
);
4943 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg
,
4944 unsigned char *pMemory
,
4946 PFORMAT_STRING pFormat
)
4948 unsigned short type
;
4952 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4956 type
= *(const unsigned short*)pFormat
;
4957 if((type
& 0xff00) != 0x8000)
4959 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4960 NDR_FREE m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
4969 PointerFree(pStubMsg
, *(unsigned char **)pMemory
, desc
);
4972 m(pStubMsg
, pMemory
, desc
);
4975 else FIXME("no freer for embedded type %02x\n", *desc
);
4979 /***********************************************************************
4980 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
4982 unsigned char * WINAPI
NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4983 unsigned char *pMemory
,
4984 PFORMAT_STRING pFormat
)
4986 unsigned char switch_type
;
4987 unsigned char increment
;
4990 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4993 switch_type
= *pFormat
& 0xf;
4994 increment
= (*pFormat
& 0xf0) >> 4;
4997 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
4999 switch_value
= get_discriminant(switch_type
, pMemory
);
5000 TRACE("got switch value 0x%x\n", switch_value
);
5002 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &switch_type
);
5003 pMemory
+= increment
;
5005 return union_arm_marshall(pStubMsg
, pMemory
, switch_value
, pFormat
);
5008 /***********************************************************************
5009 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5011 unsigned char * WINAPI
NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5012 unsigned char **ppMemory
,
5013 PFORMAT_STRING pFormat
,
5014 unsigned char fMustAlloc
)
5016 unsigned char switch_type
;
5017 unsigned char increment
;
5019 unsigned short size
;
5020 unsigned char *pMemoryArm
;
5022 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5025 switch_type
= *pFormat
& 0xf;
5026 increment
= (*pFormat
& 0xf0) >> 4;
5029 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
5030 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
5031 TRACE("got switch value 0x%x\n", switch_value
);
5033 size
= *(const unsigned short*)pFormat
+ increment
;
5034 if(!*ppMemory
|| fMustAlloc
)
5035 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5037 NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &switch_type
, FALSE
);
5038 pMemoryArm
= *ppMemory
+ increment
;
5040 return union_arm_unmarshall(pStubMsg
, &pMemoryArm
, switch_value
, pFormat
, fMustAlloc
);
5043 /***********************************************************************
5044 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5046 void WINAPI
NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5047 unsigned char *pMemory
,
5048 PFORMAT_STRING pFormat
)
5050 unsigned char switch_type
;
5051 unsigned char increment
;
5054 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5057 switch_type
= *pFormat
& 0xf;
5058 increment
= (*pFormat
& 0xf0) >> 4;
5061 ALIGN_LENGTH(pStubMsg
->BufferLength
, increment
);
5062 switch_value
= get_discriminant(switch_type
, pMemory
);
5063 TRACE("got switch value 0x%x\n", switch_value
);
5065 /* Add discriminant size */
5066 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&switch_value
, &switch_type
);
5067 pMemory
+= increment
;
5069 union_arm_buffer_size(pStubMsg
, pMemory
, switch_value
, pFormat
);
5072 /***********************************************************************
5073 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5075 ULONG WINAPI
NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5076 PFORMAT_STRING pFormat
)
5078 unsigned char switch_type
;
5079 unsigned char increment
;
5082 switch_type
= *pFormat
& 0xf;
5083 increment
= (*pFormat
& 0xf0) >> 4;
5086 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
5087 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
5088 TRACE("got switch value 0x%x\n", switch_value
);
5090 pStubMsg
->Memory
+= increment
;
5092 return increment
+ union_arm_memory_size(pStubMsg
, switch_value
, pFormat
+ *(const SHORT
*)pFormat
);
5095 /***********************************************************************
5096 * NdrEncapsulatedUnionFree [RPCRT4.@]
5098 void WINAPI
NdrEncapsulatedUnionFree(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 switch_value
= get_discriminant(switch_type
, pMemory
);
5114 TRACE("got switch value 0x%x\n", switch_value
);
5116 pMemory
+= increment
;
5118 return union_arm_free(pStubMsg
, pMemory
, switch_value
, pFormat
);
5121 /***********************************************************************
5122 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5124 unsigned char * WINAPI
NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5125 unsigned char *pMemory
,
5126 PFORMAT_STRING pFormat
)
5128 unsigned char switch_type
;
5130 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5133 switch_type
= *pFormat
;
5136 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5137 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5138 /* Marshall discriminant */
5139 NdrBaseTypeMarshall(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
5141 return union_arm_marshall(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5144 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg
,
5145 PFORMAT_STRING
*ppFormat
)
5147 long discriminant
= 0;
5157 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5166 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5167 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5175 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
5176 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5181 FIXME("Unhandled base type: 0x%02x\n", **ppFormat
);
5185 if (pStubMsg
->fHasNewCorrDesc
)
5189 return discriminant
;
5192 /**********************************************************************
5193 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5195 unsigned char * WINAPI
NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5196 unsigned char **ppMemory
,
5197 PFORMAT_STRING pFormat
,
5198 unsigned char fMustAlloc
)
5201 unsigned short size
;
5203 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5206 /* Unmarshall discriminant */
5207 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
5208 TRACE("unmarshalled discriminant %lx\n", discriminant
);
5210 pFormat
+= *(const SHORT
*)pFormat
;
5212 size
= *(const unsigned short*)pFormat
;
5214 if(!*ppMemory
|| fMustAlloc
)
5215 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5217 return union_arm_unmarshall(pStubMsg
, ppMemory
, discriminant
, pFormat
, fMustAlloc
);
5220 /***********************************************************************
5221 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5223 void WINAPI
NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5224 unsigned char *pMemory
,
5225 PFORMAT_STRING pFormat
)
5227 unsigned char switch_type
;
5229 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5232 switch_type
= *pFormat
;
5235 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5236 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5237 /* Add discriminant size */
5238 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
5240 union_arm_buffer_size(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5243 /***********************************************************************
5244 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5246 ULONG WINAPI
NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5247 PFORMAT_STRING pFormat
)
5252 /* Unmarshall discriminant */
5253 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
5254 TRACE("unmarshalled discriminant 0x%x\n", discriminant
);
5256 return union_arm_memory_size(pStubMsg
, discriminant
, pFormat
+ *(const SHORT
*)pFormat
);
5259 /***********************************************************************
5260 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5262 void WINAPI
NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
5263 unsigned char *pMemory
,
5264 PFORMAT_STRING pFormat
)
5266 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5270 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5271 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5273 return union_arm_free(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5276 /***********************************************************************
5277 * NdrByteCountPointerMarshall [RPCRT4.@]
5279 unsigned char * WINAPI
NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5280 unsigned char *pMemory
,
5281 PFORMAT_STRING pFormat
)
5287 /***********************************************************************
5288 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5290 unsigned char * WINAPI
NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5291 unsigned char **ppMemory
,
5292 PFORMAT_STRING pFormat
,
5293 unsigned char fMustAlloc
)
5299 /***********************************************************************
5300 * NdrByteCountPointerBufferSize [RPCRT4.@]
5302 void WINAPI
NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5303 unsigned char *pMemory
,
5304 PFORMAT_STRING pFormat
)
5309 /***********************************************************************
5310 * NdrByteCountPointerMemorySize [RPCRT4.@]
5312 ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5313 PFORMAT_STRING pFormat
)
5319 /***********************************************************************
5320 * NdrByteCountPointerFree [RPCRT4.@]
5322 void WINAPI
NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
5323 unsigned char *pMemory
,
5324 PFORMAT_STRING pFormat
)
5329 /***********************************************************************
5330 * NdrXmitOrRepAsMarshall [RPCRT4.@]
5332 unsigned char * WINAPI
NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5333 unsigned char *pMemory
,
5334 PFORMAT_STRING pFormat
)
5340 /***********************************************************************
5341 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
5343 unsigned char * WINAPI
NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5344 unsigned char **ppMemory
,
5345 PFORMAT_STRING pFormat
,
5346 unsigned char fMustAlloc
)
5352 /***********************************************************************
5353 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
5355 void WINAPI
NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5356 unsigned char *pMemory
,
5357 PFORMAT_STRING pFormat
)
5362 /***********************************************************************
5363 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
5365 ULONG WINAPI
NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5366 PFORMAT_STRING pFormat
)
5372 /***********************************************************************
5373 * NdrXmitOrRepAsFree [RPCRT4.@]
5375 void WINAPI
NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg
,
5376 unsigned char *pMemory
,
5377 PFORMAT_STRING pFormat
)
5382 #include "pshpack1.h"
5386 unsigned char flags_type
; /* flags in upper nibble, type in lower nibble */
5390 #include "poppack.h"
5392 /***********************************************************************
5393 * NdrRangeMarshall [internal]
5395 unsigned char *WINAPI
NdrRangeMarshall(
5396 PMIDL_STUB_MESSAGE pStubMsg
,
5397 unsigned char *pMemory
,
5398 PFORMAT_STRING pFormat
)
5400 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5401 unsigned char base_type
;
5403 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5405 if (pRange
->type
!= RPC_FC_RANGE
)
5407 ERR("invalid format type %x\n", pRange
->type
);
5408 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5412 base_type
= pRange
->flags_type
& 0xf;
5414 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &base_type
);
5417 /***********************************************************************
5418 * NdrRangeUnmarshall
5420 unsigned char *WINAPI
NdrRangeUnmarshall(
5421 PMIDL_STUB_MESSAGE pStubMsg
,
5422 unsigned char **ppMemory
,
5423 PFORMAT_STRING pFormat
,
5424 unsigned char fMustAlloc
)
5426 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5427 unsigned char base_type
;
5429 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
5431 if (pRange
->type
!= RPC_FC_RANGE
)
5433 ERR("invalid format type %x\n", pRange
->type
);
5434 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5437 base_type
= pRange
->flags_type
& 0xf;
5439 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5440 base_type
, pRange
->low_value
, pRange
->high_value
);
5442 #define RANGE_UNMARSHALL(type, format_spec) \
5445 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5446 if (fMustAlloc || !*ppMemory) \
5447 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5448 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
5450 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
5451 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
5452 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
5454 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5455 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5457 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5458 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5459 (type)pRange->high_value); \
5460 RpcRaiseException(RPC_S_INVALID_BOUND); \
5463 TRACE("*ppMemory: %p\n", *ppMemory); \
5464 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5465 pStubMsg->Buffer += sizeof(type); \
5472 RANGE_UNMARSHALL(UCHAR
, "%d");
5473 TRACE("value: 0x%02x\n", **(UCHAR
**)ppMemory
);
5477 RANGE_UNMARSHALL(CHAR
, "%u");
5478 TRACE("value: 0x%02x\n", **(UCHAR
**)ppMemory
);
5480 case RPC_FC_WCHAR
: /* FIXME: valid? */
5482 RANGE_UNMARSHALL(USHORT
, "%u");
5483 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5486 RANGE_UNMARSHALL(SHORT
, "%d");
5487 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5490 RANGE_UNMARSHALL(LONG
, "%d");
5491 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5494 RANGE_UNMARSHALL(ULONG
, "%u");
5495 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5499 FIXME("Unhandled enum type\n");
5501 case RPC_FC_ERROR_STATUS_T
: /* FIXME: valid? */
5506 ERR("invalid range base type: 0x%02x\n", base_type
);
5507 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5513 /***********************************************************************
5514 * NdrRangeBufferSize [internal]
5516 void WINAPI
NdrRangeBufferSize(
5517 PMIDL_STUB_MESSAGE pStubMsg
,
5518 unsigned char *pMemory
,
5519 PFORMAT_STRING pFormat
)
5521 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5522 unsigned char base_type
;
5524 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5526 if (pRange
->type
!= RPC_FC_RANGE
)
5528 ERR("invalid format type %x\n", pRange
->type
);
5529 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5531 base_type
= pRange
->flags_type
& 0xf;
5533 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &base_type
);
5536 /***********************************************************************
5537 * NdrRangeMemorySize [internal]
5539 ULONG WINAPI
NdrRangeMemorySize(
5540 PMIDL_STUB_MESSAGE pStubMsg
,
5541 PFORMAT_STRING pFormat
)
5543 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5544 unsigned char base_type
;
5546 if (pRange
->type
!= RPC_FC_RANGE
)
5548 ERR("invalid format type %x\n", pRange
->type
);
5549 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5552 base_type
= pRange
->flags_type
& 0xf;
5554 return NdrBaseTypeMemorySize(pStubMsg
, &base_type
);
5557 /***********************************************************************
5558 * NdrRangeFree [internal]
5560 void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg
,
5561 unsigned char *pMemory
,
5562 PFORMAT_STRING pFormat
)
5564 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5569 /***********************************************************************
5570 * NdrBaseTypeMarshall [internal]
5572 static unsigned char *WINAPI
NdrBaseTypeMarshall(
5573 PMIDL_STUB_MESSAGE pStubMsg
,
5574 unsigned char *pMemory
,
5575 PFORMAT_STRING pFormat
)
5577 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5585 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(UCHAR
));
5586 TRACE("value: 0x%02x\n", *(UCHAR
*)pMemory
);
5591 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5592 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(USHORT
));
5593 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
5597 case RPC_FC_ERROR_STATUS_T
:
5599 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
5600 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONG
));
5601 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
5604 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(float));
5605 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
5608 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(double));
5609 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
5612 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONGLONG
));
5613 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONGLONG
));
5614 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
5617 /* only 16-bits on the wire, so do a sanity check */
5618 if (*(UINT
*)pMemory
> SHRT_MAX
)
5619 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
5620 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5621 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5622 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5623 *(USHORT
*)pStubMsg
->Buffer
= *(UINT
*)pMemory
;
5624 pStubMsg
->Buffer
+= sizeof(USHORT
);
5625 TRACE("value: 0x%04x\n", *(UINT
*)pMemory
);
5630 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5633 /* FIXME: what is the correct return value? */
5637 /***********************************************************************
5638 * NdrBaseTypeUnmarshall [internal]
5640 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(
5641 PMIDL_STUB_MESSAGE pStubMsg
,
5642 unsigned char **ppMemory
,
5643 PFORMAT_STRING pFormat
,
5644 unsigned char fMustAlloc
)
5646 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
5648 #define BASE_TYPE_UNMARSHALL(type) \
5649 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5650 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
5652 *ppMemory = pStubMsg->Buffer; \
5653 TRACE("*ppMemory: %p\n", *ppMemory); \
5658 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5659 TRACE("*ppMemory: %p\n", *ppMemory); \
5660 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5662 pStubMsg->Buffer += sizeof(type);
5670 BASE_TYPE_UNMARSHALL(UCHAR
);
5671 TRACE("value: 0x%02x\n", **(UCHAR
**)ppMemory
);
5676 BASE_TYPE_UNMARSHALL(USHORT
);
5677 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5681 case RPC_FC_ERROR_STATUS_T
:
5683 BASE_TYPE_UNMARSHALL(ULONG
);
5684 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5687 BASE_TYPE_UNMARSHALL(float);
5688 TRACE("value: %f\n", **(float **)ppMemory
);
5691 BASE_TYPE_UNMARSHALL(double);
5692 TRACE("value: %f\n", **(double **)ppMemory
);
5695 BASE_TYPE_UNMARSHALL(ULONGLONG
);
5696 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG
**)ppMemory
));
5699 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5700 if (fMustAlloc
|| !*ppMemory
)
5701 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT
));
5702 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > pStubMsg
->BufferEnd
)
5703 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5704 TRACE("*ppMemory: %p\n", *ppMemory
);
5705 /* 16-bits on the wire, but int in memory */
5706 **(UINT
**)ppMemory
= *(USHORT
*)pStubMsg
->Buffer
;
5707 pStubMsg
->Buffer
+= sizeof(USHORT
);
5708 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
5713 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5715 #undef BASE_TYPE_UNMARSHALL
5717 /* FIXME: what is the correct return value? */
5722 /***********************************************************************
5723 * NdrBaseTypeBufferSize [internal]
5725 static void WINAPI
NdrBaseTypeBufferSize(
5726 PMIDL_STUB_MESSAGE pStubMsg
,
5727 unsigned char *pMemory
,
5728 PFORMAT_STRING pFormat
)
5730 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5738 safe_buffer_length_increment(pStubMsg
, sizeof(UCHAR
));
5744 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(USHORT
));
5745 safe_buffer_length_increment(pStubMsg
, sizeof(USHORT
));
5750 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONG
));
5751 safe_buffer_length_increment(pStubMsg
, sizeof(ULONG
));
5754 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(float));
5755 safe_buffer_length_increment(pStubMsg
, sizeof(float));
5758 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(double));
5759 safe_buffer_length_increment(pStubMsg
, sizeof(double));
5762 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONGLONG
));
5763 safe_buffer_length_increment(pStubMsg
, sizeof(ULONGLONG
));
5765 case RPC_FC_ERROR_STATUS_T
:
5766 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(error_status_t
));
5767 safe_buffer_length_increment(pStubMsg
, sizeof(error_status_t
));
5772 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5776 /***********************************************************************
5777 * NdrBaseTypeMemorySize [internal]
5779 static ULONG WINAPI
NdrBaseTypeMemorySize(
5780 PMIDL_STUB_MESSAGE pStubMsg
,
5781 PFORMAT_STRING pFormat
)
5783 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg
, *pFormat
);
5791 safe_buffer_increment(pStubMsg
, sizeof(UCHAR
));
5792 pStubMsg
->MemorySize
+= sizeof(UCHAR
);
5793 return sizeof(UCHAR
);
5797 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
5798 pStubMsg
->MemorySize
+= sizeof(USHORT
);
5799 return sizeof(USHORT
);
5803 safe_buffer_increment(pStubMsg
, sizeof(ULONG
));
5804 pStubMsg
->MemorySize
+= sizeof(ULONG
);
5805 return sizeof(ULONG
);
5807 safe_buffer_increment(pStubMsg
, sizeof(float));
5808 pStubMsg
->MemorySize
+= sizeof(float);
5809 return sizeof(float);
5811 safe_buffer_increment(pStubMsg
, sizeof(double));
5812 pStubMsg
->MemorySize
+= sizeof(double);
5813 return sizeof(double);
5815 safe_buffer_increment(pStubMsg
, sizeof(ULONGLONG
));
5816 pStubMsg
->MemorySize
+= sizeof(ULONGLONG
);
5817 return sizeof(ULONGLONG
);
5818 case RPC_FC_ERROR_STATUS_T
:
5819 safe_buffer_increment(pStubMsg
, sizeof(error_status_t
));
5820 pStubMsg
->MemorySize
+= sizeof(error_status_t
);
5821 return sizeof(error_status_t
);
5823 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
5824 pStubMsg
->MemorySize
+= sizeof(UINT
);
5825 return sizeof(UINT
);
5827 pStubMsg
->MemorySize
+= sizeof(void *);
5828 return sizeof(void *);
5830 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5835 /***********************************************************************
5836 * NdrBaseTypeFree [internal]
5838 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg
,
5839 unsigned char *pMemory
,
5840 PFORMAT_STRING pFormat
)
5842 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5847 /***********************************************************************
5848 * NdrContextHandleBufferSize [internal]
5850 static void WINAPI
NdrContextHandleBufferSize(
5851 PMIDL_STUB_MESSAGE pStubMsg
,
5852 unsigned char *pMemory
,
5853 PFORMAT_STRING pFormat
)
5855 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5857 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
5859 ERR("invalid format type %x\n", *pFormat
);
5860 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5862 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
5863 safe_buffer_length_increment(pStubMsg
, cbNDRContext
);
5866 /***********************************************************************
5867 * NdrContextHandleMarshall [internal]
5869 static unsigned char *WINAPI
NdrContextHandleMarshall(
5870 PMIDL_STUB_MESSAGE pStubMsg
,
5871 unsigned char *pMemory
,
5872 PFORMAT_STRING pFormat
)
5874 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5876 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
5878 ERR("invalid format type %x\n", *pFormat
);
5879 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5882 if (pFormat
[1] & 0x80)
5883 NdrClientContextMarshall(pStubMsg
, *(NDR_CCONTEXT
**)pMemory
, FALSE
);
5885 NdrClientContextMarshall(pStubMsg
, (NDR_CCONTEXT
*)pMemory
, FALSE
);
5890 /***********************************************************************
5891 * NdrContextHandleUnmarshall [internal]
5893 static unsigned char *WINAPI
NdrContextHandleUnmarshall(
5894 PMIDL_STUB_MESSAGE pStubMsg
,
5895 unsigned char **ppMemory
,
5896 PFORMAT_STRING pFormat
,
5897 unsigned char fMustAlloc
)
5899 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
5901 ERR("invalid format type %x\n", *pFormat
);
5902 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5905 **(NDR_CCONTEXT
**)ppMemory
= NULL
;
5906 NdrClientContextUnmarshall(pStubMsg
, *(NDR_CCONTEXT
**)ppMemory
, pStubMsg
->RpcMsg
->Handle
);
5911 /***********************************************************************
5912 * NdrClientContextMarshall [RPCRT4.@]
5914 void WINAPI
NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5915 NDR_CCONTEXT ContextHandle
,
5918 TRACE("(%p, %p, %d)\n", pStubMsg
, ContextHandle
, fCheck
);
5920 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5922 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5924 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
5925 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
5926 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5929 /* FIXME: what does fCheck do? */
5930 NDRCContextMarshall(ContextHandle
,
5933 pStubMsg
->Buffer
+= cbNDRContext
;
5936 /***********************************************************************
5937 * NdrClientContextUnmarshall [RPCRT4.@]
5939 void WINAPI
NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5940 NDR_CCONTEXT
* pContextHandle
,
5941 RPC_BINDING_HANDLE BindHandle
)
5943 TRACE("(%p, %p, %p)\n", pStubMsg
, pContextHandle
, BindHandle
);
5945 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5947 if (pStubMsg
->Buffer
+ cbNDRContext
> pStubMsg
->BufferEnd
)
5948 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5950 NDRCContextUnmarshall(pContextHandle
,
5953 pStubMsg
->RpcMsg
->DataRepresentation
);
5955 pStubMsg
->Buffer
+= cbNDRContext
;
5958 void WINAPI
NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5959 NDR_SCONTEXT ContextHandle
,
5960 NDR_RUNDOWN RundownRoutine
)
5962 FIXME("(%p, %p, %p): stub\n", pStubMsg
, ContextHandle
, RundownRoutine
);
5965 NDR_SCONTEXT WINAPI
NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
)
5967 FIXME("(%p): stub\n", pStubMsg
);
5971 void WINAPI
NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg
,
5972 unsigned char* pMemory
,
5973 PFORMAT_STRING pFormat
)
5975 FIXME("(%p, %p, %p): stub\n", pStubMsg
, pMemory
, pFormat
);
5978 NDR_SCONTEXT WINAPI
NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg
,
5979 PFORMAT_STRING pFormat
)
5981 FIXME("(%p, %p): stub\n", pStubMsg
, pFormat
);
5985 void WINAPI
NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5986 NDR_SCONTEXT ContextHandle
,
5987 NDR_RUNDOWN RundownRoutine
,
5988 PFORMAT_STRING pFormat
)
5990 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg
, ContextHandle
, RundownRoutine
, pFormat
);
5993 NDR_SCONTEXT WINAPI
NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5994 PFORMAT_STRING pFormat
)
5996 FIXME("(%p, %p): stub\n", pStubMsg
, pFormat
);
6000 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
6002 typedef struct ndr_context_handle
6006 } ndr_context_handle
;
6008 struct context_handle_entry
6012 RPC_BINDING_HANDLE handle
;
6013 ndr_context_handle wire_data
;
6016 static struct list context_handle_list
= LIST_INIT(context_handle_list
);
6018 static CRITICAL_SECTION ndr_context_cs
;
6019 static CRITICAL_SECTION_DEBUG ndr_context_debug
=
6021 0, 0, &ndr_context_cs
,
6022 { &ndr_context_debug
.ProcessLocksList
, &ndr_context_debug
.ProcessLocksList
},
6023 0, 0, { (DWORD_PTR
)(__FILE__
": ndr_context") }
6025 static CRITICAL_SECTION ndr_context_cs
= { &ndr_context_debug
, -1, 0, 0, 0, 0 };
6027 static struct context_handle_entry
*get_context_entry(NDR_CCONTEXT CContext
)
6029 struct context_handle_entry
*che
= (struct context_handle_entry
*) CContext
;
6031 if (che
->magic
!= NDR_CONTEXT_HANDLE_MAGIC
)
6036 static struct context_handle_entry
*context_entry_from_guid(LPCGUID uuid
)
6038 struct context_handle_entry
*che
;
6039 LIST_FOR_EACH_ENTRY(che
, &context_handle_list
, struct context_handle_entry
, entry
)
6040 if (IsEqualGUID(&che
->wire_data
.uuid
, uuid
))
6045 RPC_BINDING_HANDLE WINAPI
NDRCContextBinding(NDR_CCONTEXT CContext
)
6047 struct context_handle_entry
*che
;
6048 RPC_BINDING_HANDLE handle
= NULL
;
6050 TRACE("%p\n", CContext
);
6052 EnterCriticalSection(&ndr_context_cs
);
6053 che
= get_context_entry(CContext
);
6055 handle
= che
->handle
;
6056 LeaveCriticalSection(&ndr_context_cs
);
6059 RpcRaiseException(ERROR_INVALID_HANDLE
);
6063 void WINAPI
NDRCContextMarshall(NDR_CCONTEXT CContext
, void *pBuff
)
6065 struct context_handle_entry
*che
;
6067 TRACE("%p %p\n", CContext
, pBuff
);
6071 EnterCriticalSection(&ndr_context_cs
);
6072 che
= get_context_entry(CContext
);
6073 memcpy(pBuff
, &che
->wire_data
, sizeof (ndr_context_handle
));
6074 LeaveCriticalSection(&ndr_context_cs
);
6078 ndr_context_handle
*wire_data
= (ndr_context_handle
*)pBuff
;
6079 wire_data
->attributes
= 0;
6080 wire_data
->uuid
= GUID_NULL
;
6084 /***********************************************************************
6085 * RpcSmDestroyClientContext [RPCRT4.@]
6087 RPC_STATUS WINAPI
RpcSmDestroyClientContext(void **ContextHandle
)
6089 RPC_STATUS status
= RPC_X_SS_CONTEXT_MISMATCH
;
6090 struct context_handle_entry
*che
= NULL
;
6092 TRACE("(%p)\n", ContextHandle
);
6094 EnterCriticalSection(&ndr_context_cs
);
6095 che
= get_context_entry(*ContextHandle
);
6096 *ContextHandle
= NULL
;
6100 list_remove(&che
->entry
);
6103 LeaveCriticalSection(&ndr_context_cs
);
6107 RpcBindingFree(&che
->handle
);
6108 HeapFree(GetProcessHeap(), 0, che
);
6114 /***********************************************************************
6115 * RpcSsDestroyClientContext [RPCRT4.@]
6117 void WINAPI
RpcSsDestroyClientContext(void **ContextHandle
)
6119 RPC_STATUS status
= RpcSmDestroyClientContext(ContextHandle
);
6120 if (status
!= RPC_S_OK
)
6121 RpcRaiseException(status
);
6124 static UINT
ndr_update_context_handle(NDR_CCONTEXT
*CContext
,
6125 RPC_BINDING_HANDLE hBinding
,
6126 const ndr_context_handle
*chi
)
6128 struct context_handle_entry
*che
= NULL
;
6130 /* a null UUID means we should free the context handle */
6131 if (IsEqualGUID(&chi
->uuid
, &GUID_NULL
))
6135 che
= get_context_entry(*CContext
);
6137 return ERROR_INVALID_HANDLE
;
6138 list_remove(&che
->entry
);
6139 RpcBindingFree(&che
->handle
);
6140 HeapFree(GetProcessHeap(), 0, che
);
6144 /* if there's no existing entry matching the GUID, allocate one */
6145 else if (!(che
= context_entry_from_guid(&chi
->uuid
)))
6147 che
= HeapAlloc(GetProcessHeap(), 0, sizeof *che
);
6149 return ERROR_NOT_ENOUGH_MEMORY
;
6150 che
->magic
= NDR_CONTEXT_HANDLE_MAGIC
;
6151 RpcBindingCopy(hBinding
, &che
->handle
);
6152 list_add_tail(&context_handle_list
, &che
->entry
);
6153 memcpy(&che
->wire_data
, chi
, sizeof *chi
);
6158 return ERROR_SUCCESS
;
6161 /***********************************************************************
6162 * NDRCContextUnmarshall [RPCRT4.@]
6164 void WINAPI
NDRCContextUnmarshall(NDR_CCONTEXT
*CContext
,
6165 RPC_BINDING_HANDLE hBinding
,
6166 void *pBuff
, ULONG DataRepresentation
)
6170 TRACE("*%p=(%p) %p %p %08x\n",
6171 CContext
, *CContext
, hBinding
, pBuff
, DataRepresentation
);
6173 EnterCriticalSection(&ndr_context_cs
);
6174 r
= ndr_update_context_handle(CContext
, hBinding
, pBuff
);
6175 LeaveCriticalSection(&ndr_context_cs
);
6177 RpcRaiseException(r
);
6180 /***********************************************************************
6181 * NDRSContextMarshall [RPCRT4.@]
6183 void WINAPI
NDRSContextMarshall(NDR_SCONTEXT CContext
,
6185 NDR_RUNDOWN userRunDownIn
)
6187 FIXME("(%p %p %p): stub\n", CContext
, pBuff
, userRunDownIn
);
6190 /***********************************************************************
6191 * NDRSContextMarshallEx [RPCRT4.@]
6193 void WINAPI
NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding
,
6194 NDR_SCONTEXT CContext
,
6196 NDR_RUNDOWN userRunDownIn
)
6198 FIXME("(%p %p %p %p): stub\n", hBinding
, CContext
, pBuff
, userRunDownIn
);
6201 /***********************************************************************
6202 * NDRSContextMarshall2 [RPCRT4.@]
6204 void WINAPI
NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding
,
6205 NDR_SCONTEXT CContext
,
6207 NDR_RUNDOWN userRunDownIn
,
6208 void *CtxGuard
, ULONG Flags
)
6210 FIXME("(%p %p %p %p %p %u): stub\n",
6211 hBinding
, CContext
, pBuff
, userRunDownIn
, CtxGuard
, Flags
);
6214 /***********************************************************************
6215 * NDRSContextUnmarshall [RPCRT4.@]
6217 NDR_SCONTEXT WINAPI
NDRSContextUnmarshall(void *pBuff
,
6218 ULONG DataRepresentation
)
6220 FIXME("(%p %08x): stub\n", pBuff
, DataRepresentation
);
6224 /***********************************************************************
6225 * NDRSContextUnmarshallEx [RPCRT4.@]
6227 NDR_SCONTEXT WINAPI
NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding
,
6229 ULONG DataRepresentation
)
6231 FIXME("(%p %p %08x): stub\n", hBinding
, pBuff
, DataRepresentation
);
6235 /***********************************************************************
6236 * NDRSContextUnmarshall2 [RPCRT4.@]
6238 NDR_SCONTEXT WINAPI
NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding
,
6240 ULONG DataRepresentation
,
6241 void *CtxGuard
, ULONG Flags
)
6243 FIXME("(%p %p %08x %p %u): stub\n",
6244 hBinding
, pBuff
, DataRepresentation
, CtxGuard
, Flags
);