4 * Copyright 2002 Greg Turner
5 * Copyright 2003-2006 CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 * - Non-conformant strings
24 * - Byte count pointers
25 * - transmit_as/represent as
26 * - Multi-dimensional arrays
27 * - Conversion functions (NdrConvert)
28 * - Checks for integer addition overflow
29 * - Checks for out-of-memory conditions
45 #include "wine/unicode.h"
46 #include "wine/rpcfc.h"
48 #include "wine/debug.h"
49 #include "wine/list.h"
51 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
54 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
55 (*((UINT32 *)(pchar)) = (uint32))
57 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
58 (*((UINT32 *)(pchar)))
60 /* these would work for i386 too, but less efficient */
61 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
62 (*(pchar) = LOBYTE(LOWORD(uint32)), \
63 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
64 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
65 *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
66 (uint32)) /* allow as r-value */
68 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
70 MAKEWORD(*(pchar), *((pchar)+1)), \
71 MAKEWORD(*((pchar)+2), *((pchar)+3))))
74 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
75 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
76 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
77 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
78 *(pchar) = HIBYTE(HIWORD(uint32)), \
79 (uint32)) /* allow as r-value */
81 #define BIG_ENDIAN_UINT32_READ(pchar) \
83 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
84 MAKEWORD(*((pchar)+1), *(pchar))))
86 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
87 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
88 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
89 # define NDR_LOCAL_UINT32_READ(pchar) \
90 BIG_ENDIAN_UINT32_READ(pchar)
92 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
93 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
94 # define NDR_LOCAL_UINT32_READ(pchar) \
95 LITTLE_ENDIAN_UINT32_READ(pchar)
98 /* _Align must be the desired alignment,
99 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
100 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
101 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
102 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
103 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
105 #define STD_OVERFLOW_CHECK(_Msg) do { \
106 TRACE("buffer=%d/%d\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
107 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
108 ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
111 #define NDR_TABLE_SIZE 128
112 #define NDR_TABLE_MASK 127
114 static unsigned char *WINAPI
NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
115 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
116 static void WINAPI
NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
117 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
118 static ULONG WINAPI
NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
120 static unsigned char *WINAPI
NdrContextHandleMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
121 static void WINAPI
NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
122 static unsigned char *WINAPI
NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
124 const NDR_MARSHALL NdrMarshaller
[NDR_TABLE_SIZE
] = {
126 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
127 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
128 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
129 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
133 NdrPointerMarshall
, NdrPointerMarshall
,
134 NdrPointerMarshall
, NdrPointerMarshall
,
136 NdrSimpleStructMarshall
, NdrSimpleStructMarshall
,
137 NdrConformantStructMarshall
, NdrConformantStructMarshall
,
138 NdrConformantVaryingStructMarshall
,
139 NdrComplexStructMarshall
,
141 NdrConformantArrayMarshall
,
142 NdrConformantVaryingArrayMarshall
,
143 NdrFixedArrayMarshall
, NdrFixedArrayMarshall
,
144 NdrVaryingArrayMarshall
, NdrVaryingArrayMarshall
,
145 NdrComplexArrayMarshall
,
147 NdrConformantStringMarshall
, 0, 0,
148 NdrConformantStringMarshall
,
149 NdrNonConformantStringMarshall
, 0, 0, 0,
151 NdrEncapsulatedUnionMarshall
,
152 NdrNonEncapsulatedUnionMarshall
,
153 NdrByteCountPointerMarshall
,
154 NdrXmitOrRepAsMarshall
, NdrXmitOrRepAsMarshall
,
156 NdrInterfacePointerMarshall
,
158 NdrContextHandleMarshall
,
161 NdrUserMarshalMarshall
,
166 const NDR_UNMARSHALL NdrUnmarshaller
[NDR_TABLE_SIZE
] = {
168 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
169 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
170 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
171 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
173 NdrBaseTypeUnmarshall
,
175 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
176 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
178 NdrSimpleStructUnmarshall
, NdrSimpleStructUnmarshall
,
179 NdrConformantStructUnmarshall
, NdrConformantStructUnmarshall
,
180 NdrConformantVaryingStructUnmarshall
,
181 NdrComplexStructUnmarshall
,
183 NdrConformantArrayUnmarshall
,
184 NdrConformantVaryingArrayUnmarshall
,
185 NdrFixedArrayUnmarshall
, NdrFixedArrayUnmarshall
,
186 NdrVaryingArrayUnmarshall
, NdrVaryingArrayUnmarshall
,
187 NdrComplexArrayUnmarshall
,
189 NdrConformantStringUnmarshall
, 0, 0,
190 NdrConformantStringUnmarshall
,
191 NdrNonConformantStringUnmarshall
, 0, 0, 0,
193 NdrEncapsulatedUnionUnmarshall
,
194 NdrNonEncapsulatedUnionUnmarshall
,
195 NdrByteCountPointerUnmarshall
,
196 NdrXmitOrRepAsUnmarshall
, NdrXmitOrRepAsUnmarshall
,
198 NdrInterfacePointerUnmarshall
,
200 NdrContextHandleUnmarshall
,
203 NdrUserMarshalUnmarshall
,
208 const NDR_BUFFERSIZE NdrBufferSizer
[NDR_TABLE_SIZE
] = {
210 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
211 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
212 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
213 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
215 NdrBaseTypeBufferSize
,
217 NdrPointerBufferSize
, NdrPointerBufferSize
,
218 NdrPointerBufferSize
, NdrPointerBufferSize
,
220 NdrSimpleStructBufferSize
, NdrSimpleStructBufferSize
,
221 NdrConformantStructBufferSize
, NdrConformantStructBufferSize
,
222 NdrConformantVaryingStructBufferSize
,
223 NdrComplexStructBufferSize
,
225 NdrConformantArrayBufferSize
,
226 NdrConformantVaryingArrayBufferSize
,
227 NdrFixedArrayBufferSize
, NdrFixedArrayBufferSize
,
228 NdrVaryingArrayBufferSize
, NdrVaryingArrayBufferSize
,
229 NdrComplexArrayBufferSize
,
231 NdrConformantStringBufferSize
, 0, 0,
232 NdrConformantStringBufferSize
,
233 NdrNonConformantStringBufferSize
, 0, 0, 0,
235 NdrEncapsulatedUnionBufferSize
,
236 NdrNonEncapsulatedUnionBufferSize
,
237 NdrByteCountPointerBufferSize
,
238 NdrXmitOrRepAsBufferSize
, NdrXmitOrRepAsBufferSize
,
240 NdrInterfacePointerBufferSize
,
242 NdrContextHandleBufferSize
,
245 NdrUserMarshalBufferSize
,
250 const NDR_MEMORYSIZE NdrMemorySizer
[NDR_TABLE_SIZE
] = {
252 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
253 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
254 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
255 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
257 NdrBaseTypeMemorySize
,
259 NdrPointerMemorySize
, NdrPointerMemorySize
,
260 NdrPointerMemorySize
, NdrPointerMemorySize
,
262 NdrSimpleStructMemorySize
, NdrSimpleStructMemorySize
,
263 NdrConformantStructMemorySize
, NdrConformantStructMemorySize
,
264 NdrConformantVaryingStructMemorySize
,
265 NdrComplexStructMemorySize
,
267 NdrConformantArrayMemorySize
,
268 NdrConformantVaryingArrayMemorySize
,
269 NdrFixedArrayMemorySize
, NdrFixedArrayMemorySize
,
270 NdrVaryingArrayMemorySize
, NdrVaryingArrayMemorySize
,
271 NdrComplexArrayMemorySize
,
273 NdrConformantStringMemorySize
, 0, 0,
274 NdrConformantStringMemorySize
,
275 NdrNonConformantStringMemorySize
, 0, 0, 0,
277 NdrEncapsulatedUnionMemorySize
,
278 NdrNonEncapsulatedUnionMemorySize
,
279 NdrByteCountPointerMemorySize
,
280 NdrXmitOrRepAsMemorySize
, NdrXmitOrRepAsMemorySize
,
282 NdrInterfacePointerMemorySize
,
287 NdrUserMarshalMemorySize
,
292 const NDR_FREE NdrFreer
[NDR_TABLE_SIZE
] = {
294 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
295 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
296 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
297 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
301 NdrPointerFree
, NdrPointerFree
,
302 NdrPointerFree
, NdrPointerFree
,
304 NdrSimpleStructFree
, NdrSimpleStructFree
,
305 NdrConformantStructFree
, NdrConformantStructFree
,
306 NdrConformantVaryingStructFree
,
307 NdrComplexStructFree
,
309 NdrConformantArrayFree
,
310 NdrConformantVaryingArrayFree
,
311 NdrFixedArrayFree
, NdrFixedArrayFree
,
312 NdrVaryingArrayFree
, NdrVaryingArrayFree
,
318 NdrEncapsulatedUnionFree
,
319 NdrNonEncapsulatedUnionFree
,
321 NdrXmitOrRepAsFree
, NdrXmitOrRepAsFree
,
323 NdrInterfacePointerFree
,
334 void * WINAPI
NdrAllocate(MIDL_STUB_MESSAGE
*pStubMsg
, size_t len
)
336 /* hmm, this is probably supposed to do more? */
337 return pStubMsg
->pfnAllocate(len
);
340 static void WINAPI
NdrFree(MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *Pointer
)
342 pStubMsg
->pfnFree(Pointer
);
345 static inline BOOL
IsConformanceOrVariancePresent(PFORMAT_STRING pFormat
)
347 return (*(const ULONG
*)pFormat
!= -1);
350 static PFORMAT_STRING
ReadConformance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
)
352 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
353 if (pStubMsg
->Buffer
+ 4 > pStubMsg
->BufferEnd
)
354 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
355 pStubMsg
->MaxCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
356 pStubMsg
->Buffer
+= 4;
357 TRACE("unmarshalled conformance is %ld\n", pStubMsg
->MaxCount
);
358 if (pStubMsg
->fHasNewCorrDesc
)
364 static inline PFORMAT_STRING
ReadVariance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
, ULONG MaxValue
)
366 if (pFormat
&& !IsConformanceOrVariancePresent(pFormat
))
368 pStubMsg
->Offset
= 0;
369 pStubMsg
->ActualCount
= pStubMsg
->MaxCount
;
373 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
374 if (pStubMsg
->Buffer
+ 8 > pStubMsg
->BufferEnd
)
375 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
376 pStubMsg
->Offset
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
377 pStubMsg
->Buffer
+= 4;
378 TRACE("offset is %d\n", pStubMsg
->Offset
);
379 pStubMsg
->ActualCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
380 pStubMsg
->Buffer
+= 4;
381 TRACE("variance is %d\n", pStubMsg
->ActualCount
);
383 if ((pStubMsg
->ActualCount
> MaxValue
) ||
384 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> MaxValue
))
386 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
387 pStubMsg
->ActualCount
, pStubMsg
->Offset
, MaxValue
);
388 RpcRaiseException(RPC_S_INVALID_BOUND
);
393 if (pStubMsg
->fHasNewCorrDesc
)
399 /* writes the conformance value to the buffer */
400 static inline void WriteConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
402 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
403 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->MaxCount
);
404 pStubMsg
->Buffer
+= 4;
407 /* writes the variance values to the buffer */
408 static inline void WriteVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
410 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
411 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->Offset
);
412 pStubMsg
->Buffer
+= 4;
413 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->ActualCount
);
414 pStubMsg
->Buffer
+= 4;
417 /* requests buffer space for the conformance value */
418 static inline void SizeConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
420 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
421 pStubMsg
->BufferLength
+= 4;
424 /* requests buffer space for the variance values */
425 static inline void SizeVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
427 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
428 pStubMsg
->BufferLength
+= 8;
431 PFORMAT_STRING
ComputeConformanceOrVariance(
432 MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *pMemory
,
433 PFORMAT_STRING pFormat
, ULONG_PTR def
, ULONG_PTR
*pCount
)
435 BYTE dtype
= pFormat
[0] & 0xf;
436 short ofs
= *(const short *)&pFormat
[2];
440 if (!IsConformanceOrVariancePresent(pFormat
)) {
441 /* null descriptor */
446 switch (pFormat
[0] & 0xf0) {
447 case RPC_FC_NORMAL_CONFORMANCE
:
448 TRACE("normal conformance, ofs=%d\n", ofs
);
451 case RPC_FC_POINTER_CONFORMANCE
:
452 TRACE("pointer conformance, ofs=%d\n", ofs
);
453 ptr
= pStubMsg
->Memory
;
455 case RPC_FC_TOP_LEVEL_CONFORMANCE
:
456 TRACE("toplevel conformance, ofs=%d\n", ofs
);
457 if (pStubMsg
->StackTop
) {
458 ptr
= pStubMsg
->StackTop
;
461 /* -Os mode, *pCount is already set */
465 case RPC_FC_CONSTANT_CONFORMANCE
:
466 data
= ofs
| ((DWORD
)pFormat
[1] << 16);
467 TRACE("constant conformance, val=%d\n", data
);
470 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE
:
471 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs
);
472 if (pStubMsg
->StackTop
) {
473 ptr
= pStubMsg
->StackTop
;
481 FIXME("unknown conformance type %x\n", pFormat
[0] & 0xf0);
484 switch (pFormat
[1]) {
485 case RPC_FC_DEREFERENCE
:
486 ptr
= *(LPVOID
*)((char *)ptr
+ ofs
);
488 case RPC_FC_CALLBACK
:
490 unsigned char *old_stack_top
= pStubMsg
->StackTop
;
491 pStubMsg
->StackTop
= ptr
;
493 /* ofs is index into StubDesc->apfnExprEval */
494 TRACE("callback conformance into apfnExprEval[%d]\n", ofs
);
495 pStubMsg
->StubDesc
->apfnExprEval
[ofs
](pStubMsg
);
497 pStubMsg
->StackTop
= old_stack_top
;
499 /* the callback function always stores the computed value in MaxCount */
500 *pCount
= pStubMsg
->MaxCount
;
504 ptr
= (char *)ptr
+ ofs
;
517 data
= *(USHORT
*)ptr
;
528 FIXME("unknown conformance data type %x\n", dtype
);
531 TRACE("dereferenced data type %x at %p, got %d\n", dtype
, ptr
, data
);
534 switch (pFormat
[1]) {
535 case RPC_FC_DEREFERENCE
: /* already handled */
552 FIXME("unknown conformance op %d\n", pFormat
[1]);
557 TRACE("resulting conformance is %ld\n", *pCount
);
558 if (pStubMsg
->fHasNewCorrDesc
)
564 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
565 * the result overflows 32-bits */
566 static inline ULONG
safe_multiply(ULONG a
, ULONG b
)
568 ULONGLONG ret
= (ULONGLONG
)a
* b
;
569 if (ret
> 0xffffffff)
571 RpcRaiseException(RPC_S_INVALID_BOUND
);
577 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE
*pStubMsg
, ULONG size
)
579 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
580 (pStubMsg
->Buffer
+ size
> pStubMsg
->BufferEnd
))
581 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
582 pStubMsg
->Buffer
+= size
;
585 /* copies data from the buffer, checking that there is enough data in the buffer
587 static inline void safe_buffer_copy(MIDL_STUB_MESSAGE
*pStubMsg
, void *p
, ULONG size
)
589 if ((pStubMsg
->Buffer
+ size
< pStubMsg
->Buffer
) || /* integer overflow of pStubMsg->Buffer */
590 (pStubMsg
->Buffer
+ size
> pStubMsg
->BufferEnd
))
591 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
592 memcpy(p
, pStubMsg
->Buffer
, size
);
593 pStubMsg
->Buffer
+= size
;
597 * NdrConformantString:
599 * What MS calls a ConformantString is, in DCE terminology,
600 * a Varying-Conformant String.
602 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
603 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
604 * into unmarshalled string)
605 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
607 * data: CHARTYPE[maxlen]
609 * ], where CHARTYPE is the appropriate character type (specified externally)
613 /***********************************************************************
614 * NdrConformantStringMarshall [RPCRT4.@]
616 unsigned char *WINAPI
NdrConformantStringMarshall(MIDL_STUB_MESSAGE
*pStubMsg
,
617 unsigned char *pszMessage
, PFORMAT_STRING pFormat
)
621 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg
, pszMessage
, pFormat
);
623 if (*pFormat
== RPC_FC_C_CSTRING
) {
624 TRACE("string=%s\n", debugstr_a((char*)pszMessage
));
625 pStubMsg
->ActualCount
= strlen((char*)pszMessage
)+1;
628 else if (*pFormat
== RPC_FC_C_WSTRING
) {
629 TRACE("string=%s\n", debugstr_w((LPWSTR
)pszMessage
));
630 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pszMessage
)+1;
634 ERR("Unhandled string type: %#x\n", *pFormat
);
635 /* FIXME: raise an exception. */
639 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
640 pFormat
= ComputeConformance(pStubMsg
, pszMessage
, pFormat
+ 2, 0);
642 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
643 pStubMsg
->Offset
= 0;
644 WriteConformance(pStubMsg
);
645 WriteVariance(pStubMsg
);
647 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
648 memcpy(pStubMsg
->Buffer
, pszMessage
, size
); /* the string itself */
649 pStubMsg
->Buffer
+= size
;
651 STD_OVERFLOW_CHECK(pStubMsg
);
654 return NULL
; /* is this always right? */
657 /***********************************************************************
658 * NdrConformantStringBufferSize [RPCRT4.@]
660 void WINAPI
NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
661 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
665 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
667 SizeConformance(pStubMsg
);
668 SizeVariance(pStubMsg
);
670 if (*pFormat
== RPC_FC_C_CSTRING
) {
671 TRACE("string=%s\n", debugstr_a((char*)pMemory
));
672 pStubMsg
->ActualCount
= strlen((char*)pMemory
)+1;
675 else if (*pFormat
== RPC_FC_C_WSTRING
) {
676 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
));
677 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
)+1;
681 ERR("Unhandled string type: %#x\n", *pFormat
);
682 /* FIXME: raise an exception */
686 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
687 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
689 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
691 pStubMsg
->BufferLength
+= safe_multiply(esize
, pStubMsg
->ActualCount
);
694 /************************************************************************
695 * NdrConformantStringMemorySize [RPCRT4.@]
697 ULONG WINAPI
NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
698 PFORMAT_STRING pFormat
)
702 FIXME("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
704 assert(pStubMsg
&& pFormat
);
706 if (*pFormat
== RPC_FC_C_CSTRING
) {
707 rslt
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
); /* maxlen */
709 else if (*pFormat
== RPC_FC_C_WSTRING
) {
710 rslt
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
)*2; /* maxlen */
713 ERR("Unhandled string type: %#x\n", *pFormat
);
714 /* FIXME: raise an exception */
717 if (pFormat
[1] != RPC_FC_PAD
) {
718 FIXME("sized string format=%d\n", pFormat
[1]);
721 TRACE(" --> %u\n", rslt
);
725 /************************************************************************
726 * NdrConformantStringUnmarshall [RPCRT4.@]
728 unsigned char *WINAPI
NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
729 unsigned char** ppMemory
, PFORMAT_STRING pFormat
, unsigned char fMustAlloc
)
731 ULONG bufsize
, memsize
, esize
, i
;
733 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
734 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
736 assert(pFormat
&& ppMemory
&& pStubMsg
);
738 ReadConformance(pStubMsg
, NULL
);
739 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
741 if (*pFormat
== RPC_FC_C_CSTRING
) esize
= 1;
742 else if (*pFormat
== RPC_FC_C_WSTRING
) esize
= 2;
744 ERR("Unhandled string type: %#x\n", *pFormat
);
745 /* FIXME: raise an exception */
749 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
750 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
752 /* strings must always have null terminating bytes */
755 ERR("invalid string length of %d\n", pStubMsg
->ActualCount
);
756 RpcRaiseException(RPC_S_INVALID_BOUND
);
760 /* verify the buffer is safe to access */
761 if ((pStubMsg
->Buffer
+ bufsize
< pStubMsg
->Buffer
) ||
762 (pStubMsg
->Buffer
+ bufsize
> pStubMsg
->BufferEnd
))
764 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize
,
765 pStubMsg
->BufferEnd
, pStubMsg
->Buffer
);
766 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
770 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
771 if (pStubMsg
->Buffer
[i
] != 0)
773 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
774 i
, pStubMsg
->Buffer
[i
]);
775 RpcRaiseException(RPC_S_INVALID_BOUND
);
779 if (fMustAlloc
|| !*ppMemory
)
780 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
782 safe_buffer_copy(pStubMsg
, *ppMemory
, bufsize
);
784 if (*pFormat
== RPC_FC_C_CSTRING
) {
785 TRACE("string=%s\n", debugstr_a((char*)*ppMemory
));
787 else if (*pFormat
== RPC_FC_C_WSTRING
) {
788 TRACE("string=%s\n", debugstr_w((LPWSTR
)*ppMemory
));
791 return NULL
; /* FIXME: is this always right? */
794 /***********************************************************************
795 * NdrNonConformantStringMarshall [RPCRT4.@]
797 unsigned char * WINAPI
NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
798 unsigned char *pMemory
,
799 PFORMAT_STRING pFormat
)
805 /***********************************************************************
806 * NdrNonConformantStringUnmarshall [RPCRT4.@]
808 unsigned char * WINAPI
NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
809 unsigned char **ppMemory
,
810 PFORMAT_STRING pFormat
,
811 unsigned char fMustAlloc
)
817 /***********************************************************************
818 * NdrNonConformantStringBufferSize [RPCRT4.@]
820 void WINAPI
NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
821 unsigned char *pMemory
,
822 PFORMAT_STRING pFormat
)
827 /***********************************************************************
828 * NdrNonConformantStringMemorySize [RPCRT4.@]
830 ULONG WINAPI
NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
831 PFORMAT_STRING pFormat
)
837 static inline void dump_pointer_attr(unsigned char attr
)
839 if (attr
& RPC_FC_P_ALLOCALLNODES
)
840 TRACE(" RPC_FC_P_ALLOCALLNODES");
841 if (attr
& RPC_FC_P_DONTFREE
)
842 TRACE(" RPC_FC_P_DONTFREE");
843 if (attr
& RPC_FC_P_ONSTACK
)
844 TRACE(" RPC_FC_P_ONSTACK");
845 if (attr
& RPC_FC_P_SIMPLEPOINTER
)
846 TRACE(" RPC_FC_P_SIMPLEPOINTER");
847 if (attr
& RPC_FC_P_DEREF
)
848 TRACE(" RPC_FC_P_DEREF");
852 /***********************************************************************
853 * PointerMarshall [internal]
855 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
856 unsigned char *Buffer
,
857 unsigned char *Pointer
,
858 PFORMAT_STRING pFormat
)
860 unsigned type
= pFormat
[0], attr
= pFormat
[1];
864 int pointer_needs_marshaling
;
866 TRACE("(%p,%p,%p,%p)\n", pStubMsg
, Buffer
, Pointer
, pFormat
);
867 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
869 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
870 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
873 case RPC_FC_RP
: /* ref pointer (always non-null) */
874 #if 0 /* this causes problems for InstallShield so is disabled - we need more tests */
876 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
878 pointer_needs_marshaling
= 1;
880 case RPC_FC_UP
: /* unique pointer */
881 case RPC_FC_OP
: /* object pointer - same as unique here */
883 pointer_needs_marshaling
= 1;
885 pointer_needs_marshaling
= 0;
886 pointer_id
= (ULONG
)Pointer
;
887 TRACE("writing 0x%08x to buffer\n", pointer_id
);
888 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
891 pointer_needs_marshaling
= !NdrFullPointerQueryPointer(
892 pStubMsg
->FullPtrXlatTables
, Pointer
, 1, &pointer_id
);
893 TRACE("writing 0x%08x to buffer\n", pointer_id
);
894 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
897 FIXME("unhandled ptr type=%02x\n", type
);
898 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
902 TRACE("calling marshaller for type 0x%x\n", (int)*desc
);
904 if (pointer_needs_marshaling
) {
905 if (attr
& RPC_FC_P_DEREF
) {
906 Pointer
= *(unsigned char**)Pointer
;
907 TRACE("deref => %p\n", Pointer
);
909 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
910 if (m
) m(pStubMsg
, Pointer
, desc
);
911 else FIXME("no marshaller for data type=%02x\n", *desc
);
914 STD_OVERFLOW_CHECK(pStubMsg
);
917 /***********************************************************************
918 * PointerUnmarshall [internal]
920 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
921 unsigned char *Buffer
,
922 unsigned char **pPointer
,
923 PFORMAT_STRING pFormat
,
924 unsigned char fMustAlloc
)
926 unsigned type
= pFormat
[0], attr
= pFormat
[1];
929 DWORD pointer_id
= 0;
930 int pointer_needs_unmarshaling
;
932 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg
, Buffer
, pPointer
, pFormat
, fMustAlloc
);
933 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
935 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
936 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
939 case RPC_FC_RP
: /* ref pointer (always non-null) */
940 pointer_needs_unmarshaling
= 1;
942 case RPC_FC_UP
: /* unique pointer */
943 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
944 TRACE("pointer_id is 0x%08x\n", pointer_id
);
946 pointer_needs_unmarshaling
= 1;
949 pointer_needs_unmarshaling
= 0;
952 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
953 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
954 TRACE("pointer_id is 0x%08x\n", pointer_id
);
955 if (!fMustAlloc
&& *pPointer
)
957 FIXME("free object pointer %p\n", *pPointer
);
961 pointer_needs_unmarshaling
= 1;
963 pointer_needs_unmarshaling
= 0;
966 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
967 TRACE("pointer_id is 0x%08x\n", pointer_id
);
968 pointer_needs_unmarshaling
= !NdrFullPointerQueryRefId(
969 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, (void **)pPointer
);
972 FIXME("unhandled ptr type=%02x\n", type
);
973 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
977 if (pointer_needs_unmarshaling
) {
978 if (attr
& RPC_FC_P_DEREF
) {
979 if (!*pPointer
|| fMustAlloc
) {
980 *pPointer
= NdrAllocate(pStubMsg
, sizeof(void *));
981 *(unsigned char**) *pPointer
= NULL
;
983 pPointer
= *(unsigned char***)pPointer
;
984 TRACE("deref => %p\n", pPointer
);
986 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
987 if (m
) m(pStubMsg
, pPointer
, desc
, fMustAlloc
);
988 else FIXME("no unmarshaller for data type=%02x\n", *desc
);
990 if (type
== RPC_FC_FP
)
991 NdrFullPointerInsertRefId(pStubMsg
->FullPtrXlatTables
, pointer_id
,
995 TRACE("pointer=%p\n", *pPointer
);
998 /***********************************************************************
999 * PointerBufferSize [internal]
1001 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1002 unsigned char *Pointer
,
1003 PFORMAT_STRING pFormat
)
1005 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1006 PFORMAT_STRING desc
;
1008 int pointer_needs_sizing
;
1011 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1012 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1014 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1015 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1018 case RPC_FC_RP
: /* ref pointer (always non-null) */
1022 /* NULL pointer has no further representation */
1027 pointer_needs_sizing
= !NdrFullPointerQueryPointer(
1028 pStubMsg
->FullPtrXlatTables
, Pointer
, 0, &pointer_id
);
1029 if (!pointer_needs_sizing
)
1033 FIXME("unhandled ptr type=%02x\n", type
);
1034 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1038 if (attr
& RPC_FC_P_DEREF
) {
1039 Pointer
= *(unsigned char**)Pointer
;
1040 TRACE("deref => %p\n", Pointer
);
1043 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
1044 if (m
) m(pStubMsg
, Pointer
, desc
);
1045 else FIXME("no buffersizer for data type=%02x\n", *desc
);
1048 /***********************************************************************
1049 * PointerMemorySize [internal]
1051 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1052 unsigned char *Buffer
,
1053 PFORMAT_STRING pFormat
)
1055 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1056 PFORMAT_STRING desc
;
1059 FIXME("(%p,%p,%p): stub\n", pStubMsg
, Buffer
, pFormat
);
1060 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1062 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1063 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1066 case RPC_FC_RP
: /* ref pointer (always non-null) */
1069 FIXME("unhandled ptr type=%02x\n", type
);
1070 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1073 if (attr
& RPC_FC_P_DEREF
) {
1077 m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
1078 if (m
) m(pStubMsg
, desc
);
1079 else FIXME("no memorysizer for data type=%02x\n", *desc
);
1084 /***********************************************************************
1085 * PointerFree [internal]
1087 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1088 unsigned char *Pointer
,
1089 PFORMAT_STRING pFormat
)
1091 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1092 PFORMAT_STRING desc
;
1095 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1096 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1097 if (attr
& RPC_FC_P_DONTFREE
) return;
1099 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1100 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1102 if (!Pointer
) return;
1104 if (type
== RPC_FC_FP
) {
1105 int pointer_needs_freeing
= NdrFullPointerFree(
1106 pStubMsg
->FullPtrXlatTables
, Pointer
);
1107 if (!pointer_needs_freeing
)
1111 if (attr
& RPC_FC_P_DEREF
) {
1112 Pointer
= *(unsigned char**)Pointer
;
1113 TRACE("deref => %p\n", Pointer
);
1116 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
1117 if (m
) m(pStubMsg
, Pointer
, desc
);
1119 /* hmm... is this sensible?
1120 * perhaps we should check if the memory comes from NdrAllocate,
1121 * and deallocate only if so - checking if the pointer is between
1122 * BufferStart and BufferEnd is probably no good since the buffer
1123 * may be reallocated when the server wants to marshal the reply */
1125 case RPC_FC_BOGUS_STRUCT
:
1126 case RPC_FC_BOGUS_ARRAY
:
1127 case RPC_FC_USER_MARSHAL
:
1129 case RPC_FC_CVARRAY
:
1132 FIXME("unhandled data type=%02x\n", *desc
);
1134 case RPC_FC_C_CSTRING
:
1135 case RPC_FC_C_WSTRING
:
1136 if (pStubMsg
->ReuseBuffer
) goto notfree
;
1142 if (attr
& RPC_FC_P_ONSTACK
) {
1143 TRACE("not freeing stack ptr %p\n", Pointer
);
1146 TRACE("freeing %p\n", Pointer
);
1147 NdrFree(pStubMsg
, Pointer
);
1150 TRACE("not freeing %p\n", Pointer
);
1153 /***********************************************************************
1154 * EmbeddedPointerMarshall
1156 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1157 unsigned char *pMemory
,
1158 PFORMAT_STRING pFormat
)
1160 unsigned char *Mark
= pStubMsg
->BufferMark
;
1161 unsigned rep
, count
, stride
;
1163 unsigned char *saved_buffer
= NULL
;
1165 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1167 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1170 if (pStubMsg
->PointerBufferMark
)
1172 saved_buffer
= pStubMsg
->Buffer
;
1173 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1174 pStubMsg
->PointerBufferMark
= NULL
;
1177 while (pFormat
[0] != RPC_FC_END
) {
1178 switch (pFormat
[0]) {
1180 FIXME("unknown repeat type %d\n", pFormat
[0]);
1181 case RPC_FC_NO_REPEAT
:
1187 case RPC_FC_FIXED_REPEAT
:
1188 rep
= *(const WORD
*)&pFormat
[2];
1189 stride
= *(const WORD
*)&pFormat
[4];
1190 count
= *(const WORD
*)&pFormat
[8];
1193 case RPC_FC_VARIABLE_REPEAT
:
1194 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1195 stride
= *(const WORD
*)&pFormat
[2];
1196 count
= *(const WORD
*)&pFormat
[6];
1200 for (i
= 0; i
< rep
; i
++) {
1201 PFORMAT_STRING info
= pFormat
;
1202 unsigned char *membase
= pMemory
+ (i
* stride
);
1203 unsigned char *bufbase
= Mark
+ (i
* stride
);
1206 for (u
=0; u
<count
; u
++,info
+=8) {
1207 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1208 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1209 unsigned char *saved_memory
= pStubMsg
->Memory
;
1211 pStubMsg
->Memory
= pMemory
;
1212 PointerMarshall(pStubMsg
, bufptr
, *(unsigned char**)memptr
, info
+4);
1213 pStubMsg
->Memory
= saved_memory
;
1216 pFormat
+= 8 * count
;
1221 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1222 pStubMsg
->Buffer
= saved_buffer
;
1225 STD_OVERFLOW_CHECK(pStubMsg
);
1230 /***********************************************************************
1231 * EmbeddedPointerUnmarshall
1233 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1234 unsigned char **ppMemory
,
1235 PFORMAT_STRING pFormat
,
1236 unsigned char fMustAlloc
)
1238 unsigned char *Mark
= pStubMsg
->BufferMark
;
1239 unsigned rep
, count
, stride
;
1241 unsigned char *saved_buffer
= NULL
;
1243 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1245 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1248 if (pStubMsg
->PointerBufferMark
)
1250 saved_buffer
= pStubMsg
->Buffer
;
1251 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1252 pStubMsg
->PointerBufferMark
= NULL
;
1255 while (pFormat
[0] != RPC_FC_END
) {
1256 TRACE("pFormat[0] = 0x%x\n", pFormat
[0]);
1257 switch (pFormat
[0]) {
1259 FIXME("unknown repeat type %d\n", pFormat
[0]);
1260 case RPC_FC_NO_REPEAT
:
1266 case RPC_FC_FIXED_REPEAT
:
1267 rep
= *(const WORD
*)&pFormat
[2];
1268 stride
= *(const WORD
*)&pFormat
[4];
1269 count
= *(const WORD
*)&pFormat
[8];
1272 case RPC_FC_VARIABLE_REPEAT
:
1273 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1274 stride
= *(const WORD
*)&pFormat
[2];
1275 count
= *(const WORD
*)&pFormat
[6];
1279 for (i
= 0; i
< rep
; i
++) {
1280 PFORMAT_STRING info
= pFormat
;
1281 unsigned char *membase
= *ppMemory
+ (i
* stride
);
1282 unsigned char *bufbase
= Mark
+ (i
* stride
);
1285 for (u
=0; u
<count
; u
++,info
+=8) {
1286 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1287 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1288 PointerUnmarshall(pStubMsg
, bufptr
, (unsigned char**)memptr
, info
+4, TRUE
);
1291 pFormat
+= 8 * count
;
1296 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1297 pStubMsg
->Buffer
= saved_buffer
;
1303 /***********************************************************************
1304 * EmbeddedPointerBufferSize
1306 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1307 unsigned char *pMemory
,
1308 PFORMAT_STRING pFormat
)
1310 unsigned rep
, count
, stride
;
1312 ULONG saved_buffer_length
= 0;
1314 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1316 if (pStubMsg
->IgnoreEmbeddedPointers
) return;
1318 if (*pFormat
!= RPC_FC_PP
) return;
1321 if (pStubMsg
->PointerLength
)
1323 saved_buffer_length
= pStubMsg
->BufferLength
;
1324 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
1325 pStubMsg
->PointerLength
= 0;
1328 while (pFormat
[0] != RPC_FC_END
) {
1329 switch (pFormat
[0]) {
1331 FIXME("unknown repeat type %d\n", pFormat
[0]);
1332 case RPC_FC_NO_REPEAT
:
1338 case RPC_FC_FIXED_REPEAT
:
1339 rep
= *(const WORD
*)&pFormat
[2];
1340 stride
= *(const WORD
*)&pFormat
[4];
1341 count
= *(const WORD
*)&pFormat
[8];
1344 case RPC_FC_VARIABLE_REPEAT
:
1345 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1346 stride
= *(const WORD
*)&pFormat
[2];
1347 count
= *(const WORD
*)&pFormat
[6];
1351 for (i
= 0; i
< rep
; i
++) {
1352 PFORMAT_STRING info
= pFormat
;
1353 unsigned char *membase
= pMemory
+ (i
* stride
);
1356 for (u
=0; u
<count
; u
++,info
+=8) {
1357 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1358 unsigned char *saved_memory
= pStubMsg
->Memory
;
1360 pStubMsg
->Memory
= pMemory
;
1361 PointerBufferSize(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1362 pStubMsg
->Memory
= saved_memory
;
1365 pFormat
+= 8 * count
;
1368 if (saved_buffer_length
)
1370 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
1371 pStubMsg
->BufferLength
= saved_buffer_length
;
1375 /***********************************************************************
1376 * EmbeddedPointerMemorySize [internal]
1378 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1379 PFORMAT_STRING pFormat
)
1381 unsigned char *Mark
= pStubMsg
->BufferMark
;
1382 unsigned rep
, count
, stride
;
1385 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1387 if (pStubMsg
->IgnoreEmbeddedPointers
) return 0;
1389 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1391 if (*pFormat
!= RPC_FC_PP
) return 0;
1394 while (pFormat
[0] != RPC_FC_END
) {
1395 switch (pFormat
[0]) {
1397 FIXME("unknown repeat type %d\n", pFormat
[0]);
1398 case RPC_FC_NO_REPEAT
:
1404 case RPC_FC_FIXED_REPEAT
:
1405 rep
= *(const WORD
*)&pFormat
[2];
1406 stride
= *(const WORD
*)&pFormat
[4];
1407 count
= *(const WORD
*)&pFormat
[8];
1410 case RPC_FC_VARIABLE_REPEAT
:
1411 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1412 stride
= *(const WORD
*)&pFormat
[2];
1413 count
= *(const WORD
*)&pFormat
[6];
1417 for (i
= 0; i
< rep
; i
++) {
1418 PFORMAT_STRING info
= pFormat
;
1419 unsigned char *bufbase
= Mark
+ (i
* stride
);
1421 for (u
=0; u
<count
; u
++,info
+=8) {
1422 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1423 PointerMemorySize(pStubMsg
, bufptr
, info
+4);
1426 pFormat
+= 8 * count
;
1432 /***********************************************************************
1433 * EmbeddedPointerFree [internal]
1435 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1436 unsigned char *pMemory
,
1437 PFORMAT_STRING pFormat
)
1439 unsigned rep
, count
, stride
;
1442 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1443 if (*pFormat
!= RPC_FC_PP
) return;
1446 while (pFormat
[0] != RPC_FC_END
) {
1447 switch (pFormat
[0]) {
1449 FIXME("unknown repeat type %d\n", pFormat
[0]);
1450 case RPC_FC_NO_REPEAT
:
1456 case RPC_FC_FIXED_REPEAT
:
1457 rep
= *(const WORD
*)&pFormat
[2];
1458 stride
= *(const WORD
*)&pFormat
[4];
1459 count
= *(const WORD
*)&pFormat
[8];
1462 case RPC_FC_VARIABLE_REPEAT
:
1463 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1464 stride
= *(const WORD
*)&pFormat
[2];
1465 count
= *(const WORD
*)&pFormat
[6];
1469 for (i
= 0; i
< rep
; i
++) {
1470 PFORMAT_STRING info
= pFormat
;
1471 unsigned char *membase
= pMemory
+ (i
* stride
);
1474 for (u
=0; u
<count
; u
++,info
+=8) {
1475 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1476 unsigned char *saved_memory
= pStubMsg
->Memory
;
1478 pStubMsg
->Memory
= pMemory
;
1479 PointerFree(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1480 pStubMsg
->Memory
= saved_memory
;
1483 pFormat
+= 8 * count
;
1487 /***********************************************************************
1488 * NdrPointerMarshall [RPCRT4.@]
1490 unsigned char * WINAPI
NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1491 unsigned char *pMemory
,
1492 PFORMAT_STRING pFormat
)
1494 unsigned char *Buffer
;
1496 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1498 /* incremement the buffer here instead of in PointerMarshall,
1499 * as that is used by embedded pointers which already handle the incrementing
1500 * the buffer, and shouldn't write any additional pointer data to the wire */
1501 if (*pFormat
!= RPC_FC_RP
)
1503 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1504 Buffer
= pStubMsg
->Buffer
;
1505 pStubMsg
->Buffer
+= 4;
1508 Buffer
= pStubMsg
->Buffer
;
1510 PointerMarshall(pStubMsg
, Buffer
, pMemory
, pFormat
);
1512 STD_OVERFLOW_CHECK(pStubMsg
);
1517 /***********************************************************************
1518 * NdrPointerUnmarshall [RPCRT4.@]
1520 unsigned char * WINAPI
NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1521 unsigned char **ppMemory
,
1522 PFORMAT_STRING pFormat
,
1523 unsigned char fMustAlloc
)
1525 unsigned char *Buffer
;
1527 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1529 /* incremement the buffer here instead of in PointerUnmarshall,
1530 * as that is used by embedded pointers which already handle the incrementing
1531 * the buffer, and shouldn't read any additional pointer data from the
1533 if (*pFormat
!= RPC_FC_RP
)
1535 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1536 Buffer
= pStubMsg
->Buffer
;
1537 safe_buffer_increment(pStubMsg
, 4);
1540 Buffer
= pStubMsg
->Buffer
;
1542 PointerUnmarshall(pStubMsg
, Buffer
, ppMemory
, pFormat
, fMustAlloc
);
1547 /***********************************************************************
1548 * NdrPointerBufferSize [RPCRT4.@]
1550 void WINAPI
NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1551 unsigned char *pMemory
,
1552 PFORMAT_STRING pFormat
)
1554 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1556 /* incremement the buffer length here instead of in PointerBufferSize,
1557 * as that is used by embedded pointers which already handle the buffer
1558 * length, and shouldn't write anything more to the wire */
1559 if (*pFormat
!= RPC_FC_RP
)
1561 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
1562 pStubMsg
->BufferLength
+= 4;
1565 PointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1568 /***********************************************************************
1569 * NdrPointerMemorySize [RPCRT4.@]
1571 ULONG WINAPI
NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1572 PFORMAT_STRING pFormat
)
1574 /* unsigned size = *(LPWORD)(pFormat+2); */
1575 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1576 PointerMemorySize(pStubMsg
, pStubMsg
->Buffer
, pFormat
);
1580 /***********************************************************************
1581 * NdrPointerFree [RPCRT4.@]
1583 void WINAPI
NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1584 unsigned char *pMemory
,
1585 PFORMAT_STRING pFormat
)
1587 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1588 PointerFree(pStubMsg
, pMemory
, pFormat
);
1591 /***********************************************************************
1592 * NdrSimpleTypeMarshall [RPCRT4.@]
1594 void WINAPI
NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1595 unsigned char FormatChar
)
1597 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &FormatChar
);
1600 /***********************************************************************
1601 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1603 void WINAPI
NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1604 unsigned char FormatChar
)
1606 NdrBaseTypeUnmarshall(pStubMsg
, &pMemory
, &FormatChar
, 0);
1609 /***********************************************************************
1610 * NdrSimpleStructMarshall [RPCRT4.@]
1612 unsigned char * WINAPI
NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1613 unsigned char *pMemory
,
1614 PFORMAT_STRING pFormat
)
1616 unsigned size
= *(const WORD
*)(pFormat
+2);
1617 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1619 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1621 memcpy(pStubMsg
->Buffer
, pMemory
, size
);
1622 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1623 pStubMsg
->Buffer
+= size
;
1625 if (pFormat
[0] != RPC_FC_STRUCT
)
1626 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
+4);
1628 STD_OVERFLOW_CHECK(pStubMsg
);
1633 /***********************************************************************
1634 * NdrSimpleStructUnmarshall [RPCRT4.@]
1636 unsigned char * WINAPI
NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1637 unsigned char **ppMemory
,
1638 PFORMAT_STRING pFormat
,
1639 unsigned char fMustAlloc
)
1641 unsigned size
= *(const WORD
*)(pFormat
+2);
1642 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1644 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1647 *ppMemory
= NdrAllocate(pStubMsg
, size
);
1648 memcpy(*ppMemory
, pStubMsg
->Buffer
, size
);
1650 if (!pStubMsg
->IsClient
&& !*ppMemory
)
1651 /* for servers, we just point straight into the RPC buffer */
1652 *ppMemory
= pStubMsg
->Buffer
;
1654 /* for clients, memory should be provided by caller */
1655 memcpy(*ppMemory
, pStubMsg
->Buffer
, size
);
1658 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1659 pStubMsg
->Buffer
+= size
;
1661 if (pFormat
[0] != RPC_FC_STRUCT
)
1662 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
+4, fMustAlloc
);
1667 /***********************************************************************
1668 * NdrSimpleStructBufferSize [RPCRT4.@]
1670 void WINAPI
NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1671 unsigned char *pMemory
,
1672 PFORMAT_STRING pFormat
)
1674 unsigned size
= *(const WORD
*)(pFormat
+2);
1675 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1677 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
1679 pStubMsg
->BufferLength
+= size
;
1680 if (pFormat
[0] != RPC_FC_STRUCT
)
1681 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
+4);
1684 /***********************************************************************
1685 * NdrSimpleStructMemorySize [RPCRT4.@]
1687 ULONG WINAPI
NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1688 PFORMAT_STRING pFormat
)
1690 unsigned short size
= *(const WORD
*)(pFormat
+2);
1692 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1694 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1695 pStubMsg
->MemorySize
+= size
;
1696 pStubMsg
->Buffer
+= size
;
1698 if (pFormat
[0] != RPC_FC_STRUCT
)
1699 EmbeddedPointerMemorySize(pStubMsg
, pFormat
+4);
1703 /***********************************************************************
1704 * NdrSimpleStructFree [RPCRT4.@]
1706 void WINAPI
NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
1707 unsigned char *pMemory
,
1708 PFORMAT_STRING pFormat
)
1710 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1711 if (pFormat
[0] != RPC_FC_STRUCT
)
1712 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
+4);
1716 static unsigned long EmbeddedComplexSize(const MIDL_STUB_MESSAGE
*pStubMsg
,
1717 PFORMAT_STRING pFormat
)
1721 case RPC_FC_PSTRUCT
:
1722 case RPC_FC_CSTRUCT
:
1723 case RPC_FC_BOGUS_STRUCT
:
1724 case RPC_FC_SMFARRAY
:
1725 case RPC_FC_SMVARRAY
:
1726 return *(const WORD
*)&pFormat
[2];
1727 case RPC_FC_USER_MARSHAL
:
1728 return *(const WORD
*)&pFormat
[4];
1729 case RPC_FC_NON_ENCAPSULATED_UNION
:
1731 if (pStubMsg
->fHasNewCorrDesc
)
1736 pFormat
+= *(const SHORT
*)pFormat
;
1737 return *(const SHORT
*)pFormat
;
1739 return sizeof(void *);
1741 FIXME("unhandled embedded type %02x\n", *pFormat
);
1747 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1748 PFORMAT_STRING pFormat
)
1750 NDR_MEMORYSIZE m
= NdrMemorySizer
[*pFormat
& NDR_TABLE_MASK
];
1754 FIXME("no memorysizer for data type=%02x\n", *pFormat
);
1758 return m(pStubMsg
, pFormat
);
1762 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1763 unsigned char *pMemory
,
1764 PFORMAT_STRING pFormat
,
1765 PFORMAT_STRING pPointer
)
1767 PFORMAT_STRING desc
;
1771 while (*pFormat
!= RPC_FC_END
) {
1777 TRACE("byte=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
1778 memcpy(pStubMsg
->Buffer
, pMemory
, 1);
1779 pStubMsg
->Buffer
+= 1;
1785 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
1786 memcpy(pStubMsg
->Buffer
, pMemory
, 2);
1787 pStubMsg
->Buffer
+= 2;
1793 TRACE("long=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
1794 memcpy(pStubMsg
->Buffer
, pMemory
, 4);
1795 pStubMsg
->Buffer
+= 4;
1799 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
1800 memcpy(pStubMsg
->Buffer
, pMemory
, 8);
1801 pStubMsg
->Buffer
+= 8;
1804 case RPC_FC_POINTER
:
1806 unsigned char *saved_buffer
;
1807 int pointer_buffer_mark_set
= 0;
1808 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
1809 saved_buffer
= pStubMsg
->Buffer
;
1810 if (pStubMsg
->PointerBufferMark
)
1812 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1813 pStubMsg
->PointerBufferMark
= NULL
;
1814 pointer_buffer_mark_set
= 1;
1817 pStubMsg
->Buffer
+= 4; /* for pointer ID */
1818 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char**)pMemory
, pPointer
);
1819 if (pointer_buffer_mark_set
)
1821 STD_OVERFLOW_CHECK(pStubMsg
);
1822 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1823 pStubMsg
->Buffer
= saved_buffer
+ 4;
1829 case RPC_FC_ALIGNM4
:
1830 ALIGN_POINTER(pMemory
, 4);
1832 case RPC_FC_ALIGNM8
:
1833 ALIGN_POINTER(pMemory
, 8);
1835 case RPC_FC_STRUCTPAD1
:
1836 case RPC_FC_STRUCTPAD2
:
1837 case RPC_FC_STRUCTPAD3
:
1838 case RPC_FC_STRUCTPAD4
:
1839 case RPC_FC_STRUCTPAD5
:
1840 case RPC_FC_STRUCTPAD6
:
1841 case RPC_FC_STRUCTPAD7
:
1842 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
1844 case RPC_FC_EMBEDDED_COMPLEX
:
1845 pMemory
+= pFormat
[1];
1847 desc
= pFormat
+ *(const SHORT
*)pFormat
;
1848 size
= EmbeddedComplexSize(pStubMsg
, desc
);
1849 TRACE("embedded complex (size=%ld) <= %p\n", size
, pMemory
);
1850 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
1853 /* for some reason interface pointers aren't generated as
1854 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
1855 * they still need the derefencing treatment that pointers are
1857 if (*desc
== RPC_FC_IP
)
1858 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
1860 m(pStubMsg
, pMemory
, desc
);
1862 else FIXME("no marshaller for embedded type %02x\n", *desc
);
1869 FIXME("unhandled format 0x%02x\n", *pFormat
);
1877 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1878 unsigned char *pMemory
,
1879 PFORMAT_STRING pFormat
,
1880 PFORMAT_STRING pPointer
)
1882 PFORMAT_STRING desc
;
1886 while (*pFormat
!= RPC_FC_END
) {
1892 safe_buffer_copy(pStubMsg
, pMemory
, 1);
1893 TRACE("byte=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
1899 safe_buffer_copy(pStubMsg
, pMemory
, 2);
1900 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
1906 safe_buffer_copy(pStubMsg
, pMemory
, 4);
1907 TRACE("long=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
1911 safe_buffer_copy(pStubMsg
, pMemory
, 8);
1912 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
1915 case RPC_FC_POINTER
:
1917 unsigned char *saved_buffer
;
1918 int pointer_buffer_mark_set
= 0;
1919 TRACE("pointer => %p\n", pMemory
);
1920 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1921 saved_buffer
= pStubMsg
->Buffer
;
1922 if (pStubMsg
->PointerBufferMark
)
1924 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1925 pStubMsg
->PointerBufferMark
= NULL
;
1926 pointer_buffer_mark_set
= 1;
1929 pStubMsg
->Buffer
+= 4; /* for pointer ID */
1931 PointerUnmarshall(pStubMsg
, saved_buffer
, (unsigned char**)pMemory
, pPointer
, TRUE
);
1932 if (pointer_buffer_mark_set
)
1934 STD_OVERFLOW_CHECK(pStubMsg
);
1935 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1936 pStubMsg
->Buffer
= saved_buffer
+ 4;
1942 case RPC_FC_ALIGNM4
:
1943 ALIGN_POINTER(pMemory
, 4);
1945 case RPC_FC_ALIGNM8
:
1946 ALIGN_POINTER(pMemory
, 8);
1948 case RPC_FC_STRUCTPAD1
:
1949 case RPC_FC_STRUCTPAD2
:
1950 case RPC_FC_STRUCTPAD3
:
1951 case RPC_FC_STRUCTPAD4
:
1952 case RPC_FC_STRUCTPAD5
:
1953 case RPC_FC_STRUCTPAD6
:
1954 case RPC_FC_STRUCTPAD7
:
1955 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
1957 case RPC_FC_EMBEDDED_COMPLEX
:
1958 pMemory
+= pFormat
[1];
1960 desc
= pFormat
+ *(const SHORT
*)pFormat
;
1961 size
= EmbeddedComplexSize(pStubMsg
, desc
);
1962 TRACE("embedded complex (size=%ld) => %p\n", size
, pMemory
);
1963 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
1964 memset(pMemory
, 0, size
); /* just in case */
1967 /* for some reason interface pointers aren't generated as
1968 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
1969 * they still need the derefencing treatment that pointers are
1971 if (*desc
== RPC_FC_IP
)
1972 m(pStubMsg
, (unsigned char **)pMemory
, desc
, FALSE
);
1974 m(pStubMsg
, &pMemory
, desc
, FALSE
);
1976 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
1983 FIXME("unhandled format %d\n", *pFormat
);
1991 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1992 unsigned char *pMemory
,
1993 PFORMAT_STRING pFormat
,
1994 PFORMAT_STRING pPointer
)
1996 PFORMAT_STRING desc
;
2000 while (*pFormat
!= RPC_FC_END
) {
2006 pStubMsg
->BufferLength
+= 1;
2012 pStubMsg
->BufferLength
+= 2;
2018 pStubMsg
->BufferLength
+= 4;
2022 pStubMsg
->BufferLength
+= 8;
2025 case RPC_FC_POINTER
:
2026 if (!pStubMsg
->IgnoreEmbeddedPointers
)
2028 int saved_buffer_length
= pStubMsg
->BufferLength
;
2029 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2030 pStubMsg
->PointerLength
= 0;
2031 if(!pStubMsg
->BufferLength
)
2032 ERR("BufferLength == 0??\n");
2033 PointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
2034 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2035 pStubMsg
->BufferLength
= saved_buffer_length
;
2037 pStubMsg
->BufferLength
+= 4;
2041 case RPC_FC_ALIGNM4
:
2042 ALIGN_POINTER(pMemory
, 4);
2044 case RPC_FC_ALIGNM8
:
2045 ALIGN_POINTER(pMemory
, 8);
2047 case RPC_FC_STRUCTPAD1
:
2048 case RPC_FC_STRUCTPAD2
:
2049 case RPC_FC_STRUCTPAD3
:
2050 case RPC_FC_STRUCTPAD4
:
2051 case RPC_FC_STRUCTPAD5
:
2052 case RPC_FC_STRUCTPAD6
:
2053 case RPC_FC_STRUCTPAD7
:
2054 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2056 case RPC_FC_EMBEDDED_COMPLEX
:
2057 pMemory
+= pFormat
[1];
2059 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2060 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2061 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
2064 /* for some reason interface pointers aren't generated as
2065 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2066 * they still need the derefencing treatment that pointers are
2068 if (*desc
== RPC_FC_IP
)
2069 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2071 m(pStubMsg
, pMemory
, desc
);
2073 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
2080 FIXME("unhandled format 0x%02x\n", *pFormat
);
2088 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
2089 unsigned char *pMemory
,
2090 PFORMAT_STRING pFormat
,
2091 PFORMAT_STRING pPointer
)
2093 PFORMAT_STRING desc
;
2097 while (*pFormat
!= RPC_FC_END
) {
2118 case RPC_FC_POINTER
:
2119 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
2123 case RPC_FC_ALIGNM4
:
2124 ALIGN_POINTER(pMemory
, 4);
2126 case RPC_FC_ALIGNM8
:
2127 ALIGN_POINTER(pMemory
, 8);
2129 case RPC_FC_STRUCTPAD1
:
2130 case RPC_FC_STRUCTPAD2
:
2131 case RPC_FC_STRUCTPAD3
:
2132 case RPC_FC_STRUCTPAD4
:
2133 case RPC_FC_STRUCTPAD5
:
2134 case RPC_FC_STRUCTPAD6
:
2135 case RPC_FC_STRUCTPAD7
:
2136 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2138 case RPC_FC_EMBEDDED_COMPLEX
:
2139 pMemory
+= pFormat
[1];
2141 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2142 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2143 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
2146 /* for some reason interface pointers aren't generated as
2147 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2148 * they still need the derefencing treatment that pointers are
2150 if (*desc
== RPC_FC_IP
)
2151 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2153 m(pStubMsg
, pMemory
, desc
);
2155 else FIXME("no freer for embedded type %02x\n", *desc
);
2162 FIXME("unhandled format 0x%02x\n", *pFormat
);
2170 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2171 PFORMAT_STRING pFormat
)
2173 PFORMAT_STRING desc
;
2174 unsigned long size
= 0;
2176 while (*pFormat
!= RPC_FC_END
) {
2183 pStubMsg
->Buffer
+= 1;
2189 pStubMsg
->Buffer
+= 2;
2195 pStubMsg
->Buffer
+= 4;
2199 pStubMsg
->Buffer
+= 8;
2201 case RPC_FC_POINTER
:
2203 pStubMsg
->Buffer
+= 4;
2204 if (!pStubMsg
->IgnoreEmbeddedPointers
)
2205 FIXME("embedded pointers\n");
2207 case RPC_FC_ALIGNM4
:
2208 ALIGN_LENGTH(size
, 4);
2209 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2211 case RPC_FC_ALIGNM8
:
2212 ALIGN_LENGTH(size
, 8);
2213 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
2215 case RPC_FC_STRUCTPAD1
:
2216 case RPC_FC_STRUCTPAD2
:
2217 case RPC_FC_STRUCTPAD3
:
2218 case RPC_FC_STRUCTPAD4
:
2219 case RPC_FC_STRUCTPAD5
:
2220 case RPC_FC_STRUCTPAD6
:
2221 case RPC_FC_STRUCTPAD7
:
2222 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2224 case RPC_FC_EMBEDDED_COMPLEX
:
2227 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2228 size
+= EmbeddedComplexMemorySize(pStubMsg
, desc
);
2234 FIXME("unhandled format 0x%02x\n", *pFormat
);
2242 /***********************************************************************
2243 * NdrComplexStructMarshall [RPCRT4.@]
2245 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2246 unsigned char *pMemory
,
2247 PFORMAT_STRING pFormat
)
2249 PFORMAT_STRING conf_array
= NULL
;
2250 PFORMAT_STRING pointer_desc
= NULL
;
2251 unsigned char *OldMemory
= pStubMsg
->Memory
;
2252 int pointer_buffer_mark_set
= 0;
2254 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2256 if (!pStubMsg
->PointerBufferMark
)
2258 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2259 /* save buffer length */
2260 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2262 /* get the buffer pointer after complex array data, but before
2264 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- pStubMsg
->BufferStart
;
2265 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2266 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
2267 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2269 /* save it for use by embedded pointer code later */
2270 pStubMsg
->PointerBufferMark
= pStubMsg
->BufferStart
+ pStubMsg
->BufferLength
;
2271 TRACE("difference = 0x%x\n", pStubMsg
->PointerBufferMark
- pStubMsg
->Buffer
);
2272 pointer_buffer_mark_set
= 1;
2274 /* restore the original buffer length */
2275 pStubMsg
->BufferLength
= saved_buffer_length
;
2278 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2281 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2283 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2286 pStubMsg
->Memory
= pMemory
;
2288 ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2291 NdrConformantArrayMarshall(pStubMsg
, pMemory
, conf_array
);
2293 pStubMsg
->Memory
= OldMemory
;
2295 if (pointer_buffer_mark_set
)
2297 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2298 pStubMsg
->PointerBufferMark
= NULL
;
2301 STD_OVERFLOW_CHECK(pStubMsg
);
2306 /***********************************************************************
2307 * NdrComplexStructUnmarshall [RPCRT4.@]
2309 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2310 unsigned char **ppMemory
,
2311 PFORMAT_STRING pFormat
,
2312 unsigned char fMustAlloc
)
2314 unsigned size
= *(const WORD
*)(pFormat
+2);
2315 PFORMAT_STRING conf_array
= NULL
;
2316 PFORMAT_STRING pointer_desc
= NULL
;
2317 unsigned char *pMemory
;
2318 int pointer_buffer_mark_set
= 0;
2320 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2322 if (!pStubMsg
->PointerBufferMark
)
2324 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2325 /* save buffer pointer */
2326 unsigned char *saved_buffer
= pStubMsg
->Buffer
;
2328 /* get the buffer pointer after complex array data, but before
2330 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2331 NdrComplexStructMemorySize(pStubMsg
, pFormat
);
2332 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2334 /* save it for use by embedded pointer code later */
2335 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2336 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->PointerBufferMark
- saved_buffer
));
2337 pointer_buffer_mark_set
= 1;
2339 /* restore the original buffer */
2340 pStubMsg
->Buffer
= saved_buffer
;
2343 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2345 if (fMustAlloc
|| !*ppMemory
)
2347 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2348 memset(*ppMemory
, 0, size
);
2352 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2354 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2357 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
);
2360 NdrConformantArrayUnmarshall(pStubMsg
, &pMemory
, conf_array
, fMustAlloc
);
2362 if (pointer_buffer_mark_set
)
2364 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2365 pStubMsg
->PointerBufferMark
= NULL
;
2371 /***********************************************************************
2372 * NdrComplexStructBufferSize [RPCRT4.@]
2374 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2375 unsigned char *pMemory
,
2376 PFORMAT_STRING pFormat
)
2378 PFORMAT_STRING conf_array
= NULL
;
2379 PFORMAT_STRING pointer_desc
= NULL
;
2380 unsigned char *OldMemory
= pStubMsg
->Memory
;
2381 int pointer_length_set
= 0;
2383 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2385 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
2387 if(!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
2389 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2390 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2392 /* get the buffer length after complex struct data, but before
2394 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2395 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
2396 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2398 /* save it for use by embedded pointer code later */
2399 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2400 pointer_length_set
= 1;
2401 TRACE("difference = 0x%lx\n", pStubMsg
->PointerLength
- saved_buffer_length
);
2403 /* restore the original buffer length */
2404 pStubMsg
->BufferLength
= saved_buffer_length
;
2408 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2410 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2413 pStubMsg
->Memory
= pMemory
;
2415 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2418 NdrConformantArrayBufferSize(pStubMsg
, pMemory
, conf_array
);
2420 pStubMsg
->Memory
= OldMemory
;
2422 if(pointer_length_set
)
2424 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2425 pStubMsg
->PointerLength
= 0;
2430 /***********************************************************************
2431 * NdrComplexStructMemorySize [RPCRT4.@]
2433 ULONG WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2434 PFORMAT_STRING pFormat
)
2436 unsigned size
= *(const WORD
*)(pFormat
+2);
2437 PFORMAT_STRING conf_array
= NULL
;
2438 PFORMAT_STRING pointer_desc
= NULL
;
2440 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2442 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2445 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2447 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2450 ComplexStructMemorySize(pStubMsg
, pFormat
);
2453 NdrConformantArrayMemorySize(pStubMsg
, conf_array
);
2458 /***********************************************************************
2459 * NdrComplexStructFree [RPCRT4.@]
2461 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
2462 unsigned char *pMemory
,
2463 PFORMAT_STRING pFormat
)
2465 PFORMAT_STRING conf_array
= NULL
;
2466 PFORMAT_STRING pointer_desc
= NULL
;
2467 unsigned char *OldMemory
= pStubMsg
->Memory
;
2469 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2472 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2474 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2477 pStubMsg
->Memory
= pMemory
;
2479 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2482 NdrConformantArrayFree(pStubMsg
, pMemory
, conf_array
);
2484 pStubMsg
->Memory
= OldMemory
;
2487 /***********************************************************************
2488 * NdrConformantArrayMarshall [RPCRT4.@]
2490 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2491 unsigned char *pMemory
,
2492 PFORMAT_STRING pFormat
)
2494 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
2495 unsigned char alignment
= pFormat
[1] + 1;
2497 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2498 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2500 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2502 WriteConformance(pStubMsg
);
2504 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2506 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2507 memcpy(pStubMsg
->Buffer
, pMemory
, size
);
2508 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2509 pStubMsg
->Buffer
+= size
;
2511 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2513 STD_OVERFLOW_CHECK(pStubMsg
);
2518 /***********************************************************************
2519 * NdrConformantArrayUnmarshall [RPCRT4.@]
2521 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2522 unsigned char **ppMemory
,
2523 PFORMAT_STRING pFormat
,
2524 unsigned char fMustAlloc
)
2526 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
2527 unsigned char alignment
= pFormat
[1] + 1;
2529 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2530 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2532 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2534 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2536 if (fMustAlloc
|| !*ppMemory
)
2537 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2539 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2541 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2542 safe_buffer_copy(pStubMsg
, *ppMemory
, size
);
2544 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2549 /***********************************************************************
2550 * NdrConformantArrayBufferSize [RPCRT4.@]
2552 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2553 unsigned char *pMemory
,
2554 PFORMAT_STRING pFormat
)
2556 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
2557 unsigned char alignment
= pFormat
[1] + 1;
2559 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2560 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2562 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2564 SizeConformance(pStubMsg
);
2566 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
2568 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2569 /* conformance value plus array */
2570 pStubMsg
->BufferLength
+= size
;
2572 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
2575 /***********************************************************************
2576 * NdrConformantArrayMemorySize [RPCRT4.@]
2578 ULONG WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2579 PFORMAT_STRING pFormat
)
2581 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
2582 unsigned char alignment
= pFormat
[1] + 1;
2584 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2585 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2587 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2588 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2589 pStubMsg
->MemorySize
+= size
;
2591 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2592 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2593 pStubMsg
->Buffer
+= size
;
2595 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2597 return pStubMsg
->MemorySize
;
2600 /***********************************************************************
2601 * NdrConformantArrayFree [RPCRT4.@]
2603 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
2604 unsigned char *pMemory
,
2605 PFORMAT_STRING pFormat
)
2607 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2608 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2610 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2612 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2616 /***********************************************************************
2617 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2619 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2620 unsigned char* pMemory
,
2621 PFORMAT_STRING pFormat
)
2624 unsigned char alignment
= pFormat
[1] + 1;
2625 DWORD esize
= *(const WORD
*)(pFormat
+2);
2627 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
2629 if (pFormat
[0] != RPC_FC_CVARRAY
)
2631 ERR("invalid format type %x\n", pFormat
[0]);
2632 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2636 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2637 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2639 WriteConformance(pStubMsg
);
2640 WriteVariance(pStubMsg
);
2642 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2644 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2646 memcpy(pStubMsg
->Buffer
, pMemory
+ pStubMsg
->Offset
, bufsize
);
2647 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2648 pStubMsg
->Buffer
+= bufsize
;
2650 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2652 STD_OVERFLOW_CHECK(pStubMsg
);
2658 /***********************************************************************
2659 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2661 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2662 unsigned char** ppMemory
,
2663 PFORMAT_STRING pFormat
,
2664 unsigned char fMustAlloc
)
2666 ULONG bufsize
, memsize
;
2667 unsigned char alignment
= pFormat
[1] + 1;
2668 DWORD esize
= *(const WORD
*)(pFormat
+2);
2670 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2672 if (pFormat
[0] != RPC_FC_CVARRAY
)
2674 ERR("invalid format type %x\n", pFormat
[0]);
2675 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2679 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2680 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2682 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2684 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2685 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2687 if (!*ppMemory
|| fMustAlloc
)
2688 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2689 safe_buffer_copy(pStubMsg
, *ppMemory
+ pStubMsg
->Offset
, bufsize
);
2691 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2697 /***********************************************************************
2698 * NdrConformantVaryingArrayFree [RPCRT4.@]
2700 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
2701 unsigned char* pMemory
,
2702 PFORMAT_STRING pFormat
)
2704 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2706 if (pFormat
[0] != RPC_FC_CVARRAY
)
2708 ERR("invalid format type %x\n", pFormat
[0]);
2709 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2713 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2714 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2716 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2720 /***********************************************************************
2721 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2723 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
2724 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
2726 unsigned char alignment
= pFormat
[1] + 1;
2727 DWORD esize
= *(const WORD
*)(pFormat
+2);
2729 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
2731 if (pFormat
[0] != RPC_FC_CVARRAY
)
2733 ERR("invalid format type %x\n", pFormat
[0]);
2734 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2739 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2740 /* compute length */
2741 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2743 SizeConformance(pStubMsg
);
2744 SizeVariance(pStubMsg
);
2746 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
2748 pStubMsg
->BufferLength
+= safe_multiply(esize
, pStubMsg
->ActualCount
);
2750 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
2754 /***********************************************************************
2755 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2757 ULONG WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
2758 PFORMAT_STRING pFormat
)
2765 /***********************************************************************
2766 * NdrComplexArrayMarshall [RPCRT4.@]
2768 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2769 unsigned char *pMemory
,
2770 PFORMAT_STRING pFormat
)
2772 ULONG i
, count
, def
;
2773 BOOL variance_present
;
2774 unsigned char alignment
;
2775 int pointer_buffer_mark_set
= 0;
2777 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2779 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
2781 ERR("invalid format type %x\n", pFormat
[0]);
2782 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2786 alignment
= pFormat
[1] + 1;
2788 if (!pStubMsg
->PointerBufferMark
)
2790 /* save buffer fields that may be changed by buffer sizer functions
2791 * and that may be needed later on */
2792 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2793 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2794 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
2795 unsigned long saved_offset
= pStubMsg
->Offset
;
2796 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
2798 /* get the buffer pointer after complex array data, but before
2800 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- pStubMsg
->BufferStart
;
2801 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2802 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
2803 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2805 /* save it for use by embedded pointer code later */
2806 pStubMsg
->PointerBufferMark
= pStubMsg
->BufferStart
+ pStubMsg
->BufferLength
;
2807 TRACE("difference = 0x%x\n", pStubMsg
->Buffer
- pStubMsg
->BufferStart
);
2808 pointer_buffer_mark_set
= 1;
2810 /* restore fields */
2811 pStubMsg
->ActualCount
= saved_actual_count
;
2812 pStubMsg
->Offset
= saved_offset
;
2813 pStubMsg
->MaxCount
= saved_max_count
;
2814 pStubMsg
->BufferLength
= saved_buffer_length
;
2817 def
= *(const WORD
*)&pFormat
[2];
2820 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
2821 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
2823 variance_present
= IsConformanceOrVariancePresent(pFormat
);
2824 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
2825 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
2827 WriteConformance(pStubMsg
);
2828 if (variance_present
)
2829 WriteVariance(pStubMsg
);
2831 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2833 count
= pStubMsg
->ActualCount
;
2834 for (i
= 0; i
< count
; i
++)
2835 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
2837 STD_OVERFLOW_CHECK(pStubMsg
);
2839 if (pointer_buffer_mark_set
)
2841 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2842 pStubMsg
->PointerBufferMark
= NULL
;
2848 /***********************************************************************
2849 * NdrComplexArrayUnmarshall [RPCRT4.@]
2851 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2852 unsigned char **ppMemory
,
2853 PFORMAT_STRING pFormat
,
2854 unsigned char fMustAlloc
)
2856 ULONG i
, count
, size
;
2857 unsigned char alignment
;
2858 unsigned char *pMemory
;
2859 unsigned char *saved_buffer
;
2860 int pointer_buffer_mark_set
= 0;
2861 int saved_ignore_embedded
;
2863 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2865 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
2867 ERR("invalid format type %x\n", pFormat
[0]);
2868 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2872 alignment
= pFormat
[1] + 1;
2874 saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2875 /* save buffer pointer */
2876 saved_buffer
= pStubMsg
->Buffer
;
2877 /* get the buffer pointer after complex array data, but before
2879 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2880 pStubMsg
->MemorySize
= 0;
2881 NdrComplexArrayMemorySize(pStubMsg
, pFormat
);
2882 size
= pStubMsg
->MemorySize
;
2883 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2885 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->Buffer
- saved_buffer
));
2886 if (!pStubMsg
->PointerBufferMark
)
2888 /* save it for use by embedded pointer code later */
2889 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2890 pointer_buffer_mark_set
= 1;
2892 /* restore the original buffer */
2893 pStubMsg
->Buffer
= saved_buffer
;
2897 pFormat
= ReadConformance(pStubMsg
, pFormat
);
2898 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2900 if (fMustAlloc
|| !*ppMemory
)
2902 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2903 memset(*ppMemory
, 0, size
);
2906 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2908 pMemory
= *ppMemory
;
2909 count
= pStubMsg
->ActualCount
;
2910 for (i
= 0; i
< count
; i
++)
2911 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
2913 if (pointer_buffer_mark_set
)
2915 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2916 pStubMsg
->PointerBufferMark
= NULL
;
2922 /***********************************************************************
2923 * NdrComplexArrayBufferSize [RPCRT4.@]
2925 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2926 unsigned char *pMemory
,
2927 PFORMAT_STRING pFormat
)
2929 ULONG i
, count
, def
;
2930 unsigned char alignment
;
2931 BOOL variance_present
;
2932 int pointer_length_set
= 0;
2934 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2936 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
2938 ERR("invalid format type %x\n", pFormat
[0]);
2939 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2943 alignment
= pFormat
[1] + 1;
2945 if (!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
2947 /* save buffer fields that may be changed by buffer sizer functions
2948 * and that may be needed later on */
2949 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2950 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2951 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
2952 unsigned long saved_offset
= pStubMsg
->Offset
;
2953 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
2955 /* get the buffer pointer after complex array data, but before
2957 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2958 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
2959 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2961 /* save it for use by embedded pointer code later */
2962 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2963 pointer_length_set
= 1;
2965 /* restore fields */
2966 pStubMsg
->ActualCount
= saved_actual_count
;
2967 pStubMsg
->Offset
= saved_offset
;
2968 pStubMsg
->MaxCount
= saved_max_count
;
2969 pStubMsg
->BufferLength
= saved_buffer_length
;
2971 def
= *(const WORD
*)&pFormat
[2];
2974 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
2975 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
2976 SizeConformance(pStubMsg
);
2978 variance_present
= IsConformanceOrVariancePresent(pFormat
);
2979 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
2980 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
2982 if (variance_present
)
2983 SizeVariance(pStubMsg
);
2985 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
2987 count
= pStubMsg
->ActualCount
;
2988 for (i
= 0; i
< count
; i
++)
2989 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
2991 if(pointer_length_set
)
2993 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2994 pStubMsg
->PointerLength
= 0;
2998 /***********************************************************************
2999 * NdrComplexArrayMemorySize [RPCRT4.@]
3001 ULONG WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3002 PFORMAT_STRING pFormat
)
3004 ULONG i
, count
, esize
, SavedMemorySize
, MemorySize
;
3005 unsigned char alignment
;
3006 unsigned char *Buffer
;
3008 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3010 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3012 ERR("invalid format type %x\n", pFormat
[0]);
3013 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3017 alignment
= pFormat
[1] + 1;
3021 pFormat
= ReadConformance(pStubMsg
, pFormat
);
3022 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3024 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3026 SavedMemorySize
= pStubMsg
->MemorySize
;
3028 Buffer
= pStubMsg
->Buffer
;
3029 pStubMsg
->MemorySize
= 0;
3030 esize
= ComplexStructMemorySize(pStubMsg
, pFormat
);
3031 pStubMsg
->Buffer
= Buffer
;
3033 MemorySize
= safe_multiply(pStubMsg
->MaxCount
, esize
);
3035 count
= pStubMsg
->ActualCount
;
3036 for (i
= 0; i
< count
; i
++)
3037 ComplexStructMemorySize(pStubMsg
, pFormat
);
3039 pStubMsg
->MemorySize
= SavedMemorySize
;
3041 pStubMsg
->MemorySize
+= MemorySize
;
3045 /***********************************************************************
3046 * NdrComplexArrayFree [RPCRT4.@]
3048 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3049 unsigned char *pMemory
,
3050 PFORMAT_STRING pFormat
)
3052 ULONG i
, count
, def
;
3054 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3056 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3058 ERR("invalid format type %x\n", pFormat
[0]);
3059 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3063 def
= *(const WORD
*)&pFormat
[2];
3066 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3067 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3069 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3070 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3072 count
= pStubMsg
->ActualCount
;
3073 for (i
= 0; i
< count
; i
++)
3074 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
3077 static ULONG
UserMarshalFlags(const MIDL_STUB_MESSAGE
*pStubMsg
)
3079 return MAKELONG(pStubMsg
->dwDestContext
,
3080 pStubMsg
->RpcMsg
->DataRepresentation
);
3083 #define USER_MARSHAL_PTR_PREFIX \
3084 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3085 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3087 /***********************************************************************
3088 * NdrUserMarshalMarshall [RPCRT4.@]
3090 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3091 unsigned char *pMemory
,
3092 PFORMAT_STRING pFormat
)
3094 unsigned flags
= pFormat
[1];
3095 unsigned index
= *(const WORD
*)&pFormat
[2];
3096 unsigned char *saved_buffer
= NULL
;
3097 ULONG uflag
= UserMarshalFlags(pStubMsg
);
3098 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3099 TRACE("index=%d\n", index
);
3101 if (flags
& USER_MARSHAL_POINTER
)
3103 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3104 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, USER_MARSHAL_PTR_PREFIX
);
3105 pStubMsg
->Buffer
+= 4;
3106 if (pStubMsg
->PointerBufferMark
)
3108 saved_buffer
= pStubMsg
->Buffer
;
3109 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3110 pStubMsg
->PointerBufferMark
= NULL
;
3112 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3115 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3118 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
3119 &uflag
, pStubMsg
->Buffer
, pMemory
);
3123 STD_OVERFLOW_CHECK(pStubMsg
);
3124 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3125 pStubMsg
->Buffer
= saved_buffer
;
3128 STD_OVERFLOW_CHECK(pStubMsg
);
3133 /***********************************************************************
3134 * NdrUserMarshalUnmarshall [RPCRT4.@]
3136 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3137 unsigned char **ppMemory
,
3138 PFORMAT_STRING pFormat
,
3139 unsigned char fMustAlloc
)
3141 unsigned flags
= pFormat
[1];
3142 unsigned index
= *(const WORD
*)&pFormat
[2];
3143 DWORD memsize
= *(const WORD
*)&pFormat
[4];
3144 unsigned char *saved_buffer
= NULL
;
3145 ULONG uflag
= UserMarshalFlags(pStubMsg
);
3146 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3147 TRACE("index=%d\n", index
);
3149 if (flags
& USER_MARSHAL_POINTER
)
3151 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3152 /* skip pointer prefix */
3153 pStubMsg
->Buffer
+= 4;
3154 if (pStubMsg
->PointerBufferMark
)
3156 saved_buffer
= pStubMsg
->Buffer
;
3157 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3158 pStubMsg
->PointerBufferMark
= NULL
;
3160 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3163 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3165 if (fMustAlloc
|| !*ppMemory
)
3166 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
3169 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
3170 &uflag
, pStubMsg
->Buffer
, *ppMemory
);
3174 STD_OVERFLOW_CHECK(pStubMsg
);
3175 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3176 pStubMsg
->Buffer
= saved_buffer
;
3182 /***********************************************************************
3183 * NdrUserMarshalBufferSize [RPCRT4.@]
3185 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3186 unsigned char *pMemory
,
3187 PFORMAT_STRING pFormat
)
3189 unsigned flags
= pFormat
[1];
3190 unsigned index
= *(const WORD
*)&pFormat
[2];
3191 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
3192 ULONG uflag
= UserMarshalFlags(pStubMsg
);
3193 unsigned long saved_buffer_length
= 0;
3194 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3195 TRACE("index=%d\n", index
);
3197 if (flags
& USER_MARSHAL_POINTER
)
3199 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
3200 /* skip pointer prefix */
3201 pStubMsg
->BufferLength
+= 4;
3202 if (pStubMsg
->IgnoreEmbeddedPointers
)
3204 if (pStubMsg
->PointerLength
)
3206 saved_buffer_length
= pStubMsg
->BufferLength
;
3207 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3208 pStubMsg
->PointerLength
= 0;
3210 ALIGN_LENGTH(pStubMsg
->BufferLength
, 8);
3213 ALIGN_LENGTH(pStubMsg
->BufferLength
, (flags
& 0xf) + 1);
3216 TRACE("size=%d\n", bufsize
);
3217 pStubMsg
->BufferLength
+= bufsize
;
3220 pStubMsg
->BufferLength
=
3221 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
3222 &uflag
, pStubMsg
->BufferLength
, pMemory
);
3224 if (saved_buffer_length
)
3226 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3227 pStubMsg
->BufferLength
= saved_buffer_length
;
3232 /***********************************************************************
3233 * NdrUserMarshalMemorySize [RPCRT4.@]
3235 ULONG WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3236 PFORMAT_STRING pFormat
)
3238 unsigned flags
= pFormat
[1];
3239 unsigned index
= *(const WORD
*)&pFormat
[2];
3240 DWORD memsize
= *(const WORD
*)&pFormat
[4];
3241 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
3243 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3244 TRACE("index=%d\n", index
);
3246 pStubMsg
->MemorySize
+= memsize
;
3248 if (flags
& USER_MARSHAL_POINTER
)
3250 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3251 /* skip pointer prefix */
3252 pStubMsg
->Buffer
+= 4;
3253 if (pStubMsg
->IgnoreEmbeddedPointers
)
3254 return pStubMsg
->MemorySize
;
3255 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3258 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3261 FIXME("not implemented for varying buffer size\n");
3263 pStubMsg
->Buffer
+= bufsize
;
3265 return pStubMsg
->MemorySize
;
3268 /***********************************************************************
3269 * NdrUserMarshalFree [RPCRT4.@]
3271 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
3272 unsigned char *pMemory
,
3273 PFORMAT_STRING pFormat
)
3275 /* unsigned flags = pFormat[1]; */
3276 unsigned index
= *(const WORD
*)&pFormat
[2];
3277 ULONG uflag
= UserMarshalFlags(pStubMsg
);
3278 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3279 TRACE("index=%d\n", index
);
3281 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
3285 /***********************************************************************
3286 * NdrClearOutParameters [RPCRT4.@]
3288 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
3289 PFORMAT_STRING pFormat
,
3292 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
3295 /***********************************************************************
3296 * NdrConvert [RPCRT4.@]
3298 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
3300 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
3301 /* FIXME: since this stub doesn't do any converting, the proper behavior
3302 is to raise an exception */
3305 /***********************************************************************
3306 * NdrConvert2 [RPCRT4.@]
3308 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, LONG NumberParams
)
3310 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3311 pStubMsg
, pFormat
, NumberParams
);
3312 /* FIXME: since this stub doesn't do any converting, the proper behavior
3313 is to raise an exception */
3316 #include "pshpack1.h"
3317 typedef struct _NDR_CSTRUCT_FORMAT
3320 unsigned char alignment
;
3321 unsigned short memory_size
;
3322 short offset_to_array_description
;
3323 } NDR_CSTRUCT_FORMAT
, NDR_CVSTRUCT_FORMAT
;
3324 #include "poppack.h"
3326 /***********************************************************************
3327 * NdrConformantStructMarshall [RPCRT4.@]
3329 unsigned char * WINAPI
NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3330 unsigned char *pMemory
,
3331 PFORMAT_STRING pFormat
)
3333 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3334 PFORMAT_STRING pCArrayFormat
;
3335 ULONG esize
, bufsize
;
3337 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3339 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3340 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3342 ERR("invalid format type %x\n", pCStructFormat
->type
);
3343 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3347 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3348 pCStructFormat
->offset_to_array_description
;
3349 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3351 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3352 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3355 esize
= *(const WORD
*)(pCArrayFormat
+2);
3357 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
3358 pCArrayFormat
+ 4, 0);
3360 WriteConformance(pStubMsg
);
3362 ALIGN_POINTER(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
3364 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3366 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3367 /* copy constant sized part of struct */
3368 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3369 memcpy(pStubMsg
->Buffer
, pMemory
, pCStructFormat
->memory_size
+ bufsize
);
3370 pStubMsg
->Buffer
+= pCStructFormat
->memory_size
+ bufsize
;
3372 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3373 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3375 STD_OVERFLOW_CHECK(pStubMsg
);
3380 /***********************************************************************
3381 * NdrConformantStructUnmarshall [RPCRT4.@]
3383 unsigned char * WINAPI
NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3384 unsigned char **ppMemory
,
3385 PFORMAT_STRING pFormat
,
3386 unsigned char fMustAlloc
)
3388 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3389 PFORMAT_STRING pCArrayFormat
;
3390 ULONG esize
, bufsize
;
3392 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3394 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3395 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3397 ERR("invalid format type %x\n", pCStructFormat
->type
);
3398 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3401 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3402 pCStructFormat
->offset_to_array_description
;
3403 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3405 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3406 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3409 esize
= *(const WORD
*)(pCArrayFormat
+2);
3411 pCArrayFormat
= ReadConformance(pStubMsg
, pCArrayFormat
+ 4);
3413 ALIGN_POINTER(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
3415 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3417 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3418 /* work out how much memory to allocate if we need to do so */
3419 if (!*ppMemory
|| fMustAlloc
)
3421 SIZE_T size
= pCStructFormat
->memory_size
+ bufsize
;
3422 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3425 /* now copy the data */
3426 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3427 safe_buffer_copy(pStubMsg
, *ppMemory
, pCStructFormat
->memory_size
+ bufsize
);
3429 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3430 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3435 /***********************************************************************
3436 * NdrConformantStructBufferSize [RPCRT4.@]
3438 void WINAPI
NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3439 unsigned char *pMemory
,
3440 PFORMAT_STRING pFormat
)
3442 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3443 PFORMAT_STRING pCArrayFormat
;
3446 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3448 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3449 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3451 ERR("invalid format type %x\n", pCStructFormat
->type
);
3452 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3455 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3456 pCStructFormat
->offset_to_array_description
;
3457 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3459 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3460 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3463 esize
= *(const WORD
*)(pCArrayFormat
+2);
3465 pCArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
, pCArrayFormat
+4, 0);
3466 SizeConformance(pStubMsg
);
3468 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCStructFormat
->alignment
+ 1);
3470 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3472 pStubMsg
->BufferLength
+= pCStructFormat
->memory_size
+
3473 safe_multiply(pStubMsg
->MaxCount
, esize
);
3475 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3476 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3479 /***********************************************************************
3480 * NdrConformantStructMemorySize [RPCRT4.@]
3482 ULONG WINAPI
NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3483 PFORMAT_STRING pFormat
)
3489 /***********************************************************************
3490 * NdrConformantStructFree [RPCRT4.@]
3492 void WINAPI
NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3493 unsigned char *pMemory
,
3494 PFORMAT_STRING pFormat
)
3499 /***********************************************************************
3500 * NdrConformantVaryingStructMarshall [RPCRT4.@]
3502 unsigned char * WINAPI
NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3503 unsigned char *pMemory
,
3504 PFORMAT_STRING pFormat
)
3506 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3507 PFORMAT_STRING pCVArrayFormat
;
3508 ULONG esize
, bufsize
;
3510 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3512 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3513 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3515 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3516 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3520 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3521 pCVStructFormat
->offset_to_array_description
;
3522 switch (*pCVArrayFormat
)
3524 case RPC_FC_CVARRAY
:
3525 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3527 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3528 pCVArrayFormat
+ 4, 0);
3529 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3532 case RPC_FC_C_CSTRING
:
3533 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
3534 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
3535 esize
= sizeof(char);
3536 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3537 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3538 pCVArrayFormat
+ 2, 0);
3540 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3542 case RPC_FC_C_WSTRING
:
3543 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
3544 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
3545 esize
= sizeof(WCHAR
);
3546 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3547 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3548 pCVArrayFormat
+ 2, 0);
3550 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3553 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3554 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3558 WriteConformance(pStubMsg
);
3560 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
3562 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3564 /* write constant sized part */
3565 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3566 memcpy(pStubMsg
->Buffer
, pMemory
, pCVStructFormat
->memory_size
);
3567 pStubMsg
->Buffer
+= pCVStructFormat
->memory_size
;
3569 WriteVariance(pStubMsg
);
3571 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3573 /* write array part */
3574 memcpy(pStubMsg
->Buffer
, pMemory
+ pCVStructFormat
->memory_size
, bufsize
);
3575 pStubMsg
->Buffer
+= bufsize
;
3577 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3579 STD_OVERFLOW_CHECK(pStubMsg
);
3584 /***********************************************************************
3585 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3587 unsigned char * WINAPI
NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3588 unsigned char **ppMemory
,
3589 PFORMAT_STRING pFormat
,
3590 unsigned char fMustAlloc
)
3592 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3593 PFORMAT_STRING pCVArrayFormat
;
3594 ULONG esize
, bufsize
;
3595 unsigned char cvarray_type
;
3597 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3599 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3600 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3602 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3603 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3607 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3608 pCVStructFormat
->offset_to_array_description
;
3609 cvarray_type
= *pCVArrayFormat
;
3610 switch (cvarray_type
)
3612 case RPC_FC_CVARRAY
:
3613 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3614 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 4);
3616 case RPC_FC_C_CSTRING
:
3617 esize
= sizeof(char);
3618 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3619 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3621 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3623 case RPC_FC_C_WSTRING
:
3624 esize
= sizeof(WCHAR
);
3625 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3626 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3628 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3631 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3632 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3636 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
3638 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3640 /* work out how much memory to allocate if we need to do so */
3641 if (!*ppMemory
|| fMustAlloc
)
3643 SIZE_T size
= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->MaxCount
);
3644 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3647 /* copy the constant data */
3648 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3649 safe_buffer_copy(pStubMsg
, *ppMemory
, pCVStructFormat
->memory_size
);
3651 pCVArrayFormat
= ReadVariance(pStubMsg
, pCVArrayFormat
, pStubMsg
->MaxCount
);
3653 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3655 if ((cvarray_type
== RPC_FC_C_CSTRING
) ||
3656 (cvarray_type
== RPC_FC_C_WSTRING
))
3659 /* strings must always have null terminating bytes */
3660 if (bufsize
< esize
)
3662 ERR("invalid string length of %d\n", pStubMsg
->ActualCount
);
3663 RpcRaiseException(RPC_S_INVALID_BOUND
);
3666 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
3667 if (pStubMsg
->Buffer
[i
] != 0)
3669 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
3670 i
, pStubMsg
->Buffer
[i
]);
3671 RpcRaiseException(RPC_S_INVALID_BOUND
);
3676 /* copy the array data */
3677 safe_buffer_copy(pStubMsg
, *ppMemory
+ pCVStructFormat
->memory_size
, bufsize
);
3679 if (cvarray_type
== RPC_FC_C_CSTRING
)
3680 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory
+ pCVStructFormat
->memory_size
)));
3681 else if (cvarray_type
== RPC_FC_C_WSTRING
)
3682 TRACE("string=%s\n", debugstr_w((WCHAR
*)(*ppMemory
+ pCVStructFormat
->memory_size
)));
3684 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3689 /***********************************************************************
3690 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3692 void WINAPI
NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3693 unsigned char *pMemory
,
3694 PFORMAT_STRING pFormat
)
3696 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3697 PFORMAT_STRING pCVArrayFormat
;
3700 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3702 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3703 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3705 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3706 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3710 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3711 pCVStructFormat
->offset_to_array_description
;
3712 switch (*pCVArrayFormat
)
3714 case RPC_FC_CVARRAY
:
3715 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3717 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3718 pCVArrayFormat
+ 4, 0);
3719 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3722 case RPC_FC_C_CSTRING
:
3723 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
3724 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
3725 esize
= sizeof(char);
3726 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3727 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3728 pCVArrayFormat
+ 2, 0);
3730 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3732 case RPC_FC_C_WSTRING
:
3733 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
3734 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
3735 esize
= sizeof(WCHAR
);
3736 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3737 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3738 pCVArrayFormat
+ 2, 0);
3740 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3743 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3744 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3748 SizeConformance(pStubMsg
);
3750 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCVStructFormat
->alignment
+ 1);
3752 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3754 pStubMsg
->BufferLength
+= pCVStructFormat
->memory_size
;
3755 SizeVariance(pStubMsg
);
3756 pStubMsg
->BufferLength
+= safe_multiply(pStubMsg
->MaxCount
, esize
);
3758 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3761 /***********************************************************************
3762 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
3764 ULONG WINAPI
NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3765 PFORMAT_STRING pFormat
)
3767 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3768 PFORMAT_STRING pCVArrayFormat
;
3770 unsigned char cvarray_type
;
3772 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
3774 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3775 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3777 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3778 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3782 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3783 pCVStructFormat
->offset_to_array_description
;
3784 cvarray_type
= *pCVArrayFormat
;
3785 switch (cvarray_type
)
3787 case RPC_FC_CVARRAY
:
3788 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3789 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 4);
3791 case RPC_FC_C_CSTRING
:
3792 esize
= sizeof(char);
3793 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3794 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3796 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3798 case RPC_FC_C_WSTRING
:
3799 esize
= sizeof(WCHAR
);
3800 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3801 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3803 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3806 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3807 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3811 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
3813 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3815 pStubMsg
->Buffer
+= pCVStructFormat
->memory_size
;
3816 pCVArrayFormat
= ReadVariance(pStubMsg
, pCVArrayFormat
, pStubMsg
->MaxCount
);
3817 pStubMsg
->Buffer
+= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->ActualCount
);
3819 pStubMsg
->MemorySize
+= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->MaxCount
);
3821 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
3823 return pCVStructFormat
->memory_size
+ pStubMsg
->MaxCount
* esize
;
3826 /***********************************************************************
3827 * NdrConformantVaryingStructFree [RPCRT4.@]
3829 void WINAPI
NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3830 unsigned char *pMemory
,
3831 PFORMAT_STRING pFormat
)
3833 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3834 PFORMAT_STRING pCVArrayFormat
;
3837 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3839 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3840 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3842 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3843 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3847 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3848 pCVStructFormat
->offset_to_array_description
;
3849 switch (*pCVArrayFormat
)
3851 case RPC_FC_CVARRAY
:
3852 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3854 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3855 pCVArrayFormat
+ 4, 0);
3856 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3859 case RPC_FC_C_CSTRING
:
3860 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
3861 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
3862 esize
= sizeof(char);
3863 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3864 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3865 pCVArrayFormat
+ 2, 0);
3867 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3869 case RPC_FC_C_WSTRING
:
3870 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
3871 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
3872 esize
= sizeof(WCHAR
);
3873 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3874 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3875 pCVArrayFormat
+ 2, 0);
3877 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3880 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3881 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3885 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3887 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
3890 #include "pshpack1.h"
3894 unsigned char alignment
;
3895 unsigned short total_size
;
3896 } NDR_SMFARRAY_FORMAT
;
3901 unsigned char alignment
;
3902 unsigned long total_size
;
3903 } NDR_LGFARRAY_FORMAT
;
3904 #include "poppack.h"
3906 /***********************************************************************
3907 * NdrFixedArrayMarshall [RPCRT4.@]
3909 unsigned char * WINAPI
NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3910 unsigned char *pMemory
,
3911 PFORMAT_STRING pFormat
)
3913 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
3914 unsigned long total_size
;
3916 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3918 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
3919 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
3921 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
3922 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3926 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
3928 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
3930 total_size
= pSmFArrayFormat
->total_size
;
3931 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
3935 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
3936 total_size
= pLgFArrayFormat
->total_size
;
3937 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
3940 memcpy(pStubMsg
->Buffer
, pMemory
, total_size
);
3941 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3942 pStubMsg
->Buffer
+= total_size
;
3944 pFormat
= EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3949 /***********************************************************************
3950 * NdrFixedArrayUnmarshall [RPCRT4.@]
3952 unsigned char * WINAPI
NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3953 unsigned char **ppMemory
,
3954 PFORMAT_STRING pFormat
,
3955 unsigned char fMustAlloc
)
3957 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
3958 unsigned long total_size
;
3960 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3962 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
3963 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
3965 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
3966 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3970 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
3972 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
3974 total_size
= pSmFArrayFormat
->total_size
;
3975 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
3979 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
3980 total_size
= pLgFArrayFormat
->total_size
;
3981 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
3984 if (fMustAlloc
|| !*ppMemory
)
3985 *ppMemory
= NdrAllocate(pStubMsg
, total_size
);
3986 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3987 safe_buffer_copy(pStubMsg
, *ppMemory
, total_size
);
3989 pFormat
= EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3994 /***********************************************************************
3995 * NdrFixedArrayBufferSize [RPCRT4.@]
3997 void WINAPI
NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3998 unsigned char *pMemory
,
3999 PFORMAT_STRING pFormat
)
4001 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4002 unsigned long total_size
;
4004 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4006 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4007 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4009 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4010 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4014 ALIGN_LENGTH(pStubMsg
->BufferLength
, pSmFArrayFormat
->alignment
+ 1);
4016 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4018 total_size
= pSmFArrayFormat
->total_size
;
4019 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4023 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4024 total_size
= pLgFArrayFormat
->total_size
;
4025 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4027 pStubMsg
->BufferLength
+= total_size
;
4029 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4032 /***********************************************************************
4033 * NdrFixedArrayMemorySize [RPCRT4.@]
4035 ULONG WINAPI
NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4036 PFORMAT_STRING pFormat
)
4038 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4041 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4043 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4044 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4046 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4047 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4051 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4053 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4055 total_size
= pSmFArrayFormat
->total_size
;
4056 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4060 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4061 total_size
= pLgFArrayFormat
->total_size
;
4062 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4064 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4065 pStubMsg
->Buffer
+= total_size
;
4066 pStubMsg
->MemorySize
+= total_size
;
4068 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4073 /***********************************************************************
4074 * NdrFixedArrayFree [RPCRT4.@]
4076 void WINAPI
NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4077 unsigned char *pMemory
,
4078 PFORMAT_STRING pFormat
)
4080 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4082 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4084 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4085 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4087 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4088 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4092 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4093 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4096 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4097 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4100 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4103 /***********************************************************************
4104 * NdrVaryingArrayMarshall [RPCRT4.@]
4106 unsigned char * WINAPI
NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4107 unsigned char *pMemory
,
4108 PFORMAT_STRING pFormat
)
4110 unsigned char alignment
;
4111 DWORD elements
, esize
;
4114 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4116 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4117 (pFormat
[0] != RPC_FC_LGVARRAY
))
4119 ERR("invalid format type %x\n", pFormat
[0]);
4120 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4124 alignment
= pFormat
[1] + 1;
4126 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4129 pFormat
+= sizeof(WORD
);
4130 elements
= *(const WORD
*)pFormat
;
4131 pFormat
+= sizeof(WORD
);
4136 pFormat
+= sizeof(DWORD
);
4137 elements
= *(const DWORD
*)pFormat
;
4138 pFormat
+= sizeof(DWORD
);
4141 esize
= *(const WORD
*)pFormat
;
4142 pFormat
+= sizeof(WORD
);
4144 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4145 if ((pStubMsg
->ActualCount
> elements
) ||
4146 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4148 RpcRaiseException(RPC_S_INVALID_BOUND
);
4152 WriteVariance(pStubMsg
);
4154 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4156 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4157 memcpy(pStubMsg
->Buffer
, pMemory
+ pStubMsg
->Offset
, bufsize
);
4158 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4159 pStubMsg
->Buffer
+= bufsize
;
4161 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4163 STD_OVERFLOW_CHECK(pStubMsg
);
4168 /***********************************************************************
4169 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4171 unsigned char * WINAPI
NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4172 unsigned char **ppMemory
,
4173 PFORMAT_STRING pFormat
,
4174 unsigned char fMustAlloc
)
4176 unsigned char alignment
;
4177 DWORD size
, elements
, esize
;
4180 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4182 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4183 (pFormat
[0] != RPC_FC_LGVARRAY
))
4185 ERR("invalid format type %x\n", pFormat
[0]);
4186 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4190 alignment
= pFormat
[1] + 1;
4192 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4195 size
= *(const WORD
*)pFormat
;
4196 pFormat
+= sizeof(WORD
);
4197 elements
= *(const WORD
*)pFormat
;
4198 pFormat
+= sizeof(WORD
);
4203 size
= *(const DWORD
*)pFormat
;
4204 pFormat
+= sizeof(DWORD
);
4205 elements
= *(const DWORD
*)pFormat
;
4206 pFormat
+= sizeof(DWORD
);
4209 esize
= *(const WORD
*)pFormat
;
4210 pFormat
+= sizeof(WORD
);
4212 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
4214 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4216 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4218 if (!*ppMemory
|| fMustAlloc
)
4219 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4220 safe_buffer_copy(pStubMsg
, *ppMemory
+ pStubMsg
->Offset
, bufsize
);
4222 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4227 /***********************************************************************
4228 * NdrVaryingArrayBufferSize [RPCRT4.@]
4230 void WINAPI
NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4231 unsigned char *pMemory
,
4232 PFORMAT_STRING pFormat
)
4234 unsigned char alignment
;
4235 DWORD elements
, esize
;
4237 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4239 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4240 (pFormat
[0] != RPC_FC_LGVARRAY
))
4242 ERR("invalid format type %x\n", pFormat
[0]);
4243 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4247 alignment
= pFormat
[1] + 1;
4249 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4252 pFormat
+= sizeof(WORD
);
4253 elements
= *(const WORD
*)pFormat
;
4254 pFormat
+= sizeof(WORD
);
4259 pFormat
+= sizeof(DWORD
);
4260 elements
= *(const DWORD
*)pFormat
;
4261 pFormat
+= sizeof(DWORD
);
4264 esize
= *(const WORD
*)pFormat
;
4265 pFormat
+= sizeof(WORD
);
4267 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4268 if ((pStubMsg
->ActualCount
> elements
) ||
4269 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4271 RpcRaiseException(RPC_S_INVALID_BOUND
);
4275 SizeVariance(pStubMsg
);
4277 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
4279 pStubMsg
->BufferLength
+= safe_multiply(esize
, pStubMsg
->ActualCount
);
4281 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4284 /***********************************************************************
4285 * NdrVaryingArrayMemorySize [RPCRT4.@]
4287 ULONG WINAPI
NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4288 PFORMAT_STRING pFormat
)
4290 unsigned char alignment
;
4291 DWORD size
, elements
, esize
;
4293 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4295 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4296 (pFormat
[0] != RPC_FC_LGVARRAY
))
4298 ERR("invalid format type %x\n", pFormat
[0]);
4299 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4303 alignment
= pFormat
[1] + 1;
4305 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4308 size
= *(const WORD
*)pFormat
;
4309 pFormat
+= sizeof(WORD
);
4310 elements
= *(const WORD
*)pFormat
;
4311 pFormat
+= sizeof(WORD
);
4316 size
= *(const DWORD
*)pFormat
;
4317 pFormat
+= sizeof(DWORD
);
4318 elements
= *(const DWORD
*)pFormat
;
4319 pFormat
+= sizeof(DWORD
);
4322 esize
= *(const WORD
*)pFormat
;
4323 pFormat
+= sizeof(WORD
);
4325 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
4327 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4329 pStubMsg
->Buffer
+= safe_multiply(esize
, pStubMsg
->ActualCount
);
4330 pStubMsg
->MemorySize
+= size
;
4332 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4334 return pStubMsg
->MemorySize
;
4337 /***********************************************************************
4338 * NdrVaryingArrayFree [RPCRT4.@]
4340 void WINAPI
NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4341 unsigned char *pMemory
,
4342 PFORMAT_STRING pFormat
)
4344 unsigned char alignment
;
4347 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4349 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4350 (pFormat
[0] != RPC_FC_LGVARRAY
))
4352 ERR("invalid format type %x\n", pFormat
[0]);
4353 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4357 alignment
= pFormat
[1] + 1;
4359 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4362 pFormat
+= sizeof(WORD
);
4363 elements
= *(const WORD
*)pFormat
;
4364 pFormat
+= sizeof(WORD
);
4369 pFormat
+= sizeof(DWORD
);
4370 elements
= *(const DWORD
*)pFormat
;
4371 pFormat
+= sizeof(DWORD
);
4374 pFormat
+= sizeof(WORD
);
4376 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4377 if ((pStubMsg
->ActualCount
> elements
) ||
4378 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4380 RpcRaiseException(RPC_S_INVALID_BOUND
);
4384 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4387 static ULONG
get_discriminant(unsigned char fc
, const unsigned char *pMemory
)
4395 return *(const UCHAR
*)pMemory
;
4400 return *(const USHORT
*)pMemory
;
4404 return *(const ULONG
*)pMemory
;
4406 FIXME("Unhandled base type: 0x%02x\n", fc
);
4411 static PFORMAT_STRING
get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg
,
4412 unsigned long discriminant
,
4413 PFORMAT_STRING pFormat
)
4415 unsigned short num_arms
, arm
, type
;
4417 num_arms
= *(const SHORT
*)pFormat
& 0x0fff;
4419 for(arm
= 0; arm
< num_arms
; arm
++)
4421 if(discriminant
== *(const ULONG
*)pFormat
)
4429 type
= *(const unsigned short*)pFormat
;
4430 TRACE("type %04x\n", type
);
4431 if(arm
== num_arms
) /* default arm extras */
4435 ERR("no arm for 0x%lx and no default case\n", discriminant
);
4436 RpcRaiseException(RPC_S_INVALID_TAG
);
4441 TRACE("falling back to empty default case for 0x%lx\n", discriminant
);
4448 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
, ULONG discriminant
, PFORMAT_STRING pFormat
)
4450 unsigned short type
;
4454 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4458 type
= *(const unsigned short*)pFormat
;
4459 if((type
& 0xff00) == 0x8000)
4461 unsigned char basetype
= LOBYTE(type
);
4462 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &basetype
);
4466 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4467 NDR_MARSHALL m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
4470 unsigned char *saved_buffer
= NULL
;
4471 int pointer_buffer_mark_set
= 0;
4478 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4479 saved_buffer
= pStubMsg
->Buffer
;
4480 if (pStubMsg
->PointerBufferMark
)
4482 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4483 pStubMsg
->PointerBufferMark
= NULL
;
4484 pointer_buffer_mark_set
= 1;
4487 pStubMsg
->Buffer
+= 4; /* for pointer ID */
4489 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char **)pMemory
, desc
);
4490 if (pointer_buffer_mark_set
)
4492 STD_OVERFLOW_CHECK(pStubMsg
);
4493 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4494 pStubMsg
->Buffer
= saved_buffer
+ 4;
4498 m(pStubMsg
, pMemory
, desc
);
4501 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4506 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4507 unsigned char **ppMemory
,
4509 PFORMAT_STRING pFormat
,
4510 unsigned char fMustAlloc
)
4512 unsigned short type
;
4516 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4520 type
= *(const unsigned short*)pFormat
;
4521 if((type
& 0xff00) == 0x8000)
4523 unsigned char basetype
= LOBYTE(type
);
4524 return NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &basetype
, FALSE
);
4528 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4529 NDR_UNMARSHALL m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
4532 unsigned char *saved_buffer
= NULL
;
4533 int pointer_buffer_mark_set
= 0;
4540 **(void***)ppMemory
= NULL
;
4541 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4542 saved_buffer
= pStubMsg
->Buffer
;
4543 if (pStubMsg
->PointerBufferMark
)
4545 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4546 pStubMsg
->PointerBufferMark
= NULL
;
4547 pointer_buffer_mark_set
= 1;
4550 pStubMsg
->Buffer
+= 4; /* for pointer ID */
4552 if (saved_buffer
+ 4 > pStubMsg
->BufferEnd
)
4553 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4555 PointerUnmarshall(pStubMsg
, saved_buffer
, *(unsigned char ***)ppMemory
, desc
, fMustAlloc
);
4556 if (pointer_buffer_mark_set
)
4558 STD_OVERFLOW_CHECK(pStubMsg
);
4559 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4560 pStubMsg
->Buffer
= saved_buffer
+ 4;
4564 m(pStubMsg
, ppMemory
, desc
, fMustAlloc
);
4567 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4572 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg
,
4573 unsigned char *pMemory
,
4575 PFORMAT_STRING pFormat
)
4577 unsigned short type
;
4581 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4585 type
= *(const unsigned short*)pFormat
;
4586 if((type
& 0xff00) == 0x8000)
4588 unsigned char basetype
= LOBYTE(type
);
4589 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &basetype
);
4593 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4594 NDR_BUFFERSIZE m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
4603 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
4604 pStubMsg
->BufferLength
+= 4; /* for pointer ID */
4605 if (!pStubMsg
->IgnoreEmbeddedPointers
)
4607 int saved_buffer_length
= pStubMsg
->BufferLength
;
4608 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4609 pStubMsg
->PointerLength
= 0;
4610 if(!pStubMsg
->BufferLength
)
4611 ERR("BufferLength == 0??\n");
4612 PointerBufferSize(pStubMsg
, *(unsigned char **)pMemory
, desc
);
4613 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4614 pStubMsg
->BufferLength
= saved_buffer_length
;
4618 m(pStubMsg
, pMemory
, desc
);
4621 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
4625 static ULONG
union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg
,
4627 PFORMAT_STRING pFormat
)
4629 unsigned short type
, size
;
4631 size
= *(const unsigned short*)pFormat
;
4632 pStubMsg
->Memory
+= size
;
4635 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4639 type
= *(const unsigned short*)pFormat
;
4640 if((type
& 0xff00) == 0x8000)
4642 return NdrBaseTypeMemorySize(pStubMsg
, pFormat
);
4646 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4647 NDR_MEMORYSIZE m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
4648 unsigned char *saved_buffer
;
4657 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4658 saved_buffer
= pStubMsg
->Buffer
;
4659 pStubMsg
->Buffer
+= 4;
4660 ALIGN_LENGTH(pStubMsg
->MemorySize
, 4);
4661 pStubMsg
->MemorySize
+= 4;
4662 if (!pStubMsg
->IgnoreEmbeddedPointers
)
4663 PointerMemorySize(pStubMsg
, saved_buffer
, pFormat
);
4666 return m(pStubMsg
, desc
);
4669 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4672 TRACE("size %d\n", size
);
4676 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg
,
4677 unsigned char *pMemory
,
4679 PFORMAT_STRING pFormat
)
4681 unsigned short type
;
4685 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4689 type
= *(const unsigned short*)pFormat
;
4690 if((type
& 0xff00) != 0x8000)
4692 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4693 NDR_FREE m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
4702 PointerFree(pStubMsg
, *(unsigned char **)pMemory
, desc
);
4705 m(pStubMsg
, pMemory
, desc
);
4708 else FIXME("no freer for embedded type %02x\n", *desc
);
4712 /***********************************************************************
4713 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
4715 unsigned char * WINAPI
NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4716 unsigned char *pMemory
,
4717 PFORMAT_STRING pFormat
)
4719 unsigned char switch_type
;
4720 unsigned char increment
;
4723 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4726 switch_type
= *pFormat
& 0xf;
4727 increment
= (*pFormat
& 0xf0) >> 4;
4730 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
4732 switch_value
= get_discriminant(switch_type
, pMemory
);
4733 TRACE("got switch value 0x%x\n", switch_value
);
4735 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &switch_type
);
4736 pMemory
+= increment
;
4738 return union_arm_marshall(pStubMsg
, pMemory
, switch_value
, pFormat
);
4741 /***********************************************************************
4742 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
4744 unsigned char * WINAPI
NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4745 unsigned char **ppMemory
,
4746 PFORMAT_STRING pFormat
,
4747 unsigned char fMustAlloc
)
4749 unsigned char switch_type
;
4750 unsigned char increment
;
4752 unsigned short size
;
4753 unsigned char *pMemoryArm
;
4755 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4758 switch_type
= *pFormat
& 0xf;
4759 increment
= (*pFormat
& 0xf0) >> 4;
4762 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
4763 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
4764 TRACE("got switch value 0x%x\n", switch_value
);
4766 size
= *(const unsigned short*)pFormat
+ increment
;
4767 if(!*ppMemory
|| fMustAlloc
)
4768 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4770 NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &switch_type
, FALSE
);
4771 pMemoryArm
= *ppMemory
+ increment
;
4773 return union_arm_unmarshall(pStubMsg
, &pMemoryArm
, switch_value
, pFormat
, fMustAlloc
);
4776 /***********************************************************************
4777 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
4779 void WINAPI
NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4780 unsigned char *pMemory
,
4781 PFORMAT_STRING pFormat
)
4783 unsigned char switch_type
;
4784 unsigned char increment
;
4787 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4790 switch_type
= *pFormat
& 0xf;
4791 increment
= (*pFormat
& 0xf0) >> 4;
4794 ALIGN_LENGTH(pStubMsg
->BufferLength
, increment
);
4795 switch_value
= get_discriminant(switch_type
, pMemory
);
4796 TRACE("got switch value 0x%x\n", switch_value
);
4798 /* Add discriminant size */
4799 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&switch_value
, &switch_type
);
4800 pMemory
+= increment
;
4802 union_arm_buffer_size(pStubMsg
, pMemory
, switch_value
, pFormat
);
4805 /***********************************************************************
4806 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
4808 ULONG WINAPI
NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4809 PFORMAT_STRING pFormat
)
4811 unsigned char switch_type
;
4812 unsigned char increment
;
4815 switch_type
= *pFormat
& 0xf;
4816 increment
= (*pFormat
& 0xf0) >> 4;
4819 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
4820 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
4821 TRACE("got switch value 0x%x\n", switch_value
);
4823 pStubMsg
->Memory
+= increment
;
4825 return increment
+ union_arm_memory_size(pStubMsg
, switch_value
, pFormat
+ *(const SHORT
*)pFormat
);
4828 /***********************************************************************
4829 * NdrEncapsulatedUnionFree [RPCRT4.@]
4831 void WINAPI
NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
4832 unsigned char *pMemory
,
4833 PFORMAT_STRING pFormat
)
4835 unsigned char switch_type
;
4836 unsigned char increment
;
4839 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4842 switch_type
= *pFormat
& 0xf;
4843 increment
= (*pFormat
& 0xf0) >> 4;
4846 switch_value
= get_discriminant(switch_type
, pMemory
);
4847 TRACE("got switch value 0x%x\n", switch_value
);
4849 pMemory
+= increment
;
4851 return union_arm_free(pStubMsg
, pMemory
, switch_value
, pFormat
);
4854 /***********************************************************************
4855 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
4857 unsigned char * WINAPI
NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4858 unsigned char *pMemory
,
4859 PFORMAT_STRING pFormat
)
4861 unsigned char switch_type
;
4863 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4866 switch_type
= *pFormat
;
4869 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
4870 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
4871 /* Marshall discriminant */
4872 NdrBaseTypeMarshall(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
4874 return union_arm_marshall(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
4877 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg
,
4878 PFORMAT_STRING
*ppFormat
)
4880 long discriminant
= 0;
4890 safe_buffer_copy(pStubMsg
, &d
, sizeof(d
));
4899 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
4900 safe_buffer_copy(pStubMsg
, &d
, sizeof(d
));
4908 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
4909 safe_buffer_copy(pStubMsg
, &d
, sizeof(d
));
4914 FIXME("Unhandled base type: 0x%02x\n", **ppFormat
);
4918 if (pStubMsg
->fHasNewCorrDesc
)
4922 return discriminant
;
4925 /**********************************************************************
4926 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
4928 unsigned char * WINAPI
NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4929 unsigned char **ppMemory
,
4930 PFORMAT_STRING pFormat
,
4931 unsigned char fMustAlloc
)
4934 unsigned short size
;
4936 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4939 /* Unmarshall discriminant */
4940 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
4941 TRACE("unmarshalled discriminant %lx\n", discriminant
);
4943 pFormat
+= *(const SHORT
*)pFormat
;
4945 size
= *(const unsigned short*)pFormat
;
4947 if(!*ppMemory
|| fMustAlloc
)
4948 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4950 return union_arm_unmarshall(pStubMsg
, ppMemory
, discriminant
, pFormat
, fMustAlloc
);
4953 /***********************************************************************
4954 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
4956 void WINAPI
NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4957 unsigned char *pMemory
,
4958 PFORMAT_STRING pFormat
)
4960 unsigned char switch_type
;
4962 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4965 switch_type
= *pFormat
;
4968 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
4969 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
4970 /* Add discriminant size */
4971 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
4973 union_arm_buffer_size(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
4976 /***********************************************************************
4977 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
4979 ULONG WINAPI
NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4980 PFORMAT_STRING pFormat
)
4985 /* Unmarshall discriminant */
4986 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
4987 TRACE("unmarshalled discriminant 0x%x\n", discriminant
);
4989 return union_arm_memory_size(pStubMsg
, discriminant
, pFormat
+ *(const SHORT
*)pFormat
);
4992 /***********************************************************************
4993 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
4995 void WINAPI
NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
4996 unsigned char *pMemory
,
4997 PFORMAT_STRING pFormat
)
4999 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5003 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5004 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5006 return union_arm_free(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5009 /***********************************************************************
5010 * NdrByteCountPointerMarshall [RPCRT4.@]
5012 unsigned char * WINAPI
NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5013 unsigned char *pMemory
,
5014 PFORMAT_STRING pFormat
)
5020 /***********************************************************************
5021 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5023 unsigned char * WINAPI
NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5024 unsigned char **ppMemory
,
5025 PFORMAT_STRING pFormat
,
5026 unsigned char fMustAlloc
)
5032 /***********************************************************************
5033 * NdrByteCountPointerBufferSize [RPCRT4.@]
5035 void WINAPI
NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5036 unsigned char *pMemory
,
5037 PFORMAT_STRING pFormat
)
5042 /***********************************************************************
5043 * NdrByteCountPointerMemorySize [RPCRT4.@]
5045 ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5046 PFORMAT_STRING pFormat
)
5052 /***********************************************************************
5053 * NdrByteCountPointerFree [RPCRT4.@]
5055 void WINAPI
NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
5056 unsigned char *pMemory
,
5057 PFORMAT_STRING pFormat
)
5062 /***********************************************************************
5063 * NdrXmitOrRepAsMarshall [RPCRT4.@]
5065 unsigned char * WINAPI
NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5066 unsigned char *pMemory
,
5067 PFORMAT_STRING pFormat
)
5073 /***********************************************************************
5074 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
5076 unsigned char * WINAPI
NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5077 unsigned char **ppMemory
,
5078 PFORMAT_STRING pFormat
,
5079 unsigned char fMustAlloc
)
5085 /***********************************************************************
5086 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
5088 void WINAPI
NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5089 unsigned char *pMemory
,
5090 PFORMAT_STRING pFormat
)
5095 /***********************************************************************
5096 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
5098 ULONG WINAPI
NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5099 PFORMAT_STRING pFormat
)
5105 /***********************************************************************
5106 * NdrXmitOrRepAsFree [RPCRT4.@]
5108 void WINAPI
NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg
,
5109 unsigned char *pMemory
,
5110 PFORMAT_STRING pFormat
)
5115 #include "pshpack1.h"
5119 unsigned char flags_type
; /* flags in upper nibble, type in lower nibble */
5123 #include "poppack.h"
5125 /***********************************************************************
5126 * NdrRangeMarshall [internal]
5128 unsigned char *WINAPI
NdrRangeMarshall(
5129 PMIDL_STUB_MESSAGE pStubMsg
,
5130 unsigned char *pMemory
,
5131 PFORMAT_STRING pFormat
)
5133 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5134 unsigned char base_type
;
5136 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5138 if (pRange
->type
!= RPC_FC_RANGE
)
5140 ERR("invalid format type %x\n", pRange
->type
);
5141 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5145 base_type
= pRange
->flags_type
& 0xf;
5147 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &base_type
);
5150 /***********************************************************************
5151 * NdrRangeUnmarshall
5153 unsigned char *WINAPI
NdrRangeUnmarshall(
5154 PMIDL_STUB_MESSAGE pStubMsg
,
5155 unsigned char **ppMemory
,
5156 PFORMAT_STRING pFormat
,
5157 unsigned char fMustAlloc
)
5159 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5160 unsigned char base_type
;
5162 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
5164 if (pRange
->type
!= RPC_FC_RANGE
)
5166 ERR("invalid format type %x\n", pRange
->type
);
5167 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5170 base_type
= pRange
->flags_type
& 0xf;
5172 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5173 base_type
, pRange
->low_value
, pRange
->high_value
);
5175 #define RANGE_UNMARSHALL(type, format_spec) \
5178 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5179 if (fMustAlloc || !*ppMemory) \
5180 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5181 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5182 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5184 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5185 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5186 (type)pRange->high_value); \
5187 RpcRaiseException(RPC_S_INVALID_BOUND); \
5190 TRACE("*ppMemory: %p\n", *ppMemory); \
5191 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5192 pStubMsg->Buffer += sizeof(type); \
5199 RANGE_UNMARSHALL(UCHAR
, "%d");
5200 TRACE("value: 0x%02x\n", **(UCHAR
**)ppMemory
);
5204 RANGE_UNMARSHALL(CHAR
, "%u");
5205 TRACE("value: 0x%02x\n", **(UCHAR
**)ppMemory
);
5207 case RPC_FC_WCHAR
: /* FIXME: valid? */
5209 RANGE_UNMARSHALL(USHORT
, "%u");
5210 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5213 RANGE_UNMARSHALL(SHORT
, "%d");
5214 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5217 RANGE_UNMARSHALL(LONG
, "%d");
5218 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5221 RANGE_UNMARSHALL(ULONG
, "%u");
5222 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5226 FIXME("Unhandled enum type\n");
5228 case RPC_FC_ERROR_STATUS_T
: /* FIXME: valid? */
5233 ERR("invalid range base type: 0x%02x\n", base_type
);
5234 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5240 /***********************************************************************
5241 * NdrRangeBufferSize [internal]
5243 void WINAPI
NdrRangeBufferSize(
5244 PMIDL_STUB_MESSAGE pStubMsg
,
5245 unsigned char *pMemory
,
5246 PFORMAT_STRING pFormat
)
5248 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5249 unsigned char base_type
;
5251 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5253 if (pRange
->type
!= RPC_FC_RANGE
)
5255 ERR("invalid format type %x\n", pRange
->type
);
5256 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5258 base_type
= pRange
->flags_type
& 0xf;
5260 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &base_type
);
5263 /***********************************************************************
5264 * NdrRangeMemorySize [internal]
5266 ULONG WINAPI
NdrRangeMemorySize(
5267 PMIDL_STUB_MESSAGE pStubMsg
,
5268 PFORMAT_STRING pFormat
)
5270 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5271 unsigned char base_type
;
5273 if (pRange
->type
!= RPC_FC_RANGE
)
5275 ERR("invalid format type %x\n", pRange
->type
);
5276 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5279 base_type
= pRange
->flags_type
& 0xf;
5281 return NdrBaseTypeMemorySize(pStubMsg
, &base_type
);
5284 /***********************************************************************
5285 * NdrRangeFree [internal]
5287 void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg
,
5288 unsigned char *pMemory
,
5289 PFORMAT_STRING pFormat
)
5291 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5296 /***********************************************************************
5297 * NdrBaseTypeMarshall [internal]
5299 static unsigned char *WINAPI
NdrBaseTypeMarshall(
5300 PMIDL_STUB_MESSAGE pStubMsg
,
5301 unsigned char *pMemory
,
5302 PFORMAT_STRING pFormat
)
5304 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5312 *(UCHAR
*)pStubMsg
->Buffer
= *(UCHAR
*)pMemory
;
5313 pStubMsg
->Buffer
+= sizeof(UCHAR
);
5314 TRACE("value: 0x%02x\n", *(UCHAR
*)pMemory
);
5319 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5320 *(USHORT
*)pStubMsg
->Buffer
= *(USHORT
*)pMemory
;
5321 pStubMsg
->Buffer
+= sizeof(USHORT
);
5322 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
5326 case RPC_FC_ERROR_STATUS_T
:
5328 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
5329 *(ULONG
*)pStubMsg
->Buffer
= *(ULONG
*)pMemory
;
5330 pStubMsg
->Buffer
+= sizeof(ULONG
);
5331 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
5334 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(float));
5335 *(float *)pStubMsg
->Buffer
= *(float *)pMemory
;
5336 pStubMsg
->Buffer
+= sizeof(float);
5339 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(double));
5340 *(double *)pStubMsg
->Buffer
= *(double *)pMemory
;
5341 pStubMsg
->Buffer
+= sizeof(double);
5344 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONGLONG
));
5345 *(ULONGLONG
*)pStubMsg
->Buffer
= *(ULONGLONG
*)pMemory
;
5346 pStubMsg
->Buffer
+= sizeof(ULONGLONG
);
5347 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
5350 /* only 16-bits on the wire, so do a sanity check */
5351 if (*(UINT
*)pMemory
> SHRT_MAX
)
5352 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
5353 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5354 *(USHORT
*)pStubMsg
->Buffer
= *(UINT
*)pMemory
;
5355 pStubMsg
->Buffer
+= sizeof(USHORT
);
5356 TRACE("value: 0x%04x\n", *(UINT
*)pMemory
);
5359 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5362 STD_OVERFLOW_CHECK(pStubMsg
);
5364 /* FIXME: what is the correct return value? */
5368 /***********************************************************************
5369 * NdrBaseTypeUnmarshall [internal]
5371 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(
5372 PMIDL_STUB_MESSAGE pStubMsg
,
5373 unsigned char **ppMemory
,
5374 PFORMAT_STRING pFormat
,
5375 unsigned char fMustAlloc
)
5377 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
5379 #define BASE_TYPE_UNMARSHALL(type) \
5380 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5381 if (fMustAlloc || !*ppMemory) \
5382 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5383 TRACE("*ppMemory: %p\n", *ppMemory); \
5384 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5385 pStubMsg->Buffer += sizeof(type);
5393 BASE_TYPE_UNMARSHALL(UCHAR
);
5394 TRACE("value: 0x%02x\n", **(UCHAR
**)ppMemory
);
5399 BASE_TYPE_UNMARSHALL(USHORT
);
5400 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5404 case RPC_FC_ERROR_STATUS_T
:
5406 BASE_TYPE_UNMARSHALL(ULONG
);
5407 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5410 BASE_TYPE_UNMARSHALL(float);
5411 TRACE("value: %f\n", **(float **)ppMemory
);
5414 BASE_TYPE_UNMARSHALL(double);
5415 TRACE("value: %f\n", **(double **)ppMemory
);
5418 BASE_TYPE_UNMARSHALL(ULONGLONG
);
5419 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG
**)ppMemory
));
5422 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5423 if (fMustAlloc
|| !*ppMemory
)
5424 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT
));
5425 TRACE("*ppMemory: %p\n", *ppMemory
);
5426 /* 16-bits on the wire, but int in memory */
5427 **(UINT
**)ppMemory
= *(USHORT
*)pStubMsg
->Buffer
;
5428 pStubMsg
->Buffer
+= sizeof(USHORT
);
5429 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
5432 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5434 #undef BASE_TYPE_UNMARSHALL
5436 /* FIXME: what is the correct return value? */
5441 /***********************************************************************
5442 * NdrBaseTypeBufferSize [internal]
5444 static void WINAPI
NdrBaseTypeBufferSize(
5445 PMIDL_STUB_MESSAGE pStubMsg
,
5446 unsigned char *pMemory
,
5447 PFORMAT_STRING pFormat
)
5449 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5457 pStubMsg
->BufferLength
+= sizeof(UCHAR
);
5463 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(USHORT
));
5464 pStubMsg
->BufferLength
+= sizeof(USHORT
);
5469 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONG
));
5470 pStubMsg
->BufferLength
+= sizeof(ULONG
);
5473 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(float));
5474 pStubMsg
->BufferLength
+= sizeof(float);
5477 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(double));
5478 pStubMsg
->BufferLength
+= sizeof(double);
5481 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONGLONG
));
5482 pStubMsg
->BufferLength
+= sizeof(ULONGLONG
);
5484 case RPC_FC_ERROR_STATUS_T
:
5485 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(error_status_t
));
5486 pStubMsg
->BufferLength
+= sizeof(error_status_t
);
5489 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5493 /***********************************************************************
5494 * NdrBaseTypeMemorySize [internal]
5496 static ULONG WINAPI
NdrBaseTypeMemorySize(
5497 PMIDL_STUB_MESSAGE pStubMsg
,
5498 PFORMAT_STRING pFormat
)
5506 pStubMsg
->Buffer
+= sizeof(UCHAR
);
5507 pStubMsg
->MemorySize
+= sizeof(UCHAR
);
5508 return sizeof(UCHAR
);
5512 pStubMsg
->Buffer
+= sizeof(USHORT
);
5513 pStubMsg
->MemorySize
+= sizeof(USHORT
);
5514 return sizeof(USHORT
);
5517 pStubMsg
->Buffer
+= sizeof(ULONG
);
5518 pStubMsg
->MemorySize
+= sizeof(ULONG
);
5519 return sizeof(ULONG
);
5521 pStubMsg
->Buffer
+= sizeof(float);
5522 pStubMsg
->MemorySize
+= sizeof(float);
5523 return sizeof(float);
5525 pStubMsg
->Buffer
+= sizeof(double);
5526 pStubMsg
->MemorySize
+= sizeof(double);
5527 return sizeof(double);
5529 pStubMsg
->Buffer
+= sizeof(ULONGLONG
);
5530 pStubMsg
->MemorySize
+= sizeof(ULONGLONG
);
5531 return sizeof(ULONGLONG
);
5532 case RPC_FC_ERROR_STATUS_T
:
5533 pStubMsg
->Buffer
+= sizeof(error_status_t
);
5534 pStubMsg
->MemorySize
+= sizeof(error_status_t
);
5535 return sizeof(error_status_t
);
5538 pStubMsg
->Buffer
+= sizeof(INT
);
5539 pStubMsg
->MemorySize
+= sizeof(INT
);
5542 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5547 /***********************************************************************
5548 * NdrBaseTypeFree [internal]
5550 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg
,
5551 unsigned char *pMemory
,
5552 PFORMAT_STRING pFormat
)
5554 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5559 /***********************************************************************
5560 * NdrContextHandleBufferSize [internal]
5562 static void WINAPI
NdrContextHandleBufferSize(
5563 PMIDL_STUB_MESSAGE pStubMsg
,
5564 unsigned char *pMemory
,
5565 PFORMAT_STRING pFormat
)
5567 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5569 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
5571 ERR("invalid format type %x\n", *pFormat
);
5572 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5574 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
5575 pStubMsg
->BufferLength
+= cbNDRContext
;
5578 /***********************************************************************
5579 * NdrContextHandleMarshall [internal]
5581 static unsigned char *WINAPI
NdrContextHandleMarshall(
5582 PMIDL_STUB_MESSAGE pStubMsg
,
5583 unsigned char *pMemory
,
5584 PFORMAT_STRING pFormat
)
5586 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5588 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
5590 ERR("invalid format type %x\n", *pFormat
);
5591 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5594 if (pFormat
[1] & 0x80)
5595 NdrClientContextMarshall(pStubMsg
, *(NDR_CCONTEXT
**)pMemory
, FALSE
);
5597 NdrClientContextMarshall(pStubMsg
, (NDR_CCONTEXT
*)pMemory
, FALSE
);
5602 /***********************************************************************
5603 * NdrContextHandleUnmarshall [internal]
5605 static unsigned char *WINAPI
NdrContextHandleUnmarshall(
5606 PMIDL_STUB_MESSAGE pStubMsg
,
5607 unsigned char **ppMemory
,
5608 PFORMAT_STRING pFormat
,
5609 unsigned char fMustAlloc
)
5611 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
5613 ERR("invalid format type %x\n", *pFormat
);
5614 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5617 **(NDR_CCONTEXT
**)ppMemory
= NULL
;
5618 NdrClientContextUnmarshall(pStubMsg
, *(NDR_CCONTEXT
**)ppMemory
, pStubMsg
->RpcMsg
->Handle
);
5623 /***********************************************************************
5624 * NdrClientContextMarshall [RPCRT4.@]
5626 void WINAPI
NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5627 NDR_CCONTEXT ContextHandle
,
5630 TRACE("(%p, %p, %d)\n", pStubMsg
, ContextHandle
, fCheck
);
5632 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5634 /* FIXME: what does fCheck do? */
5635 NDRCContextMarshall(ContextHandle
,
5638 pStubMsg
->Buffer
+= cbNDRContext
;
5641 /***********************************************************************
5642 * NdrClientContextUnmarshall [RPCRT4.@]
5644 void WINAPI
NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5645 NDR_CCONTEXT
* pContextHandle
,
5646 RPC_BINDING_HANDLE BindHandle
)
5648 TRACE("(%p, %p, %p)\n", pStubMsg
, pContextHandle
, BindHandle
);
5650 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5652 if (pStubMsg
->Buffer
+ cbNDRContext
> pStubMsg
->BufferEnd
)
5653 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5655 NDRCContextUnmarshall(pContextHandle
,
5658 pStubMsg
->RpcMsg
->DataRepresentation
);
5660 pStubMsg
->Buffer
+= cbNDRContext
;
5663 void WINAPI
NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5664 NDR_SCONTEXT ContextHandle
,
5665 NDR_RUNDOWN RundownRoutine
)
5667 FIXME("(%p, %p, %p): stub\n", pStubMsg
, ContextHandle
, RundownRoutine
);
5670 NDR_SCONTEXT WINAPI
NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
)
5672 FIXME("(%p): stub\n", pStubMsg
);
5676 void WINAPI
NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg
,
5677 unsigned char* pMemory
,
5678 PFORMAT_STRING pFormat
)
5680 FIXME("(%p, %p, %p): stub\n", pStubMsg
, pMemory
, pFormat
);
5683 NDR_SCONTEXT WINAPI
NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg
,
5684 PFORMAT_STRING pFormat
)
5686 FIXME("(%p, %p): stub\n", pStubMsg
, pFormat
);
5690 void WINAPI
NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5691 NDR_SCONTEXT ContextHandle
,
5692 NDR_RUNDOWN RundownRoutine
,
5693 PFORMAT_STRING pFormat
)
5695 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg
, ContextHandle
, RundownRoutine
, pFormat
);
5698 NDR_SCONTEXT WINAPI
NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5699 PFORMAT_STRING pFormat
)
5701 FIXME("(%p, %p): stub\n", pStubMsg
, pFormat
);
5705 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
5707 typedef struct ndr_context_handle
5711 } ndr_context_handle
;
5713 struct context_handle_entry
5717 RPC_BINDING_HANDLE handle
;
5718 ndr_context_handle wire_data
;
5721 static struct list context_handle_list
= LIST_INIT(context_handle_list
);
5723 static CRITICAL_SECTION ndr_context_cs
;
5724 static CRITICAL_SECTION_DEBUG ndr_context_debug
=
5726 0, 0, &ndr_context_cs
,
5727 { &ndr_context_debug
.ProcessLocksList
, &ndr_context_debug
.ProcessLocksList
},
5728 0, 0, { (DWORD_PTR
)(__FILE__
": ndr_context") }
5730 static CRITICAL_SECTION ndr_context_cs
= { &ndr_context_debug
, -1, 0, 0, 0, 0 };
5732 static struct context_handle_entry
*get_context_entry(NDR_CCONTEXT CContext
)
5734 struct context_handle_entry
*che
= (struct context_handle_entry
*) CContext
;
5736 if (che
->magic
!= NDR_CONTEXT_HANDLE_MAGIC
)
5741 static struct context_handle_entry
*context_entry_from_guid(LPCGUID uuid
)
5743 struct context_handle_entry
*che
;
5744 LIST_FOR_EACH_ENTRY(che
, &context_handle_list
, struct context_handle_entry
, entry
)
5745 if (IsEqualGUID(&che
->wire_data
.uuid
, uuid
))
5750 RPC_BINDING_HANDLE WINAPI
NDRCContextBinding(NDR_CCONTEXT CContext
)
5752 struct context_handle_entry
*che
;
5753 RPC_BINDING_HANDLE handle
= NULL
;
5755 TRACE("%p\n", CContext
);
5757 EnterCriticalSection(&ndr_context_cs
);
5758 che
= get_context_entry(CContext
);
5760 handle
= che
->handle
;
5761 LeaveCriticalSection(&ndr_context_cs
);
5764 RpcRaiseException(ERROR_INVALID_HANDLE
);
5768 void WINAPI
NDRCContextMarshall(NDR_CCONTEXT CContext
, void *pBuff
)
5770 struct context_handle_entry
*che
;
5772 TRACE("%p %p\n", CContext
, pBuff
);
5776 EnterCriticalSection(&ndr_context_cs
);
5777 che
= get_context_entry(CContext
);
5778 memcpy(pBuff
, &che
->wire_data
, sizeof (ndr_context_handle
));
5779 LeaveCriticalSection(&ndr_context_cs
);
5783 ndr_context_handle
*wire_data
= (ndr_context_handle
*)pBuff
;
5784 wire_data
->attributes
= 0;
5785 wire_data
->uuid
= GUID_NULL
;
5789 /***********************************************************************
5790 * RpcSmDestroyClientContext [RPCRT4.@]
5792 RPC_STATUS WINAPI
RpcSmDestroyClientContext(void **ContextHandle
)
5794 RPC_STATUS status
= RPC_X_SS_CONTEXT_MISMATCH
;
5795 struct context_handle_entry
*che
= NULL
;
5797 TRACE("(%p)\n", ContextHandle
);
5799 EnterCriticalSection(&ndr_context_cs
);
5800 che
= get_context_entry(*ContextHandle
);
5801 *ContextHandle
= NULL
;
5805 list_remove(&che
->entry
);
5808 LeaveCriticalSection(&ndr_context_cs
);
5812 RpcBindingFree(&che
->handle
);
5813 HeapFree(GetProcessHeap(), 0, che
);
5819 /***********************************************************************
5820 * RpcSsDestroyClientContext [RPCRT4.@]
5822 void WINAPI
RpcSsDestroyClientContext(void **ContextHandle
)
5824 RPC_STATUS status
= RpcSmDestroyClientContext(ContextHandle
);
5825 if (status
!= RPC_S_OK
)
5826 RpcRaiseException(status
);
5829 static UINT
ndr_update_context_handle(NDR_CCONTEXT
*CContext
,
5830 RPC_BINDING_HANDLE hBinding
,
5831 const ndr_context_handle
*chi
)
5833 struct context_handle_entry
*che
= NULL
;
5835 /* a null UUID means we should free the context handle */
5836 if (IsEqualGUID(&chi
->uuid
, &GUID_NULL
))
5840 che
= get_context_entry(*CContext
);
5842 return ERROR_INVALID_HANDLE
;
5843 list_remove(&che
->entry
);
5844 RpcBindingFree(&che
->handle
);
5845 HeapFree(GetProcessHeap(), 0, che
);
5849 /* if there's no existing entry matching the GUID, allocate one */
5850 else if (!(che
= context_entry_from_guid(&chi
->uuid
)))
5852 che
= HeapAlloc(GetProcessHeap(), 0, sizeof *che
);
5854 return ERROR_NOT_ENOUGH_MEMORY
;
5855 che
->magic
= NDR_CONTEXT_HANDLE_MAGIC
;
5856 RpcBindingCopy(hBinding
, &che
->handle
);
5857 list_add_tail(&context_handle_list
, &che
->entry
);
5858 memcpy(&che
->wire_data
, chi
, sizeof *chi
);
5863 return ERROR_SUCCESS
;
5866 /***********************************************************************
5867 * NDRCContextUnmarshall [RPCRT4.@]
5869 void WINAPI
NDRCContextUnmarshall(NDR_CCONTEXT
*CContext
,
5870 RPC_BINDING_HANDLE hBinding
,
5871 void *pBuff
, ULONG DataRepresentation
)
5875 TRACE("*%p=(%p) %p %p %08x\n",
5876 CContext
, *CContext
, hBinding
, pBuff
, DataRepresentation
);
5878 EnterCriticalSection(&ndr_context_cs
);
5879 r
= ndr_update_context_handle(CContext
, hBinding
, pBuff
);
5880 LeaveCriticalSection(&ndr_context_cs
);
5882 RpcRaiseException(r
);
5885 /***********************************************************************
5886 * NDRSContextMarshall [RPCRT4.@]
5888 void WINAPI
NDRSContextMarshall(NDR_SCONTEXT CContext
,
5890 NDR_RUNDOWN userRunDownIn
)
5892 FIXME("(%p %p %p): stub\n", CContext
, pBuff
, userRunDownIn
);
5895 /***********************************************************************
5896 * NDRSContextMarshallEx [RPCRT4.@]
5898 void WINAPI
NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding
,
5899 NDR_SCONTEXT CContext
,
5901 NDR_RUNDOWN userRunDownIn
)
5903 FIXME("(%p %p %p %p): stub\n", hBinding
, CContext
, pBuff
, userRunDownIn
);
5906 /***********************************************************************
5907 * NDRSContextMarshall2 [RPCRT4.@]
5909 void WINAPI
NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding
,
5910 NDR_SCONTEXT CContext
,
5912 NDR_RUNDOWN userRunDownIn
,
5913 void *CtxGuard
, ULONG Flags
)
5915 FIXME("(%p %p %p %p %p %u): stub\n",
5916 hBinding
, CContext
, pBuff
, userRunDownIn
, CtxGuard
, Flags
);
5919 /***********************************************************************
5920 * NDRSContextUnmarshall [RPCRT4.@]
5922 NDR_SCONTEXT WINAPI
NDRSContextUnmarshall(void *pBuff
,
5923 ULONG DataRepresentation
)
5925 FIXME("(%p %08x): stub\n", pBuff
, DataRepresentation
);
5929 /***********************************************************************
5930 * NDRSContextUnmarshallEx [RPCRT4.@]
5932 NDR_SCONTEXT WINAPI
NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding
,
5934 ULONG DataRepresentation
)
5936 FIXME("(%p %p %08x): stub\n", hBinding
, pBuff
, DataRepresentation
);
5940 /***********************************************************************
5941 * NDRSContextUnmarshall2 [RPCRT4.@]
5943 NDR_SCONTEXT WINAPI
NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding
,
5945 ULONG DataRepresentation
,
5946 void *CtxGuard
, ULONG Flags
)
5948 FIXME("(%p %p %08x %p %u): stub\n",
5949 hBinding
, pBuff
, DataRepresentation
, CtxGuard
, Flags
);