4 * Copyright 2002 Greg Turner
5 * Copyright 2003-2006 CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 * - Non-conformant strings
24 * - Byte count pointers
25 * - transmit_as/represent as
26 * - Multi-dimensional arrays
27 * - Conversion functions (NdrConvert)
28 * - Checks for integer addition overflow in base type and user marshall functions
44 #include "wine/unicode.h"
45 #include "wine/rpcfc.h"
47 #include "wine/debug.h"
48 #include "wine/list.h"
50 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
53 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
54 (*((UINT32 *)(pchar)) = (uint32))
56 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
57 (*((UINT32 *)(pchar)))
59 /* these would work for i386 too, but less efficient */
60 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
61 (*(pchar) = LOBYTE(LOWORD(uint32)), \
62 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
63 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
64 *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
65 (uint32)) /* allow as r-value */
67 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
69 MAKEWORD(*(pchar), *((pchar)+1)), \
70 MAKEWORD(*((pchar)+2), *((pchar)+3))))
73 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
74 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
75 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
76 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
77 *(pchar) = HIBYTE(HIWORD(uint32)), \
78 (uint32)) /* allow as r-value */
80 #define BIG_ENDIAN_UINT32_READ(pchar) \
82 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
83 MAKEWORD(*((pchar)+1), *(pchar))))
85 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
86 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
87 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
88 # define NDR_LOCAL_UINT32_READ(pchar) \
89 BIG_ENDIAN_UINT32_READ(pchar)
91 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
92 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
93 # define NDR_LOCAL_UINT32_READ(pchar) \
94 LITTLE_ENDIAN_UINT32_READ(pchar)
97 /* _Align must be the desired alignment,
98 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
99 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
100 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
101 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
102 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
103 #define ALIGN_POINTER_CLEAR(_Ptr, _Align) \
105 memset((_Ptr), 0, ((_Align) - (ULONG_PTR)(_Ptr)) & ((_Align) - 1)); \
106 ALIGN_POINTER(_Ptr, _Align); \
109 #define STD_OVERFLOW_CHECK(_Msg) do { \
110 TRACE("buffer=%d/%d\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
111 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
112 ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
115 #define NDR_TABLE_SIZE 128
116 #define NDR_TABLE_MASK 127
118 static unsigned char *WINAPI
NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
119 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
120 static void WINAPI
NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
121 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
122 static ULONG WINAPI
NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
124 static unsigned char *WINAPI
NdrContextHandleMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
125 static void WINAPI
NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
126 static unsigned char *WINAPI
NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
128 const NDR_MARSHALL NdrMarshaller
[NDR_TABLE_SIZE
] = {
130 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
131 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
132 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
133 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
137 NdrPointerMarshall
, NdrPointerMarshall
,
138 NdrPointerMarshall
, NdrPointerMarshall
,
140 NdrSimpleStructMarshall
, NdrSimpleStructMarshall
,
141 NdrConformantStructMarshall
, NdrConformantStructMarshall
,
142 NdrConformantVaryingStructMarshall
,
143 NdrComplexStructMarshall
,
145 NdrConformantArrayMarshall
,
146 NdrConformantVaryingArrayMarshall
,
147 NdrFixedArrayMarshall
, NdrFixedArrayMarshall
,
148 NdrVaryingArrayMarshall
, NdrVaryingArrayMarshall
,
149 NdrComplexArrayMarshall
,
151 NdrConformantStringMarshall
, 0, 0,
152 NdrConformantStringMarshall
,
153 NdrNonConformantStringMarshall
, 0, 0, 0,
155 NdrEncapsulatedUnionMarshall
,
156 NdrNonEncapsulatedUnionMarshall
,
157 NdrByteCountPointerMarshall
,
158 NdrXmitOrRepAsMarshall
, NdrXmitOrRepAsMarshall
,
160 NdrInterfacePointerMarshall
,
162 NdrContextHandleMarshall
,
165 NdrUserMarshalMarshall
,
170 const NDR_UNMARSHALL NdrUnmarshaller
[NDR_TABLE_SIZE
] = {
172 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
173 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
174 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
175 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
177 NdrBaseTypeUnmarshall
,
179 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
180 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
182 NdrSimpleStructUnmarshall
, NdrSimpleStructUnmarshall
,
183 NdrConformantStructUnmarshall
, NdrConformantStructUnmarshall
,
184 NdrConformantVaryingStructUnmarshall
,
185 NdrComplexStructUnmarshall
,
187 NdrConformantArrayUnmarshall
,
188 NdrConformantVaryingArrayUnmarshall
,
189 NdrFixedArrayUnmarshall
, NdrFixedArrayUnmarshall
,
190 NdrVaryingArrayUnmarshall
, NdrVaryingArrayUnmarshall
,
191 NdrComplexArrayUnmarshall
,
193 NdrConformantStringUnmarshall
, 0, 0,
194 NdrConformantStringUnmarshall
,
195 NdrNonConformantStringUnmarshall
, 0, 0, 0,
197 NdrEncapsulatedUnionUnmarshall
,
198 NdrNonEncapsulatedUnionUnmarshall
,
199 NdrByteCountPointerUnmarshall
,
200 NdrXmitOrRepAsUnmarshall
, NdrXmitOrRepAsUnmarshall
,
202 NdrInterfacePointerUnmarshall
,
204 NdrContextHandleUnmarshall
,
207 NdrUserMarshalUnmarshall
,
212 const NDR_BUFFERSIZE NdrBufferSizer
[NDR_TABLE_SIZE
] = {
214 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
215 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
216 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
217 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
219 NdrBaseTypeBufferSize
,
221 NdrPointerBufferSize
, NdrPointerBufferSize
,
222 NdrPointerBufferSize
, NdrPointerBufferSize
,
224 NdrSimpleStructBufferSize
, NdrSimpleStructBufferSize
,
225 NdrConformantStructBufferSize
, NdrConformantStructBufferSize
,
226 NdrConformantVaryingStructBufferSize
,
227 NdrComplexStructBufferSize
,
229 NdrConformantArrayBufferSize
,
230 NdrConformantVaryingArrayBufferSize
,
231 NdrFixedArrayBufferSize
, NdrFixedArrayBufferSize
,
232 NdrVaryingArrayBufferSize
, NdrVaryingArrayBufferSize
,
233 NdrComplexArrayBufferSize
,
235 NdrConformantStringBufferSize
, 0, 0,
236 NdrConformantStringBufferSize
,
237 NdrNonConformantStringBufferSize
, 0, 0, 0,
239 NdrEncapsulatedUnionBufferSize
,
240 NdrNonEncapsulatedUnionBufferSize
,
241 NdrByteCountPointerBufferSize
,
242 NdrXmitOrRepAsBufferSize
, NdrXmitOrRepAsBufferSize
,
244 NdrInterfacePointerBufferSize
,
246 NdrContextHandleBufferSize
,
249 NdrUserMarshalBufferSize
,
254 const NDR_MEMORYSIZE NdrMemorySizer
[NDR_TABLE_SIZE
] = {
256 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
257 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
258 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
259 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
261 NdrBaseTypeMemorySize
,
263 NdrPointerMemorySize
, NdrPointerMemorySize
,
264 NdrPointerMemorySize
, NdrPointerMemorySize
,
266 NdrSimpleStructMemorySize
, NdrSimpleStructMemorySize
,
267 NdrConformantStructMemorySize
, NdrConformantStructMemorySize
,
268 NdrConformantVaryingStructMemorySize
,
269 NdrComplexStructMemorySize
,
271 NdrConformantArrayMemorySize
,
272 NdrConformantVaryingArrayMemorySize
,
273 NdrFixedArrayMemorySize
, NdrFixedArrayMemorySize
,
274 NdrVaryingArrayMemorySize
, NdrVaryingArrayMemorySize
,
275 NdrComplexArrayMemorySize
,
277 NdrConformantStringMemorySize
, 0, 0,
278 NdrConformantStringMemorySize
,
279 NdrNonConformantStringMemorySize
, 0, 0, 0,
281 NdrEncapsulatedUnionMemorySize
,
282 NdrNonEncapsulatedUnionMemorySize
,
283 NdrByteCountPointerMemorySize
,
284 NdrXmitOrRepAsMemorySize
, NdrXmitOrRepAsMemorySize
,
286 NdrInterfacePointerMemorySize
,
291 NdrUserMarshalMemorySize
,
296 const NDR_FREE NdrFreer
[NDR_TABLE_SIZE
] = {
298 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
299 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
300 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
301 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
305 NdrPointerFree
, NdrPointerFree
,
306 NdrPointerFree
, NdrPointerFree
,
308 NdrSimpleStructFree
, NdrSimpleStructFree
,
309 NdrConformantStructFree
, NdrConformantStructFree
,
310 NdrConformantVaryingStructFree
,
311 NdrComplexStructFree
,
313 NdrConformantArrayFree
,
314 NdrConformantVaryingArrayFree
,
315 NdrFixedArrayFree
, NdrFixedArrayFree
,
316 NdrVaryingArrayFree
, NdrVaryingArrayFree
,
322 NdrEncapsulatedUnionFree
,
323 NdrNonEncapsulatedUnionFree
,
325 NdrXmitOrRepAsFree
, NdrXmitOrRepAsFree
,
327 NdrInterfacePointerFree
,
338 typedef struct _NDR_MEMORY_LIST
343 struct _NDR_MEMORY_LIST
*next
;
346 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
348 /***********************************************************************
349 * NdrAllocate [RPCRT4.@]
351 * Allocates a block of memory using pStubMsg->pfnAllocate.
354 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
355 * len [I] Size of memory block to allocate.
358 * The memory block of size len that was allocated.
361 * The memory block is always 8-byte aligned.
362 * If the function is unable to allocate memory an ERROR_OUTOFMEMORY
363 * exception is raised.
365 void * WINAPI
NdrAllocate(MIDL_STUB_MESSAGE
*pStubMsg
, size_t len
)
370 NDR_MEMORY_LIST
*mem_list
;
372 aligned_len
= ALIGNED_LENGTH(len
, 8);
373 adjusted_len
= aligned_len
+ sizeof(NDR_MEMORY_LIST
);
374 /* check for overflow */
375 if (adjusted_len
< len
)
377 ERR("overflow of adjusted_len %d, len %d\n", adjusted_len
, len
);
378 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
381 p
= pStubMsg
->pfnAllocate(adjusted_len
);
382 if (!p
) RpcRaiseException(ERROR_OUTOFMEMORY
);
384 mem_list
= (NDR_MEMORY_LIST
*)((char *)p
+ aligned_len
);
385 mem_list
->magic
= MEML_MAGIC
;
386 mem_list
->size
= aligned_len
;
387 mem_list
->reserved
= 0;
388 mem_list
->next
= pStubMsg
->pMemoryList
;
389 pStubMsg
->pMemoryList
= mem_list
;
395 static void WINAPI
NdrFree(MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *Pointer
)
397 TRACE("(%p, %p)\n", pStubMsg
, Pointer
);
399 pStubMsg
->pfnFree(Pointer
);
402 static inline BOOL
IsConformanceOrVariancePresent(PFORMAT_STRING pFormat
)
404 return (*(const ULONG
*)pFormat
!= -1);
407 static PFORMAT_STRING
ReadConformance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
)
409 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
410 if (pStubMsg
->Buffer
+ 4 > pStubMsg
->BufferEnd
)
411 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
412 pStubMsg
->MaxCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
413 pStubMsg
->Buffer
+= 4;
414 TRACE("unmarshalled conformance is %ld\n", pStubMsg
->MaxCount
);
415 if (pStubMsg
->fHasNewCorrDesc
)
421 static inline PFORMAT_STRING
ReadVariance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
, ULONG MaxValue
)
423 if (pFormat
&& !IsConformanceOrVariancePresent(pFormat
))
425 pStubMsg
->Offset
= 0;
426 pStubMsg
->ActualCount
= pStubMsg
->MaxCount
;
430 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
431 if (pStubMsg
->Buffer
+ 8 > pStubMsg
->BufferEnd
)
432 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
433 pStubMsg
->Offset
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
434 pStubMsg
->Buffer
+= 4;
435 TRACE("offset is %d\n", pStubMsg
->Offset
);
436 pStubMsg
->ActualCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
437 pStubMsg
->Buffer
+= 4;
438 TRACE("variance is %d\n", pStubMsg
->ActualCount
);
440 if ((pStubMsg
->ActualCount
> MaxValue
) ||
441 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> MaxValue
))
443 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
444 pStubMsg
->ActualCount
, pStubMsg
->Offset
, MaxValue
);
445 RpcRaiseException(RPC_S_INVALID_BOUND
);
450 if (pStubMsg
->fHasNewCorrDesc
)
456 /* writes the conformance value to the buffer */
457 static inline void WriteConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
459 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
460 if (pStubMsg
->Buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
461 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
462 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->MaxCount
);
463 pStubMsg
->Buffer
+= 4;
466 /* writes the variance values to the buffer */
467 static inline void WriteVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
469 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
470 if (pStubMsg
->Buffer
+ 8 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
471 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
472 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->Offset
);
473 pStubMsg
->Buffer
+= 4;
474 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->ActualCount
);
475 pStubMsg
->Buffer
+= 4;
478 /* requests buffer space for the conformance value */
479 static inline void SizeConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
481 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
482 if (pStubMsg
->BufferLength
+ 4 < pStubMsg
->BufferLength
)
483 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
484 pStubMsg
->BufferLength
+= 4;
487 /* requests buffer space for the variance values */
488 static inline void SizeVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
490 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
491 if (pStubMsg
->BufferLength
+ 8 < pStubMsg
->BufferLength
)
492 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
493 pStubMsg
->BufferLength
+= 8;
496 PFORMAT_STRING
ComputeConformanceOrVariance(
497 MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *pMemory
,
498 PFORMAT_STRING pFormat
, ULONG_PTR def
, ULONG_PTR
*pCount
)
500 BYTE dtype
= pFormat
[0] & 0xf;
501 short ofs
= *(const short *)&pFormat
[2];
505 if (!IsConformanceOrVariancePresent(pFormat
)) {
506 /* null descriptor */
511 switch (pFormat
[0] & 0xf0) {
512 case RPC_FC_NORMAL_CONFORMANCE
:
513 TRACE("normal conformance, ofs=%d\n", ofs
);
516 case RPC_FC_POINTER_CONFORMANCE
:
517 TRACE("pointer conformance, ofs=%d\n", ofs
);
518 ptr
= pStubMsg
->Memory
;
520 case RPC_FC_TOP_LEVEL_CONFORMANCE
:
521 TRACE("toplevel conformance, ofs=%d\n", ofs
);
522 if (pStubMsg
->StackTop
) {
523 ptr
= pStubMsg
->StackTop
;
526 /* -Os mode, *pCount is already set */
530 case RPC_FC_CONSTANT_CONFORMANCE
:
531 data
= ofs
| ((DWORD
)pFormat
[1] << 16);
532 TRACE("constant conformance, val=%d\n", data
);
535 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE
:
536 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs
);
537 if (pStubMsg
->StackTop
) {
538 ptr
= pStubMsg
->StackTop
;
546 FIXME("unknown conformance type %x\n", pFormat
[0] & 0xf0);
549 switch (pFormat
[1]) {
550 case RPC_FC_DEREFERENCE
:
551 ptr
= *(LPVOID
*)((char *)ptr
+ ofs
);
553 case RPC_FC_CALLBACK
:
555 unsigned char *old_stack_top
= pStubMsg
->StackTop
;
556 pStubMsg
->StackTop
= ptr
;
558 /* ofs is index into StubDesc->apfnExprEval */
559 TRACE("callback conformance into apfnExprEval[%d]\n", ofs
);
560 pStubMsg
->StubDesc
->apfnExprEval
[ofs
](pStubMsg
);
562 pStubMsg
->StackTop
= old_stack_top
;
564 /* the callback function always stores the computed value in MaxCount */
565 *pCount
= pStubMsg
->MaxCount
;
569 ptr
= (char *)ptr
+ ofs
;
582 data
= *(USHORT
*)ptr
;
593 FIXME("unknown conformance data type %x\n", dtype
);
596 TRACE("dereferenced data type %x at %p, got %d\n", dtype
, ptr
, data
);
599 switch (pFormat
[1]) {
600 case RPC_FC_DEREFERENCE
: /* already handled */
617 FIXME("unknown conformance op %d\n", pFormat
[1]);
622 TRACE("resulting conformance is %ld\n", *pCount
);
623 if (pStubMsg
->fHasNewCorrDesc
)
629 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
630 * the result overflows 32-bits */
631 static inline ULONG
safe_multiply(ULONG a
, ULONG b
)
633 ULONGLONG ret
= (ULONGLONG
)a
* b
;
634 if (ret
> 0xffffffff)
636 RpcRaiseException(RPC_S_INVALID_BOUND
);
642 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
644 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
645 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
646 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
647 pStubMsg
->Buffer
+= size
;
650 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
652 if (pStubMsg
->BufferLength
+ size
< pStubMsg
->BufferLength
) /* integer overflow of pStubMsg->BufferSize */
654 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
655 pStubMsg
->BufferLength
, size
);
656 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
658 pStubMsg
->BufferLength
+= size
;
661 /* copies data from the buffer, checking that there is enough data in the buffer
663 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, void *p
, ULONG size
)
665 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
666 (pStubMsg
->Buffer
+ size
> pStubMsg
->BufferEnd
))
667 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
668 memcpy(p
, pStubMsg
->Buffer
, size
);
669 pStubMsg
->Buffer
+= size
;
672 /* copies data to the buffer, checking that there is enough space to do so */
673 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE
*pStubMsg
, const void *p
, ULONG size
)
675 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
676 (pStubMsg
->Buffer
+ size
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
))
678 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
679 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
,
681 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
683 memcpy(pStubMsg
->Buffer
, p
, size
);
684 pStubMsg
->Buffer
+= size
;
688 * NdrConformantString:
690 * What MS calls a ConformantString is, in DCE terminology,
691 * a Varying-Conformant String.
693 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
694 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
695 * into unmarshalled string)
696 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
698 * data: CHARTYPE[maxlen]
700 * ], where CHARTYPE is the appropriate character type (specified externally)
704 /***********************************************************************
705 * NdrConformantStringMarshall [RPCRT4.@]
707 unsigned char *WINAPI
NdrConformantStringMarshall(MIDL_STUB_MESSAGE
*pStubMsg
,
708 unsigned char *pszMessage
, PFORMAT_STRING pFormat
)
712 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg
, pszMessage
, pFormat
);
714 if (*pFormat
== RPC_FC_C_CSTRING
) {
715 TRACE("string=%s\n", debugstr_a((char*)pszMessage
));
716 pStubMsg
->ActualCount
= strlen((char*)pszMessage
)+1;
719 else if (*pFormat
== RPC_FC_C_WSTRING
) {
720 TRACE("string=%s\n", debugstr_w((LPWSTR
)pszMessage
));
721 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pszMessage
)+1;
725 ERR("Unhandled string type: %#x\n", *pFormat
);
726 /* FIXME: raise an exception. */
730 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
731 pFormat
= ComputeConformance(pStubMsg
, pszMessage
, pFormat
+ 2, 0);
733 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
734 pStubMsg
->Offset
= 0;
735 WriteConformance(pStubMsg
);
736 WriteVariance(pStubMsg
);
738 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
739 safe_copy_to_buffer(pStubMsg
, pszMessage
, size
); /* the string itself */
742 return NULL
; /* is this always right? */
745 /***********************************************************************
746 * NdrConformantStringBufferSize [RPCRT4.@]
748 void WINAPI
NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
749 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
753 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
755 SizeConformance(pStubMsg
);
756 SizeVariance(pStubMsg
);
758 if (*pFormat
== RPC_FC_C_CSTRING
) {
759 TRACE("string=%s\n", debugstr_a((char*)pMemory
));
760 pStubMsg
->ActualCount
= strlen((char*)pMemory
)+1;
763 else if (*pFormat
== RPC_FC_C_WSTRING
) {
764 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
));
765 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
)+1;
769 ERR("Unhandled string type: %#x\n", *pFormat
);
770 /* FIXME: raise an exception */
774 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
775 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
777 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
779 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
782 /************************************************************************
783 * NdrConformantStringMemorySize [RPCRT4.@]
785 ULONG WINAPI
NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
786 PFORMAT_STRING pFormat
)
790 FIXME("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
792 assert(pStubMsg
&& pFormat
);
794 if (*pFormat
== RPC_FC_C_CSTRING
) {
795 rslt
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
); /* maxlen */
797 else if (*pFormat
== RPC_FC_C_WSTRING
) {
798 rslt
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
)*2; /* maxlen */
801 ERR("Unhandled string type: %#x\n", *pFormat
);
802 /* FIXME: raise an exception */
805 if (pFormat
[1] != RPC_FC_PAD
) {
806 FIXME("sized string format=%d\n", pFormat
[1]);
809 TRACE(" --> %u\n", rslt
);
813 /************************************************************************
814 * NdrConformantStringUnmarshall [RPCRT4.@]
816 unsigned char *WINAPI
NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
817 unsigned char** ppMemory
, PFORMAT_STRING pFormat
, unsigned char fMustAlloc
)
819 ULONG bufsize
, memsize
, esize
, i
;
821 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
822 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
824 assert(pFormat
&& ppMemory
&& pStubMsg
);
826 ReadConformance(pStubMsg
, NULL
);
827 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
829 if (pFormat
[1] != RPC_FC_STRING_SIZED
&& (pStubMsg
->MaxCount
!= pStubMsg
->ActualCount
))
831 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
832 pStubMsg
->ActualCount
, pStubMsg
->MaxCount
);
833 RpcRaiseException(RPC_S_INVALID_BOUND
);
836 if (pStubMsg
->Offset
)
838 ERR("conformant strings can't have Offset (%d)\n", pStubMsg
->Offset
);
839 RpcRaiseException(RPC_S_INVALID_BOUND
);
843 if (*pFormat
== RPC_FC_C_CSTRING
) esize
= 1;
844 else if (*pFormat
== RPC_FC_C_WSTRING
) esize
= 2;
846 ERR("Unhandled string type: %#x\n", *pFormat
);
847 /* FIXME: raise an exception */
851 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
852 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
854 /* strings must always have null terminating bytes */
857 ERR("invalid string length of %d\n", pStubMsg
->ActualCount
);
858 RpcRaiseException(RPC_S_INVALID_BOUND
);
862 /* verify the buffer is safe to access */
863 if ((pStubMsg
->Buffer
+ bufsize
< pStubMsg
->Buffer
) ||
864 (pStubMsg
->Buffer
+ bufsize
> pStubMsg
->BufferEnd
))
866 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize
,
867 pStubMsg
->BufferEnd
, pStubMsg
->Buffer
);
868 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
872 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
873 if (pStubMsg
->Buffer
[i
] != 0)
875 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
876 i
, pStubMsg
->Buffer
[i
]);
877 RpcRaiseException(RPC_S_INVALID_BOUND
);
882 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
885 if (!pStubMsg
->IsClient
&& !*ppMemory
&& (pStubMsg
->MaxCount
== pStubMsg
->ActualCount
))
886 /* if the data in the RPC buffer is big enough, we just point straight
888 *ppMemory
= pStubMsg
->Buffer
;
890 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
893 if (*ppMemory
== pStubMsg
->Buffer
)
894 safe_buffer_increment(pStubMsg
, bufsize
);
896 safe_copy_from_buffer(pStubMsg
, *ppMemory
, bufsize
);
898 if (*pFormat
== RPC_FC_C_CSTRING
) {
899 TRACE("string=%s\n", debugstr_a((char*)*ppMemory
));
901 else if (*pFormat
== RPC_FC_C_WSTRING
) {
902 TRACE("string=%s\n", debugstr_w((LPWSTR
)*ppMemory
));
905 return NULL
; /* FIXME: is this always right? */
908 /***********************************************************************
909 * NdrNonConformantStringMarshall [RPCRT4.@]
911 unsigned char * WINAPI
NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
912 unsigned char *pMemory
,
913 PFORMAT_STRING pFormat
)
919 /***********************************************************************
920 * NdrNonConformantStringUnmarshall [RPCRT4.@]
922 unsigned char * WINAPI
NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
923 unsigned char **ppMemory
,
924 PFORMAT_STRING pFormat
,
925 unsigned char fMustAlloc
)
931 /***********************************************************************
932 * NdrNonConformantStringBufferSize [RPCRT4.@]
934 void WINAPI
NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
935 unsigned char *pMemory
,
936 PFORMAT_STRING pFormat
)
941 /***********************************************************************
942 * NdrNonConformantStringMemorySize [RPCRT4.@]
944 ULONG WINAPI
NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
945 PFORMAT_STRING pFormat
)
951 static inline void dump_pointer_attr(unsigned char attr
)
953 if (attr
& RPC_FC_P_ALLOCALLNODES
)
954 TRACE(" RPC_FC_P_ALLOCALLNODES");
955 if (attr
& RPC_FC_P_DONTFREE
)
956 TRACE(" RPC_FC_P_DONTFREE");
957 if (attr
& RPC_FC_P_ONSTACK
)
958 TRACE(" RPC_FC_P_ONSTACK");
959 if (attr
& RPC_FC_P_SIMPLEPOINTER
)
960 TRACE(" RPC_FC_P_SIMPLEPOINTER");
961 if (attr
& RPC_FC_P_DEREF
)
962 TRACE(" RPC_FC_P_DEREF");
966 /***********************************************************************
967 * PointerMarshall [internal]
969 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
970 unsigned char *Buffer
,
971 unsigned char *Pointer
,
972 PFORMAT_STRING pFormat
)
974 unsigned type
= pFormat
[0], attr
= pFormat
[1];
978 int pointer_needs_marshaling
;
980 TRACE("(%p,%p,%p,%p)\n", pStubMsg
, Buffer
, Pointer
, pFormat
);
981 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
983 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
984 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
987 case RPC_FC_RP
: /* ref pointer (always non-null) */
990 ERR("NULL ref pointer is not allowed\n");
991 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
993 pointer_needs_marshaling
= 1;
995 case RPC_FC_UP
: /* unique pointer */
996 case RPC_FC_OP
: /* object pointer - same as unique here */
998 pointer_needs_marshaling
= 1;
1000 pointer_needs_marshaling
= 0;
1001 pointer_id
= (ULONG
)Pointer
;
1002 TRACE("writing 0x%08x to buffer\n", pointer_id
);
1003 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
1006 pointer_needs_marshaling
= !NdrFullPointerQueryPointer(
1007 pStubMsg
->FullPtrXlatTables
, Pointer
, 1, &pointer_id
);
1008 TRACE("writing 0x%08x to buffer\n", pointer_id
);
1009 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
1012 FIXME("unhandled ptr type=%02x\n", type
);
1013 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1017 TRACE("calling marshaller for type 0x%x\n", (int)*desc
);
1019 if (pointer_needs_marshaling
) {
1020 if (attr
& RPC_FC_P_DEREF
) {
1021 Pointer
= *(unsigned char**)Pointer
;
1022 TRACE("deref => %p\n", Pointer
);
1024 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
1025 if (m
) m(pStubMsg
, Pointer
, desc
);
1026 else FIXME("no marshaller for data type=%02x\n", *desc
);
1029 STD_OVERFLOW_CHECK(pStubMsg
);
1032 /***********************************************************************
1033 * PointerUnmarshall [internal]
1035 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1036 unsigned char *Buffer
,
1037 unsigned char **pPointer
,
1038 unsigned char *pSrcPointer
,
1039 PFORMAT_STRING pFormat
,
1040 unsigned char fMustAlloc
)
1042 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1043 PFORMAT_STRING desc
;
1045 DWORD pointer_id
= 0;
1046 int pointer_needs_unmarshaling
;
1048 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg
, Buffer
, pPointer
, pSrcPointer
, pFormat
, fMustAlloc
);
1049 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1051 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1052 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1055 case RPC_FC_RP
: /* ref pointer (always non-null) */
1056 pointer_needs_unmarshaling
= 1;
1058 case RPC_FC_UP
: /* unique pointer */
1059 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1060 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1062 pointer_needs_unmarshaling
= 1;
1065 pointer_needs_unmarshaling
= 0;
1068 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
1069 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1070 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1071 if (!fMustAlloc
&& pSrcPointer
)
1073 FIXME("free object pointer %p\n", pSrcPointer
);
1077 pointer_needs_unmarshaling
= 1;
1079 pointer_needs_unmarshaling
= 0;
1082 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1083 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1084 pointer_needs_unmarshaling
= !NdrFullPointerQueryRefId(
1085 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, (void **)pPointer
);
1088 FIXME("unhandled ptr type=%02x\n", type
);
1089 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1093 if (pointer_needs_unmarshaling
) {
1094 unsigned char *base_ptr_val
= *pPointer
;
1095 unsigned char **current_ptr
= pPointer
;
1096 if (pStubMsg
->IsClient
) {
1098 /* if we aren't forcing allocation of memory then try to use the existing
1099 * (source) pointer to unmarshall the data into so that [in,out]
1100 * parameters behave correctly. it doesn't matter if the parameter is
1101 * [out] only since in that case the pointer will be NULL. we force
1102 * allocation when the source pointer is NULL here instead of in the type
1103 * unmarshalling routine for the benefit of the deref code below */
1106 TRACE("setting *pPointer to %p\n", pSrcPointer
);
1107 *pPointer
= base_ptr_val
= pSrcPointer
;
1113 /* the memory in a stub is never initialised, so we have to work out here
1114 * whether we have to initialise it so we can use the optimisation of
1115 * setting the pointer to the buffer, if possible, or set fMustAlloc to
1117 if (attr
& RPC_FC_P_DEREF
) {
1120 base_ptr_val
= NULL
;
1121 *current_ptr
= NULL
;
1125 if (attr
& RPC_FC_P_ALLOCALLNODES
)
1126 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
1128 if (attr
& RPC_FC_P_DEREF
) {
1130 base_ptr_val
= NdrAllocate(pStubMsg
, sizeof(void *));
1131 *pPointer
= base_ptr_val
;
1132 current_ptr
= (unsigned char **)base_ptr_val
;
1134 current_ptr
= *(unsigned char***)current_ptr
;
1135 TRACE("deref => %p\n", current_ptr
);
1136 if (!fMustAlloc
&& !*current_ptr
) fMustAlloc
= TRUE
;
1138 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
1139 if (m
) m(pStubMsg
, current_ptr
, desc
, fMustAlloc
);
1140 else FIXME("no unmarshaller for data type=%02x\n", *desc
);
1142 if (type
== RPC_FC_FP
)
1143 NdrFullPointerInsertRefId(pStubMsg
->FullPtrXlatTables
, pointer_id
,
1147 TRACE("pointer=%p\n", *pPointer
);
1150 /***********************************************************************
1151 * PointerBufferSize [internal]
1153 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1154 unsigned char *Pointer
,
1155 PFORMAT_STRING pFormat
)
1157 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1158 PFORMAT_STRING desc
;
1160 int pointer_needs_sizing
;
1163 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1164 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1166 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1167 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1170 case RPC_FC_RP
: /* ref pointer (always non-null) */
1173 ERR("NULL ref pointer is not allowed\n");
1174 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
1179 /* NULL pointer has no further representation */
1184 pointer_needs_sizing
= !NdrFullPointerQueryPointer(
1185 pStubMsg
->FullPtrXlatTables
, Pointer
, 0, &pointer_id
);
1186 if (!pointer_needs_sizing
)
1190 FIXME("unhandled ptr type=%02x\n", type
);
1191 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1195 if (attr
& RPC_FC_P_DEREF
) {
1196 Pointer
= *(unsigned char**)Pointer
;
1197 TRACE("deref => %p\n", Pointer
);
1200 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
1201 if (m
) m(pStubMsg
, Pointer
, desc
);
1202 else FIXME("no buffersizer for data type=%02x\n", *desc
);
1205 /***********************************************************************
1206 * PointerMemorySize [internal]
1208 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1209 unsigned char *Buffer
,
1210 PFORMAT_STRING pFormat
)
1212 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1213 PFORMAT_STRING desc
;
1215 DWORD pointer_id
= 0;
1216 int pointer_needs_sizing
;
1218 TRACE("(%p,%p,%p)\n", pStubMsg
, Buffer
, pFormat
);
1219 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1221 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1222 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1225 case RPC_FC_RP
: /* ref pointer (always non-null) */
1226 pointer_needs_sizing
= 1;
1228 case RPC_FC_UP
: /* unique pointer */
1229 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
1230 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1231 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1233 pointer_needs_sizing
= 1;
1235 pointer_needs_sizing
= 0;
1240 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
1241 TRACE("pointer_id is 0x%08x\n", pointer_id
);
1242 pointer_needs_sizing
= !NdrFullPointerQueryRefId(
1243 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, &pointer
);
1247 FIXME("unhandled ptr type=%02x\n", type
);
1248 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1252 if (attr
& RPC_FC_P_DEREF
) {
1256 if (pointer_needs_sizing
) {
1257 m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
1258 if (m
) m(pStubMsg
, desc
);
1259 else FIXME("no memorysizer for data type=%02x\n", *desc
);
1262 return pStubMsg
->MemorySize
;
1265 /***********************************************************************
1266 * PointerFree [internal]
1268 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1269 unsigned char *Pointer
,
1270 PFORMAT_STRING pFormat
)
1272 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1273 PFORMAT_STRING desc
;
1275 unsigned char *current_pointer
= Pointer
;
1277 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1278 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1279 if (attr
& RPC_FC_P_DONTFREE
) return;
1281 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1282 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1284 if (!Pointer
) return;
1286 if (type
== RPC_FC_FP
) {
1287 int pointer_needs_freeing
= NdrFullPointerFree(
1288 pStubMsg
->FullPtrXlatTables
, Pointer
);
1289 if (!pointer_needs_freeing
)
1293 if (attr
& RPC_FC_P_DEREF
) {
1294 current_pointer
= *(unsigned char**)Pointer
;
1295 TRACE("deref => %p\n", current_pointer
);
1298 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
1299 if (m
) m(pStubMsg
, current_pointer
, desc
);
1301 /* this check stops us from trying to free buffer memory. we don't have to
1302 * worry about clients, since they won't call this function.
1303 * we don't have to check for the buffer being reallocated because
1304 * BufferStart and BufferEnd won't be reset when allocating memory for
1305 * sending the response. we don't have to check for the new buffer here as
1306 * it won't be used a type memory, only for buffer memory */
1307 if (Pointer
>= (unsigned char *)pStubMsg
->BufferStart
&&
1308 Pointer
< (unsigned char *)pStubMsg
->BufferEnd
)
1311 if (attr
& RPC_FC_P_ONSTACK
) {
1312 TRACE("not freeing stack ptr %p\n", Pointer
);
1315 TRACE("freeing %p\n", Pointer
);
1316 NdrFree(pStubMsg
, Pointer
);
1319 TRACE("not freeing %p\n", Pointer
);
1322 /***********************************************************************
1323 * EmbeddedPointerMarshall
1325 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1326 unsigned char *pMemory
,
1327 PFORMAT_STRING pFormat
)
1329 unsigned char *Mark
= pStubMsg
->BufferMark
;
1330 unsigned rep
, count
, stride
;
1332 unsigned char *saved_buffer
= NULL
;
1334 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1336 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1339 if (pStubMsg
->PointerBufferMark
)
1341 saved_buffer
= pStubMsg
->Buffer
;
1342 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1343 pStubMsg
->PointerBufferMark
= NULL
;
1346 while (pFormat
[0] != RPC_FC_END
) {
1347 switch (pFormat
[0]) {
1349 FIXME("unknown repeat type %d\n", pFormat
[0]);
1350 case RPC_FC_NO_REPEAT
:
1356 case RPC_FC_FIXED_REPEAT
:
1357 rep
= *(const WORD
*)&pFormat
[2];
1358 stride
= *(const WORD
*)&pFormat
[4];
1359 count
= *(const WORD
*)&pFormat
[8];
1362 case RPC_FC_VARIABLE_REPEAT
:
1363 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1364 stride
= *(const WORD
*)&pFormat
[2];
1365 count
= *(const WORD
*)&pFormat
[6];
1369 for (i
= 0; i
< rep
; i
++) {
1370 PFORMAT_STRING info
= pFormat
;
1371 unsigned char *membase
= pMemory
+ (i
* stride
);
1372 unsigned char *bufbase
= Mark
+ (i
* stride
);
1375 for (u
=0; u
<count
; u
++,info
+=8) {
1376 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1377 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1378 unsigned char *saved_memory
= pStubMsg
->Memory
;
1380 pStubMsg
->Memory
= pMemory
;
1381 PointerMarshall(pStubMsg
, bufptr
, *(unsigned char**)memptr
, info
+4);
1382 pStubMsg
->Memory
= saved_memory
;
1385 pFormat
+= 8 * count
;
1390 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1391 pStubMsg
->Buffer
= saved_buffer
;
1394 STD_OVERFLOW_CHECK(pStubMsg
);
1399 /***********************************************************************
1400 * EmbeddedPointerUnmarshall
1402 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1403 unsigned char *pDstMemoryPtrs
,
1404 unsigned char *pSrcMemoryPtrs
,
1405 PFORMAT_STRING pFormat
,
1406 unsigned char fMustAlloc
)
1408 unsigned char *Mark
= pStubMsg
->BufferMark
;
1409 unsigned rep
, count
, stride
;
1411 unsigned char *saved_buffer
= NULL
;
1413 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg
, pDstMemoryPtrs
, pSrcMemoryPtrs
, pFormat
, fMustAlloc
);
1415 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1418 if (pStubMsg
->PointerBufferMark
)
1420 saved_buffer
= pStubMsg
->Buffer
;
1421 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1422 pStubMsg
->PointerBufferMark
= NULL
;
1425 while (pFormat
[0] != RPC_FC_END
) {
1426 TRACE("pFormat[0] = 0x%x\n", pFormat
[0]);
1427 switch (pFormat
[0]) {
1429 FIXME("unknown repeat type %d\n", pFormat
[0]);
1430 case RPC_FC_NO_REPEAT
:
1436 case RPC_FC_FIXED_REPEAT
:
1437 rep
= *(const WORD
*)&pFormat
[2];
1438 stride
= *(const WORD
*)&pFormat
[4];
1439 count
= *(const WORD
*)&pFormat
[8];
1442 case RPC_FC_VARIABLE_REPEAT
:
1443 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1444 stride
= *(const WORD
*)&pFormat
[2];
1445 count
= *(const WORD
*)&pFormat
[6];
1449 for (i
= 0; i
< rep
; i
++) {
1450 PFORMAT_STRING info
= pFormat
;
1451 unsigned char *memdstbase
= pDstMemoryPtrs
+ (i
* stride
);
1452 unsigned char *memsrcbase
= pSrcMemoryPtrs
+ (i
* stride
);
1453 unsigned char *bufbase
= Mark
+ (i
* stride
);
1456 for (u
=0; u
<count
; u
++,info
+=8) {
1457 unsigned char **memdstptr
= (unsigned char **)(memdstbase
+ *(const SHORT
*)&info
[0]);
1458 unsigned char **memsrcptr
= (unsigned char **)(memsrcbase
+ *(const SHORT
*)&info
[0]);
1459 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1460 PointerUnmarshall(pStubMsg
, bufptr
, memdstptr
, *memsrcptr
, info
+4, fMustAlloc
);
1463 pFormat
+= 8 * count
;
1468 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1469 pStubMsg
->Buffer
= saved_buffer
;
1475 /***********************************************************************
1476 * EmbeddedPointerBufferSize
1478 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1479 unsigned char *pMemory
,
1480 PFORMAT_STRING pFormat
)
1482 unsigned rep
, count
, stride
;
1484 ULONG saved_buffer_length
= 0;
1486 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1488 if (pStubMsg
->IgnoreEmbeddedPointers
) return;
1490 if (*pFormat
!= RPC_FC_PP
) return;
1493 if (pStubMsg
->PointerLength
)
1495 saved_buffer_length
= pStubMsg
->BufferLength
;
1496 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
1497 pStubMsg
->PointerLength
= 0;
1500 while (pFormat
[0] != RPC_FC_END
) {
1501 switch (pFormat
[0]) {
1503 FIXME("unknown repeat type %d\n", pFormat
[0]);
1504 case RPC_FC_NO_REPEAT
:
1510 case RPC_FC_FIXED_REPEAT
:
1511 rep
= *(const WORD
*)&pFormat
[2];
1512 stride
= *(const WORD
*)&pFormat
[4];
1513 count
= *(const WORD
*)&pFormat
[8];
1516 case RPC_FC_VARIABLE_REPEAT
:
1517 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1518 stride
= *(const WORD
*)&pFormat
[2];
1519 count
= *(const WORD
*)&pFormat
[6];
1523 for (i
= 0; i
< rep
; i
++) {
1524 PFORMAT_STRING info
= pFormat
;
1525 unsigned char *membase
= pMemory
+ (i
* stride
);
1528 for (u
=0; u
<count
; u
++,info
+=8) {
1529 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1530 unsigned char *saved_memory
= pStubMsg
->Memory
;
1532 pStubMsg
->Memory
= pMemory
;
1533 PointerBufferSize(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1534 pStubMsg
->Memory
= saved_memory
;
1537 pFormat
+= 8 * count
;
1540 if (saved_buffer_length
)
1542 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
1543 pStubMsg
->BufferLength
= saved_buffer_length
;
1547 /***********************************************************************
1548 * EmbeddedPointerMemorySize [internal]
1550 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1551 PFORMAT_STRING pFormat
)
1553 unsigned char *Mark
= pStubMsg
->BufferMark
;
1554 unsigned rep
, count
, stride
;
1556 unsigned char *saved_buffer
= NULL
;
1558 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1560 if (pStubMsg
->IgnoreEmbeddedPointers
) return 0;
1562 if (pStubMsg
->PointerBufferMark
)
1564 saved_buffer
= pStubMsg
->Buffer
;
1565 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1566 pStubMsg
->PointerBufferMark
= NULL
;
1569 if (*pFormat
!= RPC_FC_PP
) return 0;
1572 while (pFormat
[0] != RPC_FC_END
) {
1573 switch (pFormat
[0]) {
1575 FIXME("unknown repeat type %d\n", pFormat
[0]);
1576 case RPC_FC_NO_REPEAT
:
1582 case RPC_FC_FIXED_REPEAT
:
1583 rep
= *(const WORD
*)&pFormat
[2];
1584 stride
= *(const WORD
*)&pFormat
[4];
1585 count
= *(const WORD
*)&pFormat
[8];
1588 case RPC_FC_VARIABLE_REPEAT
:
1589 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1590 stride
= *(const WORD
*)&pFormat
[2];
1591 count
= *(const WORD
*)&pFormat
[6];
1595 for (i
= 0; i
< rep
; i
++) {
1596 PFORMAT_STRING info
= pFormat
;
1597 unsigned char *bufbase
= Mark
+ (i
* stride
);
1599 for (u
=0; u
<count
; u
++,info
+=8) {
1600 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1601 PointerMemorySize(pStubMsg
, bufptr
, info
+4);
1604 pFormat
+= 8 * count
;
1609 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1610 pStubMsg
->Buffer
= saved_buffer
;
1616 /***********************************************************************
1617 * EmbeddedPointerFree [internal]
1619 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1620 unsigned char *pMemory
,
1621 PFORMAT_STRING pFormat
)
1623 unsigned rep
, count
, stride
;
1626 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1627 if (*pFormat
!= RPC_FC_PP
) return;
1630 while (pFormat
[0] != RPC_FC_END
) {
1631 switch (pFormat
[0]) {
1633 FIXME("unknown repeat type %d\n", pFormat
[0]);
1634 case RPC_FC_NO_REPEAT
:
1640 case RPC_FC_FIXED_REPEAT
:
1641 rep
= *(const WORD
*)&pFormat
[2];
1642 stride
= *(const WORD
*)&pFormat
[4];
1643 count
= *(const WORD
*)&pFormat
[8];
1646 case RPC_FC_VARIABLE_REPEAT
:
1647 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1648 stride
= *(const WORD
*)&pFormat
[2];
1649 count
= *(const WORD
*)&pFormat
[6];
1653 for (i
= 0; i
< rep
; i
++) {
1654 PFORMAT_STRING info
= pFormat
;
1655 unsigned char *membase
= pMemory
+ (i
* stride
);
1658 for (u
=0; u
<count
; u
++,info
+=8) {
1659 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1660 unsigned char *saved_memory
= pStubMsg
->Memory
;
1662 pStubMsg
->Memory
= pMemory
;
1663 PointerFree(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1664 pStubMsg
->Memory
= saved_memory
;
1667 pFormat
+= 8 * count
;
1671 /***********************************************************************
1672 * NdrPointerMarshall [RPCRT4.@]
1674 unsigned char * WINAPI
NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1675 unsigned char *pMemory
,
1676 PFORMAT_STRING pFormat
)
1678 unsigned char *Buffer
;
1680 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1682 /* incremement the buffer here instead of in PointerMarshall,
1683 * as that is used by embedded pointers which already handle the incrementing
1684 * the buffer, and shouldn't write any additional pointer data to the wire */
1685 if (*pFormat
!= RPC_FC_RP
)
1687 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
1688 Buffer
= pStubMsg
->Buffer
;
1689 safe_buffer_increment(pStubMsg
, 4);
1692 Buffer
= pStubMsg
->Buffer
;
1694 PointerMarshall(pStubMsg
, Buffer
, pMemory
, pFormat
);
1699 /***********************************************************************
1700 * NdrPointerUnmarshall [RPCRT4.@]
1702 unsigned char * WINAPI
NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1703 unsigned char **ppMemory
,
1704 PFORMAT_STRING pFormat
,
1705 unsigned char fMustAlloc
)
1707 unsigned char *Buffer
;
1709 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1711 /* incremement the buffer here instead of in PointerUnmarshall,
1712 * as that is used by embedded pointers which already handle the incrementing
1713 * the buffer, and shouldn't read any additional pointer data from the
1715 if (*pFormat
!= RPC_FC_RP
)
1717 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1718 Buffer
= pStubMsg
->Buffer
;
1719 safe_buffer_increment(pStubMsg
, 4);
1722 Buffer
= pStubMsg
->Buffer
;
1724 PointerUnmarshall(pStubMsg
, Buffer
, ppMemory
, *ppMemory
, pFormat
, fMustAlloc
);
1729 /***********************************************************************
1730 * NdrPointerBufferSize [RPCRT4.@]
1732 void WINAPI
NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1733 unsigned char *pMemory
,
1734 PFORMAT_STRING pFormat
)
1736 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1738 /* incremement the buffer length here instead of in PointerBufferSize,
1739 * as that is used by embedded pointers which already handle the buffer
1740 * length, and shouldn't write anything more to the wire */
1741 if (*pFormat
!= RPC_FC_RP
)
1743 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
1744 safe_buffer_length_increment(pStubMsg
, 4);
1747 PointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1750 /***********************************************************************
1751 * NdrPointerMemorySize [RPCRT4.@]
1753 ULONG WINAPI
NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1754 PFORMAT_STRING pFormat
)
1756 /* unsigned size = *(LPWORD)(pFormat+2); */
1757 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1758 PointerMemorySize(pStubMsg
, pStubMsg
->Buffer
, pFormat
);
1762 /***********************************************************************
1763 * NdrPointerFree [RPCRT4.@]
1765 void WINAPI
NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1766 unsigned char *pMemory
,
1767 PFORMAT_STRING pFormat
)
1769 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1770 PointerFree(pStubMsg
, pMemory
, pFormat
);
1773 /***********************************************************************
1774 * NdrSimpleTypeMarshall [RPCRT4.@]
1776 void WINAPI
NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1777 unsigned char FormatChar
)
1779 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &FormatChar
);
1782 /***********************************************************************
1783 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1785 void WINAPI
NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1786 unsigned char FormatChar
)
1788 NdrBaseTypeUnmarshall(pStubMsg
, &pMemory
, &FormatChar
, 0);
1791 /***********************************************************************
1792 * NdrSimpleStructMarshall [RPCRT4.@]
1794 unsigned char * WINAPI
NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1795 unsigned char *pMemory
,
1796 PFORMAT_STRING pFormat
)
1798 unsigned size
= *(const WORD
*)(pFormat
+2);
1799 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1801 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pFormat
[1] + 1);
1803 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1804 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
1806 if (pFormat
[0] != RPC_FC_STRUCT
)
1807 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
+4);
1812 /***********************************************************************
1813 * NdrSimpleStructUnmarshall [RPCRT4.@]
1815 unsigned char * WINAPI
NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1816 unsigned char **ppMemory
,
1817 PFORMAT_STRING pFormat
,
1818 unsigned char fMustAlloc
)
1820 unsigned size
= *(const WORD
*)(pFormat
+2);
1821 unsigned char *saved_buffer
;
1822 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1824 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1827 *ppMemory
= NdrAllocate(pStubMsg
, size
);
1830 if (!pStubMsg
->IsClient
&& !*ppMemory
)
1831 /* for servers, we just point straight into the RPC buffer */
1832 *ppMemory
= pStubMsg
->Buffer
;
1835 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1836 safe_buffer_increment(pStubMsg
, size
);
1837 if (pFormat
[0] == RPC_FC_PSTRUCT
)
1838 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
+4, fMustAlloc
);
1840 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
1841 if (*ppMemory
!= saved_buffer
)
1842 memcpy(*ppMemory
, saved_buffer
, size
);
1847 /***********************************************************************
1848 * NdrSimpleStructBufferSize [RPCRT4.@]
1850 void WINAPI
NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1851 unsigned char *pMemory
,
1852 PFORMAT_STRING pFormat
)
1854 unsigned size
= *(const WORD
*)(pFormat
+2);
1855 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1857 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
1859 safe_buffer_length_increment(pStubMsg
, size
);
1860 if (pFormat
[0] != RPC_FC_STRUCT
)
1861 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
+4);
1864 /***********************************************************************
1865 * NdrSimpleStructMemorySize [RPCRT4.@]
1867 ULONG WINAPI
NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1868 PFORMAT_STRING pFormat
)
1870 unsigned short size
= *(const WORD
*)(pFormat
+2);
1872 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1874 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1875 pStubMsg
->MemorySize
+= size
;
1876 safe_buffer_increment(pStubMsg
, size
);
1878 if (pFormat
[0] != RPC_FC_STRUCT
)
1879 EmbeddedPointerMemorySize(pStubMsg
, pFormat
+4);
1880 return pStubMsg
->MemorySize
;
1883 /***********************************************************************
1884 * NdrSimpleStructFree [RPCRT4.@]
1886 void WINAPI
NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
1887 unsigned char *pMemory
,
1888 PFORMAT_STRING pFormat
)
1890 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1891 if (pFormat
[0] != RPC_FC_STRUCT
)
1892 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
+4);
1896 static unsigned long EmbeddedComplexSize(const MIDL_STUB_MESSAGE
*pStubMsg
,
1897 PFORMAT_STRING pFormat
)
1901 case RPC_FC_PSTRUCT
:
1902 case RPC_FC_CSTRUCT
:
1903 case RPC_FC_BOGUS_STRUCT
:
1904 case RPC_FC_SMFARRAY
:
1905 case RPC_FC_SMVARRAY
:
1906 return *(const WORD
*)&pFormat
[2];
1907 case RPC_FC_USER_MARSHAL
:
1908 return *(const WORD
*)&pFormat
[4];
1909 case RPC_FC_NON_ENCAPSULATED_UNION
:
1911 if (pStubMsg
->fHasNewCorrDesc
)
1916 pFormat
+= *(const SHORT
*)pFormat
;
1917 return *(const SHORT
*)pFormat
;
1919 return sizeof(void *);
1921 FIXME("unhandled embedded type %02x\n", *pFormat
);
1927 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1928 PFORMAT_STRING pFormat
)
1930 NDR_MEMORYSIZE m
= NdrMemorySizer
[*pFormat
& NDR_TABLE_MASK
];
1934 FIXME("no memorysizer for data type=%02x\n", *pFormat
);
1938 return m(pStubMsg
, pFormat
);
1942 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1943 unsigned char *pMemory
,
1944 PFORMAT_STRING pFormat
,
1945 PFORMAT_STRING pPointer
)
1947 PFORMAT_STRING desc
;
1951 while (*pFormat
!= RPC_FC_END
) {
1957 TRACE("byte=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
1958 safe_copy_to_buffer(pStubMsg
, pMemory
, 1);
1964 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
1965 safe_copy_to_buffer(pStubMsg
, pMemory
, 2);
1971 TRACE("long=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
1972 safe_copy_to_buffer(pStubMsg
, pMemory
, 4);
1976 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
1977 safe_copy_to_buffer(pStubMsg
, pMemory
, 8);
1980 case RPC_FC_POINTER
:
1982 unsigned char *saved_buffer
;
1983 int pointer_buffer_mark_set
= 0;
1984 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
1985 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
1986 saved_buffer
= pStubMsg
->Buffer
;
1987 if (pStubMsg
->PointerBufferMark
)
1989 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1990 pStubMsg
->PointerBufferMark
= NULL
;
1991 pointer_buffer_mark_set
= 1;
1994 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
1995 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char**)pMemory
, pPointer
);
1996 if (pointer_buffer_mark_set
)
1998 STD_OVERFLOW_CHECK(pStubMsg
);
1999 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2000 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
2002 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2003 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
2004 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2006 pStubMsg
->Buffer
= saved_buffer
+ 4;
2012 case RPC_FC_ALIGNM4
:
2013 ALIGN_POINTER(pMemory
, 4);
2015 case RPC_FC_ALIGNM8
:
2016 ALIGN_POINTER(pMemory
, 8);
2018 case RPC_FC_STRUCTPAD1
:
2019 case RPC_FC_STRUCTPAD2
:
2020 case RPC_FC_STRUCTPAD3
:
2021 case RPC_FC_STRUCTPAD4
:
2022 case RPC_FC_STRUCTPAD5
:
2023 case RPC_FC_STRUCTPAD6
:
2024 case RPC_FC_STRUCTPAD7
:
2025 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2027 case RPC_FC_EMBEDDED_COMPLEX
:
2028 pMemory
+= pFormat
[1];
2030 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2031 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2032 TRACE("embedded complex (size=%ld) <= %p\n", size
, pMemory
);
2033 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
2036 /* for some reason interface pointers aren't generated as
2037 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2038 * they still need the derefencing treatment that pointers are
2040 if (*desc
== RPC_FC_IP
)
2041 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2043 m(pStubMsg
, pMemory
, desc
);
2045 else FIXME("no marshaller for embedded type %02x\n", *desc
);
2052 FIXME("unhandled format 0x%02x\n", *pFormat
);
2060 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2061 unsigned char *pMemory
,
2062 PFORMAT_STRING pFormat
,
2063 PFORMAT_STRING pPointer
)
2065 PFORMAT_STRING desc
;
2069 while (*pFormat
!= RPC_FC_END
) {
2075 safe_copy_from_buffer(pStubMsg
, pMemory
, 1);
2076 TRACE("byte=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2082 safe_copy_from_buffer(pStubMsg
, pMemory
, 2);
2083 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
2089 safe_copy_from_buffer(pStubMsg
, pMemory
, 4);
2090 TRACE("long=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
2094 safe_copy_from_buffer(pStubMsg
, pMemory
, 8);
2095 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
2098 case RPC_FC_POINTER
:
2100 unsigned char *saved_buffer
;
2101 int pointer_buffer_mark_set
= 0;
2102 TRACE("pointer => %p\n", pMemory
);
2103 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2104 saved_buffer
= pStubMsg
->Buffer
;
2105 if (pStubMsg
->PointerBufferMark
)
2107 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2108 pStubMsg
->PointerBufferMark
= NULL
;
2109 pointer_buffer_mark_set
= 1;
2112 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
2114 PointerUnmarshall(pStubMsg
, saved_buffer
, (unsigned char**)pMemory
, *(unsigned char**)pMemory
, pPointer
, TRUE
);
2115 if (pointer_buffer_mark_set
)
2117 STD_OVERFLOW_CHECK(pStubMsg
);
2118 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2119 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
2121 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2122 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
2123 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
2125 pStubMsg
->Buffer
= saved_buffer
+ 4;
2131 case RPC_FC_ALIGNM4
:
2132 ALIGN_POINTER_CLEAR(pMemory
, 4);
2134 case RPC_FC_ALIGNM8
:
2135 ALIGN_POINTER_CLEAR(pMemory
, 8);
2137 case RPC_FC_STRUCTPAD1
:
2138 case RPC_FC_STRUCTPAD2
:
2139 case RPC_FC_STRUCTPAD3
:
2140 case RPC_FC_STRUCTPAD4
:
2141 case RPC_FC_STRUCTPAD5
:
2142 case RPC_FC_STRUCTPAD6
:
2143 case RPC_FC_STRUCTPAD7
:
2144 memset(pMemory
, 0, *pFormat
- RPC_FC_STRUCTPAD1
+ 1);
2145 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2147 case RPC_FC_EMBEDDED_COMPLEX
:
2148 pMemory
+= pFormat
[1];
2150 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2151 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2152 TRACE("embedded complex (size=%ld) => %p\n", size
, pMemory
);
2153 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
2154 memset(pMemory
, 0, size
); /* just in case */
2157 /* for some reason interface pointers aren't generated as
2158 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2159 * they still need the derefencing treatment that pointers are
2161 if (*desc
== RPC_FC_IP
)
2162 m(pStubMsg
, (unsigned char **)pMemory
, desc
, FALSE
);
2164 m(pStubMsg
, &pMemory
, desc
, FALSE
);
2166 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
2173 FIXME("unhandled format %d\n", *pFormat
);
2181 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2182 unsigned char *pMemory
,
2183 PFORMAT_STRING pFormat
,
2184 PFORMAT_STRING pPointer
)
2186 PFORMAT_STRING desc
;
2190 while (*pFormat
!= RPC_FC_END
) {
2196 safe_buffer_length_increment(pStubMsg
, 1);
2202 safe_buffer_length_increment(pStubMsg
, 2);
2208 safe_buffer_length_increment(pStubMsg
, 4);
2212 safe_buffer_length_increment(pStubMsg
, 8);
2215 case RPC_FC_POINTER
:
2216 if (!pStubMsg
->IgnoreEmbeddedPointers
)
2218 int saved_buffer_length
= pStubMsg
->BufferLength
;
2219 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2220 pStubMsg
->PointerLength
= 0;
2221 if(!pStubMsg
->BufferLength
)
2222 ERR("BufferLength == 0??\n");
2223 PointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
2224 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2225 pStubMsg
->BufferLength
= saved_buffer_length
;
2227 safe_buffer_length_increment(pStubMsg
, 4);
2231 case RPC_FC_ALIGNM4
:
2232 ALIGN_POINTER(pMemory
, 4);
2234 case RPC_FC_ALIGNM8
:
2235 ALIGN_POINTER(pMemory
, 8);
2237 case RPC_FC_STRUCTPAD1
:
2238 case RPC_FC_STRUCTPAD2
:
2239 case RPC_FC_STRUCTPAD3
:
2240 case RPC_FC_STRUCTPAD4
:
2241 case RPC_FC_STRUCTPAD5
:
2242 case RPC_FC_STRUCTPAD6
:
2243 case RPC_FC_STRUCTPAD7
:
2244 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2246 case RPC_FC_EMBEDDED_COMPLEX
:
2247 pMemory
+= pFormat
[1];
2249 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2250 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2251 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
2254 /* for some reason interface pointers aren't generated as
2255 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2256 * they still need the derefencing treatment that pointers are
2258 if (*desc
== RPC_FC_IP
)
2259 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2261 m(pStubMsg
, pMemory
, desc
);
2263 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
2270 FIXME("unhandled format 0x%02x\n", *pFormat
);
2278 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
2279 unsigned char *pMemory
,
2280 PFORMAT_STRING pFormat
,
2281 PFORMAT_STRING pPointer
)
2283 PFORMAT_STRING desc
;
2287 while (*pFormat
!= RPC_FC_END
) {
2308 case RPC_FC_POINTER
:
2309 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
2313 case RPC_FC_ALIGNM4
:
2314 ALIGN_POINTER(pMemory
, 4);
2316 case RPC_FC_ALIGNM8
:
2317 ALIGN_POINTER(pMemory
, 8);
2319 case RPC_FC_STRUCTPAD1
:
2320 case RPC_FC_STRUCTPAD2
:
2321 case RPC_FC_STRUCTPAD3
:
2322 case RPC_FC_STRUCTPAD4
:
2323 case RPC_FC_STRUCTPAD5
:
2324 case RPC_FC_STRUCTPAD6
:
2325 case RPC_FC_STRUCTPAD7
:
2326 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2328 case RPC_FC_EMBEDDED_COMPLEX
:
2329 pMemory
+= pFormat
[1];
2331 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2332 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2333 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
2336 /* for some reason interface pointers aren't generated as
2337 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2338 * they still need the derefencing treatment that pointers are
2340 if (*desc
== RPC_FC_IP
)
2341 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2343 m(pStubMsg
, pMemory
, desc
);
2345 else FIXME("no freer for embedded type %02x\n", *desc
);
2352 FIXME("unhandled format 0x%02x\n", *pFormat
);
2360 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2361 PFORMAT_STRING pFormat
)
2363 PFORMAT_STRING desc
;
2364 unsigned long size
= 0;
2366 while (*pFormat
!= RPC_FC_END
) {
2373 safe_buffer_increment(pStubMsg
, 1);
2379 safe_buffer_increment(pStubMsg
, 2);
2385 safe_buffer_increment(pStubMsg
, 4);
2389 safe_buffer_increment(pStubMsg
, 8);
2391 case RPC_FC_POINTER
:
2393 safe_buffer_increment(pStubMsg
, 4);
2394 if (!pStubMsg
->IgnoreEmbeddedPointers
)
2395 FIXME("embedded pointers\n");
2397 case RPC_FC_ALIGNM4
:
2398 ALIGN_LENGTH(size
, 4);
2399 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2401 case RPC_FC_ALIGNM8
:
2402 ALIGN_LENGTH(size
, 8);
2403 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
2405 case RPC_FC_STRUCTPAD1
:
2406 case RPC_FC_STRUCTPAD2
:
2407 case RPC_FC_STRUCTPAD3
:
2408 case RPC_FC_STRUCTPAD4
:
2409 case RPC_FC_STRUCTPAD5
:
2410 case RPC_FC_STRUCTPAD6
:
2411 case RPC_FC_STRUCTPAD7
:
2412 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2414 case RPC_FC_EMBEDDED_COMPLEX
:
2417 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2418 size
+= EmbeddedComplexMemorySize(pStubMsg
, desc
);
2424 FIXME("unhandled format 0x%02x\n", *pFormat
);
2432 /***********************************************************************
2433 * NdrComplexStructMarshall [RPCRT4.@]
2435 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2436 unsigned char *pMemory
,
2437 PFORMAT_STRING pFormat
)
2439 PFORMAT_STRING conf_array
= NULL
;
2440 PFORMAT_STRING pointer_desc
= NULL
;
2441 unsigned char *OldMemory
= pStubMsg
->Memory
;
2442 int pointer_buffer_mark_set
= 0;
2444 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2446 if (!pStubMsg
->PointerBufferMark
)
2448 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2449 /* save buffer length */
2450 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2452 /* get the buffer pointer after complex array data, but before
2454 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- pStubMsg
->BufferStart
;
2455 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2456 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
2457 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2459 /* save it for use by embedded pointer code later */
2460 pStubMsg
->PointerBufferMark
= pStubMsg
->BufferStart
+ pStubMsg
->BufferLength
;
2461 TRACE("difference = 0x%x\n", pStubMsg
->PointerBufferMark
- pStubMsg
->Buffer
);
2462 pointer_buffer_mark_set
= 1;
2464 /* restore the original buffer length */
2465 pStubMsg
->BufferLength
= saved_buffer_length
;
2468 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pFormat
[1] + 1);
2471 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2473 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2476 pStubMsg
->Memory
= pMemory
;
2478 ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2481 NdrConformantArrayMarshall(pStubMsg
, pMemory
, conf_array
);
2483 pStubMsg
->Memory
= OldMemory
;
2485 if (pointer_buffer_mark_set
)
2487 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2488 pStubMsg
->PointerBufferMark
= NULL
;
2491 STD_OVERFLOW_CHECK(pStubMsg
);
2496 /***********************************************************************
2497 * NdrComplexStructUnmarshall [RPCRT4.@]
2499 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2500 unsigned char **ppMemory
,
2501 PFORMAT_STRING pFormat
,
2502 unsigned char fMustAlloc
)
2504 unsigned size
= *(const WORD
*)(pFormat
+2);
2505 PFORMAT_STRING conf_array
= NULL
;
2506 PFORMAT_STRING pointer_desc
= NULL
;
2507 unsigned char *pMemory
;
2508 int pointer_buffer_mark_set
= 0;
2510 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2512 if (!pStubMsg
->PointerBufferMark
)
2514 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2515 /* save buffer pointer */
2516 unsigned char *saved_buffer
= pStubMsg
->Buffer
;
2518 /* get the buffer pointer after complex array data, but before
2520 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2521 NdrComplexStructMemorySize(pStubMsg
, pFormat
);
2522 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2524 /* save it for use by embedded pointer code later */
2525 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2526 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->PointerBufferMark
- saved_buffer
));
2527 pointer_buffer_mark_set
= 1;
2529 /* restore the original buffer */
2530 pStubMsg
->Buffer
= saved_buffer
;
2533 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2535 if (fMustAlloc
|| !*ppMemory
)
2537 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2538 memset(*ppMemory
, 0, size
);
2542 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2544 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2547 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
);
2550 NdrConformantArrayUnmarshall(pStubMsg
, &pMemory
, conf_array
, fMustAlloc
);
2552 if (pointer_buffer_mark_set
)
2554 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2555 pStubMsg
->PointerBufferMark
= NULL
;
2561 /***********************************************************************
2562 * NdrComplexStructBufferSize [RPCRT4.@]
2564 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2565 unsigned char *pMemory
,
2566 PFORMAT_STRING pFormat
)
2568 PFORMAT_STRING conf_array
= NULL
;
2569 PFORMAT_STRING pointer_desc
= NULL
;
2570 unsigned char *OldMemory
= pStubMsg
->Memory
;
2571 int pointer_length_set
= 0;
2573 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2575 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
2577 if(!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
2579 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2580 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2582 /* get the buffer length after complex struct data, but before
2584 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2585 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
2586 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2588 /* save it for use by embedded pointer code later */
2589 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2590 pointer_length_set
= 1;
2591 TRACE("difference = 0x%lx\n", pStubMsg
->PointerLength
- saved_buffer_length
);
2593 /* restore the original buffer length */
2594 pStubMsg
->BufferLength
= saved_buffer_length
;
2598 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2600 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2603 pStubMsg
->Memory
= pMemory
;
2605 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2608 NdrConformantArrayBufferSize(pStubMsg
, pMemory
, conf_array
);
2610 pStubMsg
->Memory
= OldMemory
;
2612 if(pointer_length_set
)
2614 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2615 pStubMsg
->PointerLength
= 0;
2620 /***********************************************************************
2621 * NdrComplexStructMemorySize [RPCRT4.@]
2623 ULONG WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2624 PFORMAT_STRING pFormat
)
2626 unsigned size
= *(const WORD
*)(pFormat
+2);
2627 PFORMAT_STRING conf_array
= NULL
;
2628 PFORMAT_STRING pointer_desc
= NULL
;
2630 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2632 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2635 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2637 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2640 ComplexStructMemorySize(pStubMsg
, pFormat
);
2643 NdrConformantArrayMemorySize(pStubMsg
, conf_array
);
2648 /***********************************************************************
2649 * NdrComplexStructFree [RPCRT4.@]
2651 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
2652 unsigned char *pMemory
,
2653 PFORMAT_STRING pFormat
)
2655 PFORMAT_STRING conf_array
= NULL
;
2656 PFORMAT_STRING pointer_desc
= NULL
;
2657 unsigned char *OldMemory
= pStubMsg
->Memory
;
2659 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2662 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2664 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2667 pStubMsg
->Memory
= pMemory
;
2669 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2672 NdrConformantArrayFree(pStubMsg
, pMemory
, conf_array
);
2674 pStubMsg
->Memory
= OldMemory
;
2677 /***********************************************************************
2678 * NdrConformantArrayMarshall [RPCRT4.@]
2680 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2681 unsigned char *pMemory
,
2682 PFORMAT_STRING pFormat
)
2684 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
2685 unsigned char alignment
= pFormat
[1] + 1;
2687 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2688 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2690 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2692 WriteConformance(pStubMsg
);
2694 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
2696 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2697 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2698 safe_copy_to_buffer(pStubMsg
, pMemory
, size
);
2700 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2705 /***********************************************************************
2706 * NdrConformantArrayUnmarshall [RPCRT4.@]
2708 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2709 unsigned char **ppMemory
,
2710 PFORMAT_STRING pFormat
,
2711 unsigned char fMustAlloc
)
2713 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
2714 unsigned char alignment
= pFormat
[1] + 1;
2715 unsigned char *saved_buffer
;
2717 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2718 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2720 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2722 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2723 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2726 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2729 if (!pStubMsg
->IsClient
&& !*ppMemory
)
2730 /* for servers, we just point straight into the RPC buffer */
2731 *ppMemory
= pStubMsg
->Buffer
;
2734 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2735 safe_buffer_increment(pStubMsg
, size
);
2736 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
2738 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
2739 if (*ppMemory
!= saved_buffer
)
2740 memcpy(*ppMemory
, saved_buffer
, size
);
2745 /***********************************************************************
2746 * NdrConformantArrayBufferSize [RPCRT4.@]
2748 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2749 unsigned char *pMemory
,
2750 PFORMAT_STRING pFormat
)
2752 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
2753 unsigned char alignment
= pFormat
[1] + 1;
2755 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2756 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2758 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2760 SizeConformance(pStubMsg
);
2762 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
2764 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2765 /* conformance value plus array */
2766 safe_buffer_length_increment(pStubMsg
, size
);
2768 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
2771 /***********************************************************************
2772 * NdrConformantArrayMemorySize [RPCRT4.@]
2774 ULONG WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2775 PFORMAT_STRING pFormat
)
2777 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
2778 unsigned char alignment
= pFormat
[1] + 1;
2780 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2781 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2783 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2784 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2785 pStubMsg
->MemorySize
+= size
;
2787 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2788 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2789 safe_buffer_increment(pStubMsg
, size
);
2791 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2793 return pStubMsg
->MemorySize
;
2796 /***********************************************************************
2797 * NdrConformantArrayFree [RPCRT4.@]
2799 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
2800 unsigned char *pMemory
,
2801 PFORMAT_STRING pFormat
)
2803 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2804 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2806 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2808 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2812 /***********************************************************************
2813 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2815 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2816 unsigned char* pMemory
,
2817 PFORMAT_STRING pFormat
)
2820 unsigned char alignment
= pFormat
[1] + 1;
2821 DWORD esize
= *(const WORD
*)(pFormat
+2);
2823 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
2825 if (pFormat
[0] != RPC_FC_CVARRAY
)
2827 ERR("invalid format type %x\n", pFormat
[0]);
2828 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2832 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2833 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2835 WriteConformance(pStubMsg
);
2836 WriteVariance(pStubMsg
);
2838 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
2840 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2842 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2843 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
2845 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2851 /***********************************************************************
2852 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2854 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2855 unsigned char** ppMemory
,
2856 PFORMAT_STRING pFormat
,
2857 unsigned char fMustAlloc
)
2859 ULONG bufsize
, memsize
;
2860 unsigned char alignment
= pFormat
[1] + 1;
2861 DWORD esize
= *(const WORD
*)(pFormat
+2);
2863 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2865 if (pFormat
[0] != RPC_FC_CVARRAY
)
2867 ERR("invalid format type %x\n", pFormat
[0]);
2868 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2872 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2873 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2875 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2877 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2878 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2880 if (!*ppMemory
|| fMustAlloc
)
2881 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2882 safe_copy_from_buffer(pStubMsg
, *ppMemory
+ pStubMsg
->Offset
, bufsize
);
2884 EmbeddedPointerUnmarshall(pStubMsg
, *ppMemory
, *ppMemory
, pFormat
, TRUE
/* FIXME */);
2890 /***********************************************************************
2891 * NdrConformantVaryingArrayFree [RPCRT4.@]
2893 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
2894 unsigned char* pMemory
,
2895 PFORMAT_STRING pFormat
)
2897 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2899 if (pFormat
[0] != RPC_FC_CVARRAY
)
2901 ERR("invalid format type %x\n", pFormat
[0]);
2902 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2906 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2907 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2909 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2913 /***********************************************************************
2914 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2916 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
2917 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
2919 unsigned char alignment
= pFormat
[1] + 1;
2920 DWORD esize
= *(const WORD
*)(pFormat
+2);
2922 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
2924 if (pFormat
[0] != RPC_FC_CVARRAY
)
2926 ERR("invalid format type %x\n", pFormat
[0]);
2927 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2932 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2933 /* compute length */
2934 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2936 SizeConformance(pStubMsg
);
2937 SizeVariance(pStubMsg
);
2939 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
2941 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
2943 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
2947 /***********************************************************************
2948 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2950 ULONG WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
2951 PFORMAT_STRING pFormat
)
2953 ULONG bufsize
, memsize
;
2954 unsigned char alignment
= pFormat
[1] + 1;
2955 DWORD esize
= *(const WORD
*)(pFormat
+2);
2957 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
2959 if (pFormat
[0] != RPC_FC_CVARRAY
)
2961 ERR("invalid format type %x\n", pFormat
[0]);
2962 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2963 return pStubMsg
->MemorySize
;
2966 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2967 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2969 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2971 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2972 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2974 safe_buffer_increment(pStubMsg
, bufsize
);
2975 pStubMsg
->MemorySize
+= memsize
;
2977 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2979 return pStubMsg
->MemorySize
;
2983 /***********************************************************************
2984 * NdrComplexArrayMarshall [RPCRT4.@]
2986 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2987 unsigned char *pMemory
,
2988 PFORMAT_STRING pFormat
)
2990 ULONG i
, count
, def
;
2991 BOOL variance_present
;
2992 unsigned char alignment
;
2993 int pointer_buffer_mark_set
= 0;
2995 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2997 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
2999 ERR("invalid format type %x\n", pFormat
[0]);
3000 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3004 alignment
= pFormat
[1] + 1;
3006 if (!pStubMsg
->PointerBufferMark
)
3008 /* save buffer fields that may be changed by buffer sizer functions
3009 * and that may be needed later on */
3010 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3011 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
3012 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
3013 unsigned long saved_offset
= pStubMsg
->Offset
;
3014 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
3016 /* get the buffer pointer after complex array data, but before
3018 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- pStubMsg
->BufferStart
;
3019 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3020 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
3021 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3023 /* save it for use by embedded pointer code later */
3024 pStubMsg
->PointerBufferMark
= pStubMsg
->BufferStart
+ pStubMsg
->BufferLength
;
3025 TRACE("difference = 0x%x\n", pStubMsg
->Buffer
- pStubMsg
->BufferStart
);
3026 pointer_buffer_mark_set
= 1;
3028 /* restore fields */
3029 pStubMsg
->ActualCount
= saved_actual_count
;
3030 pStubMsg
->Offset
= saved_offset
;
3031 pStubMsg
->MaxCount
= saved_max_count
;
3032 pStubMsg
->BufferLength
= saved_buffer_length
;
3035 def
= *(const WORD
*)&pFormat
[2];
3038 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3039 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3041 variance_present
= IsConformanceOrVariancePresent(pFormat
);
3042 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3043 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3045 WriteConformance(pStubMsg
);
3046 if (variance_present
)
3047 WriteVariance(pStubMsg
);
3049 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
3051 count
= pStubMsg
->ActualCount
;
3052 for (i
= 0; i
< count
; i
++)
3053 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
3055 STD_OVERFLOW_CHECK(pStubMsg
);
3057 if (pointer_buffer_mark_set
)
3059 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3060 pStubMsg
->PointerBufferMark
= NULL
;
3066 /***********************************************************************
3067 * NdrComplexArrayUnmarshall [RPCRT4.@]
3069 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3070 unsigned char **ppMemory
,
3071 PFORMAT_STRING pFormat
,
3072 unsigned char fMustAlloc
)
3074 ULONG i
, count
, size
;
3075 unsigned char alignment
;
3076 unsigned char *pMemory
;
3077 unsigned char *saved_buffer
;
3078 int pointer_buffer_mark_set
= 0;
3079 int saved_ignore_embedded
;
3081 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3083 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3085 ERR("invalid format type %x\n", pFormat
[0]);
3086 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3090 alignment
= pFormat
[1] + 1;
3092 saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3093 /* save buffer pointer */
3094 saved_buffer
= pStubMsg
->Buffer
;
3095 /* get the buffer pointer after complex array data, but before
3097 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3098 pStubMsg
->MemorySize
= 0;
3099 NdrComplexArrayMemorySize(pStubMsg
, pFormat
);
3100 size
= pStubMsg
->MemorySize
;
3101 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3103 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->Buffer
- saved_buffer
));
3104 if (!pStubMsg
->PointerBufferMark
)
3106 /* save it for use by embedded pointer code later */
3107 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3108 pointer_buffer_mark_set
= 1;
3110 /* restore the original buffer */
3111 pStubMsg
->Buffer
= saved_buffer
;
3115 pFormat
= ReadConformance(pStubMsg
, pFormat
);
3116 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3118 if (fMustAlloc
|| !*ppMemory
)
3120 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3121 memset(*ppMemory
, 0, size
);
3124 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3126 pMemory
= *ppMemory
;
3127 count
= pStubMsg
->ActualCount
;
3128 for (i
= 0; i
< count
; i
++)
3129 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
3131 if (pointer_buffer_mark_set
)
3133 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3134 pStubMsg
->PointerBufferMark
= NULL
;
3140 /***********************************************************************
3141 * NdrComplexArrayBufferSize [RPCRT4.@]
3143 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3144 unsigned char *pMemory
,
3145 PFORMAT_STRING pFormat
)
3147 ULONG i
, count
, def
;
3148 unsigned char alignment
;
3149 BOOL variance_present
;
3150 int pointer_length_set
= 0;
3152 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3154 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3156 ERR("invalid format type %x\n", pFormat
[0]);
3157 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3161 alignment
= pFormat
[1] + 1;
3163 if (!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
3165 /* save buffer fields that may be changed by buffer sizer functions
3166 * and that may be needed later on */
3167 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
3168 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
3169 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
3170 unsigned long saved_offset
= pStubMsg
->Offset
;
3171 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
3173 /* get the buffer pointer after complex array data, but before
3175 pStubMsg
->IgnoreEmbeddedPointers
= 1;
3176 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
3177 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
3179 /* save it for use by embedded pointer code later */
3180 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3181 pointer_length_set
= 1;
3183 /* restore fields */
3184 pStubMsg
->ActualCount
= saved_actual_count
;
3185 pStubMsg
->Offset
= saved_offset
;
3186 pStubMsg
->MaxCount
= saved_max_count
;
3187 pStubMsg
->BufferLength
= saved_buffer_length
;
3189 def
= *(const WORD
*)&pFormat
[2];
3192 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3193 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3194 SizeConformance(pStubMsg
);
3196 variance_present
= IsConformanceOrVariancePresent(pFormat
);
3197 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3198 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3200 if (variance_present
)
3201 SizeVariance(pStubMsg
);
3203 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
3205 count
= pStubMsg
->ActualCount
;
3206 for (i
= 0; i
< count
; i
++)
3207 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
3209 if(pointer_length_set
)
3211 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3212 pStubMsg
->PointerLength
= 0;
3216 /***********************************************************************
3217 * NdrComplexArrayMemorySize [RPCRT4.@]
3219 ULONG WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3220 PFORMAT_STRING pFormat
)
3222 ULONG i
, count
, esize
, SavedMemorySize
, MemorySize
;
3223 unsigned char alignment
;
3224 unsigned char *Buffer
;
3226 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3228 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3230 ERR("invalid format type %x\n", pFormat
[0]);
3231 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3235 alignment
= pFormat
[1] + 1;
3239 pFormat
= ReadConformance(pStubMsg
, pFormat
);
3240 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3242 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3244 SavedMemorySize
= pStubMsg
->MemorySize
;
3246 Buffer
= pStubMsg
->Buffer
;
3247 pStubMsg
->MemorySize
= 0;
3248 esize
= ComplexStructMemorySize(pStubMsg
, pFormat
);
3249 pStubMsg
->Buffer
= Buffer
;
3251 MemorySize
= safe_multiply(pStubMsg
->MaxCount
, esize
);
3253 count
= pStubMsg
->ActualCount
;
3254 for (i
= 0; i
< count
; i
++)
3255 ComplexStructMemorySize(pStubMsg
, pFormat
);
3257 pStubMsg
->MemorySize
= SavedMemorySize
;
3259 pStubMsg
->MemorySize
+= MemorySize
;
3263 /***********************************************************************
3264 * NdrComplexArrayFree [RPCRT4.@]
3266 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3267 unsigned char *pMemory
,
3268 PFORMAT_STRING pFormat
)
3270 ULONG i
, count
, def
;
3272 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3274 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3276 ERR("invalid format type %x\n", pFormat
[0]);
3277 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3281 def
= *(const WORD
*)&pFormat
[2];
3284 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3285 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3287 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3288 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3290 count
= pStubMsg
->ActualCount
;
3291 for (i
= 0; i
< count
; i
++)
3292 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
3295 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg
,
3296 USER_MARSHAL_CB_TYPE cbtype
, PFORMAT_STRING pFormat
,
3297 USER_MARSHAL_CB
*umcb
)
3299 umcb
->Flags
= MAKELONG(pStubMsg
->dwDestContext
,
3300 pStubMsg
->RpcMsg
->DataRepresentation
);
3301 umcb
->pStubMsg
= pStubMsg
;
3302 umcb
->pReserve
= NULL
;
3303 umcb
->Signature
= USER_MARSHAL_CB_SIGNATURE
;
3304 umcb
->CBType
= cbtype
;
3305 umcb
->pFormat
= pFormat
;
3306 umcb
->pTypeFormat
= NULL
/* FIXME */;
3309 #define USER_MARSHAL_PTR_PREFIX \
3310 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3311 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3313 /***********************************************************************
3314 * NdrUserMarshalMarshall [RPCRT4.@]
3316 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3317 unsigned char *pMemory
,
3318 PFORMAT_STRING pFormat
)
3320 unsigned flags
= pFormat
[1];
3321 unsigned index
= *(const WORD
*)&pFormat
[2];
3322 unsigned char *saved_buffer
= NULL
;
3323 USER_MARSHAL_CB umcb
;
3325 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3326 TRACE("index=%d\n", index
);
3328 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_MARSHALL
, pFormat
, &umcb
);
3330 if (flags
& USER_MARSHAL_POINTER
)
3332 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
3333 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, USER_MARSHAL_PTR_PREFIX
);
3334 pStubMsg
->Buffer
+= 4;
3335 if (pStubMsg
->PointerBufferMark
)
3337 saved_buffer
= pStubMsg
->Buffer
;
3338 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3339 pStubMsg
->PointerBufferMark
= NULL
;
3341 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 8);
3344 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3347 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
3348 &umcb
.Flags
, pStubMsg
->Buffer
, pMemory
);
3352 STD_OVERFLOW_CHECK(pStubMsg
);
3353 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3354 pStubMsg
->Buffer
= saved_buffer
;
3357 STD_OVERFLOW_CHECK(pStubMsg
);
3362 /***********************************************************************
3363 * NdrUserMarshalUnmarshall [RPCRT4.@]
3365 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3366 unsigned char **ppMemory
,
3367 PFORMAT_STRING pFormat
,
3368 unsigned char fMustAlloc
)
3370 unsigned flags
= pFormat
[1];
3371 unsigned index
= *(const WORD
*)&pFormat
[2];
3372 DWORD memsize
= *(const WORD
*)&pFormat
[4];
3373 unsigned char *saved_buffer
= NULL
;
3374 USER_MARSHAL_CB umcb
;
3376 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3377 TRACE("index=%d\n", index
);
3379 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_UNMARSHALL
, pFormat
, &umcb
);
3381 if (flags
& USER_MARSHAL_POINTER
)
3383 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3384 /* skip pointer prefix */
3385 pStubMsg
->Buffer
+= 4;
3386 if (pStubMsg
->PointerBufferMark
)
3388 saved_buffer
= pStubMsg
->Buffer
;
3389 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3390 pStubMsg
->PointerBufferMark
= NULL
;
3392 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3395 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3397 if (fMustAlloc
|| !*ppMemory
)
3398 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
3401 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
3402 &umcb
.Flags
, pStubMsg
->Buffer
, *ppMemory
);
3406 STD_OVERFLOW_CHECK(pStubMsg
);
3407 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3408 pStubMsg
->Buffer
= saved_buffer
;
3414 /***********************************************************************
3415 * NdrUserMarshalBufferSize [RPCRT4.@]
3417 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3418 unsigned char *pMemory
,
3419 PFORMAT_STRING pFormat
)
3421 unsigned flags
= pFormat
[1];
3422 unsigned index
= *(const WORD
*)&pFormat
[2];
3423 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
3424 USER_MARSHAL_CB umcb
;
3425 unsigned long saved_buffer_length
= 0;
3427 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3428 TRACE("index=%d\n", index
);
3430 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_BUFFER_SIZE
, pFormat
, &umcb
);
3432 if (flags
& USER_MARSHAL_POINTER
)
3434 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
3435 /* skip pointer prefix */
3436 safe_buffer_length_increment(pStubMsg
, 4);
3437 if (pStubMsg
->IgnoreEmbeddedPointers
)
3439 if (pStubMsg
->PointerLength
)
3441 saved_buffer_length
= pStubMsg
->BufferLength
;
3442 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3443 pStubMsg
->PointerLength
= 0;
3445 ALIGN_LENGTH(pStubMsg
->BufferLength
, 8);
3448 ALIGN_LENGTH(pStubMsg
->BufferLength
, (flags
& 0xf) + 1);
3451 TRACE("size=%d\n", bufsize
);
3452 safe_buffer_length_increment(pStubMsg
, bufsize
);
3455 pStubMsg
->BufferLength
=
3456 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
3457 &umcb
.Flags
, pStubMsg
->BufferLength
, pMemory
);
3459 if (saved_buffer_length
)
3461 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3462 pStubMsg
->BufferLength
= saved_buffer_length
;
3467 /***********************************************************************
3468 * NdrUserMarshalMemorySize [RPCRT4.@]
3470 ULONG WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3471 PFORMAT_STRING pFormat
)
3473 unsigned flags
= pFormat
[1];
3474 unsigned index
= *(const WORD
*)&pFormat
[2];
3475 DWORD memsize
= *(const WORD
*)&pFormat
[4];
3476 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
3478 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3479 TRACE("index=%d\n", index
);
3481 pStubMsg
->MemorySize
+= memsize
;
3483 if (flags
& USER_MARSHAL_POINTER
)
3485 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3486 /* skip pointer prefix */
3487 pStubMsg
->Buffer
+= 4;
3488 if (pStubMsg
->IgnoreEmbeddedPointers
)
3489 return pStubMsg
->MemorySize
;
3490 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3493 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3496 FIXME("not implemented for varying buffer size\n");
3498 pStubMsg
->Buffer
+= bufsize
;
3500 return pStubMsg
->MemorySize
;
3503 /***********************************************************************
3504 * NdrUserMarshalFree [RPCRT4.@]
3506 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
3507 unsigned char *pMemory
,
3508 PFORMAT_STRING pFormat
)
3510 /* unsigned flags = pFormat[1]; */
3511 unsigned index
= *(const WORD
*)&pFormat
[2];
3512 USER_MARSHAL_CB umcb
;
3514 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3515 TRACE("index=%d\n", index
);
3517 UserMarshalCB(pStubMsg
, USER_MARSHAL_CB_FREE
, pFormat
, &umcb
);
3519 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
3520 &umcb
.Flags
, pMemory
);
3523 /***********************************************************************
3524 * NdrClearOutParameters [RPCRT4.@]
3526 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
3527 PFORMAT_STRING pFormat
,
3530 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
3533 /***********************************************************************
3534 * NdrConvert [RPCRT4.@]
3536 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
3538 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
3539 /* FIXME: since this stub doesn't do any converting, the proper behavior
3540 is to raise an exception */
3543 /***********************************************************************
3544 * NdrConvert2 [RPCRT4.@]
3546 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, LONG NumberParams
)
3548 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3549 pStubMsg
, pFormat
, NumberParams
);
3550 /* FIXME: since this stub doesn't do any converting, the proper behavior
3551 is to raise an exception */
3554 #include "pshpack1.h"
3555 typedef struct _NDR_CSTRUCT_FORMAT
3558 unsigned char alignment
;
3559 unsigned short memory_size
;
3560 short offset_to_array_description
;
3561 } NDR_CSTRUCT_FORMAT
, NDR_CVSTRUCT_FORMAT
;
3562 #include "poppack.h"
3564 /***********************************************************************
3565 * NdrConformantStructMarshall [RPCRT4.@]
3567 unsigned char * WINAPI
NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3568 unsigned char *pMemory
,
3569 PFORMAT_STRING pFormat
)
3571 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3572 PFORMAT_STRING pCArrayFormat
;
3573 ULONG esize
, bufsize
;
3575 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3577 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3578 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3580 ERR("invalid format type %x\n", pCStructFormat
->type
);
3581 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3585 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3586 pCStructFormat
->offset_to_array_description
;
3587 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3589 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3590 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3593 esize
= *(const WORD
*)(pCArrayFormat
+2);
3595 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
3596 pCArrayFormat
+ 4, 0);
3598 WriteConformance(pStubMsg
);
3600 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
3602 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3604 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3605 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
3607 ERR("integer overflow of memory_size %u with bufsize %u\n",
3608 pCStructFormat
->memory_size
, bufsize
);
3609 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3611 /* copy constant sized part of struct */
3612 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3613 safe_copy_to_buffer(pStubMsg
, pMemory
, pCStructFormat
->memory_size
+ bufsize
);
3615 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3616 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3621 /***********************************************************************
3622 * NdrConformantStructUnmarshall [RPCRT4.@]
3624 unsigned char * WINAPI
NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3625 unsigned char **ppMemory
,
3626 PFORMAT_STRING pFormat
,
3627 unsigned char fMustAlloc
)
3629 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3630 PFORMAT_STRING pCArrayFormat
;
3631 ULONG esize
, bufsize
;
3632 unsigned char *saved_buffer
;
3634 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3636 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3637 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3639 ERR("invalid format type %x\n", pCStructFormat
->type
);
3640 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3643 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3644 pCStructFormat
->offset_to_array_description
;
3645 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3647 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3648 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3651 esize
= *(const WORD
*)(pCArrayFormat
+2);
3653 pCArrayFormat
= ReadConformance(pStubMsg
, pCArrayFormat
+ 4);
3655 ALIGN_POINTER(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
3657 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3659 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3660 if (pCStructFormat
->memory_size
+ bufsize
< pCStructFormat
->memory_size
) /* integer overflow */
3662 ERR("integer overflow of memory_size %u with bufsize %u\n",
3663 pCStructFormat
->memory_size
, bufsize
);
3664 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
3669 SIZE_T size
= pCStructFormat
->memory_size
+ bufsize
;
3670 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3674 if (!pStubMsg
->IsClient
&& !*ppMemory
)
3675 /* for servers, we just point straight into the RPC buffer */
3676 *ppMemory
= pStubMsg
->Buffer
;
3679 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3680 safe_buffer_increment(pStubMsg
, pCStructFormat
->memory_size
+ bufsize
);
3681 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3682 EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
3684 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
3685 if (*ppMemory
!= saved_buffer
)
3686 memcpy(*ppMemory
, saved_buffer
, pCStructFormat
->memory_size
+ bufsize
);
3691 /***********************************************************************
3692 * NdrConformantStructBufferSize [RPCRT4.@]
3694 void WINAPI
NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3695 unsigned char *pMemory
,
3696 PFORMAT_STRING pFormat
)
3698 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3699 PFORMAT_STRING pCArrayFormat
;
3702 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3704 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3705 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3707 ERR("invalid format type %x\n", pCStructFormat
->type
);
3708 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3711 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3712 pCStructFormat
->offset_to_array_description
;
3713 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3715 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3716 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3719 esize
= *(const WORD
*)(pCArrayFormat
+2);
3721 pCArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
, pCArrayFormat
+4, 0);
3722 SizeConformance(pStubMsg
);
3724 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCStructFormat
->alignment
+ 1);
3726 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3728 safe_buffer_length_increment(pStubMsg
, pCStructFormat
->memory_size
);
3729 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
3731 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3732 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3735 /***********************************************************************
3736 * NdrConformantStructMemorySize [RPCRT4.@]
3738 ULONG WINAPI
NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3739 PFORMAT_STRING pFormat
)
3745 /***********************************************************************
3746 * NdrConformantStructFree [RPCRT4.@]
3748 void WINAPI
NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3749 unsigned char *pMemory
,
3750 PFORMAT_STRING pFormat
)
3752 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3753 PFORMAT_STRING pCArrayFormat
;
3756 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3758 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3759 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3761 ERR("invalid format type %x\n", pCStructFormat
->type
);
3762 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3766 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3767 pCStructFormat
->offset_to_array_description
;
3768 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3770 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3771 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3774 esize
= *(const WORD
*)(pCArrayFormat
+2);
3776 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
3777 pCArrayFormat
+ 4, 0);
3779 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3781 /* copy constant sized part of struct */
3782 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3784 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3785 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
3788 /***********************************************************************
3789 * NdrConformantVaryingStructMarshall [RPCRT4.@]
3791 unsigned char * WINAPI
NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3792 unsigned char *pMemory
,
3793 PFORMAT_STRING pFormat
)
3795 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3796 PFORMAT_STRING pCVArrayFormat
;
3797 ULONG esize
, bufsize
;
3799 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3801 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3802 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3804 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3805 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3809 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3810 pCVStructFormat
->offset_to_array_description
;
3811 switch (*pCVArrayFormat
)
3813 case RPC_FC_CVARRAY
:
3814 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3816 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3817 pCVArrayFormat
+ 4, 0);
3818 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3821 case RPC_FC_C_CSTRING
:
3822 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
3823 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
3824 esize
= sizeof(char);
3825 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3826 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3827 pCVArrayFormat
+ 2, 0);
3829 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3831 case RPC_FC_C_WSTRING
:
3832 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
3833 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
3834 esize
= sizeof(WCHAR
);
3835 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3836 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3837 pCVArrayFormat
+ 2, 0);
3839 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3842 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3843 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3847 WriteConformance(pStubMsg
);
3849 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
3851 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3853 /* write constant sized part */
3854 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3855 safe_copy_to_buffer(pStubMsg
, pMemory
, pCVStructFormat
->memory_size
);
3857 WriteVariance(pStubMsg
);
3859 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3861 /* write array part */
3862 safe_copy_to_buffer(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
, bufsize
);
3864 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3869 /***********************************************************************
3870 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3872 unsigned char * WINAPI
NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3873 unsigned char **ppMemory
,
3874 PFORMAT_STRING pFormat
,
3875 unsigned char fMustAlloc
)
3877 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3878 PFORMAT_STRING pCVArrayFormat
;
3879 ULONG esize
, bufsize
;
3880 unsigned char cvarray_type
;
3882 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3884 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3885 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3887 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3888 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3892 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3893 pCVStructFormat
->offset_to_array_description
;
3894 cvarray_type
= *pCVArrayFormat
;
3895 switch (cvarray_type
)
3897 case RPC_FC_CVARRAY
:
3898 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3899 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 4);
3901 case RPC_FC_C_CSTRING
:
3902 esize
= sizeof(char);
3903 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3904 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3906 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3908 case RPC_FC_C_WSTRING
:
3909 esize
= sizeof(WCHAR
);
3910 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3911 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3913 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3916 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3917 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3921 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
3923 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3925 /* work out how much memory to allocate if we need to do so */
3926 if (!*ppMemory
|| fMustAlloc
)
3928 SIZE_T size
= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->MaxCount
);
3929 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3932 /* copy the constant data */
3933 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3934 safe_copy_from_buffer(pStubMsg
, *ppMemory
, pCVStructFormat
->memory_size
);
3936 pCVArrayFormat
= ReadVariance(pStubMsg
, pCVArrayFormat
, pStubMsg
->MaxCount
);
3938 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3940 if ((cvarray_type
== RPC_FC_C_CSTRING
) ||
3941 (cvarray_type
== RPC_FC_C_WSTRING
))
3944 /* strings must always have null terminating bytes */
3945 if (bufsize
< esize
)
3947 ERR("invalid string length of %d\n", pStubMsg
->ActualCount
);
3948 RpcRaiseException(RPC_S_INVALID_BOUND
);
3951 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
3952 if (pStubMsg
->Buffer
[i
] != 0)
3954 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
3955 i
, pStubMsg
->Buffer
[i
]);
3956 RpcRaiseException(RPC_S_INVALID_BOUND
);
3961 /* copy the array data */
3962 safe_copy_from_buffer(pStubMsg
, *ppMemory
+ pCVStructFormat
->memory_size
, bufsize
);
3964 if (cvarray_type
== RPC_FC_C_CSTRING
)
3965 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory
+ pCVStructFormat
->memory_size
)));
3966 else if (cvarray_type
== RPC_FC_C_WSTRING
)
3967 TRACE("string=%s\n", debugstr_w((WCHAR
*)(*ppMemory
+ pCVStructFormat
->memory_size
)));
3969 EmbeddedPointerUnmarshall(pStubMsg
, *ppMemory
, *ppMemory
, pFormat
, TRUE
/* FIXME */);
3974 /***********************************************************************
3975 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3977 void WINAPI
NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3978 unsigned char *pMemory
,
3979 PFORMAT_STRING pFormat
)
3981 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3982 PFORMAT_STRING pCVArrayFormat
;
3985 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3987 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3988 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3990 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3991 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3995 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3996 pCVStructFormat
->offset_to_array_description
;
3997 switch (*pCVArrayFormat
)
3999 case RPC_FC_CVARRAY
:
4000 esize
= *(const WORD
*)(pCVArrayFormat
+2);
4002 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4003 pCVArrayFormat
+ 4, 0);
4004 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4007 case RPC_FC_C_CSTRING
:
4008 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
4009 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
4010 esize
= sizeof(char);
4011 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4012 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4013 pCVArrayFormat
+ 2, 0);
4015 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4017 case RPC_FC_C_WSTRING
:
4018 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
4019 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
4020 esize
= sizeof(WCHAR
);
4021 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4022 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4023 pCVArrayFormat
+ 2, 0);
4025 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4028 ERR("invalid array format type %x\n", *pCVArrayFormat
);
4029 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4033 SizeConformance(pStubMsg
);
4035 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCVStructFormat
->alignment
+ 1);
4037 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4039 safe_buffer_length_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4040 SizeVariance(pStubMsg
);
4041 safe_buffer_length_increment(pStubMsg
, safe_multiply(pStubMsg
->MaxCount
, esize
));
4043 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4046 /***********************************************************************
4047 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4049 ULONG WINAPI
NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4050 PFORMAT_STRING pFormat
)
4052 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4053 PFORMAT_STRING pCVArrayFormat
;
4055 unsigned char cvarray_type
;
4057 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4059 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4060 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4062 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4063 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4067 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4068 pCVStructFormat
->offset_to_array_description
;
4069 cvarray_type
= *pCVArrayFormat
;
4070 switch (cvarray_type
)
4072 case RPC_FC_CVARRAY
:
4073 esize
= *(const WORD
*)(pCVArrayFormat
+2);
4074 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 4);
4076 case RPC_FC_C_CSTRING
:
4077 esize
= sizeof(char);
4078 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4079 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
4081 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
4083 case RPC_FC_C_WSTRING
:
4084 esize
= sizeof(WCHAR
);
4085 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4086 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
4088 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
4091 ERR("invalid array format type %x\n", *pCVArrayFormat
);
4092 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4096 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
4098 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4100 safe_buffer_increment(pStubMsg
, pCVStructFormat
->memory_size
);
4101 pCVArrayFormat
= ReadVariance(pStubMsg
, pCVArrayFormat
, pStubMsg
->MaxCount
);
4102 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
4104 pStubMsg
->MemorySize
+= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->MaxCount
);
4106 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4108 return pCVStructFormat
->memory_size
+ pStubMsg
->MaxCount
* esize
;
4111 /***********************************************************************
4112 * NdrConformantVaryingStructFree [RPCRT4.@]
4114 void WINAPI
NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
4115 unsigned char *pMemory
,
4116 PFORMAT_STRING pFormat
)
4118 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
4119 PFORMAT_STRING pCVArrayFormat
;
4122 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4124 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
4125 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
4127 ERR("invalid format type %x\n", pCVStructFormat
->type
);
4128 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4132 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
4133 pCVStructFormat
->offset_to_array_description
;
4134 switch (*pCVArrayFormat
)
4136 case RPC_FC_CVARRAY
:
4137 esize
= *(const WORD
*)(pCVArrayFormat
+2);
4139 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4140 pCVArrayFormat
+ 4, 0);
4141 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4144 case RPC_FC_C_CSTRING
:
4145 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
4146 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
4147 esize
= sizeof(char);
4148 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4149 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4150 pCVArrayFormat
+ 2, 0);
4152 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4154 case RPC_FC_C_WSTRING
:
4155 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
4156 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
4157 esize
= sizeof(WCHAR
);
4158 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
4159 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
4160 pCVArrayFormat
+ 2, 0);
4162 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
4165 ERR("invalid array format type %x\n", *pCVArrayFormat
);
4166 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4170 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
4172 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4175 #include "pshpack1.h"
4179 unsigned char alignment
;
4180 unsigned short total_size
;
4181 } NDR_SMFARRAY_FORMAT
;
4186 unsigned char alignment
;
4187 unsigned long total_size
;
4188 } NDR_LGFARRAY_FORMAT
;
4189 #include "poppack.h"
4191 /***********************************************************************
4192 * NdrFixedArrayMarshall [RPCRT4.@]
4194 unsigned char * WINAPI
NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4195 unsigned char *pMemory
,
4196 PFORMAT_STRING pFormat
)
4198 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4199 unsigned long total_size
;
4201 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4203 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4204 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4206 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4207 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4211 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4213 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4215 total_size
= pSmFArrayFormat
->total_size
;
4216 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4220 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4221 total_size
= pLgFArrayFormat
->total_size
;
4222 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4225 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4226 safe_copy_to_buffer(pStubMsg
, pMemory
, total_size
);
4228 pFormat
= EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4233 /***********************************************************************
4234 * NdrFixedArrayUnmarshall [RPCRT4.@]
4236 unsigned char * WINAPI
NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4237 unsigned char **ppMemory
,
4238 PFORMAT_STRING pFormat
,
4239 unsigned char fMustAlloc
)
4241 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4242 unsigned long total_size
;
4243 unsigned char *saved_buffer
;
4245 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4247 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4248 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4250 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4251 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4255 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4257 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4259 total_size
= pSmFArrayFormat
->total_size
;
4260 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4264 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4265 total_size
= pLgFArrayFormat
->total_size
;
4266 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4270 *ppMemory
= NdrAllocate(pStubMsg
, total_size
);
4273 if (!pStubMsg
->IsClient
&& !*ppMemory
)
4274 /* for servers, we just point straight into the RPC buffer */
4275 *ppMemory
= pStubMsg
->Buffer
;
4278 saved_buffer
= pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4279 safe_buffer_increment(pStubMsg
, total_size
);
4280 pFormat
= EmbeddedPointerUnmarshall(pStubMsg
, saved_buffer
, *ppMemory
, pFormat
, fMustAlloc
);
4282 TRACE("copying %p to %p\n", saved_buffer
, *ppMemory
);
4283 if (*ppMemory
!= saved_buffer
)
4284 memcpy(*ppMemory
, saved_buffer
, total_size
);
4289 /***********************************************************************
4290 * NdrFixedArrayBufferSize [RPCRT4.@]
4292 void WINAPI
NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4293 unsigned char *pMemory
,
4294 PFORMAT_STRING pFormat
)
4296 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4297 unsigned long total_size
;
4299 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4301 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4302 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4304 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4305 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4309 ALIGN_LENGTH(pStubMsg
->BufferLength
, pSmFArrayFormat
->alignment
+ 1);
4311 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4313 total_size
= pSmFArrayFormat
->total_size
;
4314 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4318 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4319 total_size
= pLgFArrayFormat
->total_size
;
4320 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4322 safe_buffer_length_increment(pStubMsg
, total_size
);
4324 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4327 /***********************************************************************
4328 * NdrFixedArrayMemorySize [RPCRT4.@]
4330 ULONG WINAPI
NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4331 PFORMAT_STRING pFormat
)
4333 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4336 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4338 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4339 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4341 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4342 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4346 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4348 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4350 total_size
= pSmFArrayFormat
->total_size
;
4351 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4355 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4356 total_size
= pLgFArrayFormat
->total_size
;
4357 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4359 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4360 safe_buffer_increment(pStubMsg
, total_size
);
4361 pStubMsg
->MemorySize
+= total_size
;
4363 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4368 /***********************************************************************
4369 * NdrFixedArrayFree [RPCRT4.@]
4371 void WINAPI
NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4372 unsigned char *pMemory
,
4373 PFORMAT_STRING pFormat
)
4375 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4377 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4379 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4380 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4382 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4383 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4387 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4388 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4391 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4392 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4395 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4398 /***********************************************************************
4399 * NdrVaryingArrayMarshall [RPCRT4.@]
4401 unsigned char * WINAPI
NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4402 unsigned char *pMemory
,
4403 PFORMAT_STRING pFormat
)
4405 unsigned char alignment
;
4406 DWORD elements
, esize
;
4409 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4411 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4412 (pFormat
[0] != RPC_FC_LGVARRAY
))
4414 ERR("invalid format type %x\n", pFormat
[0]);
4415 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4419 alignment
= pFormat
[1] + 1;
4421 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4424 pFormat
+= sizeof(WORD
);
4425 elements
= *(const WORD
*)pFormat
;
4426 pFormat
+= sizeof(WORD
);
4431 pFormat
+= sizeof(DWORD
);
4432 elements
= *(const DWORD
*)pFormat
;
4433 pFormat
+= sizeof(DWORD
);
4436 esize
= *(const WORD
*)pFormat
;
4437 pFormat
+= sizeof(WORD
);
4439 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4440 if ((pStubMsg
->ActualCount
> elements
) ||
4441 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4443 RpcRaiseException(RPC_S_INVALID_BOUND
);
4447 WriteVariance(pStubMsg
);
4449 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, alignment
);
4451 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4452 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4453 safe_copy_to_buffer(pStubMsg
, pMemory
+ pStubMsg
->Offset
, bufsize
);
4455 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4460 /***********************************************************************
4461 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4463 unsigned char * WINAPI
NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4464 unsigned char **ppMemory
,
4465 PFORMAT_STRING pFormat
,
4466 unsigned char fMustAlloc
)
4468 unsigned char alignment
;
4469 DWORD size
, elements
, esize
;
4472 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4474 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4475 (pFormat
[0] != RPC_FC_LGVARRAY
))
4477 ERR("invalid format type %x\n", pFormat
[0]);
4478 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4482 alignment
= pFormat
[1] + 1;
4484 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4487 size
= *(const WORD
*)pFormat
;
4488 pFormat
+= sizeof(WORD
);
4489 elements
= *(const WORD
*)pFormat
;
4490 pFormat
+= sizeof(WORD
);
4495 size
= *(const DWORD
*)pFormat
;
4496 pFormat
+= sizeof(DWORD
);
4497 elements
= *(const DWORD
*)pFormat
;
4498 pFormat
+= sizeof(DWORD
);
4501 esize
= *(const WORD
*)pFormat
;
4502 pFormat
+= sizeof(WORD
);
4504 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
4506 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4508 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4510 if (!*ppMemory
|| fMustAlloc
)
4511 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4512 safe_copy_from_buffer(pStubMsg
, *ppMemory
+ pStubMsg
->Offset
, bufsize
);
4514 EmbeddedPointerUnmarshall(pStubMsg
, *ppMemory
, *ppMemory
, pFormat
, TRUE
/* FIXME */);
4519 /***********************************************************************
4520 * NdrVaryingArrayBufferSize [RPCRT4.@]
4522 void WINAPI
NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4523 unsigned char *pMemory
,
4524 PFORMAT_STRING pFormat
)
4526 unsigned char alignment
;
4527 DWORD elements
, esize
;
4529 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4531 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4532 (pFormat
[0] != RPC_FC_LGVARRAY
))
4534 ERR("invalid format type %x\n", pFormat
[0]);
4535 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4539 alignment
= pFormat
[1] + 1;
4541 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4544 pFormat
+= sizeof(WORD
);
4545 elements
= *(const WORD
*)pFormat
;
4546 pFormat
+= sizeof(WORD
);
4551 pFormat
+= sizeof(DWORD
);
4552 elements
= *(const DWORD
*)pFormat
;
4553 pFormat
+= sizeof(DWORD
);
4556 esize
= *(const WORD
*)pFormat
;
4557 pFormat
+= sizeof(WORD
);
4559 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4560 if ((pStubMsg
->ActualCount
> elements
) ||
4561 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4563 RpcRaiseException(RPC_S_INVALID_BOUND
);
4567 SizeVariance(pStubMsg
);
4569 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
4571 safe_buffer_length_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
4573 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4576 /***********************************************************************
4577 * NdrVaryingArrayMemorySize [RPCRT4.@]
4579 ULONG WINAPI
NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4580 PFORMAT_STRING pFormat
)
4582 unsigned char alignment
;
4583 DWORD size
, elements
, esize
;
4585 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4587 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4588 (pFormat
[0] != RPC_FC_LGVARRAY
))
4590 ERR("invalid format type %x\n", pFormat
[0]);
4591 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4595 alignment
= pFormat
[1] + 1;
4597 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4600 size
= *(const WORD
*)pFormat
;
4601 pFormat
+= sizeof(WORD
);
4602 elements
= *(const WORD
*)pFormat
;
4603 pFormat
+= sizeof(WORD
);
4608 size
= *(const DWORD
*)pFormat
;
4609 pFormat
+= sizeof(DWORD
);
4610 elements
= *(const DWORD
*)pFormat
;
4611 pFormat
+= sizeof(DWORD
);
4614 esize
= *(const WORD
*)pFormat
;
4615 pFormat
+= sizeof(WORD
);
4617 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
4619 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4621 safe_buffer_increment(pStubMsg
, safe_multiply(esize
, pStubMsg
->ActualCount
));
4622 pStubMsg
->MemorySize
+= size
;
4624 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4626 return pStubMsg
->MemorySize
;
4629 /***********************************************************************
4630 * NdrVaryingArrayFree [RPCRT4.@]
4632 void WINAPI
NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4633 unsigned char *pMemory
,
4634 PFORMAT_STRING pFormat
)
4636 unsigned char alignment
;
4639 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4641 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4642 (pFormat
[0] != RPC_FC_LGVARRAY
))
4644 ERR("invalid format type %x\n", pFormat
[0]);
4645 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4649 alignment
= pFormat
[1] + 1;
4651 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4654 pFormat
+= sizeof(WORD
);
4655 elements
= *(const WORD
*)pFormat
;
4656 pFormat
+= sizeof(WORD
);
4661 pFormat
+= sizeof(DWORD
);
4662 elements
= *(const DWORD
*)pFormat
;
4663 pFormat
+= sizeof(DWORD
);
4666 pFormat
+= sizeof(WORD
);
4668 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4669 if ((pStubMsg
->ActualCount
> elements
) ||
4670 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4672 RpcRaiseException(RPC_S_INVALID_BOUND
);
4676 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4679 static ULONG
get_discriminant(unsigned char fc
, const unsigned char *pMemory
)
4687 return *(const UCHAR
*)pMemory
;
4692 return *(const USHORT
*)pMemory
;
4696 return *(const ULONG
*)pMemory
;
4698 FIXME("Unhandled base type: 0x%02x\n", fc
);
4703 static PFORMAT_STRING
get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg
,
4704 unsigned long discriminant
,
4705 PFORMAT_STRING pFormat
)
4707 unsigned short num_arms
, arm
, type
;
4709 num_arms
= *(const SHORT
*)pFormat
& 0x0fff;
4711 for(arm
= 0; arm
< num_arms
; arm
++)
4713 if(discriminant
== *(const ULONG
*)pFormat
)
4721 type
= *(const unsigned short*)pFormat
;
4722 TRACE("type %04x\n", type
);
4723 if(arm
== num_arms
) /* default arm extras */
4727 ERR("no arm for 0x%lx and no default case\n", discriminant
);
4728 RpcRaiseException(RPC_S_INVALID_TAG
);
4733 TRACE("falling back to empty default case for 0x%lx\n", discriminant
);
4740 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
, ULONG discriminant
, PFORMAT_STRING pFormat
)
4742 unsigned short type
;
4746 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4750 type
= *(const unsigned short*)pFormat
;
4751 if((type
& 0xff00) == 0x8000)
4753 unsigned char basetype
= LOBYTE(type
);
4754 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &basetype
);
4758 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4759 NDR_MARSHALL m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
4762 unsigned char *saved_buffer
= NULL
;
4763 int pointer_buffer_mark_set
= 0;
4770 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
4771 saved_buffer
= pStubMsg
->Buffer
;
4772 if (pStubMsg
->PointerBufferMark
)
4774 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4775 pStubMsg
->PointerBufferMark
= NULL
;
4776 pointer_buffer_mark_set
= 1;
4779 safe_buffer_increment(pStubMsg
, 4); /* for pointer ID */
4781 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char **)pMemory
, desc
);
4782 if (pointer_buffer_mark_set
)
4784 STD_OVERFLOW_CHECK(pStubMsg
);
4785 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4786 if (saved_buffer
+ 4 > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
4788 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
4789 saved_buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
4790 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4792 pStubMsg
->Buffer
= saved_buffer
+ 4;
4796 m(pStubMsg
, pMemory
, desc
);
4799 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4804 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4805 unsigned char **ppMemory
,
4807 PFORMAT_STRING pFormat
,
4808 unsigned char fMustAlloc
)
4810 unsigned short type
;
4814 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4818 type
= *(const unsigned short*)pFormat
;
4819 if((type
& 0xff00) == 0x8000)
4821 unsigned char basetype
= LOBYTE(type
);
4822 return NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &basetype
, FALSE
);
4826 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4827 NDR_UNMARSHALL m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
4830 unsigned char *saved_buffer
= NULL
;
4831 int pointer_buffer_mark_set
= 0;
4838 **(void***)ppMemory
= NULL
;
4839 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4840 saved_buffer
= pStubMsg
->Buffer
;
4841 if (pStubMsg
->PointerBufferMark
)
4843 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4844 pStubMsg
->PointerBufferMark
= NULL
;
4845 pointer_buffer_mark_set
= 1;
4848 pStubMsg
->Buffer
+= 4; /* for pointer ID */
4850 if (saved_buffer
+ 4 > pStubMsg
->BufferEnd
)
4852 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
4853 saved_buffer
, pStubMsg
->BufferEnd
);
4854 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4857 PointerUnmarshall(pStubMsg
, saved_buffer
, *(unsigned char ***)ppMemory
, **(unsigned char ***)ppMemory
, desc
, fMustAlloc
);
4858 if (pointer_buffer_mark_set
)
4860 STD_OVERFLOW_CHECK(pStubMsg
);
4861 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4862 pStubMsg
->Buffer
= saved_buffer
+ 4;
4866 m(pStubMsg
, ppMemory
, desc
, fMustAlloc
);
4869 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4874 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg
,
4875 unsigned char *pMemory
,
4877 PFORMAT_STRING pFormat
)
4879 unsigned short type
;
4883 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4887 type
= *(const unsigned short*)pFormat
;
4888 if((type
& 0xff00) == 0x8000)
4890 unsigned char basetype
= LOBYTE(type
);
4891 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &basetype
);
4895 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4896 NDR_BUFFERSIZE m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
4905 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
4906 safe_buffer_length_increment(pStubMsg
, 4); /* for pointer ID */
4907 if (!pStubMsg
->IgnoreEmbeddedPointers
)
4909 int saved_buffer_length
= pStubMsg
->BufferLength
;
4910 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4911 pStubMsg
->PointerLength
= 0;
4912 if(!pStubMsg
->BufferLength
)
4913 ERR("BufferLength == 0??\n");
4914 PointerBufferSize(pStubMsg
, *(unsigned char **)pMemory
, desc
);
4915 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4916 pStubMsg
->BufferLength
= saved_buffer_length
;
4920 m(pStubMsg
, pMemory
, desc
);
4923 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
4927 static ULONG
union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg
,
4929 PFORMAT_STRING pFormat
)
4931 unsigned short type
, size
;
4933 size
= *(const unsigned short*)pFormat
;
4934 pStubMsg
->Memory
+= size
;
4937 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4941 type
= *(const unsigned short*)pFormat
;
4942 if((type
& 0xff00) == 0x8000)
4944 return NdrBaseTypeMemorySize(pStubMsg
, pFormat
);
4948 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4949 NDR_MEMORYSIZE m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
4950 unsigned char *saved_buffer
;
4959 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4960 saved_buffer
= pStubMsg
->Buffer
;
4961 safe_buffer_increment(pStubMsg
, 4);
4962 ALIGN_LENGTH(pStubMsg
->MemorySize
, 4);
4963 pStubMsg
->MemorySize
+= 4;
4964 if (!pStubMsg
->IgnoreEmbeddedPointers
)
4965 PointerMemorySize(pStubMsg
, saved_buffer
, pFormat
);
4968 return m(pStubMsg
, desc
);
4971 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4974 TRACE("size %d\n", size
);
4978 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg
,
4979 unsigned char *pMemory
,
4981 PFORMAT_STRING pFormat
)
4983 unsigned short type
;
4987 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4991 type
= *(const unsigned short*)pFormat
;
4992 if((type
& 0xff00) != 0x8000)
4994 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4995 NDR_FREE m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
5004 PointerFree(pStubMsg
, *(unsigned char **)pMemory
, desc
);
5007 m(pStubMsg
, pMemory
, desc
);
5010 else FIXME("no freer for embedded type %02x\n", *desc
);
5014 /***********************************************************************
5015 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5017 unsigned char * WINAPI
NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5018 unsigned char *pMemory
,
5019 PFORMAT_STRING pFormat
)
5021 unsigned char switch_type
;
5022 unsigned char increment
;
5025 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5028 switch_type
= *pFormat
& 0xf;
5029 increment
= (*pFormat
& 0xf0) >> 4;
5032 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, increment
);
5034 switch_value
= get_discriminant(switch_type
, pMemory
);
5035 TRACE("got switch value 0x%x\n", switch_value
);
5037 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &switch_type
);
5038 pMemory
+= increment
;
5040 return union_arm_marshall(pStubMsg
, pMemory
, switch_value
, pFormat
);
5043 /***********************************************************************
5044 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5046 unsigned char * WINAPI
NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5047 unsigned char **ppMemory
,
5048 PFORMAT_STRING pFormat
,
5049 unsigned char fMustAlloc
)
5051 unsigned char switch_type
;
5052 unsigned char increment
;
5054 unsigned short size
;
5055 unsigned char *pMemoryArm
;
5057 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5060 switch_type
= *pFormat
& 0xf;
5061 increment
= (*pFormat
& 0xf0) >> 4;
5064 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
5065 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
5066 TRACE("got switch value 0x%x\n", switch_value
);
5068 size
= *(const unsigned short*)pFormat
+ increment
;
5069 if(!*ppMemory
|| fMustAlloc
)
5070 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5072 NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &switch_type
, FALSE
);
5073 pMemoryArm
= *ppMemory
+ increment
;
5075 return union_arm_unmarshall(pStubMsg
, &pMemoryArm
, switch_value
, pFormat
, fMustAlloc
);
5078 /***********************************************************************
5079 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5081 void WINAPI
NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5082 unsigned char *pMemory
,
5083 PFORMAT_STRING pFormat
)
5085 unsigned char switch_type
;
5086 unsigned char increment
;
5089 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5092 switch_type
= *pFormat
& 0xf;
5093 increment
= (*pFormat
& 0xf0) >> 4;
5096 ALIGN_LENGTH(pStubMsg
->BufferLength
, increment
);
5097 switch_value
= get_discriminant(switch_type
, pMemory
);
5098 TRACE("got switch value 0x%x\n", switch_value
);
5100 /* Add discriminant size */
5101 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&switch_value
, &switch_type
);
5102 pMemory
+= increment
;
5104 union_arm_buffer_size(pStubMsg
, pMemory
, switch_value
, pFormat
);
5107 /***********************************************************************
5108 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5110 ULONG WINAPI
NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5111 PFORMAT_STRING pFormat
)
5113 unsigned char switch_type
;
5114 unsigned char increment
;
5117 switch_type
= *pFormat
& 0xf;
5118 increment
= (*pFormat
& 0xf0) >> 4;
5121 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
5122 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
5123 TRACE("got switch value 0x%x\n", switch_value
);
5125 pStubMsg
->Memory
+= increment
;
5127 return increment
+ union_arm_memory_size(pStubMsg
, switch_value
, pFormat
+ *(const SHORT
*)pFormat
);
5130 /***********************************************************************
5131 * NdrEncapsulatedUnionFree [RPCRT4.@]
5133 void WINAPI
NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
5134 unsigned char *pMemory
,
5135 PFORMAT_STRING pFormat
)
5137 unsigned char switch_type
;
5138 unsigned char increment
;
5141 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5144 switch_type
= *pFormat
& 0xf;
5145 increment
= (*pFormat
& 0xf0) >> 4;
5148 switch_value
= get_discriminant(switch_type
, pMemory
);
5149 TRACE("got switch value 0x%x\n", switch_value
);
5151 pMemory
+= increment
;
5153 return union_arm_free(pStubMsg
, pMemory
, switch_value
, pFormat
);
5156 /***********************************************************************
5157 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5159 unsigned char * WINAPI
NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5160 unsigned char *pMemory
,
5161 PFORMAT_STRING pFormat
)
5163 unsigned char switch_type
;
5165 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5168 switch_type
= *pFormat
;
5171 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5172 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5173 /* Marshall discriminant */
5174 NdrBaseTypeMarshall(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
5176 return union_arm_marshall(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5179 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg
,
5180 PFORMAT_STRING
*ppFormat
)
5182 long discriminant
= 0;
5192 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5201 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5202 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5210 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
5211 safe_copy_from_buffer(pStubMsg
, &d
, sizeof(d
));
5216 FIXME("Unhandled base type: 0x%02x\n", **ppFormat
);
5220 if (pStubMsg
->fHasNewCorrDesc
)
5224 return discriminant
;
5227 /**********************************************************************
5228 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5230 unsigned char * WINAPI
NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5231 unsigned char **ppMemory
,
5232 PFORMAT_STRING pFormat
,
5233 unsigned char fMustAlloc
)
5236 unsigned short size
;
5238 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
5241 /* Unmarshall discriminant */
5242 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
5243 TRACE("unmarshalled discriminant %lx\n", discriminant
);
5245 pFormat
+= *(const SHORT
*)pFormat
;
5247 size
= *(const unsigned short*)pFormat
;
5249 if(!*ppMemory
|| fMustAlloc
)
5250 *ppMemory
= NdrAllocate(pStubMsg
, size
);
5252 return union_arm_unmarshall(pStubMsg
, ppMemory
, discriminant
, pFormat
, fMustAlloc
);
5255 /***********************************************************************
5256 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5258 void WINAPI
NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5259 unsigned char *pMemory
,
5260 PFORMAT_STRING pFormat
)
5262 unsigned char switch_type
;
5264 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5267 switch_type
= *pFormat
;
5270 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5271 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5272 /* Add discriminant size */
5273 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
5275 union_arm_buffer_size(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5278 /***********************************************************************
5279 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5281 ULONG WINAPI
NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5282 PFORMAT_STRING pFormat
)
5287 /* Unmarshall discriminant */
5288 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
5289 TRACE("unmarshalled discriminant 0x%x\n", discriminant
);
5291 return union_arm_memory_size(pStubMsg
, discriminant
, pFormat
+ *(const SHORT
*)pFormat
);
5294 /***********************************************************************
5295 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5297 void WINAPI
NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
5298 unsigned char *pMemory
,
5299 PFORMAT_STRING pFormat
)
5301 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5305 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5306 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5308 return union_arm_free(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5311 /***********************************************************************
5312 * NdrByteCountPointerMarshall [RPCRT4.@]
5314 unsigned char * WINAPI
NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5315 unsigned char *pMemory
,
5316 PFORMAT_STRING pFormat
)
5322 /***********************************************************************
5323 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5325 unsigned char * WINAPI
NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5326 unsigned char **ppMemory
,
5327 PFORMAT_STRING pFormat
,
5328 unsigned char fMustAlloc
)
5334 /***********************************************************************
5335 * NdrByteCountPointerBufferSize [RPCRT4.@]
5337 void WINAPI
NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5338 unsigned char *pMemory
,
5339 PFORMAT_STRING pFormat
)
5344 /***********************************************************************
5345 * NdrByteCountPointerMemorySize [RPCRT4.@]
5347 ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5348 PFORMAT_STRING pFormat
)
5354 /***********************************************************************
5355 * NdrByteCountPointerFree [RPCRT4.@]
5357 void WINAPI
NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
5358 unsigned char *pMemory
,
5359 PFORMAT_STRING pFormat
)
5364 /***********************************************************************
5365 * NdrXmitOrRepAsMarshall [RPCRT4.@]
5367 unsigned char * WINAPI
NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5368 unsigned char *pMemory
,
5369 PFORMAT_STRING pFormat
)
5375 /***********************************************************************
5376 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
5378 unsigned char * WINAPI
NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5379 unsigned char **ppMemory
,
5380 PFORMAT_STRING pFormat
,
5381 unsigned char fMustAlloc
)
5387 /***********************************************************************
5388 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
5390 void WINAPI
NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5391 unsigned char *pMemory
,
5392 PFORMAT_STRING pFormat
)
5397 /***********************************************************************
5398 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
5400 ULONG WINAPI
NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5401 PFORMAT_STRING pFormat
)
5407 /***********************************************************************
5408 * NdrXmitOrRepAsFree [RPCRT4.@]
5410 void WINAPI
NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg
,
5411 unsigned char *pMemory
,
5412 PFORMAT_STRING pFormat
)
5417 #include "pshpack1.h"
5421 unsigned char flags_type
; /* flags in upper nibble, type in lower nibble */
5425 #include "poppack.h"
5427 /***********************************************************************
5428 * NdrRangeMarshall [internal]
5430 unsigned char *WINAPI
NdrRangeMarshall(
5431 PMIDL_STUB_MESSAGE pStubMsg
,
5432 unsigned char *pMemory
,
5433 PFORMAT_STRING pFormat
)
5435 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5436 unsigned char base_type
;
5438 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5440 if (pRange
->type
!= RPC_FC_RANGE
)
5442 ERR("invalid format type %x\n", pRange
->type
);
5443 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5447 base_type
= pRange
->flags_type
& 0xf;
5449 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &base_type
);
5452 /***********************************************************************
5453 * NdrRangeUnmarshall
5455 unsigned char *WINAPI
NdrRangeUnmarshall(
5456 PMIDL_STUB_MESSAGE pStubMsg
,
5457 unsigned char **ppMemory
,
5458 PFORMAT_STRING pFormat
,
5459 unsigned char fMustAlloc
)
5461 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5462 unsigned char base_type
;
5464 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
5466 if (pRange
->type
!= RPC_FC_RANGE
)
5468 ERR("invalid format type %x\n", pRange
->type
);
5469 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5472 base_type
= pRange
->flags_type
& 0xf;
5474 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5475 base_type
, pRange
->low_value
, pRange
->high_value
);
5477 #define RANGE_UNMARSHALL(type, format_spec) \
5480 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5481 if (fMustAlloc || !*ppMemory) \
5482 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5483 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
5485 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
5486 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
5487 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
5489 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5490 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5492 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5493 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5494 (type)pRange->high_value); \
5495 RpcRaiseException(RPC_S_INVALID_BOUND); \
5498 TRACE("*ppMemory: %p\n", *ppMemory); \
5499 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5500 pStubMsg->Buffer += sizeof(type); \
5507 RANGE_UNMARSHALL(UCHAR
, "%d");
5508 TRACE("value: 0x%02x\n", **(UCHAR
**)ppMemory
);
5512 RANGE_UNMARSHALL(CHAR
, "%u");
5513 TRACE("value: 0x%02x\n", **(UCHAR
**)ppMemory
);
5515 case RPC_FC_WCHAR
: /* FIXME: valid? */
5517 RANGE_UNMARSHALL(USHORT
, "%u");
5518 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5521 RANGE_UNMARSHALL(SHORT
, "%d");
5522 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5525 RANGE_UNMARSHALL(LONG
, "%d");
5526 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5529 RANGE_UNMARSHALL(ULONG
, "%u");
5530 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5534 FIXME("Unhandled enum type\n");
5536 case RPC_FC_ERROR_STATUS_T
: /* FIXME: valid? */
5541 ERR("invalid range base type: 0x%02x\n", base_type
);
5542 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5548 /***********************************************************************
5549 * NdrRangeBufferSize [internal]
5551 void WINAPI
NdrRangeBufferSize(
5552 PMIDL_STUB_MESSAGE pStubMsg
,
5553 unsigned char *pMemory
,
5554 PFORMAT_STRING pFormat
)
5556 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5557 unsigned char base_type
;
5559 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5561 if (pRange
->type
!= RPC_FC_RANGE
)
5563 ERR("invalid format type %x\n", pRange
->type
);
5564 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5566 base_type
= pRange
->flags_type
& 0xf;
5568 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &base_type
);
5571 /***********************************************************************
5572 * NdrRangeMemorySize [internal]
5574 ULONG WINAPI
NdrRangeMemorySize(
5575 PMIDL_STUB_MESSAGE pStubMsg
,
5576 PFORMAT_STRING pFormat
)
5578 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5579 unsigned char base_type
;
5581 if (pRange
->type
!= RPC_FC_RANGE
)
5583 ERR("invalid format type %x\n", pRange
->type
);
5584 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5587 base_type
= pRange
->flags_type
& 0xf;
5589 return NdrBaseTypeMemorySize(pStubMsg
, &base_type
);
5592 /***********************************************************************
5593 * NdrRangeFree [internal]
5595 void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg
,
5596 unsigned char *pMemory
,
5597 PFORMAT_STRING pFormat
)
5599 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5604 /***********************************************************************
5605 * NdrBaseTypeMarshall [internal]
5607 static unsigned char *WINAPI
NdrBaseTypeMarshall(
5608 PMIDL_STUB_MESSAGE pStubMsg
,
5609 unsigned char *pMemory
,
5610 PFORMAT_STRING pFormat
)
5612 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5620 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(UCHAR
));
5621 TRACE("value: 0x%02x\n", *(UCHAR
*)pMemory
);
5626 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(USHORT
));
5627 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(USHORT
));
5628 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
5632 case RPC_FC_ERROR_STATUS_T
:
5634 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(ULONG
));
5635 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONG
));
5636 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
5639 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(float));
5640 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(float));
5643 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(double));
5644 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(double));
5647 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(ULONGLONG
));
5648 safe_copy_to_buffer(pStubMsg
, pMemory
, sizeof(ULONGLONG
));
5649 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
5652 /* only 16-bits on the wire, so do a sanity check */
5653 if (*(UINT
*)pMemory
> SHRT_MAX
)
5654 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
5655 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, sizeof(USHORT
));
5656 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5657 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5658 *(USHORT
*)pStubMsg
->Buffer
= *(UINT
*)pMemory
;
5659 pStubMsg
->Buffer
+= sizeof(USHORT
);
5660 TRACE("value: 0x%04x\n", *(UINT
*)pMemory
);
5665 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5668 /* FIXME: what is the correct return value? */
5672 /***********************************************************************
5673 * NdrBaseTypeUnmarshall [internal]
5675 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(
5676 PMIDL_STUB_MESSAGE pStubMsg
,
5677 unsigned char **ppMemory
,
5678 PFORMAT_STRING pFormat
,
5679 unsigned char fMustAlloc
)
5681 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
5683 #define BASE_TYPE_UNMARSHALL(type) \
5684 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5685 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
5687 *ppMemory = pStubMsg->Buffer; \
5688 TRACE("*ppMemory: %p\n", *ppMemory); \
5693 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5694 TRACE("*ppMemory: %p\n", *ppMemory); \
5695 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5697 pStubMsg->Buffer += sizeof(type);
5705 BASE_TYPE_UNMARSHALL(UCHAR
);
5706 TRACE("value: 0x%02x\n", **(UCHAR
**)ppMemory
);
5711 BASE_TYPE_UNMARSHALL(USHORT
);
5712 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5716 case RPC_FC_ERROR_STATUS_T
:
5718 BASE_TYPE_UNMARSHALL(ULONG
);
5719 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5722 BASE_TYPE_UNMARSHALL(float);
5723 TRACE("value: %f\n", **(float **)ppMemory
);
5726 BASE_TYPE_UNMARSHALL(double);
5727 TRACE("value: %f\n", **(double **)ppMemory
);
5730 BASE_TYPE_UNMARSHALL(ULONGLONG
);
5731 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG
**)ppMemory
));
5734 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5735 if (fMustAlloc
|| !*ppMemory
)
5736 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT
));
5737 if (pStubMsg
->Buffer
+ sizeof(USHORT
) > pStubMsg
->BufferEnd
)
5738 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5739 TRACE("*ppMemory: %p\n", *ppMemory
);
5740 /* 16-bits on the wire, but int in memory */
5741 **(UINT
**)ppMemory
= *(USHORT
*)pStubMsg
->Buffer
;
5742 pStubMsg
->Buffer
+= sizeof(USHORT
);
5743 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
5748 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5750 #undef BASE_TYPE_UNMARSHALL
5752 /* FIXME: what is the correct return value? */
5757 /***********************************************************************
5758 * NdrBaseTypeBufferSize [internal]
5760 static void WINAPI
NdrBaseTypeBufferSize(
5761 PMIDL_STUB_MESSAGE pStubMsg
,
5762 unsigned char *pMemory
,
5763 PFORMAT_STRING pFormat
)
5765 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5773 safe_buffer_length_increment(pStubMsg
, sizeof(UCHAR
));
5779 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(USHORT
));
5780 safe_buffer_length_increment(pStubMsg
, sizeof(USHORT
));
5785 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONG
));
5786 safe_buffer_length_increment(pStubMsg
, sizeof(ULONG
));
5789 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(float));
5790 safe_buffer_length_increment(pStubMsg
, sizeof(float));
5793 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(double));
5794 safe_buffer_length_increment(pStubMsg
, sizeof(double));
5797 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONGLONG
));
5798 safe_buffer_length_increment(pStubMsg
, sizeof(ULONGLONG
));
5800 case RPC_FC_ERROR_STATUS_T
:
5801 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(error_status_t
));
5802 safe_buffer_length_increment(pStubMsg
, sizeof(error_status_t
));
5807 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5811 /***********************************************************************
5812 * NdrBaseTypeMemorySize [internal]
5814 static ULONG WINAPI
NdrBaseTypeMemorySize(
5815 PMIDL_STUB_MESSAGE pStubMsg
,
5816 PFORMAT_STRING pFormat
)
5818 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg
, *pFormat
);
5826 safe_buffer_increment(pStubMsg
, sizeof(UCHAR
));
5827 pStubMsg
->MemorySize
+= sizeof(UCHAR
);
5828 return sizeof(UCHAR
);
5832 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
5833 pStubMsg
->MemorySize
+= sizeof(USHORT
);
5834 return sizeof(USHORT
);
5838 safe_buffer_increment(pStubMsg
, sizeof(ULONG
));
5839 pStubMsg
->MemorySize
+= sizeof(ULONG
);
5840 return sizeof(ULONG
);
5842 safe_buffer_increment(pStubMsg
, sizeof(float));
5843 pStubMsg
->MemorySize
+= sizeof(float);
5844 return sizeof(float);
5846 safe_buffer_increment(pStubMsg
, sizeof(double));
5847 pStubMsg
->MemorySize
+= sizeof(double);
5848 return sizeof(double);
5850 safe_buffer_increment(pStubMsg
, sizeof(ULONGLONG
));
5851 pStubMsg
->MemorySize
+= sizeof(ULONGLONG
);
5852 return sizeof(ULONGLONG
);
5853 case RPC_FC_ERROR_STATUS_T
:
5854 safe_buffer_increment(pStubMsg
, sizeof(error_status_t
));
5855 pStubMsg
->MemorySize
+= sizeof(error_status_t
);
5856 return sizeof(error_status_t
);
5858 safe_buffer_increment(pStubMsg
, sizeof(USHORT
));
5859 pStubMsg
->MemorySize
+= sizeof(UINT
);
5860 return sizeof(UINT
);
5862 pStubMsg
->MemorySize
+= sizeof(void *);
5863 return sizeof(void *);
5865 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5870 /***********************************************************************
5871 * NdrBaseTypeFree [internal]
5873 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg
,
5874 unsigned char *pMemory
,
5875 PFORMAT_STRING pFormat
)
5877 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5882 /***********************************************************************
5883 * NdrContextHandleBufferSize [internal]
5885 static void WINAPI
NdrContextHandleBufferSize(
5886 PMIDL_STUB_MESSAGE pStubMsg
,
5887 unsigned char *pMemory
,
5888 PFORMAT_STRING pFormat
)
5890 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5892 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
5894 ERR("invalid format type %x\n", *pFormat
);
5895 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5897 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
5898 safe_buffer_length_increment(pStubMsg
, cbNDRContext
);
5901 /***********************************************************************
5902 * NdrContextHandleMarshall [internal]
5904 static unsigned char *WINAPI
NdrContextHandleMarshall(
5905 PMIDL_STUB_MESSAGE pStubMsg
,
5906 unsigned char *pMemory
,
5907 PFORMAT_STRING pFormat
)
5909 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5911 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
5913 ERR("invalid format type %x\n", *pFormat
);
5914 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5917 if (pFormat
[1] & 0x80)
5918 NdrClientContextMarshall(pStubMsg
, *(NDR_CCONTEXT
**)pMemory
, FALSE
);
5920 NdrClientContextMarshall(pStubMsg
, (NDR_CCONTEXT
*)pMemory
, FALSE
);
5925 /***********************************************************************
5926 * NdrContextHandleUnmarshall [internal]
5928 static unsigned char *WINAPI
NdrContextHandleUnmarshall(
5929 PMIDL_STUB_MESSAGE pStubMsg
,
5930 unsigned char **ppMemory
,
5931 PFORMAT_STRING pFormat
,
5932 unsigned char fMustAlloc
)
5934 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
5936 ERR("invalid format type %x\n", *pFormat
);
5937 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5940 **(NDR_CCONTEXT
**)ppMemory
= NULL
;
5941 NdrClientContextUnmarshall(pStubMsg
, *(NDR_CCONTEXT
**)ppMemory
, pStubMsg
->RpcMsg
->Handle
);
5946 /***********************************************************************
5947 * NdrClientContextMarshall [RPCRT4.@]
5949 void WINAPI
NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5950 NDR_CCONTEXT ContextHandle
,
5953 TRACE("(%p, %p, %d)\n", pStubMsg
, ContextHandle
, fCheck
);
5955 ALIGN_POINTER_CLEAR(pStubMsg
->Buffer
, 4);
5957 if (pStubMsg
->Buffer
+ cbNDRContext
> (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
)
5959 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
5960 pStubMsg
->Buffer
, (unsigned char *)pStubMsg
->RpcMsg
->Buffer
+ pStubMsg
->BufferLength
);
5961 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5964 /* FIXME: what does fCheck do? */
5965 NDRCContextMarshall(ContextHandle
,
5968 pStubMsg
->Buffer
+= cbNDRContext
;
5971 /***********************************************************************
5972 * NdrClientContextUnmarshall [RPCRT4.@]
5974 void WINAPI
NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5975 NDR_CCONTEXT
* pContextHandle
,
5976 RPC_BINDING_HANDLE BindHandle
)
5978 TRACE("(%p, %p, %p)\n", pStubMsg
, pContextHandle
, BindHandle
);
5980 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5982 if (pStubMsg
->Buffer
+ cbNDRContext
> pStubMsg
->BufferEnd
)
5983 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5985 NDRCContextUnmarshall(pContextHandle
,
5988 pStubMsg
->RpcMsg
->DataRepresentation
);
5990 pStubMsg
->Buffer
+= cbNDRContext
;
5993 void WINAPI
NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5994 NDR_SCONTEXT ContextHandle
,
5995 NDR_RUNDOWN RundownRoutine
)
5997 FIXME("(%p, %p, %p): stub\n", pStubMsg
, ContextHandle
, RundownRoutine
);
6000 NDR_SCONTEXT WINAPI
NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
)
6002 FIXME("(%p): stub\n", pStubMsg
);
6006 void WINAPI
NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg
,
6007 unsigned char* pMemory
,
6008 PFORMAT_STRING pFormat
)
6010 FIXME("(%p, %p, %p): stub\n", pStubMsg
, pMemory
, pFormat
);
6013 NDR_SCONTEXT WINAPI
NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg
,
6014 PFORMAT_STRING pFormat
)
6016 FIXME("(%p, %p): stub\n", pStubMsg
, pFormat
);
6020 void WINAPI
NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6021 NDR_SCONTEXT ContextHandle
,
6022 NDR_RUNDOWN RundownRoutine
,
6023 PFORMAT_STRING pFormat
)
6025 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg
, ContextHandle
, RundownRoutine
, pFormat
);
6028 NDR_SCONTEXT WINAPI
NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
6029 PFORMAT_STRING pFormat
)
6031 FIXME("(%p, %p): stub\n", pStubMsg
, pFormat
);
6035 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
6037 typedef struct ndr_context_handle
6041 } ndr_context_handle
;
6043 struct context_handle_entry
6047 RPC_BINDING_HANDLE handle
;
6048 ndr_context_handle wire_data
;
6051 static struct list context_handle_list
= LIST_INIT(context_handle_list
);
6053 static CRITICAL_SECTION ndr_context_cs
;
6054 static CRITICAL_SECTION_DEBUG ndr_context_debug
=
6056 0, 0, &ndr_context_cs
,
6057 { &ndr_context_debug
.ProcessLocksList
, &ndr_context_debug
.ProcessLocksList
},
6058 0, 0, { (DWORD_PTR
)(__FILE__
": ndr_context") }
6060 static CRITICAL_SECTION ndr_context_cs
= { &ndr_context_debug
, -1, 0, 0, 0, 0 };
6062 static struct context_handle_entry
*get_context_entry(NDR_CCONTEXT CContext
)
6064 struct context_handle_entry
*che
= (struct context_handle_entry
*) CContext
;
6066 if (che
->magic
!= NDR_CONTEXT_HANDLE_MAGIC
)
6071 static struct context_handle_entry
*context_entry_from_guid(LPCGUID uuid
)
6073 struct context_handle_entry
*che
;
6074 LIST_FOR_EACH_ENTRY(che
, &context_handle_list
, struct context_handle_entry
, entry
)
6075 if (IsEqualGUID(&che
->wire_data
.uuid
, uuid
))
6080 RPC_BINDING_HANDLE WINAPI
NDRCContextBinding(NDR_CCONTEXT CContext
)
6082 struct context_handle_entry
*che
;
6083 RPC_BINDING_HANDLE handle
= NULL
;
6085 TRACE("%p\n", CContext
);
6087 EnterCriticalSection(&ndr_context_cs
);
6088 che
= get_context_entry(CContext
);
6090 handle
= che
->handle
;
6091 LeaveCriticalSection(&ndr_context_cs
);
6094 RpcRaiseException(ERROR_INVALID_HANDLE
);
6098 void WINAPI
NDRCContextMarshall(NDR_CCONTEXT CContext
, void *pBuff
)
6100 struct context_handle_entry
*che
;
6102 TRACE("%p %p\n", CContext
, pBuff
);
6106 EnterCriticalSection(&ndr_context_cs
);
6107 che
= get_context_entry(CContext
);
6108 memcpy(pBuff
, &che
->wire_data
, sizeof (ndr_context_handle
));
6109 LeaveCriticalSection(&ndr_context_cs
);
6113 ndr_context_handle
*wire_data
= (ndr_context_handle
*)pBuff
;
6114 wire_data
->attributes
= 0;
6115 wire_data
->uuid
= GUID_NULL
;
6119 /***********************************************************************
6120 * RpcSmDestroyClientContext [RPCRT4.@]
6122 RPC_STATUS WINAPI
RpcSmDestroyClientContext(void **ContextHandle
)
6124 RPC_STATUS status
= RPC_X_SS_CONTEXT_MISMATCH
;
6125 struct context_handle_entry
*che
= NULL
;
6127 TRACE("(%p)\n", ContextHandle
);
6129 EnterCriticalSection(&ndr_context_cs
);
6130 che
= get_context_entry(*ContextHandle
);
6131 *ContextHandle
= NULL
;
6135 list_remove(&che
->entry
);
6138 LeaveCriticalSection(&ndr_context_cs
);
6142 RpcBindingFree(&che
->handle
);
6143 HeapFree(GetProcessHeap(), 0, che
);
6149 /***********************************************************************
6150 * RpcSsDestroyClientContext [RPCRT4.@]
6152 void WINAPI
RpcSsDestroyClientContext(void **ContextHandle
)
6154 RPC_STATUS status
= RpcSmDestroyClientContext(ContextHandle
);
6155 if (status
!= RPC_S_OK
)
6156 RpcRaiseException(status
);
6159 static UINT
ndr_update_context_handle(NDR_CCONTEXT
*CContext
,
6160 RPC_BINDING_HANDLE hBinding
,
6161 const ndr_context_handle
*chi
)
6163 struct context_handle_entry
*che
= NULL
;
6165 /* a null UUID means we should free the context handle */
6166 if (IsEqualGUID(&chi
->uuid
, &GUID_NULL
))
6170 che
= get_context_entry(*CContext
);
6172 return ERROR_INVALID_HANDLE
;
6173 list_remove(&che
->entry
);
6174 RpcBindingFree(&che
->handle
);
6175 HeapFree(GetProcessHeap(), 0, che
);
6179 /* if there's no existing entry matching the GUID, allocate one */
6180 else if (!(che
= context_entry_from_guid(&chi
->uuid
)))
6182 che
= HeapAlloc(GetProcessHeap(), 0, sizeof *che
);
6184 return ERROR_NOT_ENOUGH_MEMORY
;
6185 che
->magic
= NDR_CONTEXT_HANDLE_MAGIC
;
6186 RpcBindingCopy(hBinding
, &che
->handle
);
6187 list_add_tail(&context_handle_list
, &che
->entry
);
6188 memcpy(&che
->wire_data
, chi
, sizeof *chi
);
6193 return ERROR_SUCCESS
;
6196 /***********************************************************************
6197 * NDRCContextUnmarshall [RPCRT4.@]
6199 void WINAPI
NDRCContextUnmarshall(NDR_CCONTEXT
*CContext
,
6200 RPC_BINDING_HANDLE hBinding
,
6201 void *pBuff
, ULONG DataRepresentation
)
6205 TRACE("*%p=(%p) %p %p %08x\n",
6206 CContext
, *CContext
, hBinding
, pBuff
, DataRepresentation
);
6208 EnterCriticalSection(&ndr_context_cs
);
6209 r
= ndr_update_context_handle(CContext
, hBinding
, pBuff
);
6210 LeaveCriticalSection(&ndr_context_cs
);
6212 RpcRaiseException(r
);
6215 /***********************************************************************
6216 * NDRSContextMarshall [RPCRT4.@]
6218 void WINAPI
NDRSContextMarshall(NDR_SCONTEXT CContext
,
6220 NDR_RUNDOWN userRunDownIn
)
6222 FIXME("(%p %p %p): stub\n", CContext
, pBuff
, userRunDownIn
);
6225 /***********************************************************************
6226 * NDRSContextMarshallEx [RPCRT4.@]
6228 void WINAPI
NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding
,
6229 NDR_SCONTEXT CContext
,
6231 NDR_RUNDOWN userRunDownIn
)
6233 FIXME("(%p %p %p %p): stub\n", hBinding
, CContext
, pBuff
, userRunDownIn
);
6236 /***********************************************************************
6237 * NDRSContextMarshall2 [RPCRT4.@]
6239 void WINAPI
NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding
,
6240 NDR_SCONTEXT CContext
,
6242 NDR_RUNDOWN userRunDownIn
,
6243 void *CtxGuard
, ULONG Flags
)
6245 FIXME("(%p %p %p %p %p %u): stub\n",
6246 hBinding
, CContext
, pBuff
, userRunDownIn
, CtxGuard
, Flags
);
6249 /***********************************************************************
6250 * NDRSContextUnmarshall [RPCRT4.@]
6252 NDR_SCONTEXT WINAPI
NDRSContextUnmarshall(void *pBuff
,
6253 ULONG DataRepresentation
)
6255 FIXME("(%p %08x): stub\n", pBuff
, DataRepresentation
);
6259 /***********************************************************************
6260 * NDRSContextUnmarshallEx [RPCRT4.@]
6262 NDR_SCONTEXT WINAPI
NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding
,
6264 ULONG DataRepresentation
)
6266 FIXME("(%p %p %08x): stub\n", hBinding
, pBuff
, DataRepresentation
);
6270 /***********************************************************************
6271 * NDRSContextUnmarshall2 [RPCRT4.@]
6273 NDR_SCONTEXT WINAPI
NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding
,
6275 ULONG DataRepresentation
,
6276 void *CtxGuard
, ULONG Flags
)
6278 FIXME("(%p %p %08x %p %u): stub\n",
6279 hBinding
, pBuff
, DataRepresentation
, CtxGuard
, Flags
);