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 pPointer
= *(unsigned char***)pPointer
;
982 TRACE("deref => %p\n", pPointer
);
984 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
985 if (m
) m(pStubMsg
, pPointer
, desc
, fMustAlloc
);
986 else FIXME("no unmarshaller for data type=%02x\n", *desc
);
988 if (type
== RPC_FC_FP
)
989 NdrFullPointerInsertRefId(pStubMsg
->FullPtrXlatTables
, pointer_id
,
993 TRACE("pointer=%p\n", *pPointer
);
996 /***********************************************************************
997 * PointerBufferSize [internal]
999 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1000 unsigned char *Pointer
,
1001 PFORMAT_STRING pFormat
)
1003 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1004 PFORMAT_STRING desc
;
1006 int pointer_needs_sizing
;
1009 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1010 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1012 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1013 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1016 case RPC_FC_RP
: /* ref pointer (always non-null) */
1020 /* NULL pointer has no further representation */
1025 pointer_needs_sizing
= !NdrFullPointerQueryPointer(
1026 pStubMsg
->FullPtrXlatTables
, Pointer
, 0, &pointer_id
);
1027 if (!pointer_needs_sizing
)
1031 FIXME("unhandled ptr type=%02x\n", type
);
1032 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1036 if (attr
& RPC_FC_P_DEREF
) {
1037 Pointer
= *(unsigned char**)Pointer
;
1038 TRACE("deref => %p\n", Pointer
);
1041 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
1042 if (m
) m(pStubMsg
, Pointer
, desc
);
1043 else FIXME("no buffersizer for data type=%02x\n", *desc
);
1046 /***********************************************************************
1047 * PointerMemorySize [internal]
1049 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1050 unsigned char *Buffer
,
1051 PFORMAT_STRING pFormat
)
1053 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1054 PFORMAT_STRING desc
;
1057 FIXME("(%p,%p,%p): stub\n", pStubMsg
, Buffer
, pFormat
);
1058 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1060 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1061 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1064 case RPC_FC_RP
: /* ref pointer (always non-null) */
1067 FIXME("unhandled ptr type=%02x\n", type
);
1068 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1071 if (attr
& RPC_FC_P_DEREF
) {
1075 m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
1076 if (m
) m(pStubMsg
, desc
);
1077 else FIXME("no memorysizer for data type=%02x\n", *desc
);
1082 /***********************************************************************
1083 * PointerFree [internal]
1085 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1086 unsigned char *Pointer
,
1087 PFORMAT_STRING pFormat
)
1089 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1090 PFORMAT_STRING desc
;
1093 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1094 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1095 if (attr
& RPC_FC_P_DONTFREE
) return;
1097 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1098 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1100 if (!Pointer
) return;
1102 if (type
== RPC_FC_FP
) {
1103 int pointer_needs_freeing
= NdrFullPointerFree(
1104 pStubMsg
->FullPtrXlatTables
, Pointer
);
1105 if (!pointer_needs_freeing
)
1109 if (attr
& RPC_FC_P_DEREF
) {
1110 Pointer
= *(unsigned char**)Pointer
;
1111 TRACE("deref => %p\n", Pointer
);
1114 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
1115 if (m
) m(pStubMsg
, Pointer
, desc
);
1117 /* hmm... is this sensible?
1118 * perhaps we should check if the memory comes from NdrAllocate,
1119 * and deallocate only if so - checking if the pointer is between
1120 * BufferStart and BufferEnd is probably no good since the buffer
1121 * may be reallocated when the server wants to marshal the reply */
1123 case RPC_FC_BOGUS_STRUCT
:
1124 case RPC_FC_BOGUS_ARRAY
:
1125 case RPC_FC_USER_MARSHAL
:
1127 case RPC_FC_CVARRAY
:
1130 FIXME("unhandled data type=%02x\n", *desc
);
1132 case RPC_FC_C_CSTRING
:
1133 case RPC_FC_C_WSTRING
:
1134 if (pStubMsg
->ReuseBuffer
) goto notfree
;
1140 if (attr
& RPC_FC_P_ONSTACK
) {
1141 TRACE("not freeing stack ptr %p\n", Pointer
);
1144 TRACE("freeing %p\n", Pointer
);
1145 NdrFree(pStubMsg
, Pointer
);
1148 TRACE("not freeing %p\n", Pointer
);
1151 /***********************************************************************
1152 * EmbeddedPointerMarshall
1154 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1155 unsigned char *pMemory
,
1156 PFORMAT_STRING pFormat
)
1158 unsigned char *Mark
= pStubMsg
->BufferMark
;
1159 unsigned long Offset
= pStubMsg
->Offset
;
1160 unsigned ofs
, rep
, count
, stride
, xofs
;
1162 unsigned char *saved_buffer
= NULL
;
1164 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1166 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1169 if (pStubMsg
->PointerBufferMark
)
1171 saved_buffer
= pStubMsg
->Buffer
;
1172 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1173 pStubMsg
->PointerBufferMark
= NULL
;
1176 while (pFormat
[0] != RPC_FC_END
) {
1177 switch (pFormat
[0]) {
1179 FIXME("unknown repeat type %d\n", pFormat
[0]);
1180 case RPC_FC_NO_REPEAT
:
1188 case RPC_FC_FIXED_REPEAT
:
1189 rep
= *(const WORD
*)&pFormat
[2];
1190 stride
= *(const WORD
*)&pFormat
[4];
1191 ofs
= *(const WORD
*)&pFormat
[6];
1192 count
= *(const WORD
*)&pFormat
[8];
1196 case RPC_FC_VARIABLE_REPEAT
:
1197 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1198 stride
= *(const WORD
*)&pFormat
[2];
1199 ofs
= *(const WORD
*)&pFormat
[4];
1200 count
= *(const WORD
*)&pFormat
[6];
1201 xofs
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? Offset
* stride
: 0;
1205 for (i
= 0; i
< rep
; i
++) {
1206 PFORMAT_STRING info
= pFormat
;
1207 unsigned char *membase
= pMemory
+ ofs
+ (i
* stride
);
1208 unsigned char *bufbase
= Mark
+ ofs
+ (i
* stride
);
1211 for (u
=0; u
<count
; u
++,info
+=8) {
1212 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1213 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1214 unsigned char *saved_memory
= pStubMsg
->Memory
;
1216 pStubMsg
->Memory
= pMemory
;
1217 PointerMarshall(pStubMsg
, bufptr
, *(unsigned char**)memptr
, info
+4);
1218 pStubMsg
->Memory
= saved_memory
;
1221 pFormat
+= 8 * count
;
1226 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1227 pStubMsg
->Buffer
= saved_buffer
;
1230 STD_OVERFLOW_CHECK(pStubMsg
);
1235 /***********************************************************************
1236 * EmbeddedPointerUnmarshall
1238 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1239 unsigned char **ppMemory
,
1240 PFORMAT_STRING pFormat
,
1241 unsigned char fMustAlloc
)
1243 unsigned char *Mark
= pStubMsg
->BufferMark
;
1244 unsigned long Offset
= pStubMsg
->Offset
;
1245 unsigned ofs
, rep
, count
, stride
, xofs
;
1247 unsigned char *saved_buffer
= NULL
;
1249 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1251 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1254 if (pStubMsg
->PointerBufferMark
)
1256 saved_buffer
= pStubMsg
->Buffer
;
1257 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1258 pStubMsg
->PointerBufferMark
= NULL
;
1261 while (pFormat
[0] != RPC_FC_END
) {
1262 TRACE("pFormat[0] = 0x%x\n", pFormat
[0]);
1263 switch (pFormat
[0]) {
1265 FIXME("unknown repeat type %d\n", pFormat
[0]);
1266 case RPC_FC_NO_REPEAT
:
1274 case RPC_FC_FIXED_REPEAT
:
1275 rep
= *(const WORD
*)&pFormat
[2];
1276 stride
= *(const WORD
*)&pFormat
[4];
1277 ofs
= *(const WORD
*)&pFormat
[6];
1278 count
= *(const WORD
*)&pFormat
[8];
1282 case RPC_FC_VARIABLE_REPEAT
:
1283 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1284 stride
= *(const WORD
*)&pFormat
[2];
1285 ofs
= *(const WORD
*)&pFormat
[4];
1286 count
= *(const WORD
*)&pFormat
[6];
1287 xofs
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? Offset
* stride
: 0;
1291 /* ofs doesn't seem to matter in this context */
1292 for (i
= 0; i
< rep
; i
++) {
1293 PFORMAT_STRING info
= pFormat
;
1294 unsigned char *membase
= *ppMemory
+ ofs
+ (i
* stride
);
1295 unsigned char *bufbase
= Mark
+ ofs
+ (i
* stride
);
1298 for (u
=0; u
<count
; u
++,info
+=8) {
1299 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1300 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1301 PointerUnmarshall(pStubMsg
, bufptr
, (unsigned char**)memptr
, info
+4, TRUE
);
1304 pFormat
+= 8 * count
;
1309 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1310 pStubMsg
->Buffer
= saved_buffer
;
1316 /***********************************************************************
1317 * EmbeddedPointerBufferSize
1319 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1320 unsigned char *pMemory
,
1321 PFORMAT_STRING pFormat
)
1323 unsigned long Offset
= pStubMsg
->Offset
;
1324 unsigned ofs
, rep
, count
, stride
, xofs
;
1326 ULONG saved_buffer_length
= 0;
1328 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1330 if (pStubMsg
->IgnoreEmbeddedPointers
) return;
1332 if (*pFormat
!= RPC_FC_PP
) return;
1335 if (pStubMsg
->PointerLength
)
1337 saved_buffer_length
= pStubMsg
->BufferLength
;
1338 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
1339 pStubMsg
->PointerLength
= 0;
1342 while (pFormat
[0] != RPC_FC_END
) {
1343 switch (pFormat
[0]) {
1345 FIXME("unknown repeat type %d\n", pFormat
[0]);
1346 case RPC_FC_NO_REPEAT
:
1354 case RPC_FC_FIXED_REPEAT
:
1355 rep
= *(const WORD
*)&pFormat
[2];
1356 stride
= *(const WORD
*)&pFormat
[4];
1357 ofs
= *(const WORD
*)&pFormat
[6];
1358 count
= *(const WORD
*)&pFormat
[8];
1362 case RPC_FC_VARIABLE_REPEAT
:
1363 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1364 stride
= *(const WORD
*)&pFormat
[2];
1365 ofs
= *(const WORD
*)&pFormat
[4];
1366 count
= *(const WORD
*)&pFormat
[6];
1367 xofs
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? Offset
* stride
: 0;
1371 for (i
= 0; i
< rep
; i
++) {
1372 PFORMAT_STRING info
= pFormat
;
1373 unsigned char *membase
= pMemory
+ ofs
+ (i
* stride
);
1376 for (u
=0; u
<count
; u
++,info
+=8) {
1377 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1378 unsigned char *saved_memory
= pStubMsg
->Memory
;
1380 pStubMsg
->Memory
= pMemory
;
1381 PointerBufferSize(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1382 pStubMsg
->Memory
= saved_memory
;
1385 pFormat
+= 8 * count
;
1388 if (saved_buffer_length
)
1390 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
1391 pStubMsg
->BufferLength
= saved_buffer_length
;
1395 /***********************************************************************
1396 * EmbeddedPointerMemorySize [internal]
1398 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1399 PFORMAT_STRING pFormat
)
1401 unsigned long Offset
= pStubMsg
->Offset
;
1402 unsigned char *Mark
= pStubMsg
->BufferMark
;
1403 unsigned ofs
, rep
, count
, stride
, xofs
;
1406 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1408 if (pStubMsg
->IgnoreEmbeddedPointers
) return 0;
1410 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1412 if (*pFormat
!= RPC_FC_PP
) return 0;
1415 while (pFormat
[0] != RPC_FC_END
) {
1416 switch (pFormat
[0]) {
1418 FIXME("unknown repeat type %d\n", pFormat
[0]);
1419 case RPC_FC_NO_REPEAT
:
1427 case RPC_FC_FIXED_REPEAT
:
1428 rep
= *(const WORD
*)&pFormat
[2];
1429 stride
= *(const WORD
*)&pFormat
[4];
1430 ofs
= *(const WORD
*)&pFormat
[6];
1431 count
= *(const WORD
*)&pFormat
[8];
1435 case RPC_FC_VARIABLE_REPEAT
:
1436 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1437 stride
= *(const WORD
*)&pFormat
[2];
1438 ofs
= *(const WORD
*)&pFormat
[4];
1439 count
= *(const WORD
*)&pFormat
[6];
1440 xofs
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? Offset
* stride
: 0;
1444 /* ofs doesn't seem to matter in this context */
1445 for (i
= 0; i
< rep
; i
++) {
1446 PFORMAT_STRING info
= pFormat
;
1447 unsigned char *bufbase
= Mark
+ ofs
+ (i
* stride
);
1449 for (u
=0; u
<count
; u
++,info
+=8) {
1450 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1451 PointerMemorySize(pStubMsg
, bufptr
, info
+4);
1454 pFormat
+= 8 * count
;
1460 /***********************************************************************
1461 * EmbeddedPointerFree [internal]
1463 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1464 unsigned char *pMemory
,
1465 PFORMAT_STRING pFormat
)
1467 unsigned long Offset
= pStubMsg
->Offset
;
1468 unsigned ofs
, rep
, count
, stride
, xofs
;
1471 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1472 if (*pFormat
!= RPC_FC_PP
) return;
1475 while (pFormat
[0] != RPC_FC_END
) {
1476 switch (pFormat
[0]) {
1478 FIXME("unknown repeat type %d\n", pFormat
[0]);
1479 case RPC_FC_NO_REPEAT
:
1487 case RPC_FC_FIXED_REPEAT
:
1488 rep
= *(const WORD
*)&pFormat
[2];
1489 stride
= *(const WORD
*)&pFormat
[4];
1490 ofs
= *(const WORD
*)&pFormat
[6];
1491 count
= *(const WORD
*)&pFormat
[8];
1495 case RPC_FC_VARIABLE_REPEAT
:
1496 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1497 stride
= *(const WORD
*)&pFormat
[2];
1498 ofs
= *(const WORD
*)&pFormat
[4];
1499 count
= *(const WORD
*)&pFormat
[6];
1500 xofs
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? Offset
* stride
: 0;
1504 for (i
= 0; i
< rep
; i
++) {
1505 PFORMAT_STRING info
= pFormat
;
1506 unsigned char *membase
= pMemory
+ (i
* stride
);
1509 for (u
=0; u
<count
; u
++,info
+=8) {
1510 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1511 unsigned char *saved_memory
= pStubMsg
->Memory
;
1513 pStubMsg
->Memory
= pMemory
;
1514 PointerFree(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1515 pStubMsg
->Memory
= saved_memory
;
1518 pFormat
+= 8 * count
;
1522 /***********************************************************************
1523 * NdrPointerMarshall [RPCRT4.@]
1525 unsigned char * WINAPI
NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1526 unsigned char *pMemory
,
1527 PFORMAT_STRING pFormat
)
1529 unsigned char *Buffer
;
1531 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1533 /* incremement the buffer here instead of in PointerMarshall,
1534 * as that is used by embedded pointers which already handle the incrementing
1535 * the buffer, and shouldn't write any additional pointer data to the wire */
1536 if (*pFormat
!= RPC_FC_RP
)
1538 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1539 Buffer
= pStubMsg
->Buffer
;
1540 pStubMsg
->Buffer
+= 4;
1543 Buffer
= pStubMsg
->Buffer
;
1545 PointerMarshall(pStubMsg
, Buffer
, pMemory
, pFormat
);
1547 STD_OVERFLOW_CHECK(pStubMsg
);
1552 /***********************************************************************
1553 * NdrPointerUnmarshall [RPCRT4.@]
1555 unsigned char * WINAPI
NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1556 unsigned char **ppMemory
,
1557 PFORMAT_STRING pFormat
,
1558 unsigned char fMustAlloc
)
1560 unsigned char *Buffer
;
1562 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1564 /* incremement the buffer here instead of in PointerUnmarshall,
1565 * as that is used by embedded pointers which already handle the incrementing
1566 * the buffer, and shouldn't read any additional pointer data from the
1568 if (*pFormat
!= RPC_FC_RP
)
1570 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1571 Buffer
= pStubMsg
->Buffer
;
1572 safe_buffer_increment(pStubMsg
, 4);
1575 Buffer
= pStubMsg
->Buffer
;
1577 PointerUnmarshall(pStubMsg
, Buffer
, ppMemory
, pFormat
, fMustAlloc
);
1582 /***********************************************************************
1583 * NdrPointerBufferSize [RPCRT4.@]
1585 void WINAPI
NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1586 unsigned char *pMemory
,
1587 PFORMAT_STRING pFormat
)
1589 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1591 /* incremement the buffer length here instead of in PointerBufferSize,
1592 * as that is used by embedded pointers which already handle the buffer
1593 * length, and shouldn't write anything more to the wire */
1594 if (*pFormat
!= RPC_FC_RP
)
1596 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
1597 pStubMsg
->BufferLength
+= 4;
1600 PointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1603 /***********************************************************************
1604 * NdrPointerMemorySize [RPCRT4.@]
1606 ULONG WINAPI
NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1607 PFORMAT_STRING pFormat
)
1609 /* unsigned size = *(LPWORD)(pFormat+2); */
1610 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1611 PointerMemorySize(pStubMsg
, pStubMsg
->Buffer
, pFormat
);
1615 /***********************************************************************
1616 * NdrPointerFree [RPCRT4.@]
1618 void WINAPI
NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1619 unsigned char *pMemory
,
1620 PFORMAT_STRING pFormat
)
1622 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1623 PointerFree(pStubMsg
, pMemory
, pFormat
);
1626 /***********************************************************************
1627 * NdrSimpleTypeMarshall [RPCRT4.@]
1629 void WINAPI
NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1630 unsigned char FormatChar
)
1632 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &FormatChar
);
1635 /***********************************************************************
1636 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1638 void WINAPI
NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1639 unsigned char FormatChar
)
1641 NdrBaseTypeUnmarshall(pStubMsg
, &pMemory
, &FormatChar
, 0);
1644 /***********************************************************************
1645 * NdrSimpleStructMarshall [RPCRT4.@]
1647 unsigned char * WINAPI
NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1648 unsigned char *pMemory
,
1649 PFORMAT_STRING pFormat
)
1651 unsigned size
= *(const WORD
*)(pFormat
+2);
1652 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1654 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1656 memcpy(pStubMsg
->Buffer
, pMemory
, size
);
1657 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1658 pStubMsg
->Buffer
+= size
;
1660 if (pFormat
[0] != RPC_FC_STRUCT
)
1661 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
+4);
1663 STD_OVERFLOW_CHECK(pStubMsg
);
1668 /***********************************************************************
1669 * NdrSimpleStructUnmarshall [RPCRT4.@]
1671 unsigned char * WINAPI
NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1672 unsigned char **ppMemory
,
1673 PFORMAT_STRING pFormat
,
1674 unsigned char fMustAlloc
)
1676 unsigned size
= *(const WORD
*)(pFormat
+2);
1677 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1679 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1682 *ppMemory
= NdrAllocate(pStubMsg
, size
);
1683 memcpy(*ppMemory
, pStubMsg
->Buffer
, size
);
1685 if (!pStubMsg
->IsClient
&& !*ppMemory
)
1686 /* for servers, we just point straight into the RPC buffer */
1687 *ppMemory
= pStubMsg
->Buffer
;
1689 /* for clients, memory should be provided by caller */
1690 memcpy(*ppMemory
, pStubMsg
->Buffer
, size
);
1693 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1694 pStubMsg
->Buffer
+= size
;
1696 if (pFormat
[0] != RPC_FC_STRUCT
)
1697 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
+4, fMustAlloc
);
1702 /***********************************************************************
1703 * NdrSimpleStructBufferSize [RPCRT4.@]
1705 void WINAPI
NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1706 unsigned char *pMemory
,
1707 PFORMAT_STRING pFormat
)
1709 unsigned size
= *(const WORD
*)(pFormat
+2);
1710 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1712 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
1714 pStubMsg
->BufferLength
+= size
;
1715 if (pFormat
[0] != RPC_FC_STRUCT
)
1716 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
+4);
1719 /***********************************************************************
1720 * NdrSimpleStructMemorySize [RPCRT4.@]
1722 ULONG WINAPI
NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1723 PFORMAT_STRING pFormat
)
1725 unsigned short size
= *(const WORD
*)(pFormat
+2);
1727 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1729 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1730 pStubMsg
->MemorySize
+= size
;
1731 pStubMsg
->Buffer
+= size
;
1733 if (pFormat
[0] != RPC_FC_STRUCT
)
1734 EmbeddedPointerMemorySize(pStubMsg
, pFormat
+4);
1738 /***********************************************************************
1739 * NdrSimpleStructFree [RPCRT4.@]
1741 void WINAPI
NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
1742 unsigned char *pMemory
,
1743 PFORMAT_STRING pFormat
)
1745 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1746 if (pFormat
[0] != RPC_FC_STRUCT
)
1747 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
+4);
1751 static unsigned long EmbeddedComplexSize(const MIDL_STUB_MESSAGE
*pStubMsg
,
1752 PFORMAT_STRING pFormat
)
1756 case RPC_FC_PSTRUCT
:
1757 case RPC_FC_CSTRUCT
:
1758 case RPC_FC_BOGUS_STRUCT
:
1759 case RPC_FC_SMFARRAY
:
1760 case RPC_FC_SMVARRAY
:
1761 return *(const WORD
*)&pFormat
[2];
1762 case RPC_FC_USER_MARSHAL
:
1763 return *(const WORD
*)&pFormat
[4];
1764 case RPC_FC_NON_ENCAPSULATED_UNION
:
1766 if (pStubMsg
->fHasNewCorrDesc
)
1771 pFormat
+= *(const SHORT
*)pFormat
;
1772 return *(const SHORT
*)pFormat
;
1774 return sizeof(void *);
1776 FIXME("unhandled embedded type %02x\n", *pFormat
);
1782 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1783 PFORMAT_STRING pFormat
)
1785 NDR_MEMORYSIZE m
= NdrMemorySizer
[*pFormat
& NDR_TABLE_MASK
];
1789 FIXME("no memorysizer for data type=%02x\n", *pFormat
);
1793 return m(pStubMsg
, pFormat
);
1797 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1798 unsigned char *pMemory
,
1799 PFORMAT_STRING pFormat
,
1800 PFORMAT_STRING pPointer
)
1802 PFORMAT_STRING desc
;
1806 while (*pFormat
!= RPC_FC_END
) {
1812 TRACE("byte=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
1813 memcpy(pStubMsg
->Buffer
, pMemory
, 1);
1814 pStubMsg
->Buffer
+= 1;
1820 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
1821 memcpy(pStubMsg
->Buffer
, pMemory
, 2);
1822 pStubMsg
->Buffer
+= 2;
1828 TRACE("long=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
1829 memcpy(pStubMsg
->Buffer
, pMemory
, 4);
1830 pStubMsg
->Buffer
+= 4;
1834 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
1835 memcpy(pStubMsg
->Buffer
, pMemory
, 8);
1836 pStubMsg
->Buffer
+= 8;
1839 case RPC_FC_POINTER
:
1841 unsigned char *saved_buffer
;
1842 int pointer_buffer_mark_set
= 0;
1843 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
1844 saved_buffer
= pStubMsg
->Buffer
;
1845 if (pStubMsg
->PointerBufferMark
)
1847 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1848 pStubMsg
->PointerBufferMark
= NULL
;
1849 pointer_buffer_mark_set
= 1;
1852 pStubMsg
->Buffer
+= 4; /* for pointer ID */
1853 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char**)pMemory
, pPointer
);
1854 if (pointer_buffer_mark_set
)
1856 STD_OVERFLOW_CHECK(pStubMsg
);
1857 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1858 pStubMsg
->Buffer
= saved_buffer
+ 4;
1864 case RPC_FC_ALIGNM4
:
1865 ALIGN_POINTER(pMemory
, 4);
1867 case RPC_FC_ALIGNM8
:
1868 ALIGN_POINTER(pMemory
, 8);
1870 case RPC_FC_STRUCTPAD1
:
1871 case RPC_FC_STRUCTPAD2
:
1872 case RPC_FC_STRUCTPAD3
:
1873 case RPC_FC_STRUCTPAD4
:
1874 case RPC_FC_STRUCTPAD5
:
1875 case RPC_FC_STRUCTPAD6
:
1876 case RPC_FC_STRUCTPAD7
:
1877 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
1879 case RPC_FC_EMBEDDED_COMPLEX
:
1880 pMemory
+= pFormat
[1];
1882 desc
= pFormat
+ *(const SHORT
*)pFormat
;
1883 size
= EmbeddedComplexSize(pStubMsg
, desc
);
1884 TRACE("embedded complex (size=%ld) <= %p\n", size
, pMemory
);
1885 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
1888 /* for some reason interface pointers aren't generated as
1889 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
1890 * they still need the derefencing treatment that pointers are
1892 if (*desc
== RPC_FC_IP
)
1893 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
1895 m(pStubMsg
, pMemory
, desc
);
1897 else FIXME("no marshaller for embedded type %02x\n", *desc
);
1904 FIXME("unhandled format 0x%02x\n", *pFormat
);
1912 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1913 unsigned char *pMemory
,
1914 PFORMAT_STRING pFormat
,
1915 PFORMAT_STRING pPointer
)
1917 PFORMAT_STRING desc
;
1921 while (*pFormat
!= RPC_FC_END
) {
1927 safe_buffer_copy(pStubMsg
, pMemory
, 1);
1928 TRACE("byte=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
1934 safe_buffer_copy(pStubMsg
, pMemory
, 2);
1935 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
1941 safe_buffer_copy(pStubMsg
, pMemory
, 4);
1942 TRACE("long=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
1946 safe_buffer_copy(pStubMsg
, pMemory
, 8);
1947 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
1950 case RPC_FC_POINTER
:
1952 unsigned char *saved_buffer
;
1953 int pointer_buffer_mark_set
= 0;
1954 TRACE("pointer => %p\n", pMemory
);
1955 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1956 saved_buffer
= pStubMsg
->Buffer
;
1957 if (pStubMsg
->PointerBufferMark
)
1959 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1960 pStubMsg
->PointerBufferMark
= NULL
;
1961 pointer_buffer_mark_set
= 1;
1964 pStubMsg
->Buffer
+= 4; /* for pointer ID */
1966 PointerUnmarshall(pStubMsg
, saved_buffer
, (unsigned char**)pMemory
, pPointer
, TRUE
);
1967 if (pointer_buffer_mark_set
)
1969 STD_OVERFLOW_CHECK(pStubMsg
);
1970 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1971 pStubMsg
->Buffer
= saved_buffer
+ 4;
1977 case RPC_FC_ALIGNM4
:
1978 ALIGN_POINTER(pMemory
, 4);
1980 case RPC_FC_ALIGNM8
:
1981 ALIGN_POINTER(pMemory
, 8);
1983 case RPC_FC_STRUCTPAD1
:
1984 case RPC_FC_STRUCTPAD2
:
1985 case RPC_FC_STRUCTPAD3
:
1986 case RPC_FC_STRUCTPAD4
:
1987 case RPC_FC_STRUCTPAD5
:
1988 case RPC_FC_STRUCTPAD6
:
1989 case RPC_FC_STRUCTPAD7
:
1990 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
1992 case RPC_FC_EMBEDDED_COMPLEX
:
1993 pMemory
+= pFormat
[1];
1995 desc
= pFormat
+ *(const SHORT
*)pFormat
;
1996 size
= EmbeddedComplexSize(pStubMsg
, desc
);
1997 TRACE("embedded complex (size=%ld) => %p\n", size
, pMemory
);
1998 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
1999 memset(pMemory
, 0, size
); /* just in case */
2002 /* for some reason interface pointers aren't generated as
2003 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2004 * they still need the derefencing treatment that pointers are
2006 if (*desc
== RPC_FC_IP
)
2007 m(pStubMsg
, (unsigned char **)pMemory
, desc
, FALSE
);
2009 m(pStubMsg
, &pMemory
, desc
, FALSE
);
2011 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
2018 FIXME("unhandled format %d\n", *pFormat
);
2026 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2027 unsigned char *pMemory
,
2028 PFORMAT_STRING pFormat
,
2029 PFORMAT_STRING pPointer
)
2031 PFORMAT_STRING desc
;
2035 while (*pFormat
!= RPC_FC_END
) {
2041 pStubMsg
->BufferLength
+= 1;
2047 pStubMsg
->BufferLength
+= 2;
2053 pStubMsg
->BufferLength
+= 4;
2057 pStubMsg
->BufferLength
+= 8;
2060 case RPC_FC_POINTER
:
2061 if (!pStubMsg
->IgnoreEmbeddedPointers
)
2063 int saved_buffer_length
= pStubMsg
->BufferLength
;
2064 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2065 pStubMsg
->PointerLength
= 0;
2066 if(!pStubMsg
->BufferLength
)
2067 ERR("BufferLength == 0??\n");
2068 PointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
2069 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2070 pStubMsg
->BufferLength
= saved_buffer_length
;
2072 pStubMsg
->BufferLength
+= 4;
2076 case RPC_FC_ALIGNM4
:
2077 ALIGN_POINTER(pMemory
, 4);
2079 case RPC_FC_ALIGNM8
:
2080 ALIGN_POINTER(pMemory
, 8);
2082 case RPC_FC_STRUCTPAD1
:
2083 case RPC_FC_STRUCTPAD2
:
2084 case RPC_FC_STRUCTPAD3
:
2085 case RPC_FC_STRUCTPAD4
:
2086 case RPC_FC_STRUCTPAD5
:
2087 case RPC_FC_STRUCTPAD6
:
2088 case RPC_FC_STRUCTPAD7
:
2089 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2091 case RPC_FC_EMBEDDED_COMPLEX
:
2092 pMemory
+= pFormat
[1];
2094 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2095 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2096 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
2099 /* for some reason interface pointers aren't generated as
2100 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2101 * they still need the derefencing treatment that pointers are
2103 if (*desc
== RPC_FC_IP
)
2104 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2106 m(pStubMsg
, pMemory
, desc
);
2108 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
2115 FIXME("unhandled format 0x%02x\n", *pFormat
);
2123 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
2124 unsigned char *pMemory
,
2125 PFORMAT_STRING pFormat
,
2126 PFORMAT_STRING pPointer
)
2128 PFORMAT_STRING desc
;
2132 while (*pFormat
!= RPC_FC_END
) {
2153 case RPC_FC_POINTER
:
2154 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
2158 case RPC_FC_ALIGNM4
:
2159 ALIGN_POINTER(pMemory
, 4);
2161 case RPC_FC_ALIGNM8
:
2162 ALIGN_POINTER(pMemory
, 8);
2164 case RPC_FC_STRUCTPAD1
:
2165 case RPC_FC_STRUCTPAD2
:
2166 case RPC_FC_STRUCTPAD3
:
2167 case RPC_FC_STRUCTPAD4
:
2168 case RPC_FC_STRUCTPAD5
:
2169 case RPC_FC_STRUCTPAD6
:
2170 case RPC_FC_STRUCTPAD7
:
2171 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2173 case RPC_FC_EMBEDDED_COMPLEX
:
2174 pMemory
+= pFormat
[1];
2176 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2177 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2178 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
2181 /* for some reason interface pointers aren't generated as
2182 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2183 * they still need the derefencing treatment that pointers are
2185 if (*desc
== RPC_FC_IP
)
2186 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2188 m(pStubMsg
, pMemory
, desc
);
2190 else FIXME("no freer for embedded type %02x\n", *desc
);
2197 FIXME("unhandled format 0x%02x\n", *pFormat
);
2205 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2206 PFORMAT_STRING pFormat
)
2208 PFORMAT_STRING desc
;
2209 unsigned long size
= 0;
2211 while (*pFormat
!= RPC_FC_END
) {
2218 pStubMsg
->Buffer
+= 1;
2224 pStubMsg
->Buffer
+= 2;
2230 pStubMsg
->Buffer
+= 4;
2234 pStubMsg
->Buffer
+= 8;
2236 case RPC_FC_POINTER
:
2238 pStubMsg
->Buffer
+= 4;
2239 if (!pStubMsg
->IgnoreEmbeddedPointers
)
2240 FIXME("embedded pointers\n");
2242 case RPC_FC_ALIGNM4
:
2243 ALIGN_LENGTH(size
, 4);
2244 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2246 case RPC_FC_ALIGNM8
:
2247 ALIGN_LENGTH(size
, 8);
2248 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
2250 case RPC_FC_STRUCTPAD1
:
2251 case RPC_FC_STRUCTPAD2
:
2252 case RPC_FC_STRUCTPAD3
:
2253 case RPC_FC_STRUCTPAD4
:
2254 case RPC_FC_STRUCTPAD5
:
2255 case RPC_FC_STRUCTPAD6
:
2256 case RPC_FC_STRUCTPAD7
:
2257 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2259 case RPC_FC_EMBEDDED_COMPLEX
:
2262 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2263 size
+= EmbeddedComplexMemorySize(pStubMsg
, desc
);
2269 FIXME("unhandled format 0x%02x\n", *pFormat
);
2277 /***********************************************************************
2278 * NdrComplexStructMarshall [RPCRT4.@]
2280 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2281 unsigned char *pMemory
,
2282 PFORMAT_STRING pFormat
)
2284 PFORMAT_STRING conf_array
= NULL
;
2285 PFORMAT_STRING pointer_desc
= NULL
;
2286 unsigned char *OldMemory
= pStubMsg
->Memory
;
2287 int pointer_buffer_mark_set
= 0;
2289 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2291 if (!pStubMsg
->PointerBufferMark
)
2293 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2294 /* save buffer length */
2295 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2297 /* get the buffer pointer after complex array data, but before
2299 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- pStubMsg
->BufferStart
;
2300 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2301 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
2302 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2304 /* save it for use by embedded pointer code later */
2305 pStubMsg
->PointerBufferMark
= pStubMsg
->BufferStart
+ pStubMsg
->BufferLength
;
2306 TRACE("difference = 0x%x\n", pStubMsg
->PointerBufferMark
- pStubMsg
->Buffer
);
2307 pointer_buffer_mark_set
= 1;
2309 /* restore the original buffer length */
2310 pStubMsg
->BufferLength
= saved_buffer_length
;
2313 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2316 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2318 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2321 pStubMsg
->Memory
= pMemory
;
2323 ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2326 NdrConformantArrayMarshall(pStubMsg
, pMemory
, conf_array
);
2328 pStubMsg
->Memory
= OldMemory
;
2330 if (pointer_buffer_mark_set
)
2332 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2333 pStubMsg
->PointerBufferMark
= NULL
;
2336 STD_OVERFLOW_CHECK(pStubMsg
);
2341 /***********************************************************************
2342 * NdrComplexStructUnmarshall [RPCRT4.@]
2344 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2345 unsigned char **ppMemory
,
2346 PFORMAT_STRING pFormat
,
2347 unsigned char fMustAlloc
)
2349 unsigned size
= *(const WORD
*)(pFormat
+2);
2350 PFORMAT_STRING conf_array
= NULL
;
2351 PFORMAT_STRING pointer_desc
= NULL
;
2352 unsigned char *pMemory
;
2353 int pointer_buffer_mark_set
= 0;
2355 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2357 if (!pStubMsg
->PointerBufferMark
)
2359 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2360 /* save buffer pointer */
2361 unsigned char *saved_buffer
= pStubMsg
->Buffer
;
2363 /* get the buffer pointer after complex array data, but before
2365 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2366 NdrComplexStructMemorySize(pStubMsg
, pFormat
);
2367 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2369 /* save it for use by embedded pointer code later */
2370 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2371 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->PointerBufferMark
- saved_buffer
));
2372 pointer_buffer_mark_set
= 1;
2374 /* restore the original buffer */
2375 pStubMsg
->Buffer
= saved_buffer
;
2378 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2380 if (fMustAlloc
|| !*ppMemory
)
2382 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2383 memset(*ppMemory
, 0, size
);
2387 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2389 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2392 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
);
2395 NdrConformantArrayUnmarshall(pStubMsg
, &pMemory
, conf_array
, fMustAlloc
);
2397 if (pointer_buffer_mark_set
)
2399 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2400 pStubMsg
->PointerBufferMark
= NULL
;
2406 /***********************************************************************
2407 * NdrComplexStructBufferSize [RPCRT4.@]
2409 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2410 unsigned char *pMemory
,
2411 PFORMAT_STRING pFormat
)
2413 PFORMAT_STRING conf_array
= NULL
;
2414 PFORMAT_STRING pointer_desc
= NULL
;
2415 unsigned char *OldMemory
= pStubMsg
->Memory
;
2416 int pointer_length_set
= 0;
2418 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2420 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
2422 if(!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
2424 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2425 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2427 /* get the buffer length after complex struct data, but before
2429 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2430 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
2431 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2433 /* save it for use by embedded pointer code later */
2434 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2435 pointer_length_set
= 1;
2436 TRACE("difference = 0x%lx\n", pStubMsg
->PointerLength
- saved_buffer_length
);
2438 /* restore the original buffer length */
2439 pStubMsg
->BufferLength
= saved_buffer_length
;
2443 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2445 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2448 pStubMsg
->Memory
= pMemory
;
2450 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2453 NdrConformantArrayBufferSize(pStubMsg
, pMemory
, conf_array
);
2455 pStubMsg
->Memory
= OldMemory
;
2457 if(pointer_length_set
)
2459 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2460 pStubMsg
->PointerLength
= 0;
2465 /***********************************************************************
2466 * NdrComplexStructMemorySize [RPCRT4.@]
2468 ULONG WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2469 PFORMAT_STRING pFormat
)
2471 unsigned size
= *(const WORD
*)(pFormat
+2);
2472 PFORMAT_STRING conf_array
= NULL
;
2473 PFORMAT_STRING pointer_desc
= NULL
;
2475 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2477 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2480 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2482 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2485 ComplexStructMemorySize(pStubMsg
, pFormat
);
2488 NdrConformantArrayMemorySize(pStubMsg
, conf_array
);
2493 /***********************************************************************
2494 * NdrComplexStructFree [RPCRT4.@]
2496 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
2497 unsigned char *pMemory
,
2498 PFORMAT_STRING pFormat
)
2500 PFORMAT_STRING conf_array
= NULL
;
2501 PFORMAT_STRING pointer_desc
= NULL
;
2502 unsigned char *OldMemory
= pStubMsg
->Memory
;
2504 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2507 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2509 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2512 pStubMsg
->Memory
= pMemory
;
2514 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2517 NdrConformantArrayFree(pStubMsg
, pMemory
, conf_array
);
2519 pStubMsg
->Memory
= OldMemory
;
2522 /***********************************************************************
2523 * NdrConformantArrayMarshall [RPCRT4.@]
2525 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2526 unsigned char *pMemory
,
2527 PFORMAT_STRING pFormat
)
2529 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
2530 unsigned char alignment
= pFormat
[1] + 1;
2532 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2533 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2535 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2537 WriteConformance(pStubMsg
);
2539 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2541 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2542 memcpy(pStubMsg
->Buffer
, pMemory
, size
);
2543 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2544 pStubMsg
->Buffer
+= size
;
2546 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2548 STD_OVERFLOW_CHECK(pStubMsg
);
2553 /***********************************************************************
2554 * NdrConformantArrayUnmarshall [RPCRT4.@]
2556 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2557 unsigned char **ppMemory
,
2558 PFORMAT_STRING pFormat
,
2559 unsigned char fMustAlloc
)
2561 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
2562 unsigned char alignment
= pFormat
[1] + 1;
2564 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2565 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2567 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2569 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2571 if (fMustAlloc
|| !*ppMemory
)
2572 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2574 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2576 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2577 safe_buffer_copy(pStubMsg
, *ppMemory
, size
);
2579 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2584 /***********************************************************************
2585 * NdrConformantArrayBufferSize [RPCRT4.@]
2587 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2588 unsigned char *pMemory
,
2589 PFORMAT_STRING pFormat
)
2591 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
2592 unsigned char alignment
= pFormat
[1] + 1;
2594 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2595 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2597 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2599 SizeConformance(pStubMsg
);
2601 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
2603 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2604 /* conformance value plus array */
2605 pStubMsg
->BufferLength
+= size
;
2607 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
2610 /***********************************************************************
2611 * NdrConformantArrayMemorySize [RPCRT4.@]
2613 ULONG WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2614 PFORMAT_STRING pFormat
)
2616 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
2617 unsigned char alignment
= pFormat
[1] + 1;
2619 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2620 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2622 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2623 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2624 pStubMsg
->MemorySize
+= size
;
2626 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2627 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2628 pStubMsg
->Buffer
+= size
;
2630 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2632 return pStubMsg
->MemorySize
;
2635 /***********************************************************************
2636 * NdrConformantArrayFree [RPCRT4.@]
2638 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
2639 unsigned char *pMemory
,
2640 PFORMAT_STRING pFormat
)
2642 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2643 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2645 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2647 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2651 /***********************************************************************
2652 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2654 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2655 unsigned char* pMemory
,
2656 PFORMAT_STRING pFormat
)
2659 unsigned char alignment
= pFormat
[1] + 1;
2660 DWORD esize
= *(const WORD
*)(pFormat
+2);
2662 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
2664 if (pFormat
[0] != RPC_FC_CVARRAY
)
2666 ERR("invalid format type %x\n", pFormat
[0]);
2667 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2671 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2672 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2674 WriteConformance(pStubMsg
);
2675 WriteVariance(pStubMsg
);
2677 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2679 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2681 memcpy(pStubMsg
->Buffer
, pMemory
+ pStubMsg
->Offset
, bufsize
);
2682 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2683 pStubMsg
->Buffer
+= bufsize
;
2685 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2687 STD_OVERFLOW_CHECK(pStubMsg
);
2693 /***********************************************************************
2694 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2696 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2697 unsigned char** ppMemory
,
2698 PFORMAT_STRING pFormat
,
2699 unsigned char fMustAlloc
)
2701 ULONG bufsize
, memsize
;
2702 unsigned char alignment
= pFormat
[1] + 1;
2703 DWORD esize
= *(const WORD
*)(pFormat
+2);
2705 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2707 if (pFormat
[0] != RPC_FC_CVARRAY
)
2709 ERR("invalid format type %x\n", pFormat
[0]);
2710 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2714 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2715 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2717 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2719 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2720 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2722 if (!*ppMemory
|| fMustAlloc
)
2723 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2724 safe_buffer_copy(pStubMsg
, *ppMemory
+ pStubMsg
->Offset
, bufsize
);
2726 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2732 /***********************************************************************
2733 * NdrConformantVaryingArrayFree [RPCRT4.@]
2735 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
2736 unsigned char* pMemory
,
2737 PFORMAT_STRING pFormat
)
2739 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2741 if (pFormat
[0] != RPC_FC_CVARRAY
)
2743 ERR("invalid format type %x\n", pFormat
[0]);
2744 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2748 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2749 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2751 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2755 /***********************************************************************
2756 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2758 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
2759 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
2761 unsigned char alignment
= pFormat
[1] + 1;
2762 DWORD esize
= *(const WORD
*)(pFormat
+2);
2764 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
2766 if (pFormat
[0] != RPC_FC_CVARRAY
)
2768 ERR("invalid format type %x\n", pFormat
[0]);
2769 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2774 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2775 /* compute length */
2776 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2778 SizeConformance(pStubMsg
);
2779 SizeVariance(pStubMsg
);
2781 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
2783 pStubMsg
->BufferLength
+= safe_multiply(esize
, pStubMsg
->ActualCount
);
2785 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
2789 /***********************************************************************
2790 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2792 ULONG WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
2793 PFORMAT_STRING pFormat
)
2800 /***********************************************************************
2801 * NdrComplexArrayMarshall [RPCRT4.@]
2803 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2804 unsigned char *pMemory
,
2805 PFORMAT_STRING pFormat
)
2807 ULONG i
, count
, def
;
2808 BOOL variance_present
;
2809 unsigned char alignment
;
2810 int pointer_buffer_mark_set
= 0;
2812 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2814 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
2816 ERR("invalid format type %x\n", pFormat
[0]);
2817 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2821 alignment
= pFormat
[1] + 1;
2823 if (!pStubMsg
->PointerBufferMark
)
2825 /* save buffer fields that may be changed by buffer sizer functions
2826 * and that may be needed later on */
2827 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2828 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2829 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
2830 unsigned long saved_offset
= pStubMsg
->Offset
;
2831 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
2833 /* get the buffer pointer after complex array data, but before
2835 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- pStubMsg
->BufferStart
;
2836 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2837 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
2838 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2840 /* save it for use by embedded pointer code later */
2841 pStubMsg
->PointerBufferMark
= pStubMsg
->BufferStart
+ pStubMsg
->BufferLength
;
2842 TRACE("difference = 0x%x\n", pStubMsg
->Buffer
- pStubMsg
->BufferStart
);
2843 pointer_buffer_mark_set
= 1;
2845 /* restore fields */
2846 pStubMsg
->ActualCount
= saved_actual_count
;
2847 pStubMsg
->Offset
= saved_offset
;
2848 pStubMsg
->MaxCount
= saved_max_count
;
2849 pStubMsg
->BufferLength
= saved_buffer_length
;
2852 def
= *(const WORD
*)&pFormat
[2];
2855 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
2856 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
2858 variance_present
= IsConformanceOrVariancePresent(pFormat
);
2859 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
2860 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
2862 WriteConformance(pStubMsg
);
2863 if (variance_present
)
2864 WriteVariance(pStubMsg
);
2866 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2868 count
= pStubMsg
->ActualCount
;
2869 for (i
= 0; i
< count
; i
++)
2870 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
2872 STD_OVERFLOW_CHECK(pStubMsg
);
2874 if (pointer_buffer_mark_set
)
2876 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2877 pStubMsg
->PointerBufferMark
= NULL
;
2883 /***********************************************************************
2884 * NdrComplexArrayUnmarshall [RPCRT4.@]
2886 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2887 unsigned char **ppMemory
,
2888 PFORMAT_STRING pFormat
,
2889 unsigned char fMustAlloc
)
2891 ULONG i
, count
, size
;
2892 unsigned char alignment
;
2893 unsigned char *pMemory
;
2894 unsigned char *saved_buffer
;
2895 int pointer_buffer_mark_set
= 0;
2896 int saved_ignore_embedded
;
2898 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2900 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
2902 ERR("invalid format type %x\n", pFormat
[0]);
2903 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2907 alignment
= pFormat
[1] + 1;
2909 saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2910 /* save buffer pointer */
2911 saved_buffer
= pStubMsg
->Buffer
;
2912 /* get the buffer pointer after complex array data, but before
2914 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2915 pStubMsg
->MemorySize
= 0;
2916 NdrComplexArrayMemorySize(pStubMsg
, pFormat
);
2917 size
= pStubMsg
->MemorySize
;
2918 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2920 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->Buffer
- saved_buffer
));
2921 if (!pStubMsg
->PointerBufferMark
)
2923 /* save it for use by embedded pointer code later */
2924 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2925 pointer_buffer_mark_set
= 1;
2927 /* restore the original buffer */
2928 pStubMsg
->Buffer
= saved_buffer
;
2932 pFormat
= ReadConformance(pStubMsg
, pFormat
);
2933 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2935 if (fMustAlloc
|| !*ppMemory
)
2937 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2938 memset(*ppMemory
, 0, size
);
2941 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2943 pMemory
= *ppMemory
;
2944 count
= pStubMsg
->ActualCount
;
2945 for (i
= 0; i
< count
; i
++)
2946 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
2948 if (pointer_buffer_mark_set
)
2950 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2951 pStubMsg
->PointerBufferMark
= NULL
;
2957 /***********************************************************************
2958 * NdrComplexArrayBufferSize [RPCRT4.@]
2960 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2961 unsigned char *pMemory
,
2962 PFORMAT_STRING pFormat
)
2964 ULONG i
, count
, def
;
2965 unsigned char alignment
;
2966 BOOL variance_present
;
2967 int pointer_length_set
= 0;
2969 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2971 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
2973 ERR("invalid format type %x\n", pFormat
[0]);
2974 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2978 alignment
= pFormat
[1] + 1;
2980 if (!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
2982 /* save buffer fields that may be changed by buffer sizer functions
2983 * and that may be needed later on */
2984 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2985 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2986 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
2987 unsigned long saved_offset
= pStubMsg
->Offset
;
2988 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
2990 /* get the buffer pointer after complex array data, but before
2992 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2993 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
2994 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2996 /* save it for use by embedded pointer code later */
2997 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2998 pointer_length_set
= 1;
3000 /* restore fields */
3001 pStubMsg
->ActualCount
= saved_actual_count
;
3002 pStubMsg
->Offset
= saved_offset
;
3003 pStubMsg
->MaxCount
= saved_max_count
;
3004 pStubMsg
->BufferLength
= saved_buffer_length
;
3006 def
= *(const WORD
*)&pFormat
[2];
3009 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3010 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3011 SizeConformance(pStubMsg
);
3013 variance_present
= IsConformanceOrVariancePresent(pFormat
);
3014 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3015 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3017 if (variance_present
)
3018 SizeVariance(pStubMsg
);
3020 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
3022 count
= pStubMsg
->ActualCount
;
3023 for (i
= 0; i
< count
; i
++)
3024 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
3026 if(pointer_length_set
)
3028 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3029 pStubMsg
->PointerLength
= 0;
3033 /***********************************************************************
3034 * NdrComplexArrayMemorySize [RPCRT4.@]
3036 ULONG WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3037 PFORMAT_STRING pFormat
)
3039 ULONG i
, count
, esize
, SavedMemorySize
, MemorySize
;
3040 unsigned char alignment
;
3041 unsigned char *Buffer
;
3043 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3045 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3047 ERR("invalid format type %x\n", pFormat
[0]);
3048 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3052 alignment
= pFormat
[1] + 1;
3056 pFormat
= ReadConformance(pStubMsg
, pFormat
);
3057 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3059 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3061 SavedMemorySize
= pStubMsg
->MemorySize
;
3063 Buffer
= pStubMsg
->Buffer
;
3064 pStubMsg
->MemorySize
= 0;
3065 esize
= ComplexStructMemorySize(pStubMsg
, pFormat
);
3066 pStubMsg
->Buffer
= Buffer
;
3068 MemorySize
= safe_multiply(pStubMsg
->MaxCount
, esize
);
3070 count
= pStubMsg
->ActualCount
;
3071 for (i
= 0; i
< count
; i
++)
3072 ComplexStructMemorySize(pStubMsg
, pFormat
);
3074 pStubMsg
->MemorySize
= SavedMemorySize
;
3076 pStubMsg
->MemorySize
+= MemorySize
;
3080 /***********************************************************************
3081 * NdrComplexArrayFree [RPCRT4.@]
3083 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3084 unsigned char *pMemory
,
3085 PFORMAT_STRING pFormat
)
3087 ULONG i
, count
, def
;
3089 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3091 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3093 ERR("invalid format type %x\n", pFormat
[0]);
3094 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3098 def
= *(const WORD
*)&pFormat
[2];
3101 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3102 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3104 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3105 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3107 count
= pStubMsg
->ActualCount
;
3108 for (i
= 0; i
< count
; i
++)
3109 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
3112 static ULONG
UserMarshalFlags(const MIDL_STUB_MESSAGE
*pStubMsg
)
3114 return MAKELONG(pStubMsg
->dwDestContext
,
3115 pStubMsg
->RpcMsg
->DataRepresentation
);
3118 #define USER_MARSHAL_PTR_PREFIX \
3119 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3120 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3122 /***********************************************************************
3123 * NdrUserMarshalMarshall [RPCRT4.@]
3125 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3126 unsigned char *pMemory
,
3127 PFORMAT_STRING pFormat
)
3129 unsigned flags
= pFormat
[1];
3130 unsigned index
= *(const WORD
*)&pFormat
[2];
3131 unsigned char *saved_buffer
= NULL
;
3132 ULONG uflag
= UserMarshalFlags(pStubMsg
);
3133 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3134 TRACE("index=%d\n", index
);
3136 if (flags
& USER_MARSHAL_POINTER
)
3138 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3139 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, USER_MARSHAL_PTR_PREFIX
);
3140 pStubMsg
->Buffer
+= 4;
3141 if (pStubMsg
->PointerBufferMark
)
3143 saved_buffer
= pStubMsg
->Buffer
;
3144 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3145 pStubMsg
->PointerBufferMark
= NULL
;
3147 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3150 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3153 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
3154 &uflag
, pStubMsg
->Buffer
, pMemory
);
3158 STD_OVERFLOW_CHECK(pStubMsg
);
3159 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3160 pStubMsg
->Buffer
= saved_buffer
;
3163 STD_OVERFLOW_CHECK(pStubMsg
);
3168 /***********************************************************************
3169 * NdrUserMarshalUnmarshall [RPCRT4.@]
3171 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3172 unsigned char **ppMemory
,
3173 PFORMAT_STRING pFormat
,
3174 unsigned char fMustAlloc
)
3176 unsigned flags
= pFormat
[1];
3177 unsigned index
= *(const WORD
*)&pFormat
[2];
3178 DWORD memsize
= *(const WORD
*)&pFormat
[4];
3179 unsigned char *saved_buffer
= NULL
;
3180 ULONG uflag
= UserMarshalFlags(pStubMsg
);
3181 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3182 TRACE("index=%d\n", index
);
3184 if (flags
& USER_MARSHAL_POINTER
)
3186 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3187 /* skip pointer prefix */
3188 pStubMsg
->Buffer
+= 4;
3189 if (pStubMsg
->PointerBufferMark
)
3191 saved_buffer
= pStubMsg
->Buffer
;
3192 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3193 pStubMsg
->PointerBufferMark
= NULL
;
3195 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3198 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3200 if (fMustAlloc
|| !*ppMemory
)
3201 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
3204 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
3205 &uflag
, pStubMsg
->Buffer
, *ppMemory
);
3209 STD_OVERFLOW_CHECK(pStubMsg
);
3210 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3211 pStubMsg
->Buffer
= saved_buffer
;
3217 /***********************************************************************
3218 * NdrUserMarshalBufferSize [RPCRT4.@]
3220 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3221 unsigned char *pMemory
,
3222 PFORMAT_STRING pFormat
)
3224 unsigned flags
= pFormat
[1];
3225 unsigned index
= *(const WORD
*)&pFormat
[2];
3226 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
3227 ULONG uflag
= UserMarshalFlags(pStubMsg
);
3228 unsigned long saved_buffer_length
= 0;
3229 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3230 TRACE("index=%d\n", index
);
3232 if (flags
& USER_MARSHAL_POINTER
)
3234 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
3235 /* skip pointer prefix */
3236 pStubMsg
->BufferLength
+= 4;
3237 if (pStubMsg
->IgnoreEmbeddedPointers
)
3239 if (pStubMsg
->PointerLength
)
3241 saved_buffer_length
= pStubMsg
->BufferLength
;
3242 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3243 pStubMsg
->PointerLength
= 0;
3245 ALIGN_LENGTH(pStubMsg
->BufferLength
, 8);
3248 ALIGN_LENGTH(pStubMsg
->BufferLength
, (flags
& 0xf) + 1);
3251 TRACE("size=%d\n", bufsize
);
3252 pStubMsg
->BufferLength
+= bufsize
;
3255 pStubMsg
->BufferLength
=
3256 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
3257 &uflag
, pStubMsg
->BufferLength
, pMemory
);
3259 if (saved_buffer_length
)
3261 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3262 pStubMsg
->BufferLength
= saved_buffer_length
;
3267 /***********************************************************************
3268 * NdrUserMarshalMemorySize [RPCRT4.@]
3270 ULONG WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3271 PFORMAT_STRING pFormat
)
3273 unsigned flags
= pFormat
[1];
3274 unsigned index
= *(const WORD
*)&pFormat
[2];
3275 DWORD memsize
= *(const WORD
*)&pFormat
[4];
3276 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
3278 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3279 TRACE("index=%d\n", index
);
3281 pStubMsg
->MemorySize
+= memsize
;
3283 if (flags
& USER_MARSHAL_POINTER
)
3285 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3286 /* skip pointer prefix */
3287 pStubMsg
->Buffer
+= 4;
3288 if (pStubMsg
->IgnoreEmbeddedPointers
)
3289 return pStubMsg
->MemorySize
;
3290 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3293 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3296 FIXME("not implemented for varying buffer size\n");
3298 pStubMsg
->Buffer
+= bufsize
;
3300 return pStubMsg
->MemorySize
;
3303 /***********************************************************************
3304 * NdrUserMarshalFree [RPCRT4.@]
3306 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
3307 unsigned char *pMemory
,
3308 PFORMAT_STRING pFormat
)
3310 /* unsigned flags = pFormat[1]; */
3311 unsigned index
= *(const WORD
*)&pFormat
[2];
3312 ULONG uflag
= UserMarshalFlags(pStubMsg
);
3313 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3314 TRACE("index=%d\n", index
);
3316 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
3320 /***********************************************************************
3321 * NdrClearOutParameters [RPCRT4.@]
3323 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
3324 PFORMAT_STRING pFormat
,
3327 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
3330 /***********************************************************************
3331 * NdrConvert [RPCRT4.@]
3333 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
3335 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
3336 /* FIXME: since this stub doesn't do any converting, the proper behavior
3337 is to raise an exception */
3340 /***********************************************************************
3341 * NdrConvert2 [RPCRT4.@]
3343 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, LONG NumberParams
)
3345 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3346 pStubMsg
, pFormat
, NumberParams
);
3347 /* FIXME: since this stub doesn't do any converting, the proper behavior
3348 is to raise an exception */
3351 #include "pshpack1.h"
3352 typedef struct _NDR_CSTRUCT_FORMAT
3355 unsigned char alignment
;
3356 unsigned short memory_size
;
3357 short offset_to_array_description
;
3358 } NDR_CSTRUCT_FORMAT
, NDR_CVSTRUCT_FORMAT
;
3359 #include "poppack.h"
3361 /***********************************************************************
3362 * NdrConformantStructMarshall [RPCRT4.@]
3364 unsigned char * WINAPI
NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3365 unsigned char *pMemory
,
3366 PFORMAT_STRING pFormat
)
3368 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3369 PFORMAT_STRING pCArrayFormat
;
3370 ULONG esize
, bufsize
;
3372 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3374 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3375 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3377 ERR("invalid format type %x\n", pCStructFormat
->type
);
3378 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3382 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3383 pCStructFormat
->offset_to_array_description
;
3384 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3386 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3387 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3390 esize
= *(const WORD
*)(pCArrayFormat
+2);
3392 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
3393 pCArrayFormat
+ 4, 0);
3395 WriteConformance(pStubMsg
);
3397 ALIGN_POINTER(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
3399 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3401 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3402 /* copy constant sized part of struct */
3403 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3404 memcpy(pStubMsg
->Buffer
, pMemory
, pCStructFormat
->memory_size
+ bufsize
);
3405 pStubMsg
->Buffer
+= pCStructFormat
->memory_size
+ bufsize
;
3407 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3408 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3410 STD_OVERFLOW_CHECK(pStubMsg
);
3415 /***********************************************************************
3416 * NdrConformantStructUnmarshall [RPCRT4.@]
3418 unsigned char * WINAPI
NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3419 unsigned char **ppMemory
,
3420 PFORMAT_STRING pFormat
,
3421 unsigned char fMustAlloc
)
3423 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3424 PFORMAT_STRING pCArrayFormat
;
3425 ULONG esize
, bufsize
;
3427 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3429 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3430 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3432 ERR("invalid format type %x\n", pCStructFormat
->type
);
3433 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3436 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3437 pCStructFormat
->offset_to_array_description
;
3438 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3440 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3441 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3444 esize
= *(const WORD
*)(pCArrayFormat
+2);
3446 pCArrayFormat
= ReadConformance(pStubMsg
, pCArrayFormat
+ 4);
3448 ALIGN_POINTER(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
3450 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3452 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3453 /* work out how much memory to allocate if we need to do so */
3454 if (!*ppMemory
|| fMustAlloc
)
3456 SIZE_T size
= pCStructFormat
->memory_size
+ bufsize
;
3457 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3460 /* now copy the data */
3461 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3462 safe_buffer_copy(pStubMsg
, *ppMemory
, pCStructFormat
->memory_size
+ bufsize
);
3464 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3465 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3470 /***********************************************************************
3471 * NdrConformantStructBufferSize [RPCRT4.@]
3473 void WINAPI
NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3474 unsigned char *pMemory
,
3475 PFORMAT_STRING pFormat
)
3477 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3478 PFORMAT_STRING pCArrayFormat
;
3481 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3483 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3484 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3486 ERR("invalid format type %x\n", pCStructFormat
->type
);
3487 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3490 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3491 pCStructFormat
->offset_to_array_description
;
3492 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3494 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3495 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3498 esize
= *(const WORD
*)(pCArrayFormat
+2);
3500 pCArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
, pCArrayFormat
+4, 0);
3501 SizeConformance(pStubMsg
);
3503 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCStructFormat
->alignment
+ 1);
3505 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3507 pStubMsg
->BufferLength
+= pCStructFormat
->memory_size
+
3508 safe_multiply(pStubMsg
->MaxCount
, esize
);
3510 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3511 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3514 /***********************************************************************
3515 * NdrConformantStructMemorySize [RPCRT4.@]
3517 ULONG WINAPI
NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3518 PFORMAT_STRING pFormat
)
3524 /***********************************************************************
3525 * NdrConformantStructFree [RPCRT4.@]
3527 void WINAPI
NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3528 unsigned char *pMemory
,
3529 PFORMAT_STRING pFormat
)
3534 /***********************************************************************
3535 * NdrConformantVaryingStructMarshall [RPCRT4.@]
3537 unsigned char * WINAPI
NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3538 unsigned char *pMemory
,
3539 PFORMAT_STRING pFormat
)
3541 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3542 PFORMAT_STRING pCVArrayFormat
;
3543 ULONG esize
, bufsize
;
3545 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3547 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3548 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3550 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3551 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3555 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3556 pCVStructFormat
->offset_to_array_description
;
3557 switch (*pCVArrayFormat
)
3559 case RPC_FC_CVARRAY
:
3560 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3562 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3563 pCVArrayFormat
+ 4, 0);
3564 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3567 case RPC_FC_C_CSTRING
:
3568 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
3569 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
3570 esize
= sizeof(char);
3571 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3572 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3573 pCVArrayFormat
+ 2, 0);
3575 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3577 case RPC_FC_C_WSTRING
:
3578 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
3579 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
3580 esize
= sizeof(WCHAR
);
3581 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3582 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3583 pCVArrayFormat
+ 2, 0);
3585 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3588 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3589 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3593 WriteConformance(pStubMsg
);
3595 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
3597 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3599 /* write constant sized part */
3600 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3601 memcpy(pStubMsg
->Buffer
, pMemory
, pCVStructFormat
->memory_size
);
3602 pStubMsg
->Buffer
+= pCVStructFormat
->memory_size
;
3604 WriteVariance(pStubMsg
);
3606 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3608 /* write array part */
3609 memcpy(pStubMsg
->Buffer
, pMemory
+ pCVStructFormat
->memory_size
, bufsize
);
3610 pStubMsg
->Buffer
+= bufsize
;
3612 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3614 STD_OVERFLOW_CHECK(pStubMsg
);
3619 /***********************************************************************
3620 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3622 unsigned char * WINAPI
NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3623 unsigned char **ppMemory
,
3624 PFORMAT_STRING pFormat
,
3625 unsigned char fMustAlloc
)
3627 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3628 PFORMAT_STRING pCVArrayFormat
;
3629 ULONG esize
, bufsize
;
3630 unsigned char cvarray_type
;
3632 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3634 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3635 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3637 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3638 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3642 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3643 pCVStructFormat
->offset_to_array_description
;
3644 cvarray_type
= *pCVArrayFormat
;
3645 switch (cvarray_type
)
3647 case RPC_FC_CVARRAY
:
3648 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3649 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 4);
3651 case RPC_FC_C_CSTRING
:
3652 esize
= sizeof(char);
3653 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3654 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3656 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3658 case RPC_FC_C_WSTRING
:
3659 esize
= sizeof(WCHAR
);
3660 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3661 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3663 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3666 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3667 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3671 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
3673 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3675 /* work out how much memory to allocate if we need to do so */
3676 if (!*ppMemory
|| fMustAlloc
)
3678 SIZE_T size
= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->MaxCount
);
3679 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3682 /* copy the constant data */
3683 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3684 safe_buffer_copy(pStubMsg
, *ppMemory
, pCVStructFormat
->memory_size
);
3686 pCVArrayFormat
= ReadVariance(pStubMsg
, pCVArrayFormat
, pStubMsg
->MaxCount
);
3688 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3690 if ((cvarray_type
== RPC_FC_C_CSTRING
) ||
3691 (cvarray_type
== RPC_FC_C_WSTRING
))
3694 /* strings must always have null terminating bytes */
3695 if (bufsize
< esize
)
3697 ERR("invalid string length of %d\n", pStubMsg
->ActualCount
);
3698 RpcRaiseException(RPC_S_INVALID_BOUND
);
3701 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
3702 if (pStubMsg
->Buffer
[i
] != 0)
3704 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
3705 i
, pStubMsg
->Buffer
[i
]);
3706 RpcRaiseException(RPC_S_INVALID_BOUND
);
3711 /* copy the array data */
3712 safe_buffer_copy(pStubMsg
, *ppMemory
+ pCVStructFormat
->memory_size
, bufsize
);
3714 if (cvarray_type
== RPC_FC_C_CSTRING
)
3715 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory
+ pCVStructFormat
->memory_size
)));
3716 else if (cvarray_type
== RPC_FC_C_WSTRING
)
3717 TRACE("string=%s\n", debugstr_w((WCHAR
*)(*ppMemory
+ pCVStructFormat
->memory_size
)));
3719 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3724 /***********************************************************************
3725 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3727 void WINAPI
NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3728 unsigned char *pMemory
,
3729 PFORMAT_STRING pFormat
)
3731 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3732 PFORMAT_STRING pCVArrayFormat
;
3735 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3737 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3738 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3740 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3741 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3745 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3746 pCVStructFormat
->offset_to_array_description
;
3747 switch (*pCVArrayFormat
)
3749 case RPC_FC_CVARRAY
:
3750 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3752 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3753 pCVArrayFormat
+ 4, 0);
3754 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3757 case RPC_FC_C_CSTRING
:
3758 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
3759 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
3760 esize
= sizeof(char);
3761 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3762 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3763 pCVArrayFormat
+ 2, 0);
3765 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3767 case RPC_FC_C_WSTRING
:
3768 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
3769 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
3770 esize
= sizeof(WCHAR
);
3771 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3772 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3773 pCVArrayFormat
+ 2, 0);
3775 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3778 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3779 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3783 SizeConformance(pStubMsg
);
3785 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCVStructFormat
->alignment
+ 1);
3787 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3789 pStubMsg
->BufferLength
+= pCVStructFormat
->memory_size
;
3790 SizeVariance(pStubMsg
);
3791 pStubMsg
->BufferLength
+= safe_multiply(pStubMsg
->MaxCount
, esize
);
3793 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3796 /***********************************************************************
3797 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
3799 ULONG WINAPI
NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3800 PFORMAT_STRING pFormat
)
3802 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3803 PFORMAT_STRING pCVArrayFormat
;
3805 unsigned char cvarray_type
;
3807 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
3809 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3810 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3812 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3813 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3817 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3818 pCVStructFormat
->offset_to_array_description
;
3819 cvarray_type
= *pCVArrayFormat
;
3820 switch (cvarray_type
)
3822 case RPC_FC_CVARRAY
:
3823 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3824 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 4);
3826 case RPC_FC_C_CSTRING
:
3827 esize
= sizeof(char);
3828 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3829 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3831 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3833 case RPC_FC_C_WSTRING
:
3834 esize
= sizeof(WCHAR
);
3835 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3836 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3838 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3841 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3842 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3846 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
3848 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3850 pStubMsg
->Buffer
+= pCVStructFormat
->memory_size
;
3851 pCVArrayFormat
= ReadVariance(pStubMsg
, pCVArrayFormat
, pStubMsg
->MaxCount
);
3852 pStubMsg
->Buffer
+= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->ActualCount
);
3854 pStubMsg
->MemorySize
+= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->MaxCount
);
3856 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
3858 return pCVStructFormat
->memory_size
+ pStubMsg
->MaxCount
* esize
;
3861 /***********************************************************************
3862 * NdrConformantVaryingStructFree [RPCRT4.@]
3864 void WINAPI
NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3865 unsigned char *pMemory
,
3866 PFORMAT_STRING pFormat
)
3868 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3869 PFORMAT_STRING pCVArrayFormat
;
3872 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3874 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3875 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3877 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3878 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3882 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3883 pCVStructFormat
->offset_to_array_description
;
3884 switch (*pCVArrayFormat
)
3886 case RPC_FC_CVARRAY
:
3887 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3889 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3890 pCVArrayFormat
+ 4, 0);
3891 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3894 case RPC_FC_C_CSTRING
:
3895 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
3896 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
3897 esize
= sizeof(char);
3898 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3899 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3900 pCVArrayFormat
+ 2, 0);
3902 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3904 case RPC_FC_C_WSTRING
:
3905 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
3906 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
3907 esize
= sizeof(WCHAR
);
3908 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3909 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3910 pCVArrayFormat
+ 2, 0);
3912 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3915 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3916 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3920 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3922 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
3925 #include "pshpack1.h"
3929 unsigned char alignment
;
3930 unsigned short total_size
;
3931 } NDR_SMFARRAY_FORMAT
;
3936 unsigned char alignment
;
3937 unsigned long total_size
;
3938 } NDR_LGFARRAY_FORMAT
;
3939 #include "poppack.h"
3941 /***********************************************************************
3942 * NdrFixedArrayMarshall [RPCRT4.@]
3944 unsigned char * WINAPI
NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3945 unsigned char *pMemory
,
3946 PFORMAT_STRING pFormat
)
3948 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
3949 unsigned long total_size
;
3951 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3953 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
3954 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
3956 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
3957 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3961 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
3963 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
3965 total_size
= pSmFArrayFormat
->total_size
;
3966 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
3970 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
3971 total_size
= pLgFArrayFormat
->total_size
;
3972 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
3975 memcpy(pStubMsg
->Buffer
, pMemory
, total_size
);
3976 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3977 pStubMsg
->Buffer
+= total_size
;
3979 pFormat
= EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3984 /***********************************************************************
3985 * NdrFixedArrayUnmarshall [RPCRT4.@]
3987 unsigned char * WINAPI
NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3988 unsigned char **ppMemory
,
3989 PFORMAT_STRING pFormat
,
3990 unsigned char fMustAlloc
)
3992 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
3993 unsigned long total_size
;
3995 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3997 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
3998 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4000 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4001 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4005 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4007 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4009 total_size
= pSmFArrayFormat
->total_size
;
4010 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4014 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4015 total_size
= pLgFArrayFormat
->total_size
;
4016 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4019 if (fMustAlloc
|| !*ppMemory
)
4020 *ppMemory
= NdrAllocate(pStubMsg
, total_size
);
4021 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4022 safe_buffer_copy(pStubMsg
, *ppMemory
, total_size
);
4024 pFormat
= EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4029 /***********************************************************************
4030 * NdrFixedArrayBufferSize [RPCRT4.@]
4032 void WINAPI
NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4033 unsigned char *pMemory
,
4034 PFORMAT_STRING pFormat
)
4036 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4037 unsigned long total_size
;
4039 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4041 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4042 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4044 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4045 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4049 ALIGN_LENGTH(pStubMsg
->BufferLength
, pSmFArrayFormat
->alignment
+ 1);
4051 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4053 total_size
= pSmFArrayFormat
->total_size
;
4054 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4058 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4059 total_size
= pLgFArrayFormat
->total_size
;
4060 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4062 pStubMsg
->BufferLength
+= total_size
;
4064 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4067 /***********************************************************************
4068 * NdrFixedArrayMemorySize [RPCRT4.@]
4070 ULONG WINAPI
NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4071 PFORMAT_STRING pFormat
)
4073 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4076 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4078 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4079 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4081 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4082 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4086 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4088 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4090 total_size
= pSmFArrayFormat
->total_size
;
4091 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4095 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4096 total_size
= pLgFArrayFormat
->total_size
;
4097 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4099 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4100 pStubMsg
->Buffer
+= total_size
;
4101 pStubMsg
->MemorySize
+= total_size
;
4103 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4108 /***********************************************************************
4109 * NdrFixedArrayFree [RPCRT4.@]
4111 void WINAPI
NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4112 unsigned char *pMemory
,
4113 PFORMAT_STRING pFormat
)
4115 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4117 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4119 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4120 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4122 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4123 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4127 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4128 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4131 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4132 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4135 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4138 /***********************************************************************
4139 * NdrVaryingArrayMarshall [RPCRT4.@]
4141 unsigned char * WINAPI
NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4142 unsigned char *pMemory
,
4143 PFORMAT_STRING pFormat
)
4145 unsigned char alignment
;
4146 DWORD elements
, esize
;
4149 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4151 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4152 (pFormat
[0] != RPC_FC_LGVARRAY
))
4154 ERR("invalid format type %x\n", pFormat
[0]);
4155 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4159 alignment
= pFormat
[1] + 1;
4161 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4164 pFormat
+= sizeof(WORD
);
4165 elements
= *(const WORD
*)pFormat
;
4166 pFormat
+= sizeof(WORD
);
4171 pFormat
+= sizeof(DWORD
);
4172 elements
= *(const DWORD
*)pFormat
;
4173 pFormat
+= sizeof(DWORD
);
4176 esize
= *(const WORD
*)pFormat
;
4177 pFormat
+= sizeof(WORD
);
4179 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4180 if ((pStubMsg
->ActualCount
> elements
) ||
4181 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4183 RpcRaiseException(RPC_S_INVALID_BOUND
);
4187 WriteVariance(pStubMsg
);
4189 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4191 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4192 memcpy(pStubMsg
->Buffer
, pMemory
+ pStubMsg
->Offset
, bufsize
);
4193 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4194 pStubMsg
->Buffer
+= bufsize
;
4196 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4198 STD_OVERFLOW_CHECK(pStubMsg
);
4203 /***********************************************************************
4204 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4206 unsigned char * WINAPI
NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4207 unsigned char **ppMemory
,
4208 PFORMAT_STRING pFormat
,
4209 unsigned char fMustAlloc
)
4211 unsigned char alignment
;
4212 DWORD size
, elements
, esize
;
4215 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4217 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4218 (pFormat
[0] != RPC_FC_LGVARRAY
))
4220 ERR("invalid format type %x\n", pFormat
[0]);
4221 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4225 alignment
= pFormat
[1] + 1;
4227 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4230 size
= *(const WORD
*)pFormat
;
4231 pFormat
+= sizeof(WORD
);
4232 elements
= *(const WORD
*)pFormat
;
4233 pFormat
+= sizeof(WORD
);
4238 size
= *(const DWORD
*)pFormat
;
4239 pFormat
+= sizeof(DWORD
);
4240 elements
= *(const DWORD
*)pFormat
;
4241 pFormat
+= sizeof(DWORD
);
4244 esize
= *(const WORD
*)pFormat
;
4245 pFormat
+= sizeof(WORD
);
4247 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
4249 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4251 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4253 if (!*ppMemory
|| fMustAlloc
)
4254 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4255 safe_buffer_copy(pStubMsg
, *ppMemory
+ pStubMsg
->Offset
, bufsize
);
4257 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4262 /***********************************************************************
4263 * NdrVaryingArrayBufferSize [RPCRT4.@]
4265 void WINAPI
NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4266 unsigned char *pMemory
,
4267 PFORMAT_STRING pFormat
)
4269 unsigned char alignment
;
4270 DWORD elements
, esize
;
4272 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4274 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4275 (pFormat
[0] != RPC_FC_LGVARRAY
))
4277 ERR("invalid format type %x\n", pFormat
[0]);
4278 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4282 alignment
= pFormat
[1] + 1;
4284 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4287 pFormat
+= sizeof(WORD
);
4288 elements
= *(const WORD
*)pFormat
;
4289 pFormat
+= sizeof(WORD
);
4294 pFormat
+= sizeof(DWORD
);
4295 elements
= *(const DWORD
*)pFormat
;
4296 pFormat
+= sizeof(DWORD
);
4299 esize
= *(const WORD
*)pFormat
;
4300 pFormat
+= sizeof(WORD
);
4302 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4303 if ((pStubMsg
->ActualCount
> elements
) ||
4304 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4306 RpcRaiseException(RPC_S_INVALID_BOUND
);
4310 SizeVariance(pStubMsg
);
4312 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
4314 pStubMsg
->BufferLength
+= safe_multiply(esize
, pStubMsg
->ActualCount
);
4316 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4319 /***********************************************************************
4320 * NdrVaryingArrayMemorySize [RPCRT4.@]
4322 ULONG WINAPI
NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4323 PFORMAT_STRING pFormat
)
4325 unsigned char alignment
;
4326 DWORD size
, elements
, esize
;
4328 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4330 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4331 (pFormat
[0] != RPC_FC_LGVARRAY
))
4333 ERR("invalid format type %x\n", pFormat
[0]);
4334 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4338 alignment
= pFormat
[1] + 1;
4340 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4343 size
= *(const WORD
*)pFormat
;
4344 pFormat
+= sizeof(WORD
);
4345 elements
= *(const WORD
*)pFormat
;
4346 pFormat
+= sizeof(WORD
);
4351 size
= *(const DWORD
*)pFormat
;
4352 pFormat
+= sizeof(DWORD
);
4353 elements
= *(const DWORD
*)pFormat
;
4354 pFormat
+= sizeof(DWORD
);
4357 esize
= *(const WORD
*)pFormat
;
4358 pFormat
+= sizeof(WORD
);
4360 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
4362 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4364 pStubMsg
->Buffer
+= safe_multiply(esize
, pStubMsg
->ActualCount
);
4365 pStubMsg
->MemorySize
+= size
;
4367 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4369 return pStubMsg
->MemorySize
;
4372 /***********************************************************************
4373 * NdrVaryingArrayFree [RPCRT4.@]
4375 void WINAPI
NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4376 unsigned char *pMemory
,
4377 PFORMAT_STRING pFormat
)
4379 unsigned char alignment
;
4382 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4384 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4385 (pFormat
[0] != RPC_FC_LGVARRAY
))
4387 ERR("invalid format type %x\n", pFormat
[0]);
4388 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4392 alignment
= pFormat
[1] + 1;
4394 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4397 pFormat
+= sizeof(WORD
);
4398 elements
= *(const WORD
*)pFormat
;
4399 pFormat
+= sizeof(WORD
);
4404 pFormat
+= sizeof(DWORD
);
4405 elements
= *(const DWORD
*)pFormat
;
4406 pFormat
+= sizeof(DWORD
);
4409 pFormat
+= sizeof(WORD
);
4411 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4412 if ((pStubMsg
->ActualCount
> elements
) ||
4413 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4415 RpcRaiseException(RPC_S_INVALID_BOUND
);
4419 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4422 static ULONG
get_discriminant(unsigned char fc
, const unsigned char *pMemory
)
4430 return *(const UCHAR
*)pMemory
;
4435 return *(const USHORT
*)pMemory
;
4439 return *(const ULONG
*)pMemory
;
4441 FIXME("Unhandled base type: 0x%02x\n", fc
);
4446 static PFORMAT_STRING
get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg
,
4447 unsigned long discriminant
,
4448 PFORMAT_STRING pFormat
)
4450 unsigned short num_arms
, arm
, type
;
4452 num_arms
= *(const SHORT
*)pFormat
& 0x0fff;
4454 for(arm
= 0; arm
< num_arms
; arm
++)
4456 if(discriminant
== *(const ULONG
*)pFormat
)
4464 type
= *(const unsigned short*)pFormat
;
4465 TRACE("type %04x\n", type
);
4466 if(arm
== num_arms
) /* default arm extras */
4470 ERR("no arm for 0x%lx and no default case\n", discriminant
);
4471 RpcRaiseException(RPC_S_INVALID_TAG
);
4476 TRACE("falling back to empty default case for 0x%lx\n", discriminant
);
4483 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
, ULONG discriminant
, PFORMAT_STRING pFormat
)
4485 unsigned short type
;
4489 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4493 type
= *(const unsigned short*)pFormat
;
4494 if((type
& 0xff00) == 0x8000)
4496 unsigned char basetype
= LOBYTE(type
);
4497 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &basetype
);
4501 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4502 NDR_MARSHALL m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
4505 unsigned char *saved_buffer
= NULL
;
4506 int pointer_buffer_mark_set
= 0;
4513 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4514 saved_buffer
= pStubMsg
->Buffer
;
4515 if (pStubMsg
->PointerBufferMark
)
4517 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4518 pStubMsg
->PointerBufferMark
= NULL
;
4519 pointer_buffer_mark_set
= 1;
4522 pStubMsg
->Buffer
+= 4; /* for pointer ID */
4524 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char **)pMemory
, desc
);
4525 if (pointer_buffer_mark_set
)
4527 STD_OVERFLOW_CHECK(pStubMsg
);
4528 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4529 pStubMsg
->Buffer
= saved_buffer
+ 4;
4533 m(pStubMsg
, pMemory
, desc
);
4536 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4541 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4542 unsigned char **ppMemory
,
4544 PFORMAT_STRING pFormat
,
4545 unsigned char fMustAlloc
)
4547 unsigned short type
;
4551 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4555 type
= *(const unsigned short*)pFormat
;
4556 if((type
& 0xff00) == 0x8000)
4558 unsigned char basetype
= LOBYTE(type
);
4559 return NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &basetype
, FALSE
);
4563 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4564 NDR_UNMARSHALL m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
4567 unsigned char *saved_buffer
= NULL
;
4568 int pointer_buffer_mark_set
= 0;
4575 **(void***)ppMemory
= NULL
;
4576 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4577 saved_buffer
= pStubMsg
->Buffer
;
4578 if (pStubMsg
->PointerBufferMark
)
4580 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4581 pStubMsg
->PointerBufferMark
= NULL
;
4582 pointer_buffer_mark_set
= 1;
4585 pStubMsg
->Buffer
+= 4; /* for pointer ID */
4587 if (saved_buffer
+ 4 > pStubMsg
->BufferEnd
)
4588 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
4590 PointerUnmarshall(pStubMsg
, saved_buffer
, *(unsigned char ***)ppMemory
, desc
, fMustAlloc
);
4591 if (pointer_buffer_mark_set
)
4593 STD_OVERFLOW_CHECK(pStubMsg
);
4594 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4595 pStubMsg
->Buffer
= saved_buffer
+ 4;
4599 m(pStubMsg
, ppMemory
, desc
, fMustAlloc
);
4602 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4607 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg
,
4608 unsigned char *pMemory
,
4610 PFORMAT_STRING pFormat
)
4612 unsigned short type
;
4616 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4620 type
= *(const unsigned short*)pFormat
;
4621 if((type
& 0xff00) == 0x8000)
4623 unsigned char basetype
= LOBYTE(type
);
4624 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &basetype
);
4628 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4629 NDR_BUFFERSIZE m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
4638 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
4639 pStubMsg
->BufferLength
+= 4; /* for pointer ID */
4640 if (!pStubMsg
->IgnoreEmbeddedPointers
)
4642 int saved_buffer_length
= pStubMsg
->BufferLength
;
4643 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4644 pStubMsg
->PointerLength
= 0;
4645 if(!pStubMsg
->BufferLength
)
4646 ERR("BufferLength == 0??\n");
4647 PointerBufferSize(pStubMsg
, *(unsigned char **)pMemory
, desc
);
4648 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4649 pStubMsg
->BufferLength
= saved_buffer_length
;
4653 m(pStubMsg
, pMemory
, desc
);
4656 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
4660 static ULONG
union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg
,
4662 PFORMAT_STRING pFormat
)
4664 unsigned short type
, size
;
4666 size
= *(const unsigned short*)pFormat
;
4667 pStubMsg
->Memory
+= size
;
4670 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4674 type
= *(const unsigned short*)pFormat
;
4675 if((type
& 0xff00) == 0x8000)
4677 return NdrBaseTypeMemorySize(pStubMsg
, pFormat
);
4681 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4682 NDR_MEMORYSIZE m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
4683 unsigned char *saved_buffer
;
4692 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4693 saved_buffer
= pStubMsg
->Buffer
;
4694 pStubMsg
->Buffer
+= 4;
4695 ALIGN_LENGTH(pStubMsg
->MemorySize
, 4);
4696 pStubMsg
->MemorySize
+= 4;
4697 if (!pStubMsg
->IgnoreEmbeddedPointers
)
4698 PointerMemorySize(pStubMsg
, saved_buffer
, pFormat
);
4701 return m(pStubMsg
, desc
);
4704 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4707 TRACE("size %d\n", size
);
4711 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg
,
4712 unsigned char *pMemory
,
4714 PFORMAT_STRING pFormat
)
4716 unsigned short type
;
4720 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4724 type
= *(const unsigned short*)pFormat
;
4725 if((type
& 0xff00) != 0x8000)
4727 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4728 NDR_FREE m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
4737 PointerFree(pStubMsg
, *(unsigned char **)pMemory
, desc
);
4740 m(pStubMsg
, pMemory
, desc
);
4743 else FIXME("no freer for embedded type %02x\n", *desc
);
4747 /***********************************************************************
4748 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
4750 unsigned char * WINAPI
NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4751 unsigned char *pMemory
,
4752 PFORMAT_STRING pFormat
)
4754 unsigned char switch_type
;
4755 unsigned char increment
;
4758 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4761 switch_type
= *pFormat
& 0xf;
4762 increment
= (*pFormat
& 0xf0) >> 4;
4765 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
4767 switch_value
= get_discriminant(switch_type
, pMemory
);
4768 TRACE("got switch value 0x%x\n", switch_value
);
4770 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &switch_type
);
4771 pMemory
+= increment
;
4773 return union_arm_marshall(pStubMsg
, pMemory
, switch_value
, pFormat
);
4776 /***********************************************************************
4777 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
4779 unsigned char * WINAPI
NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4780 unsigned char **ppMemory
,
4781 PFORMAT_STRING pFormat
,
4782 unsigned char fMustAlloc
)
4784 unsigned char switch_type
;
4785 unsigned char increment
;
4787 unsigned short size
;
4788 unsigned char *pMemoryArm
;
4790 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4793 switch_type
= *pFormat
& 0xf;
4794 increment
= (*pFormat
& 0xf0) >> 4;
4797 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
4798 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
4799 TRACE("got switch value 0x%x\n", switch_value
);
4801 size
= *(const unsigned short*)pFormat
+ increment
;
4802 if(!*ppMemory
|| fMustAlloc
)
4803 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4805 NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &switch_type
, FALSE
);
4806 pMemoryArm
= *ppMemory
+ increment
;
4808 return union_arm_unmarshall(pStubMsg
, &pMemoryArm
, switch_value
, pFormat
, fMustAlloc
);
4811 /***********************************************************************
4812 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
4814 void WINAPI
NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4815 unsigned char *pMemory
,
4816 PFORMAT_STRING pFormat
)
4818 unsigned char switch_type
;
4819 unsigned char increment
;
4822 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4825 switch_type
= *pFormat
& 0xf;
4826 increment
= (*pFormat
& 0xf0) >> 4;
4829 ALIGN_LENGTH(pStubMsg
->BufferLength
, increment
);
4830 switch_value
= get_discriminant(switch_type
, pMemory
);
4831 TRACE("got switch value 0x%x\n", switch_value
);
4833 /* Add discriminant size */
4834 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&switch_value
, &switch_type
);
4835 pMemory
+= increment
;
4837 union_arm_buffer_size(pStubMsg
, pMemory
, switch_value
, pFormat
);
4840 /***********************************************************************
4841 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
4843 ULONG WINAPI
NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4844 PFORMAT_STRING pFormat
)
4846 unsigned char switch_type
;
4847 unsigned char increment
;
4850 switch_type
= *pFormat
& 0xf;
4851 increment
= (*pFormat
& 0xf0) >> 4;
4854 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
4855 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
4856 TRACE("got switch value 0x%x\n", switch_value
);
4858 pStubMsg
->Memory
+= increment
;
4860 return increment
+ union_arm_memory_size(pStubMsg
, switch_value
, pFormat
+ *(const SHORT
*)pFormat
);
4863 /***********************************************************************
4864 * NdrEncapsulatedUnionFree [RPCRT4.@]
4866 void WINAPI
NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
4867 unsigned char *pMemory
,
4868 PFORMAT_STRING pFormat
)
4870 unsigned char switch_type
;
4871 unsigned char increment
;
4874 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4877 switch_type
= *pFormat
& 0xf;
4878 increment
= (*pFormat
& 0xf0) >> 4;
4881 switch_value
= get_discriminant(switch_type
, pMemory
);
4882 TRACE("got switch value 0x%x\n", switch_value
);
4884 pMemory
+= increment
;
4886 return union_arm_free(pStubMsg
, pMemory
, switch_value
, pFormat
);
4889 /***********************************************************************
4890 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
4892 unsigned char * WINAPI
NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4893 unsigned char *pMemory
,
4894 PFORMAT_STRING pFormat
)
4896 unsigned char switch_type
;
4898 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4901 switch_type
= *pFormat
;
4904 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
4905 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
4906 /* Marshall discriminant */
4907 NdrBaseTypeMarshall(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
4909 return union_arm_marshall(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
4912 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg
,
4913 PFORMAT_STRING
*ppFormat
)
4915 long discriminant
= 0;
4925 safe_buffer_copy(pStubMsg
, &d
, sizeof(d
));
4934 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
4935 safe_buffer_copy(pStubMsg
, &d
, sizeof(d
));
4943 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
4944 safe_buffer_copy(pStubMsg
, &d
, sizeof(d
));
4949 FIXME("Unhandled base type: 0x%02x\n", **ppFormat
);
4953 if (pStubMsg
->fHasNewCorrDesc
)
4957 return discriminant
;
4960 /**********************************************************************
4961 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
4963 unsigned char * WINAPI
NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4964 unsigned char **ppMemory
,
4965 PFORMAT_STRING pFormat
,
4966 unsigned char fMustAlloc
)
4969 unsigned short size
;
4971 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4974 /* Unmarshall discriminant */
4975 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
4976 TRACE("unmarshalled discriminant %lx\n", discriminant
);
4978 pFormat
+= *(const SHORT
*)pFormat
;
4980 size
= *(const unsigned short*)pFormat
;
4982 if(!*ppMemory
|| fMustAlloc
)
4983 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4985 return union_arm_unmarshall(pStubMsg
, ppMemory
, discriminant
, pFormat
, fMustAlloc
);
4988 /***********************************************************************
4989 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
4991 void WINAPI
NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4992 unsigned char *pMemory
,
4993 PFORMAT_STRING pFormat
)
4995 unsigned char switch_type
;
4997 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5000 switch_type
= *pFormat
;
5003 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5004 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5005 /* Add discriminant size */
5006 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
5008 union_arm_buffer_size(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5011 /***********************************************************************
5012 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5014 ULONG WINAPI
NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5015 PFORMAT_STRING pFormat
)
5020 /* Unmarshall discriminant */
5021 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
5022 TRACE("unmarshalled discriminant 0x%x\n", discriminant
);
5024 return union_arm_memory_size(pStubMsg
, discriminant
, pFormat
+ *(const SHORT
*)pFormat
);
5027 /***********************************************************************
5028 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5030 void WINAPI
NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
5031 unsigned char *pMemory
,
5032 PFORMAT_STRING pFormat
)
5034 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5038 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5039 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5041 return union_arm_free(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5044 /***********************************************************************
5045 * NdrByteCountPointerMarshall [RPCRT4.@]
5047 unsigned char * WINAPI
NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5048 unsigned char *pMemory
,
5049 PFORMAT_STRING pFormat
)
5055 /***********************************************************************
5056 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5058 unsigned char * WINAPI
NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5059 unsigned char **ppMemory
,
5060 PFORMAT_STRING pFormat
,
5061 unsigned char fMustAlloc
)
5067 /***********************************************************************
5068 * NdrByteCountPointerBufferSize [RPCRT4.@]
5070 void WINAPI
NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5071 unsigned char *pMemory
,
5072 PFORMAT_STRING pFormat
)
5077 /***********************************************************************
5078 * NdrByteCountPointerMemorySize [RPCRT4.@]
5080 ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5081 PFORMAT_STRING pFormat
)
5087 /***********************************************************************
5088 * NdrByteCountPointerFree [RPCRT4.@]
5090 void WINAPI
NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
5091 unsigned char *pMemory
,
5092 PFORMAT_STRING pFormat
)
5097 /***********************************************************************
5098 * NdrXmitOrRepAsMarshall [RPCRT4.@]
5100 unsigned char * WINAPI
NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5101 unsigned char *pMemory
,
5102 PFORMAT_STRING pFormat
)
5108 /***********************************************************************
5109 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
5111 unsigned char * WINAPI
NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5112 unsigned char **ppMemory
,
5113 PFORMAT_STRING pFormat
,
5114 unsigned char fMustAlloc
)
5120 /***********************************************************************
5121 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
5123 void WINAPI
NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5124 unsigned char *pMemory
,
5125 PFORMAT_STRING pFormat
)
5130 /***********************************************************************
5131 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
5133 ULONG WINAPI
NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5134 PFORMAT_STRING pFormat
)
5140 /***********************************************************************
5141 * NdrXmitOrRepAsFree [RPCRT4.@]
5143 void WINAPI
NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg
,
5144 unsigned char *pMemory
,
5145 PFORMAT_STRING pFormat
)
5150 #include "pshpack1.h"
5154 unsigned char flags_type
; /* flags in upper nibble, type in lower nibble */
5158 #include "poppack.h"
5160 /***********************************************************************
5161 * NdrRangeMarshall [internal]
5163 unsigned char *WINAPI
NdrRangeMarshall(
5164 PMIDL_STUB_MESSAGE pStubMsg
,
5165 unsigned char *pMemory
,
5166 PFORMAT_STRING pFormat
)
5168 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5169 unsigned char base_type
;
5171 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5173 if (pRange
->type
!= RPC_FC_RANGE
)
5175 ERR("invalid format type %x\n", pRange
->type
);
5176 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5180 base_type
= pRange
->flags_type
& 0xf;
5182 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &base_type
);
5185 /***********************************************************************
5186 * NdrRangeUnmarshall
5188 unsigned char *WINAPI
NdrRangeUnmarshall(
5189 PMIDL_STUB_MESSAGE pStubMsg
,
5190 unsigned char **ppMemory
,
5191 PFORMAT_STRING pFormat
,
5192 unsigned char fMustAlloc
)
5194 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5195 unsigned char base_type
;
5197 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
5199 if (pRange
->type
!= RPC_FC_RANGE
)
5201 ERR("invalid format type %x\n", pRange
->type
);
5202 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5205 base_type
= pRange
->flags_type
& 0xf;
5207 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5208 base_type
, pRange
->low_value
, pRange
->high_value
);
5210 #define RANGE_UNMARSHALL(type, format_spec) \
5213 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5214 if (fMustAlloc || !*ppMemory) \
5215 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5216 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5217 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5219 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5220 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5221 (type)pRange->high_value); \
5222 RpcRaiseException(RPC_S_INVALID_BOUND); \
5225 TRACE("*ppMemory: %p\n", *ppMemory); \
5226 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5227 pStubMsg->Buffer += sizeof(type); \
5234 RANGE_UNMARSHALL(UCHAR
, "%d");
5235 TRACE("value: 0x%02x\n", **(UCHAR
**)ppMemory
);
5239 RANGE_UNMARSHALL(CHAR
, "%u");
5240 TRACE("value: 0x%02x\n", **(UCHAR
**)ppMemory
);
5242 case RPC_FC_WCHAR
: /* FIXME: valid? */
5244 RANGE_UNMARSHALL(USHORT
, "%u");
5245 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5248 RANGE_UNMARSHALL(SHORT
, "%d");
5249 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5252 RANGE_UNMARSHALL(LONG
, "%d");
5253 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5256 RANGE_UNMARSHALL(ULONG
, "%u");
5257 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5261 FIXME("Unhandled enum type\n");
5263 case RPC_FC_ERROR_STATUS_T
: /* FIXME: valid? */
5268 ERR("invalid range base type: 0x%02x\n", base_type
);
5269 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5275 /***********************************************************************
5276 * NdrRangeBufferSize [internal]
5278 void WINAPI
NdrRangeBufferSize(
5279 PMIDL_STUB_MESSAGE pStubMsg
,
5280 unsigned char *pMemory
,
5281 PFORMAT_STRING pFormat
)
5283 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5284 unsigned char base_type
;
5286 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5288 if (pRange
->type
!= RPC_FC_RANGE
)
5290 ERR("invalid format type %x\n", pRange
->type
);
5291 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5293 base_type
= pRange
->flags_type
& 0xf;
5295 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &base_type
);
5298 /***********************************************************************
5299 * NdrRangeMemorySize [internal]
5301 ULONG WINAPI
NdrRangeMemorySize(
5302 PMIDL_STUB_MESSAGE pStubMsg
,
5303 PFORMAT_STRING pFormat
)
5305 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5306 unsigned char base_type
;
5308 if (pRange
->type
!= RPC_FC_RANGE
)
5310 ERR("invalid format type %x\n", pRange
->type
);
5311 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5314 base_type
= pRange
->flags_type
& 0xf;
5316 return NdrBaseTypeMemorySize(pStubMsg
, &base_type
);
5319 /***********************************************************************
5320 * NdrRangeFree [internal]
5322 void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg
,
5323 unsigned char *pMemory
,
5324 PFORMAT_STRING pFormat
)
5326 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5331 /***********************************************************************
5332 * NdrBaseTypeMarshall [internal]
5334 static unsigned char *WINAPI
NdrBaseTypeMarshall(
5335 PMIDL_STUB_MESSAGE pStubMsg
,
5336 unsigned char *pMemory
,
5337 PFORMAT_STRING pFormat
)
5339 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5347 *(UCHAR
*)pStubMsg
->Buffer
= *(UCHAR
*)pMemory
;
5348 pStubMsg
->Buffer
+= sizeof(UCHAR
);
5349 TRACE("value: 0x%02x\n", *(UCHAR
*)pMemory
);
5354 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5355 *(USHORT
*)pStubMsg
->Buffer
= *(USHORT
*)pMemory
;
5356 pStubMsg
->Buffer
+= sizeof(USHORT
);
5357 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
5361 case RPC_FC_ERROR_STATUS_T
:
5363 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
5364 *(ULONG
*)pStubMsg
->Buffer
= *(ULONG
*)pMemory
;
5365 pStubMsg
->Buffer
+= sizeof(ULONG
);
5366 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
5369 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(float));
5370 *(float *)pStubMsg
->Buffer
= *(float *)pMemory
;
5371 pStubMsg
->Buffer
+= sizeof(float);
5374 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(double));
5375 *(double *)pStubMsg
->Buffer
= *(double *)pMemory
;
5376 pStubMsg
->Buffer
+= sizeof(double);
5379 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONGLONG
));
5380 *(ULONGLONG
*)pStubMsg
->Buffer
= *(ULONGLONG
*)pMemory
;
5381 pStubMsg
->Buffer
+= sizeof(ULONGLONG
);
5382 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
5385 /* only 16-bits on the wire, so do a sanity check */
5386 if (*(UINT
*)pMemory
> SHRT_MAX
)
5387 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
5388 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5389 *(USHORT
*)pStubMsg
->Buffer
= *(UINT
*)pMemory
;
5390 pStubMsg
->Buffer
+= sizeof(USHORT
);
5391 TRACE("value: 0x%04x\n", *(UINT
*)pMemory
);
5394 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5397 STD_OVERFLOW_CHECK(pStubMsg
);
5399 /* FIXME: what is the correct return value? */
5403 /***********************************************************************
5404 * NdrBaseTypeUnmarshall [internal]
5406 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(
5407 PMIDL_STUB_MESSAGE pStubMsg
,
5408 unsigned char **ppMemory
,
5409 PFORMAT_STRING pFormat
,
5410 unsigned char fMustAlloc
)
5412 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
5414 #define BASE_TYPE_UNMARSHALL(type) \
5415 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5416 if (fMustAlloc || !*ppMemory) \
5417 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5418 TRACE("*ppMemory: %p\n", *ppMemory); \
5419 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5420 pStubMsg->Buffer += sizeof(type);
5428 BASE_TYPE_UNMARSHALL(UCHAR
);
5429 TRACE("value: 0x%02x\n", **(UCHAR
**)ppMemory
);
5434 BASE_TYPE_UNMARSHALL(USHORT
);
5435 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5439 case RPC_FC_ERROR_STATUS_T
:
5441 BASE_TYPE_UNMARSHALL(ULONG
);
5442 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5445 BASE_TYPE_UNMARSHALL(float);
5446 TRACE("value: %f\n", **(float **)ppMemory
);
5449 BASE_TYPE_UNMARSHALL(double);
5450 TRACE("value: %f\n", **(double **)ppMemory
);
5453 BASE_TYPE_UNMARSHALL(ULONGLONG
);
5454 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG
**)ppMemory
));
5457 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5458 if (fMustAlloc
|| !*ppMemory
)
5459 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT
));
5460 TRACE("*ppMemory: %p\n", *ppMemory
);
5461 /* 16-bits on the wire, but int in memory */
5462 **(UINT
**)ppMemory
= *(USHORT
*)pStubMsg
->Buffer
;
5463 pStubMsg
->Buffer
+= sizeof(USHORT
);
5464 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
5467 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5469 #undef BASE_TYPE_UNMARSHALL
5471 /* FIXME: what is the correct return value? */
5476 /***********************************************************************
5477 * NdrBaseTypeBufferSize [internal]
5479 static void WINAPI
NdrBaseTypeBufferSize(
5480 PMIDL_STUB_MESSAGE pStubMsg
,
5481 unsigned char *pMemory
,
5482 PFORMAT_STRING pFormat
)
5484 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5492 pStubMsg
->BufferLength
+= sizeof(UCHAR
);
5498 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(USHORT
));
5499 pStubMsg
->BufferLength
+= sizeof(USHORT
);
5504 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONG
));
5505 pStubMsg
->BufferLength
+= sizeof(ULONG
);
5508 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(float));
5509 pStubMsg
->BufferLength
+= sizeof(float);
5512 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(double));
5513 pStubMsg
->BufferLength
+= sizeof(double);
5516 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONGLONG
));
5517 pStubMsg
->BufferLength
+= sizeof(ULONGLONG
);
5519 case RPC_FC_ERROR_STATUS_T
:
5520 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(error_status_t
));
5521 pStubMsg
->BufferLength
+= sizeof(error_status_t
);
5524 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5528 /***********************************************************************
5529 * NdrBaseTypeMemorySize [internal]
5531 static ULONG WINAPI
NdrBaseTypeMemorySize(
5532 PMIDL_STUB_MESSAGE pStubMsg
,
5533 PFORMAT_STRING pFormat
)
5541 pStubMsg
->Buffer
+= sizeof(UCHAR
);
5542 pStubMsg
->MemorySize
+= sizeof(UCHAR
);
5543 return sizeof(UCHAR
);
5547 pStubMsg
->Buffer
+= sizeof(USHORT
);
5548 pStubMsg
->MemorySize
+= sizeof(USHORT
);
5549 return sizeof(USHORT
);
5552 pStubMsg
->Buffer
+= sizeof(ULONG
);
5553 pStubMsg
->MemorySize
+= sizeof(ULONG
);
5554 return sizeof(ULONG
);
5556 pStubMsg
->Buffer
+= sizeof(float);
5557 pStubMsg
->MemorySize
+= sizeof(float);
5558 return sizeof(float);
5560 pStubMsg
->Buffer
+= sizeof(double);
5561 pStubMsg
->MemorySize
+= sizeof(double);
5562 return sizeof(double);
5564 pStubMsg
->Buffer
+= sizeof(ULONGLONG
);
5565 pStubMsg
->MemorySize
+= sizeof(ULONGLONG
);
5566 return sizeof(ULONGLONG
);
5567 case RPC_FC_ERROR_STATUS_T
:
5568 pStubMsg
->Buffer
+= sizeof(error_status_t
);
5569 pStubMsg
->MemorySize
+= sizeof(error_status_t
);
5570 return sizeof(error_status_t
);
5573 pStubMsg
->Buffer
+= sizeof(INT
);
5574 pStubMsg
->MemorySize
+= sizeof(INT
);
5577 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5582 /***********************************************************************
5583 * NdrBaseTypeFree [internal]
5585 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg
,
5586 unsigned char *pMemory
,
5587 PFORMAT_STRING pFormat
)
5589 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5594 /***********************************************************************
5595 * NdrContextHandleBufferSize [internal]
5597 static void WINAPI
NdrContextHandleBufferSize(
5598 PMIDL_STUB_MESSAGE pStubMsg
,
5599 unsigned char *pMemory
,
5600 PFORMAT_STRING pFormat
)
5602 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5604 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
5606 ERR("invalid format type %x\n", *pFormat
);
5607 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5609 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
5610 pStubMsg
->BufferLength
+= cbNDRContext
;
5613 /***********************************************************************
5614 * NdrContextHandleMarshall [internal]
5616 static unsigned char *WINAPI
NdrContextHandleMarshall(
5617 PMIDL_STUB_MESSAGE pStubMsg
,
5618 unsigned char *pMemory
,
5619 PFORMAT_STRING pFormat
)
5621 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5623 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
5625 ERR("invalid format type %x\n", *pFormat
);
5626 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5629 if (pFormat
[1] & 0x80)
5630 NdrClientContextMarshall(pStubMsg
, *(NDR_CCONTEXT
**)pMemory
, FALSE
);
5632 NdrClientContextMarshall(pStubMsg
, (NDR_CCONTEXT
*)pMemory
, FALSE
);
5637 /***********************************************************************
5638 * NdrContextHandleUnmarshall [internal]
5640 static unsigned char *WINAPI
NdrContextHandleUnmarshall(
5641 PMIDL_STUB_MESSAGE pStubMsg
,
5642 unsigned char **ppMemory
,
5643 PFORMAT_STRING pFormat
,
5644 unsigned char fMustAlloc
)
5646 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
5648 ERR("invalid format type %x\n", *pFormat
);
5649 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5652 **(NDR_CCONTEXT
**)ppMemory
= NULL
;
5653 NdrClientContextUnmarshall(pStubMsg
, *(NDR_CCONTEXT
**)ppMemory
, pStubMsg
->RpcMsg
->Handle
);
5658 /***********************************************************************
5659 * NdrClientContextMarshall [RPCRT4.@]
5661 void WINAPI
NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5662 NDR_CCONTEXT ContextHandle
,
5665 TRACE("(%p, %p, %d)\n", pStubMsg
, ContextHandle
, fCheck
);
5667 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5669 /* FIXME: what does fCheck do? */
5670 NDRCContextMarshall(ContextHandle
,
5673 pStubMsg
->Buffer
+= cbNDRContext
;
5676 /***********************************************************************
5677 * NdrClientContextUnmarshall [RPCRT4.@]
5679 void WINAPI
NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5680 NDR_CCONTEXT
* pContextHandle
,
5681 RPC_BINDING_HANDLE BindHandle
)
5683 TRACE("(%p, %p, %p)\n", pStubMsg
, pContextHandle
, BindHandle
);
5685 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5687 if (pStubMsg
->Buffer
+ cbNDRContext
> pStubMsg
->BufferEnd
)
5688 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
5690 NDRCContextUnmarshall(pContextHandle
,
5693 pStubMsg
->RpcMsg
->DataRepresentation
);
5695 pStubMsg
->Buffer
+= cbNDRContext
;
5698 void WINAPI
NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5699 NDR_SCONTEXT ContextHandle
,
5700 NDR_RUNDOWN RundownRoutine
)
5702 FIXME("(%p, %p, %p): stub\n", pStubMsg
, ContextHandle
, RundownRoutine
);
5705 NDR_SCONTEXT WINAPI
NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
)
5707 FIXME("(%p): stub\n", pStubMsg
);
5711 void WINAPI
NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg
,
5712 unsigned char* pMemory
,
5713 PFORMAT_STRING pFormat
)
5715 FIXME("(%p, %p, %p): stub\n", pStubMsg
, pMemory
, pFormat
);
5718 NDR_SCONTEXT WINAPI
NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg
,
5719 PFORMAT_STRING pFormat
)
5721 FIXME("(%p, %p): stub\n", pStubMsg
, pFormat
);
5725 void WINAPI
NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5726 NDR_SCONTEXT ContextHandle
,
5727 NDR_RUNDOWN RundownRoutine
,
5728 PFORMAT_STRING pFormat
)
5730 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg
, ContextHandle
, RundownRoutine
, pFormat
);
5733 NDR_SCONTEXT WINAPI
NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5734 PFORMAT_STRING pFormat
)
5736 FIXME("(%p, %p): stub\n", pStubMsg
, pFormat
);
5740 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
5742 typedef struct ndr_context_handle
5746 } ndr_context_handle
;
5748 struct context_handle_entry
5752 RPC_BINDING_HANDLE handle
;
5753 ndr_context_handle wire_data
;
5756 static struct list context_handle_list
= LIST_INIT(context_handle_list
);
5758 static CRITICAL_SECTION ndr_context_cs
;
5759 static CRITICAL_SECTION_DEBUG ndr_context_debug
=
5761 0, 0, &ndr_context_cs
,
5762 { &ndr_context_debug
.ProcessLocksList
, &ndr_context_debug
.ProcessLocksList
},
5763 0, 0, { (DWORD_PTR
)(__FILE__
": ndr_context") }
5765 static CRITICAL_SECTION ndr_context_cs
= { &ndr_context_debug
, -1, 0, 0, 0, 0 };
5767 static struct context_handle_entry
*get_context_entry(NDR_CCONTEXT CContext
)
5769 struct context_handle_entry
*che
= (struct context_handle_entry
*) CContext
;
5771 if (che
->magic
!= NDR_CONTEXT_HANDLE_MAGIC
)
5776 static struct context_handle_entry
*context_entry_from_guid(LPCGUID uuid
)
5778 struct context_handle_entry
*che
;
5779 LIST_FOR_EACH_ENTRY(che
, &context_handle_list
, struct context_handle_entry
, entry
)
5780 if (IsEqualGUID(&che
->wire_data
.uuid
, uuid
))
5785 RPC_BINDING_HANDLE WINAPI
NDRCContextBinding(NDR_CCONTEXT CContext
)
5787 struct context_handle_entry
*che
;
5788 RPC_BINDING_HANDLE handle
= NULL
;
5790 TRACE("%p\n", CContext
);
5792 EnterCriticalSection(&ndr_context_cs
);
5793 che
= get_context_entry(CContext
);
5795 handle
= che
->handle
;
5796 LeaveCriticalSection(&ndr_context_cs
);
5799 RpcRaiseException(ERROR_INVALID_HANDLE
);
5803 void WINAPI
NDRCContextMarshall(NDR_CCONTEXT CContext
, void *pBuff
)
5805 struct context_handle_entry
*che
;
5807 TRACE("%p %p\n", CContext
, pBuff
);
5811 EnterCriticalSection(&ndr_context_cs
);
5812 che
= get_context_entry(CContext
);
5813 memcpy(pBuff
, &che
->wire_data
, sizeof (ndr_context_handle
));
5814 LeaveCriticalSection(&ndr_context_cs
);
5818 ndr_context_handle
*wire_data
= (ndr_context_handle
*)pBuff
;
5819 wire_data
->attributes
= 0;
5820 wire_data
->uuid
= GUID_NULL
;
5824 static UINT
ndr_update_context_handle(NDR_CCONTEXT
*CContext
,
5825 RPC_BINDING_HANDLE hBinding
,
5826 const ndr_context_handle
*chi
)
5828 struct context_handle_entry
*che
= NULL
;
5830 /* a null UUID means we should free the context handle */
5831 if (IsEqualGUID(&chi
->uuid
, &GUID_NULL
))
5835 che
= get_context_entry(*CContext
);
5837 return ERROR_INVALID_HANDLE
;
5838 list_remove(&che
->entry
);
5839 RpcBindingFree(&che
->handle
);
5840 HeapFree(GetProcessHeap(), 0, che
);
5844 /* if there's no existing entry matching the GUID, allocate one */
5845 else if (!(che
= context_entry_from_guid(&chi
->uuid
)))
5847 che
= HeapAlloc(GetProcessHeap(), 0, sizeof *che
);
5849 return ERROR_NOT_ENOUGH_MEMORY
;
5850 che
->magic
= NDR_CONTEXT_HANDLE_MAGIC
;
5851 RpcBindingCopy(hBinding
, &che
->handle
);
5852 list_add_tail(&context_handle_list
, &che
->entry
);
5853 memcpy(&che
->wire_data
, chi
, sizeof *chi
);
5858 return ERROR_SUCCESS
;
5861 /***********************************************************************
5862 * NDRCContextUnmarshall [RPCRT4.@]
5864 void WINAPI
NDRCContextUnmarshall(NDR_CCONTEXT
*CContext
,
5865 RPC_BINDING_HANDLE hBinding
,
5866 void *pBuff
, ULONG DataRepresentation
)
5870 TRACE("*%p=(%p) %p %p %08x\n",
5871 CContext
, *CContext
, hBinding
, pBuff
, DataRepresentation
);
5873 EnterCriticalSection(&ndr_context_cs
);
5874 r
= ndr_update_context_handle(CContext
, hBinding
, pBuff
);
5875 LeaveCriticalSection(&ndr_context_cs
);
5877 RpcRaiseException(r
);
5880 /***********************************************************************
5881 * NDRSContextMarshall [RPCRT4.@]
5883 void WINAPI
NDRSContextMarshall(NDR_SCONTEXT CContext
,
5885 NDR_RUNDOWN userRunDownIn
)
5887 FIXME("(%p %p %p): stub\n", CContext
, pBuff
, userRunDownIn
);
5890 /***********************************************************************
5891 * NDRSContextMarshallEx [RPCRT4.@]
5893 void WINAPI
NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding
,
5894 NDR_SCONTEXT CContext
,
5896 NDR_RUNDOWN userRunDownIn
)
5898 FIXME("(%p %p %p %p): stub\n", hBinding
, CContext
, pBuff
, userRunDownIn
);
5901 /***********************************************************************
5902 * NDRSContextMarshall2 [RPCRT4.@]
5904 void WINAPI
NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding
,
5905 NDR_SCONTEXT CContext
,
5907 NDR_RUNDOWN userRunDownIn
,
5908 void *CtxGuard
, ULONG Flags
)
5910 FIXME("(%p %p %p %p %p %u): stub\n",
5911 hBinding
, CContext
, pBuff
, userRunDownIn
, CtxGuard
, Flags
);
5914 /***********************************************************************
5915 * NDRSContextUnmarshall [RPCRT4.@]
5917 NDR_SCONTEXT WINAPI
NDRSContextUnmarshall(void *pBuff
,
5918 ULONG DataRepresentation
)
5920 FIXME("(%p %08x): stub\n", pBuff
, DataRepresentation
);
5924 /***********************************************************************
5925 * NDRSContextUnmarshallEx [RPCRT4.@]
5927 NDR_SCONTEXT WINAPI
NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding
,
5929 ULONG DataRepresentation
)
5931 FIXME("(%p %p %08x): stub\n", hBinding
, pBuff
, DataRepresentation
);
5935 /***********************************************************************
5936 * NDRSContextUnmarshall2 [RPCRT4.@]
5938 NDR_SCONTEXT WINAPI
NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding
,
5940 ULONG DataRepresentation
,
5941 void *CtxGuard
, ULONG Flags
)
5943 FIXME("(%p %p %08x %p %u): stub\n",
5944 hBinding
, pBuff
, DataRepresentation
, CtxGuard
, Flags
);