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 * - Encapsulated unions
25 * - Byte count pointers
26 * - transmit_as/represent as
27 * - Multi-dimensional arrays
28 * - Conversion functions (NdrConvert)
29 * - Checks for integer addition overflow
30 * - Checks for out-of-memory conditions
46 #include "wine/unicode.h"
47 #include "wine/rpcfc.h"
49 #include "wine/debug.h"
50 #include "wine/list.h"
52 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
55 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
56 (*((UINT32 *)(pchar)) = (uint32))
58 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
59 (*((UINT32 *)(pchar)))
61 /* these would work for i386 too, but less efficient */
62 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
63 (*(pchar) = LOBYTE(LOWORD(uint32)), \
64 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
65 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
66 *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
67 (uint32)) /* allow as r-value */
69 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
71 MAKEWORD(*(pchar), *((pchar)+1)), \
72 MAKEWORD(*((pchar)+2), *((pchar)+3))))
75 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
76 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
77 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
78 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
79 *(pchar) = HIBYTE(HIWORD(uint32)), \
80 (uint32)) /* allow as r-value */
82 #define BIG_ENDIAN_UINT32_READ(pchar) \
84 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
85 MAKEWORD(*((pchar)+1), *(pchar))))
87 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
88 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
89 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
90 # define NDR_LOCAL_UINT32_READ(pchar) \
91 BIG_ENDIAN_UINT32_READ(pchar)
93 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
94 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
95 # define NDR_LOCAL_UINT32_READ(pchar) \
96 LITTLE_ENDIAN_UINT32_READ(pchar)
99 /* _Align must be the desired alignment,
100 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
101 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
102 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
103 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
104 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
106 #define STD_OVERFLOW_CHECK(_Msg) do { \
107 TRACE("buffer=%d/%d\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
108 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
109 ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
112 #define NDR_TABLE_SIZE 128
113 #define NDR_TABLE_MASK 127
115 static unsigned char *WINAPI
NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
116 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
117 static void WINAPI
NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
118 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
119 static ULONG WINAPI
NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
121 static unsigned char *WINAPI
NdrContextHandleMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
122 static void WINAPI
NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
123 static unsigned char *WINAPI
NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
125 const NDR_MARSHALL NdrMarshaller
[NDR_TABLE_SIZE
] = {
127 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
128 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
129 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
130 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
134 NdrPointerMarshall
, NdrPointerMarshall
,
135 NdrPointerMarshall
, NdrPointerMarshall
,
137 NdrSimpleStructMarshall
, NdrSimpleStructMarshall
,
138 NdrConformantStructMarshall
, NdrConformantStructMarshall
,
139 NdrConformantVaryingStructMarshall
,
140 NdrComplexStructMarshall
,
142 NdrConformantArrayMarshall
,
143 NdrConformantVaryingArrayMarshall
,
144 NdrFixedArrayMarshall
, NdrFixedArrayMarshall
,
145 NdrVaryingArrayMarshall
, NdrVaryingArrayMarshall
,
146 NdrComplexArrayMarshall
,
148 NdrConformantStringMarshall
, 0, 0,
149 NdrConformantStringMarshall
,
150 NdrNonConformantStringMarshall
, 0, 0, 0,
152 NdrEncapsulatedUnionMarshall
,
153 NdrNonEncapsulatedUnionMarshall
,
154 NdrByteCountPointerMarshall
,
155 NdrXmitOrRepAsMarshall
, NdrXmitOrRepAsMarshall
,
157 NdrInterfacePointerMarshall
,
159 NdrContextHandleMarshall
,
162 NdrUserMarshalMarshall
,
167 const NDR_UNMARSHALL NdrUnmarshaller
[NDR_TABLE_SIZE
] = {
169 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
170 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
171 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
172 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
174 NdrBaseTypeUnmarshall
,
176 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
177 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
179 NdrSimpleStructUnmarshall
, NdrSimpleStructUnmarshall
,
180 NdrConformantStructUnmarshall
, NdrConformantStructUnmarshall
,
181 NdrConformantVaryingStructUnmarshall
,
182 NdrComplexStructUnmarshall
,
184 NdrConformantArrayUnmarshall
,
185 NdrConformantVaryingArrayUnmarshall
,
186 NdrFixedArrayUnmarshall
, NdrFixedArrayUnmarshall
,
187 NdrVaryingArrayUnmarshall
, NdrVaryingArrayUnmarshall
,
188 NdrComplexArrayUnmarshall
,
190 NdrConformantStringUnmarshall
, 0, 0,
191 NdrConformantStringUnmarshall
,
192 NdrNonConformantStringUnmarshall
, 0, 0, 0,
194 NdrEncapsulatedUnionUnmarshall
,
195 NdrNonEncapsulatedUnionUnmarshall
,
196 NdrByteCountPointerUnmarshall
,
197 NdrXmitOrRepAsUnmarshall
, NdrXmitOrRepAsUnmarshall
,
199 NdrInterfacePointerUnmarshall
,
201 NdrContextHandleUnmarshall
,
204 NdrUserMarshalUnmarshall
,
209 const NDR_BUFFERSIZE NdrBufferSizer
[NDR_TABLE_SIZE
] = {
211 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
212 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
213 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
214 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
216 NdrBaseTypeBufferSize
,
218 NdrPointerBufferSize
, NdrPointerBufferSize
,
219 NdrPointerBufferSize
, NdrPointerBufferSize
,
221 NdrSimpleStructBufferSize
, NdrSimpleStructBufferSize
,
222 NdrConformantStructBufferSize
, NdrConformantStructBufferSize
,
223 NdrConformantVaryingStructBufferSize
,
224 NdrComplexStructBufferSize
,
226 NdrConformantArrayBufferSize
,
227 NdrConformantVaryingArrayBufferSize
,
228 NdrFixedArrayBufferSize
, NdrFixedArrayBufferSize
,
229 NdrVaryingArrayBufferSize
, NdrVaryingArrayBufferSize
,
230 NdrComplexArrayBufferSize
,
232 NdrConformantStringBufferSize
, 0, 0,
233 NdrConformantStringBufferSize
,
234 NdrNonConformantStringBufferSize
, 0, 0, 0,
236 NdrEncapsulatedUnionBufferSize
,
237 NdrNonEncapsulatedUnionBufferSize
,
238 NdrByteCountPointerBufferSize
,
239 NdrXmitOrRepAsBufferSize
, NdrXmitOrRepAsBufferSize
,
241 NdrInterfacePointerBufferSize
,
243 NdrContextHandleBufferSize
,
246 NdrUserMarshalBufferSize
,
251 const NDR_MEMORYSIZE NdrMemorySizer
[NDR_TABLE_SIZE
] = {
253 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
254 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
255 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
256 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
258 NdrBaseTypeMemorySize
,
260 NdrPointerMemorySize
, NdrPointerMemorySize
,
261 NdrPointerMemorySize
, NdrPointerMemorySize
,
263 NdrSimpleStructMemorySize
, NdrSimpleStructMemorySize
,
264 NdrConformantStructMemorySize
, NdrConformantStructMemorySize
,
265 NdrConformantVaryingStructMemorySize
,
266 NdrComplexStructMemorySize
,
268 NdrConformantArrayMemorySize
,
269 NdrConformantVaryingArrayMemorySize
,
270 NdrFixedArrayMemorySize
, NdrFixedArrayMemorySize
,
271 NdrVaryingArrayMemorySize
, NdrVaryingArrayMemorySize
,
272 NdrComplexArrayMemorySize
,
274 NdrConformantStringMemorySize
, 0, 0,
275 NdrConformantStringMemorySize
,
276 NdrNonConformantStringMemorySize
, 0, 0, 0,
278 NdrEncapsulatedUnionMemorySize
,
279 NdrNonEncapsulatedUnionMemorySize
,
280 NdrByteCountPointerMemorySize
,
281 NdrXmitOrRepAsMemorySize
, NdrXmitOrRepAsMemorySize
,
283 NdrInterfacePointerMemorySize
,
288 NdrUserMarshalMemorySize
,
293 const NDR_FREE NdrFreer
[NDR_TABLE_SIZE
] = {
295 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
296 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
297 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
298 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
302 NdrPointerFree
, NdrPointerFree
,
303 NdrPointerFree
, NdrPointerFree
,
305 NdrSimpleStructFree
, NdrSimpleStructFree
,
306 NdrConformantStructFree
, NdrConformantStructFree
,
307 NdrConformantVaryingStructFree
,
308 NdrComplexStructFree
,
310 NdrConformantArrayFree
,
311 NdrConformantVaryingArrayFree
,
312 NdrFixedArrayFree
, NdrFixedArrayFree
,
313 NdrVaryingArrayFree
, NdrVaryingArrayFree
,
319 NdrEncapsulatedUnionFree
,
320 NdrNonEncapsulatedUnionFree
,
322 NdrXmitOrRepAsFree
, NdrXmitOrRepAsFree
,
324 NdrInterfacePointerFree
,
335 void * WINAPI
NdrAllocate(MIDL_STUB_MESSAGE
*pStubMsg
, size_t len
)
337 /* hmm, this is probably supposed to do more? */
338 return pStubMsg
->pfnAllocate(len
);
341 static void WINAPI
NdrFree(MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *Pointer
)
343 pStubMsg
->pfnFree(Pointer
);
346 static inline BOOL
IsConformanceOrVariancePresent(PFORMAT_STRING pFormat
)
348 return (*(const ULONG
*)pFormat
!= -1);
351 static PFORMAT_STRING
ReadConformance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
)
353 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
354 pStubMsg
->MaxCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
355 pStubMsg
->Buffer
+= 4;
356 TRACE("unmarshalled conformance is %ld\n", pStubMsg
->MaxCount
);
357 if (pStubMsg
->fHasNewCorrDesc
)
363 static inline PFORMAT_STRING
ReadVariance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
, ULONG MaxValue
)
365 if (pFormat
&& !IsConformanceOrVariancePresent(pFormat
))
367 pStubMsg
->Offset
= 0;
368 pStubMsg
->ActualCount
= pStubMsg
->MaxCount
;
372 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
373 pStubMsg
->Offset
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
374 pStubMsg
->Buffer
+= 4;
375 TRACE("offset is %d\n", pStubMsg
->Offset
);
376 pStubMsg
->ActualCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
377 pStubMsg
->Buffer
+= 4;
378 TRACE("variance is %d\n", pStubMsg
->ActualCount
);
380 if ((pStubMsg
->ActualCount
> MaxValue
) ||
381 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> MaxValue
))
383 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
384 pStubMsg
->ActualCount
, pStubMsg
->Offset
, MaxValue
);
385 RpcRaiseException(RPC_S_INVALID_BOUND
);
390 if (pStubMsg
->fHasNewCorrDesc
)
396 /* writes the conformance value to the buffer */
397 static inline void WriteConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
399 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
400 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->MaxCount
);
401 pStubMsg
->Buffer
+= 4;
404 /* writes the variance values to the buffer */
405 static inline void WriteVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
407 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
408 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->Offset
);
409 pStubMsg
->Buffer
+= 4;
410 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->ActualCount
);
411 pStubMsg
->Buffer
+= 4;
414 /* requests buffer space for the conformance value */
415 static inline void SizeConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
417 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
418 pStubMsg
->BufferLength
+= 4;
421 /* requests buffer space for the variance values */
422 static inline void SizeVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
424 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
425 pStubMsg
->BufferLength
+= 8;
428 PFORMAT_STRING
ComputeConformanceOrVariance(
429 MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *pMemory
,
430 PFORMAT_STRING pFormat
, ULONG_PTR def
, ULONG_PTR
*pCount
)
432 BYTE dtype
= pFormat
[0] & 0xf;
433 short ofs
= *(const short *)&pFormat
[2];
437 if (!IsConformanceOrVariancePresent(pFormat
)) {
438 /* null descriptor */
443 switch (pFormat
[0] & 0xf0) {
444 case RPC_FC_NORMAL_CONFORMANCE
:
445 TRACE("normal conformance, ofs=%d\n", ofs
);
448 case RPC_FC_POINTER_CONFORMANCE
:
449 TRACE("pointer conformance, ofs=%d\n", ofs
);
450 ptr
= pStubMsg
->Memory
;
452 case RPC_FC_TOP_LEVEL_CONFORMANCE
:
453 TRACE("toplevel conformance, ofs=%d\n", ofs
);
454 if (pStubMsg
->StackTop
) {
455 ptr
= pStubMsg
->StackTop
;
458 /* -Os mode, *pCount is already set */
462 case RPC_FC_CONSTANT_CONFORMANCE
:
463 data
= ofs
| ((DWORD
)pFormat
[1] << 16);
464 TRACE("constant conformance, val=%d\n", data
);
467 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE
:
468 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs
);
469 if (pStubMsg
->StackTop
) {
470 ptr
= pStubMsg
->StackTop
;
478 FIXME("unknown conformance type %x\n", pFormat
[0] & 0xf0);
481 switch (pFormat
[1]) {
482 case RPC_FC_DEREFERENCE
:
483 ptr
= *(LPVOID
*)((char *)ptr
+ ofs
);
485 case RPC_FC_CALLBACK
:
487 unsigned char *old_stack_top
= pStubMsg
->StackTop
;
488 pStubMsg
->StackTop
= ptr
;
490 /* ofs is index into StubDesc->apfnExprEval */
491 TRACE("callback conformance into apfnExprEval[%d]\n", ofs
);
492 pStubMsg
->StubDesc
->apfnExprEval
[ofs
](pStubMsg
);
494 pStubMsg
->StackTop
= old_stack_top
;
496 /* the callback function always stores the computed value in MaxCount */
497 *pCount
= pStubMsg
->MaxCount
;
501 ptr
= (char *)ptr
+ ofs
;
514 data
= *(USHORT
*)ptr
;
525 FIXME("unknown conformance data type %x\n", dtype
);
528 TRACE("dereferenced data type %x at %p, got %d\n", dtype
, ptr
, data
);
531 switch (pFormat
[1]) {
532 case RPC_FC_DEREFERENCE
: /* already handled */
549 FIXME("unknown conformance op %d\n", pFormat
[1]);
554 TRACE("resulting conformance is %ld\n", *pCount
);
555 if (pStubMsg
->fHasNewCorrDesc
)
561 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
562 * the result overflows 32-bits */
563 static inline ULONG
safe_multiply(ULONG a
, ULONG b
)
565 ULONGLONG ret
= (ULONGLONG
)a
* b
;
566 if (ret
> 0xffffffff)
568 RpcRaiseException(RPC_S_INVALID_BOUND
);
576 * NdrConformantString:
578 * What MS calls a ConformantString is, in DCE terminology,
579 * a Varying-Conformant String.
581 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
582 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
583 * into unmarshalled string)
584 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
586 * data: CHARTYPE[maxlen]
588 * ], where CHARTYPE is the appropriate character type (specified externally)
592 /***********************************************************************
593 * NdrConformantStringMarshall [RPCRT4.@]
595 unsigned char *WINAPI
NdrConformantStringMarshall(MIDL_STUB_MESSAGE
*pStubMsg
,
596 unsigned char *pszMessage
, PFORMAT_STRING pFormat
)
600 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg
, pszMessage
, pFormat
);
602 if (*pFormat
== RPC_FC_C_CSTRING
) {
603 TRACE("string=%s\n", debugstr_a((char*)pszMessage
));
604 pStubMsg
->ActualCount
= strlen((char*)pszMessage
)+1;
607 else if (*pFormat
== RPC_FC_C_WSTRING
) {
608 TRACE("string=%s\n", debugstr_w((LPWSTR
)pszMessage
));
609 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pszMessage
)+1;
613 ERR("Unhandled string type: %#x\n", *pFormat
);
614 /* FIXME: raise an exception. */
618 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
619 pFormat
= ComputeConformance(pStubMsg
, pszMessage
, pFormat
+ 2, 0);
621 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
622 pStubMsg
->Offset
= 0;
623 WriteConformance(pStubMsg
);
624 WriteVariance(pStubMsg
);
626 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
627 memcpy(pStubMsg
->Buffer
, pszMessage
, size
); /* the string itself */
628 pStubMsg
->Buffer
+= size
;
630 STD_OVERFLOW_CHECK(pStubMsg
);
633 return NULL
; /* is this always right? */
636 /***********************************************************************
637 * NdrConformantStringBufferSize [RPCRT4.@]
639 void WINAPI
NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
640 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
644 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
646 SizeConformance(pStubMsg
);
647 SizeVariance(pStubMsg
);
649 if (*pFormat
== RPC_FC_C_CSTRING
) {
650 TRACE("string=%s\n", debugstr_a((char*)pMemory
));
651 pStubMsg
->ActualCount
= strlen((char*)pMemory
)+1;
654 else if (*pFormat
== RPC_FC_C_WSTRING
) {
655 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
));
656 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
)+1;
660 ERR("Unhandled string type: %#x\n", *pFormat
);
661 /* FIXME: raise an exception */
665 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
666 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
668 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
670 pStubMsg
->BufferLength
+= safe_multiply(esize
, pStubMsg
->ActualCount
);
673 /************************************************************************
674 * NdrConformantStringMemorySize [RPCRT4.@]
676 ULONG WINAPI
NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
677 PFORMAT_STRING pFormat
)
681 FIXME("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
683 assert(pStubMsg
&& pFormat
);
685 if (*pFormat
== RPC_FC_C_CSTRING
) {
686 rslt
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
); /* maxlen */
688 else if (*pFormat
== RPC_FC_C_WSTRING
) {
689 rslt
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
)*2; /* maxlen */
692 ERR("Unhandled string type: %#x\n", *pFormat
);
693 /* FIXME: raise an exception */
696 if (pFormat
[1] != RPC_FC_PAD
) {
697 FIXME("sized string format=%d\n", pFormat
[1]);
700 TRACE(" --> %u\n", rslt
);
704 /************************************************************************
705 * NdrConformantStringUnmarshall [RPCRT4.@]
707 unsigned char *WINAPI
NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
708 unsigned char** ppMemory
, PFORMAT_STRING pFormat
, unsigned char fMustAlloc
)
710 ULONG bufsize
, memsize
, esize
, i
;
712 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
713 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
715 assert(pFormat
&& ppMemory
&& pStubMsg
);
717 ReadConformance(pStubMsg
, NULL
);
718 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
720 if (*pFormat
== RPC_FC_C_CSTRING
) esize
= 1;
721 else if (*pFormat
== RPC_FC_C_WSTRING
) esize
= 2;
723 ERR("Unhandled string type: %#x\n", *pFormat
);
724 /* FIXME: raise an exception */
728 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
729 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
731 /* strings must always have null terminating bytes */
734 ERR("invalid string length of %d\n", pStubMsg
->ActualCount
);
735 RpcRaiseException(RPC_S_INVALID_BOUND
);
738 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
739 if (pStubMsg
->Buffer
[i
] != 0)
741 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
742 i
, pStubMsg
->Buffer
[i
]);
743 RpcRaiseException(RPC_S_INVALID_BOUND
);
747 if (fMustAlloc
|| !*ppMemory
)
748 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
750 memcpy(*ppMemory
, pStubMsg
->Buffer
, bufsize
);
752 pStubMsg
->Buffer
+= bufsize
;
754 if (*pFormat
== RPC_FC_C_CSTRING
) {
755 TRACE("string=%s\n", debugstr_a((char*)*ppMemory
));
757 else if (*pFormat
== RPC_FC_C_WSTRING
) {
758 TRACE("string=%s\n", debugstr_w((LPWSTR
)*ppMemory
));
761 return NULL
; /* FIXME: is this always right? */
764 /***********************************************************************
765 * NdrNonConformantStringMarshall [RPCRT4.@]
767 unsigned char * WINAPI
NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
768 unsigned char *pMemory
,
769 PFORMAT_STRING pFormat
)
775 /***********************************************************************
776 * NdrNonConformantStringUnmarshall [RPCRT4.@]
778 unsigned char * WINAPI
NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
779 unsigned char **ppMemory
,
780 PFORMAT_STRING pFormat
,
781 unsigned char fMustAlloc
)
787 /***********************************************************************
788 * NdrNonConformantStringBufferSize [RPCRT4.@]
790 void WINAPI
NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
791 unsigned char *pMemory
,
792 PFORMAT_STRING pFormat
)
797 /***********************************************************************
798 * NdrNonConformantStringMemorySize [RPCRT4.@]
800 ULONG WINAPI
NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
801 PFORMAT_STRING pFormat
)
807 static inline void dump_pointer_attr(unsigned char attr
)
809 if (attr
& RPC_FC_P_ALLOCALLNODES
)
810 TRACE(" RPC_FC_P_ALLOCALLNODES");
811 if (attr
& RPC_FC_P_DONTFREE
)
812 TRACE(" RPC_FC_P_DONTFREE");
813 if (attr
& RPC_FC_P_ONSTACK
)
814 TRACE(" RPC_FC_P_ONSTACK");
815 if (attr
& RPC_FC_P_SIMPLEPOINTER
)
816 TRACE(" RPC_FC_P_SIMPLEPOINTER");
817 if (attr
& RPC_FC_P_DEREF
)
818 TRACE(" RPC_FC_P_DEREF");
822 /***********************************************************************
823 * PointerMarshall [internal]
825 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
826 unsigned char *Buffer
,
827 unsigned char *Pointer
,
828 PFORMAT_STRING pFormat
)
830 unsigned type
= pFormat
[0], attr
= pFormat
[1];
834 int pointer_needs_marshaling
;
836 TRACE("(%p,%p,%p,%p)\n", pStubMsg
, Buffer
, Pointer
, pFormat
);
837 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
839 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
840 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
843 case RPC_FC_RP
: /* ref pointer (always non-null) */
844 #if 0 /* this causes problems for InstallShield so is disabled - we need more tests */
846 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
848 pointer_needs_marshaling
= 1;
850 case RPC_FC_UP
: /* unique pointer */
851 case RPC_FC_OP
: /* object pointer - same as unique here */
853 pointer_needs_marshaling
= 1;
855 pointer_needs_marshaling
= 0;
856 pointer_id
= (ULONG
)Pointer
;
857 TRACE("writing 0x%08x to buffer\n", pointer_id
);
858 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
861 pointer_needs_marshaling
= !NdrFullPointerQueryPointer(
862 pStubMsg
->FullPtrXlatTables
, Pointer
, 1, &pointer_id
);
863 TRACE("writing 0x%08x to buffer\n", pointer_id
);
864 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
867 FIXME("unhandled ptr type=%02x\n", type
);
868 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
872 TRACE("calling marshaller for type 0x%x\n", (int)*desc
);
874 if (pointer_needs_marshaling
) {
875 if (attr
& RPC_FC_P_DEREF
) {
876 Pointer
= *(unsigned char**)Pointer
;
877 TRACE("deref => %p\n", Pointer
);
879 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
880 if (m
) m(pStubMsg
, Pointer
, desc
);
881 else FIXME("no marshaller for data type=%02x\n", *desc
);
884 STD_OVERFLOW_CHECK(pStubMsg
);
887 /***********************************************************************
888 * PointerUnmarshall [internal]
890 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
891 unsigned char *Buffer
,
892 unsigned char **pPointer
,
893 PFORMAT_STRING pFormat
,
894 unsigned char fMustAlloc
)
896 unsigned type
= pFormat
[0], attr
= pFormat
[1];
899 DWORD pointer_id
= 0;
900 int pointer_needs_unmarshaling
;
902 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg
, Buffer
, pPointer
, pFormat
, fMustAlloc
);
903 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
905 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
906 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
909 case RPC_FC_RP
: /* ref pointer (always non-null) */
910 pointer_needs_unmarshaling
= 1;
912 case RPC_FC_UP
: /* unique pointer */
913 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
914 TRACE("pointer_id is 0x%08x\n", pointer_id
);
916 pointer_needs_unmarshaling
= 1;
919 pointer_needs_unmarshaling
= 0;
922 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
923 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
924 TRACE("pointer_id is 0x%08x\n", pointer_id
);
925 if (!fMustAlloc
&& *pPointer
)
927 FIXME("free object pointer %p\n", *pPointer
);
931 pointer_needs_unmarshaling
= 1;
933 pointer_needs_unmarshaling
= 0;
936 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
937 TRACE("pointer_id is 0x%08x\n", pointer_id
);
938 pointer_needs_unmarshaling
= !NdrFullPointerQueryRefId(
939 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, (void **)pPointer
);
942 FIXME("unhandled ptr type=%02x\n", type
);
943 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
947 if (pointer_needs_unmarshaling
) {
948 if (attr
& RPC_FC_P_DEREF
) {
949 if (!*pPointer
|| fMustAlloc
)
950 *pPointer
= NdrAllocate(pStubMsg
, sizeof(void *));
951 pPointer
= *(unsigned char***)pPointer
;
952 TRACE("deref => %p\n", pPointer
);
954 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
955 if (m
) m(pStubMsg
, pPointer
, desc
, fMustAlloc
);
956 else FIXME("no unmarshaller for data type=%02x\n", *desc
);
958 if (type
== RPC_FC_FP
)
959 NdrFullPointerInsertRefId(pStubMsg
->FullPtrXlatTables
, pointer_id
,
963 TRACE("pointer=%p\n", *pPointer
);
966 /***********************************************************************
967 * PointerBufferSize [internal]
969 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
970 unsigned char *Pointer
,
971 PFORMAT_STRING pFormat
)
973 unsigned type
= pFormat
[0], attr
= pFormat
[1];
976 int pointer_needs_sizing
;
979 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
980 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
982 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
983 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
986 case RPC_FC_RP
: /* ref pointer (always non-null) */
990 /* NULL pointer has no further representation */
995 pointer_needs_sizing
= !NdrFullPointerQueryPointer(
996 pStubMsg
->FullPtrXlatTables
, Pointer
, 0, &pointer_id
);
997 if (!pointer_needs_sizing
)
1001 FIXME("unhandled ptr type=%02x\n", type
);
1002 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1006 if (attr
& RPC_FC_P_DEREF
) {
1007 Pointer
= *(unsigned char**)Pointer
;
1008 TRACE("deref => %p\n", Pointer
);
1011 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
1012 if (m
) m(pStubMsg
, Pointer
, desc
);
1013 else FIXME("no buffersizer for data type=%02x\n", *desc
);
1016 /***********************************************************************
1017 * PointerMemorySize [internal]
1019 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1020 unsigned char *Buffer
,
1021 PFORMAT_STRING pFormat
)
1023 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1024 PFORMAT_STRING desc
;
1027 FIXME("(%p,%p,%p): stub\n", pStubMsg
, Buffer
, pFormat
);
1028 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1030 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1031 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1034 case RPC_FC_RP
: /* ref pointer (always non-null) */
1037 FIXME("unhandled ptr type=%02x\n", type
);
1038 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1041 if (attr
& RPC_FC_P_DEREF
) {
1045 m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
1046 if (m
) m(pStubMsg
, desc
);
1047 else FIXME("no memorysizer for data type=%02x\n", *desc
);
1052 /***********************************************************************
1053 * PointerFree [internal]
1055 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1056 unsigned char *Pointer
,
1057 PFORMAT_STRING pFormat
)
1059 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1060 PFORMAT_STRING desc
;
1063 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1064 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1065 if (attr
& RPC_FC_P_DONTFREE
) return;
1067 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1068 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1070 if (!Pointer
) return;
1072 if (type
== RPC_FC_FP
) {
1073 int pointer_needs_freeing
= NdrFullPointerFree(
1074 pStubMsg
->FullPtrXlatTables
, Pointer
);
1075 if (!pointer_needs_freeing
)
1079 if (attr
& RPC_FC_P_DEREF
) {
1080 Pointer
= *(unsigned char**)Pointer
;
1081 TRACE("deref => %p\n", Pointer
);
1084 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
1085 if (m
) m(pStubMsg
, Pointer
, desc
);
1087 /* hmm... is this sensible?
1088 * perhaps we should check if the memory comes from NdrAllocate,
1089 * and deallocate only if so - checking if the pointer is between
1090 * BufferStart and BufferEnd is probably no good since the buffer
1091 * may be reallocated when the server wants to marshal the reply */
1093 case RPC_FC_BOGUS_STRUCT
:
1094 case RPC_FC_BOGUS_ARRAY
:
1095 case RPC_FC_USER_MARSHAL
:
1097 case RPC_FC_CVARRAY
:
1100 FIXME("unhandled data type=%02x\n", *desc
);
1102 case RPC_FC_C_CSTRING
:
1103 case RPC_FC_C_WSTRING
:
1104 if (pStubMsg
->ReuseBuffer
) goto notfree
;
1110 if (attr
& RPC_FC_P_ONSTACK
) {
1111 TRACE("not freeing stack ptr %p\n", Pointer
);
1114 TRACE("freeing %p\n", Pointer
);
1115 NdrFree(pStubMsg
, Pointer
);
1118 TRACE("not freeing %p\n", Pointer
);
1121 /***********************************************************************
1122 * EmbeddedPointerMarshall
1124 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1125 unsigned char *pMemory
,
1126 PFORMAT_STRING pFormat
)
1128 unsigned char *Mark
= pStubMsg
->BufferMark
;
1129 unsigned long Offset
= pStubMsg
->Offset
;
1130 unsigned ofs
, rep
, count
, stride
, xofs
;
1132 unsigned char *saved_buffer
= NULL
;
1134 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1136 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1139 if (pStubMsg
->PointerBufferMark
)
1141 saved_buffer
= pStubMsg
->Buffer
;
1142 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1143 pStubMsg
->PointerBufferMark
= NULL
;
1146 while (pFormat
[0] != RPC_FC_END
) {
1147 switch (pFormat
[0]) {
1149 FIXME("unknown repeat type %d\n", pFormat
[0]);
1150 case RPC_FC_NO_REPEAT
:
1158 case RPC_FC_FIXED_REPEAT
:
1159 rep
= *(const WORD
*)&pFormat
[2];
1160 stride
= *(const WORD
*)&pFormat
[4];
1161 ofs
= *(const WORD
*)&pFormat
[6];
1162 count
= *(const WORD
*)&pFormat
[8];
1166 case RPC_FC_VARIABLE_REPEAT
:
1167 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1168 stride
= *(const WORD
*)&pFormat
[2];
1169 ofs
= *(const WORD
*)&pFormat
[4];
1170 count
= *(const WORD
*)&pFormat
[6];
1171 xofs
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? Offset
* stride
: 0;
1175 for (i
= 0; i
< rep
; i
++) {
1176 PFORMAT_STRING info
= pFormat
;
1177 unsigned char *membase
= pMemory
+ ofs
+ (i
* stride
);
1178 unsigned char *bufbase
= Mark
+ ofs
+ (i
* stride
);
1181 for (u
=0; u
<count
; u
++,info
+=8) {
1182 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1183 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1184 unsigned char *saved_memory
= pStubMsg
->Memory
;
1186 pStubMsg
->Memory
= pMemory
;
1187 PointerMarshall(pStubMsg
, bufptr
, *(unsigned char**)memptr
, info
+4);
1188 pStubMsg
->Memory
= saved_memory
;
1191 pFormat
+= 8 * count
;
1196 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1197 pStubMsg
->Buffer
= saved_buffer
;
1200 STD_OVERFLOW_CHECK(pStubMsg
);
1205 /***********************************************************************
1206 * EmbeddedPointerUnmarshall
1208 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1209 unsigned char **ppMemory
,
1210 PFORMAT_STRING pFormat
,
1211 unsigned char fMustAlloc
)
1213 unsigned char *Mark
= pStubMsg
->BufferMark
;
1214 unsigned long Offset
= pStubMsg
->Offset
;
1215 unsigned ofs
, rep
, count
, stride
, xofs
;
1217 unsigned char *saved_buffer
= NULL
;
1219 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1221 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1224 if (pStubMsg
->PointerBufferMark
)
1226 saved_buffer
= pStubMsg
->Buffer
;
1227 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1228 pStubMsg
->PointerBufferMark
= NULL
;
1231 while (pFormat
[0] != RPC_FC_END
) {
1232 TRACE("pFormat[0] = 0x%x\n", pFormat
[0]);
1233 switch (pFormat
[0]) {
1235 FIXME("unknown repeat type %d\n", pFormat
[0]);
1236 case RPC_FC_NO_REPEAT
:
1244 case RPC_FC_FIXED_REPEAT
:
1245 rep
= *(const WORD
*)&pFormat
[2];
1246 stride
= *(const WORD
*)&pFormat
[4];
1247 ofs
= *(const WORD
*)&pFormat
[6];
1248 count
= *(const WORD
*)&pFormat
[8];
1252 case RPC_FC_VARIABLE_REPEAT
:
1253 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1254 stride
= *(const WORD
*)&pFormat
[2];
1255 ofs
= *(const WORD
*)&pFormat
[4];
1256 count
= *(const WORD
*)&pFormat
[6];
1257 xofs
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? Offset
* stride
: 0;
1261 /* ofs doesn't seem to matter in this context */
1262 for (i
= 0; i
< rep
; i
++) {
1263 PFORMAT_STRING info
= pFormat
;
1264 unsigned char *membase
= *ppMemory
+ ofs
+ (i
* stride
);
1265 unsigned char *bufbase
= Mark
+ ofs
+ (i
* stride
);
1268 for (u
=0; u
<count
; u
++,info
+=8) {
1269 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1270 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1271 PointerUnmarshall(pStubMsg
, bufptr
, (unsigned char**)memptr
, info
+4, TRUE
);
1274 pFormat
+= 8 * count
;
1279 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1280 pStubMsg
->Buffer
= saved_buffer
;
1286 /***********************************************************************
1287 * EmbeddedPointerBufferSize
1289 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1290 unsigned char *pMemory
,
1291 PFORMAT_STRING pFormat
)
1293 unsigned long Offset
= pStubMsg
->Offset
;
1294 unsigned ofs
, rep
, count
, stride
, xofs
;
1296 ULONG saved_buffer_length
= 0;
1298 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1300 if (pStubMsg
->IgnoreEmbeddedPointers
) return;
1302 if (*pFormat
!= RPC_FC_PP
) return;
1305 if (pStubMsg
->PointerLength
)
1307 saved_buffer_length
= pStubMsg
->BufferLength
;
1308 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
1309 pStubMsg
->PointerLength
= 0;
1312 while (pFormat
[0] != RPC_FC_END
) {
1313 switch (pFormat
[0]) {
1315 FIXME("unknown repeat type %d\n", pFormat
[0]);
1316 case RPC_FC_NO_REPEAT
:
1324 case RPC_FC_FIXED_REPEAT
:
1325 rep
= *(const WORD
*)&pFormat
[2];
1326 stride
= *(const WORD
*)&pFormat
[4];
1327 ofs
= *(const WORD
*)&pFormat
[6];
1328 count
= *(const WORD
*)&pFormat
[8];
1332 case RPC_FC_VARIABLE_REPEAT
:
1333 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1334 stride
= *(const WORD
*)&pFormat
[2];
1335 ofs
= *(const WORD
*)&pFormat
[4];
1336 count
= *(const WORD
*)&pFormat
[6];
1337 xofs
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? Offset
* stride
: 0;
1341 for (i
= 0; i
< rep
; i
++) {
1342 PFORMAT_STRING info
= pFormat
;
1343 unsigned char *membase
= pMemory
+ ofs
+ (i
* stride
);
1346 for (u
=0; u
<count
; u
++,info
+=8) {
1347 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1348 unsigned char *saved_memory
= pStubMsg
->Memory
;
1350 pStubMsg
->Memory
= pMemory
;
1351 PointerBufferSize(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1352 pStubMsg
->Memory
= saved_memory
;
1355 pFormat
+= 8 * count
;
1358 if (saved_buffer_length
)
1360 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
1361 pStubMsg
->BufferLength
= saved_buffer_length
;
1365 /***********************************************************************
1366 * EmbeddedPointerMemorySize [internal]
1368 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1369 PFORMAT_STRING pFormat
)
1371 unsigned long Offset
= pStubMsg
->Offset
;
1372 unsigned char *Mark
= pStubMsg
->BufferMark
;
1373 unsigned ofs
, rep
, count
, stride
, xofs
;
1376 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1378 if (pStubMsg
->IgnoreEmbeddedPointers
) return 0;
1380 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1382 if (*pFormat
!= RPC_FC_PP
) return 0;
1385 while (pFormat
[0] != RPC_FC_END
) {
1386 switch (pFormat
[0]) {
1388 FIXME("unknown repeat type %d\n", pFormat
[0]);
1389 case RPC_FC_NO_REPEAT
:
1397 case RPC_FC_FIXED_REPEAT
:
1398 rep
= *(const WORD
*)&pFormat
[2];
1399 stride
= *(const WORD
*)&pFormat
[4];
1400 ofs
= *(const WORD
*)&pFormat
[6];
1401 count
= *(const WORD
*)&pFormat
[8];
1405 case RPC_FC_VARIABLE_REPEAT
:
1406 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1407 stride
= *(const WORD
*)&pFormat
[2];
1408 ofs
= *(const WORD
*)&pFormat
[4];
1409 count
= *(const WORD
*)&pFormat
[6];
1410 xofs
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? Offset
* stride
: 0;
1414 /* ofs doesn't seem to matter in this context */
1415 for (i
= 0; i
< rep
; i
++) {
1416 PFORMAT_STRING info
= pFormat
;
1417 unsigned char *bufbase
= Mark
+ ofs
+ (i
* stride
);
1419 for (u
=0; u
<count
; u
++,info
+=8) {
1420 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1421 PointerMemorySize(pStubMsg
, bufptr
, info
+4);
1424 pFormat
+= 8 * count
;
1430 /***********************************************************************
1431 * EmbeddedPointerFree [internal]
1433 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1434 unsigned char *pMemory
,
1435 PFORMAT_STRING pFormat
)
1437 unsigned long Offset
= pStubMsg
->Offset
;
1438 unsigned ofs
, rep
, count
, stride
, xofs
;
1441 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1442 if (*pFormat
!= RPC_FC_PP
) return;
1445 while (pFormat
[0] != RPC_FC_END
) {
1446 switch (pFormat
[0]) {
1448 FIXME("unknown repeat type %d\n", pFormat
[0]);
1449 case RPC_FC_NO_REPEAT
:
1457 case RPC_FC_FIXED_REPEAT
:
1458 rep
= *(const WORD
*)&pFormat
[2];
1459 stride
= *(const WORD
*)&pFormat
[4];
1460 ofs
= *(const WORD
*)&pFormat
[6];
1461 count
= *(const WORD
*)&pFormat
[8];
1465 case RPC_FC_VARIABLE_REPEAT
:
1466 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1467 stride
= *(const WORD
*)&pFormat
[2];
1468 ofs
= *(const WORD
*)&pFormat
[4];
1469 count
= *(const WORD
*)&pFormat
[6];
1470 xofs
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? Offset
* stride
: 0;
1474 for (i
= 0; i
< rep
; i
++) {
1475 PFORMAT_STRING info
= pFormat
;
1476 unsigned char *membase
= pMemory
+ (i
* stride
);
1479 for (u
=0; u
<count
; u
++,info
+=8) {
1480 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1481 unsigned char *saved_memory
= pStubMsg
->Memory
;
1483 pStubMsg
->Memory
= pMemory
;
1484 PointerFree(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1485 pStubMsg
->Memory
= saved_memory
;
1488 pFormat
+= 8 * count
;
1492 /***********************************************************************
1493 * NdrPointerMarshall [RPCRT4.@]
1495 unsigned char * WINAPI
NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1496 unsigned char *pMemory
,
1497 PFORMAT_STRING pFormat
)
1499 unsigned char *Buffer
;
1501 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1503 /* incremement the buffer here instead of in PointerMarshall,
1504 * as that is used by embedded pointers which already handle the incrementing
1505 * the buffer, and shouldn't write any additional pointer data to the wire */
1506 if (*pFormat
!= RPC_FC_RP
)
1508 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1509 Buffer
= pStubMsg
->Buffer
;
1510 pStubMsg
->Buffer
+= 4;
1513 Buffer
= pStubMsg
->Buffer
;
1515 PointerMarshall(pStubMsg
, Buffer
, pMemory
, pFormat
);
1517 STD_OVERFLOW_CHECK(pStubMsg
);
1522 /***********************************************************************
1523 * NdrPointerUnmarshall [RPCRT4.@]
1525 unsigned char * WINAPI
NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1526 unsigned char **ppMemory
,
1527 PFORMAT_STRING pFormat
,
1528 unsigned char fMustAlloc
)
1530 unsigned char *Buffer
;
1532 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1534 /* incremement the buffer here instead of in PointerUnmarshall,
1535 * as that is used by embedded pointers which already handle the incrementing
1536 * the buffer, and shouldn't read any additional pointer data from the
1538 if (*pFormat
!= RPC_FC_RP
)
1540 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1541 Buffer
= pStubMsg
->Buffer
;
1542 pStubMsg
->Buffer
+= 4;
1545 Buffer
= pStubMsg
->Buffer
;
1547 PointerUnmarshall(pStubMsg
, Buffer
, ppMemory
, pFormat
, fMustAlloc
);
1552 /***********************************************************************
1553 * NdrPointerBufferSize [RPCRT4.@]
1555 void WINAPI
NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1556 unsigned char *pMemory
,
1557 PFORMAT_STRING pFormat
)
1559 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1561 /* incremement the buffer length here instead of in PointerBufferSize,
1562 * as that is used by embedded pointers which already handle the buffer
1563 * length, and shouldn't write anything more to the wire */
1564 if (*pFormat
!= RPC_FC_RP
)
1566 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
1567 pStubMsg
->BufferLength
+= 4;
1570 PointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1573 /***********************************************************************
1574 * NdrPointerMemorySize [RPCRT4.@]
1576 ULONG WINAPI
NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1577 PFORMAT_STRING pFormat
)
1579 /* unsigned size = *(LPWORD)(pFormat+2); */
1580 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1581 PointerMemorySize(pStubMsg
, pStubMsg
->Buffer
, pFormat
);
1585 /***********************************************************************
1586 * NdrPointerFree [RPCRT4.@]
1588 void WINAPI
NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1589 unsigned char *pMemory
,
1590 PFORMAT_STRING pFormat
)
1592 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1593 PointerFree(pStubMsg
, pMemory
, pFormat
);
1596 /***********************************************************************
1597 * NdrSimpleTypeMarshall [RPCRT4.@]
1599 void WINAPI
NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1600 unsigned char FormatChar
)
1602 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &FormatChar
);
1605 /***********************************************************************
1606 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1608 void WINAPI
NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1609 unsigned char FormatChar
)
1611 NdrBaseTypeUnmarshall(pStubMsg
, &pMemory
, &FormatChar
, 0);
1614 /***********************************************************************
1615 * NdrSimpleStructMarshall [RPCRT4.@]
1617 unsigned char * WINAPI
NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1618 unsigned char *pMemory
,
1619 PFORMAT_STRING pFormat
)
1621 unsigned size
= *(const WORD
*)(pFormat
+2);
1622 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1624 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1626 memcpy(pStubMsg
->Buffer
, pMemory
, size
);
1627 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1628 pStubMsg
->Buffer
+= size
;
1630 if (pFormat
[0] != RPC_FC_STRUCT
)
1631 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
+4);
1633 STD_OVERFLOW_CHECK(pStubMsg
);
1638 /***********************************************************************
1639 * NdrSimpleStructUnmarshall [RPCRT4.@]
1641 unsigned char * WINAPI
NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1642 unsigned char **ppMemory
,
1643 PFORMAT_STRING pFormat
,
1644 unsigned char fMustAlloc
)
1646 unsigned size
= *(const WORD
*)(pFormat
+2);
1647 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1649 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1652 *ppMemory
= NdrAllocate(pStubMsg
, size
);
1653 memcpy(*ppMemory
, pStubMsg
->Buffer
, size
);
1655 if (!pStubMsg
->IsClient
&& !*ppMemory
)
1656 /* for servers, we just point straight into the RPC buffer */
1657 *ppMemory
= pStubMsg
->Buffer
;
1659 /* for clients, memory should be provided by caller */
1660 memcpy(*ppMemory
, pStubMsg
->Buffer
, size
);
1663 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1664 pStubMsg
->Buffer
+= size
;
1666 if (pFormat
[0] != RPC_FC_STRUCT
)
1667 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
+4, fMustAlloc
);
1672 /***********************************************************************
1673 * NdrSimpleStructBufferSize [RPCRT4.@]
1675 void WINAPI
NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1676 unsigned char *pMemory
,
1677 PFORMAT_STRING pFormat
)
1679 unsigned size
= *(const WORD
*)(pFormat
+2);
1680 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1682 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
1684 pStubMsg
->BufferLength
+= size
;
1685 if (pFormat
[0] != RPC_FC_STRUCT
)
1686 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
+4);
1689 /***********************************************************************
1690 * NdrSimpleStructMemorySize [RPCRT4.@]
1692 ULONG WINAPI
NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1693 PFORMAT_STRING pFormat
)
1695 unsigned short size
= *(const WORD
*)(pFormat
+2);
1697 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1699 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1700 pStubMsg
->MemorySize
+= size
;
1701 pStubMsg
->Buffer
+= size
;
1703 if (pFormat
[0] != RPC_FC_STRUCT
)
1704 EmbeddedPointerMemorySize(pStubMsg
, pFormat
+4);
1708 /***********************************************************************
1709 * NdrSimpleStructFree [RPCRT4.@]
1711 void WINAPI
NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
1712 unsigned char *pMemory
,
1713 PFORMAT_STRING pFormat
)
1715 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1716 if (pFormat
[0] != RPC_FC_STRUCT
)
1717 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
+4);
1721 static unsigned long EmbeddedComplexSize(PMIDL_STUB_MESSAGE pStubMsg
,
1722 PFORMAT_STRING pFormat
)
1726 case RPC_FC_PSTRUCT
:
1727 case RPC_FC_CSTRUCT
:
1728 case RPC_FC_BOGUS_STRUCT
:
1729 case RPC_FC_SMFARRAY
:
1730 case RPC_FC_SMVARRAY
:
1731 return *(const WORD
*)&pFormat
[2];
1732 case RPC_FC_USER_MARSHAL
:
1733 return *(const WORD
*)&pFormat
[4];
1734 case RPC_FC_NON_ENCAPSULATED_UNION
:
1736 if (pStubMsg
->fHasNewCorrDesc
)
1741 pFormat
+= *(const SHORT
*)pFormat
;
1742 return *(const SHORT
*)pFormat
;
1744 return sizeof(void *);
1746 FIXME("unhandled embedded type %02x\n", *pFormat
);
1752 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1753 PFORMAT_STRING pFormat
)
1755 NDR_MEMORYSIZE m
= NdrMemorySizer
[*pFormat
& NDR_TABLE_MASK
];
1759 FIXME("no memorysizer for data type=%02x\n", *pFormat
);
1763 return m(pStubMsg
, pFormat
);
1767 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1768 unsigned char *pMemory
,
1769 PFORMAT_STRING pFormat
,
1770 PFORMAT_STRING pPointer
)
1772 PFORMAT_STRING desc
;
1776 while (*pFormat
!= RPC_FC_END
) {
1782 TRACE("byte=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
1783 memcpy(pStubMsg
->Buffer
, pMemory
, 1);
1784 pStubMsg
->Buffer
+= 1;
1790 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
1791 memcpy(pStubMsg
->Buffer
, pMemory
, 2);
1792 pStubMsg
->Buffer
+= 2;
1798 TRACE("long=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
1799 memcpy(pStubMsg
->Buffer
, pMemory
, 4);
1800 pStubMsg
->Buffer
+= 4;
1804 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
1805 memcpy(pStubMsg
->Buffer
, pMemory
, 8);
1806 pStubMsg
->Buffer
+= 8;
1809 case RPC_FC_POINTER
:
1811 unsigned char *saved_buffer
;
1812 int pointer_buffer_mark_set
= 0;
1813 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
1814 saved_buffer
= pStubMsg
->Buffer
;
1815 if (pStubMsg
->PointerBufferMark
)
1817 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1818 pStubMsg
->PointerBufferMark
= NULL
;
1819 pointer_buffer_mark_set
= 1;
1822 pStubMsg
->Buffer
+= 4; /* for pointer ID */
1823 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char**)pMemory
, pPointer
);
1824 if (pointer_buffer_mark_set
)
1826 STD_OVERFLOW_CHECK(pStubMsg
);
1827 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1828 pStubMsg
->Buffer
= saved_buffer
+ 4;
1834 case RPC_FC_ALIGNM4
:
1835 ALIGN_POINTER(pMemory
, 4);
1837 case RPC_FC_ALIGNM8
:
1838 ALIGN_POINTER(pMemory
, 8);
1840 case RPC_FC_STRUCTPAD1
:
1841 case RPC_FC_STRUCTPAD2
:
1842 case RPC_FC_STRUCTPAD3
:
1843 case RPC_FC_STRUCTPAD4
:
1844 case RPC_FC_STRUCTPAD5
:
1845 case RPC_FC_STRUCTPAD6
:
1846 case RPC_FC_STRUCTPAD7
:
1847 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
1849 case RPC_FC_EMBEDDED_COMPLEX
:
1850 pMemory
+= pFormat
[1];
1852 desc
= pFormat
+ *(const SHORT
*)pFormat
;
1853 size
= EmbeddedComplexSize(pStubMsg
, desc
);
1854 TRACE("embedded complex (size=%ld) <= %p\n", size
, pMemory
);
1855 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
1858 /* for some reason interface pointers aren't generated as
1859 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
1860 * they still need the derefencing treatment that pointers are
1862 if (*desc
== RPC_FC_IP
)
1863 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
1865 m(pStubMsg
, pMemory
, desc
);
1867 else FIXME("no marshaller for embedded type %02x\n", *desc
);
1874 FIXME("unhandled format 0x%02x\n", *pFormat
);
1882 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1883 unsigned char *pMemory
,
1884 PFORMAT_STRING pFormat
,
1885 PFORMAT_STRING pPointer
)
1887 PFORMAT_STRING desc
;
1891 while (*pFormat
!= RPC_FC_END
) {
1897 memcpy(pMemory
, pStubMsg
->Buffer
, 1);
1898 TRACE("byte=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
1899 pStubMsg
->Buffer
+= 1;
1905 memcpy(pMemory
, pStubMsg
->Buffer
, 2);
1906 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
1907 pStubMsg
->Buffer
+= 2;
1913 memcpy(pMemory
, pStubMsg
->Buffer
, 4);
1914 TRACE("long=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
1915 pStubMsg
->Buffer
+= 4;
1919 memcpy(pMemory
, pStubMsg
->Buffer
, 8);
1920 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
1921 pStubMsg
->Buffer
+= 8;
1924 case RPC_FC_POINTER
:
1926 unsigned char *saved_buffer
;
1927 int pointer_buffer_mark_set
= 0;
1928 TRACE("pointer => %p\n", pMemory
);
1929 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1930 saved_buffer
= pStubMsg
->Buffer
;
1931 if (pStubMsg
->PointerBufferMark
)
1933 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
1934 pStubMsg
->PointerBufferMark
= NULL
;
1935 pointer_buffer_mark_set
= 1;
1938 pStubMsg
->Buffer
+= 4; /* for pointer ID */
1940 PointerUnmarshall(pStubMsg
, saved_buffer
, (unsigned char**)pMemory
, pPointer
, TRUE
);
1941 if (pointer_buffer_mark_set
)
1943 STD_OVERFLOW_CHECK(pStubMsg
);
1944 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
1945 pStubMsg
->Buffer
= saved_buffer
+ 4;
1951 case RPC_FC_ALIGNM4
:
1952 ALIGN_POINTER(pMemory
, 4);
1954 case RPC_FC_ALIGNM8
:
1955 ALIGN_POINTER(pMemory
, 8);
1957 case RPC_FC_STRUCTPAD1
:
1958 case RPC_FC_STRUCTPAD2
:
1959 case RPC_FC_STRUCTPAD3
:
1960 case RPC_FC_STRUCTPAD4
:
1961 case RPC_FC_STRUCTPAD5
:
1962 case RPC_FC_STRUCTPAD6
:
1963 case RPC_FC_STRUCTPAD7
:
1964 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
1966 case RPC_FC_EMBEDDED_COMPLEX
:
1967 pMemory
+= pFormat
[1];
1969 desc
= pFormat
+ *(const SHORT
*)pFormat
;
1970 size
= EmbeddedComplexSize(pStubMsg
, desc
);
1971 TRACE("embedded complex (size=%ld) => %p\n", size
, pMemory
);
1972 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
1973 memset(pMemory
, 0, size
); /* just in case */
1976 /* for some reason interface pointers aren't generated as
1977 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
1978 * they still need the derefencing treatment that pointers are
1980 if (*desc
== RPC_FC_IP
)
1981 m(pStubMsg
, (unsigned char **)pMemory
, desc
, FALSE
);
1983 m(pStubMsg
, &pMemory
, desc
, FALSE
);
1985 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
1992 FIXME("unhandled format %d\n", *pFormat
);
2000 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2001 unsigned char *pMemory
,
2002 PFORMAT_STRING pFormat
,
2003 PFORMAT_STRING pPointer
)
2005 PFORMAT_STRING desc
;
2009 while (*pFormat
!= RPC_FC_END
) {
2015 pStubMsg
->BufferLength
+= 1;
2021 pStubMsg
->BufferLength
+= 2;
2027 pStubMsg
->BufferLength
+= 4;
2031 pStubMsg
->BufferLength
+= 8;
2034 case RPC_FC_POINTER
:
2035 if (!pStubMsg
->IgnoreEmbeddedPointers
)
2037 int saved_buffer_length
= pStubMsg
->BufferLength
;
2038 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2039 pStubMsg
->PointerLength
= 0;
2040 if(!pStubMsg
->BufferLength
)
2041 ERR("BufferLength == 0??\n");
2042 PointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
2043 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2044 pStubMsg
->BufferLength
= saved_buffer_length
;
2046 pStubMsg
->BufferLength
+= 4;
2050 case RPC_FC_ALIGNM4
:
2051 ALIGN_POINTER(pMemory
, 4);
2053 case RPC_FC_ALIGNM8
:
2054 ALIGN_POINTER(pMemory
, 8);
2056 case RPC_FC_STRUCTPAD1
:
2057 case RPC_FC_STRUCTPAD2
:
2058 case RPC_FC_STRUCTPAD3
:
2059 case RPC_FC_STRUCTPAD4
:
2060 case RPC_FC_STRUCTPAD5
:
2061 case RPC_FC_STRUCTPAD6
:
2062 case RPC_FC_STRUCTPAD7
:
2063 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2065 case RPC_FC_EMBEDDED_COMPLEX
:
2066 pMemory
+= pFormat
[1];
2068 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2069 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2070 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
2073 /* for some reason interface pointers aren't generated as
2074 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2075 * they still need the derefencing treatment that pointers are
2077 if (*desc
== RPC_FC_IP
)
2078 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2080 m(pStubMsg
, pMemory
, desc
);
2082 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
2089 FIXME("unhandled format 0x%02x\n", *pFormat
);
2097 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
2098 unsigned char *pMemory
,
2099 PFORMAT_STRING pFormat
,
2100 PFORMAT_STRING pPointer
)
2102 PFORMAT_STRING desc
;
2106 while (*pFormat
!= RPC_FC_END
) {
2127 case RPC_FC_POINTER
:
2128 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
2132 case RPC_FC_ALIGNM4
:
2133 ALIGN_POINTER(pMemory
, 4);
2135 case RPC_FC_ALIGNM8
:
2136 ALIGN_POINTER(pMemory
, 8);
2138 case RPC_FC_STRUCTPAD1
:
2139 case RPC_FC_STRUCTPAD2
:
2140 case RPC_FC_STRUCTPAD3
:
2141 case RPC_FC_STRUCTPAD4
:
2142 case RPC_FC_STRUCTPAD5
:
2143 case RPC_FC_STRUCTPAD6
:
2144 case RPC_FC_STRUCTPAD7
:
2145 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2147 case RPC_FC_EMBEDDED_COMPLEX
:
2148 pMemory
+= pFormat
[1];
2150 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2151 size
= EmbeddedComplexSize(pStubMsg
, desc
);
2152 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
2155 /* for some reason interface pointers aren't generated as
2156 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2157 * they still need the derefencing treatment that pointers are
2159 if (*desc
== RPC_FC_IP
)
2160 m(pStubMsg
, *(unsigned char **)pMemory
, desc
);
2162 m(pStubMsg
, pMemory
, desc
);
2164 else FIXME("no freer for embedded type %02x\n", *desc
);
2171 FIXME("unhandled format 0x%02x\n", *pFormat
);
2179 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2180 PFORMAT_STRING pFormat
)
2182 PFORMAT_STRING desc
;
2183 unsigned long size
= 0;
2185 while (*pFormat
!= RPC_FC_END
) {
2192 pStubMsg
->Buffer
+= 1;
2198 pStubMsg
->Buffer
+= 2;
2204 pStubMsg
->Buffer
+= 4;
2208 pStubMsg
->Buffer
+= 8;
2210 case RPC_FC_POINTER
:
2212 pStubMsg
->Buffer
+= 4;
2213 if (!pStubMsg
->IgnoreEmbeddedPointers
)
2214 FIXME("embedded pointers\n");
2216 case RPC_FC_ALIGNM4
:
2217 ALIGN_LENGTH(size
, 4);
2218 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2220 case RPC_FC_ALIGNM8
:
2221 ALIGN_LENGTH(size
, 8);
2222 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
2224 case RPC_FC_STRUCTPAD1
:
2225 case RPC_FC_STRUCTPAD2
:
2226 case RPC_FC_STRUCTPAD3
:
2227 case RPC_FC_STRUCTPAD4
:
2228 case RPC_FC_STRUCTPAD5
:
2229 case RPC_FC_STRUCTPAD6
:
2230 case RPC_FC_STRUCTPAD7
:
2231 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2233 case RPC_FC_EMBEDDED_COMPLEX
:
2236 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2237 size
+= EmbeddedComplexMemorySize(pStubMsg
, desc
);
2243 FIXME("unhandled format 0x%02x\n", *pFormat
);
2251 /***********************************************************************
2252 * NdrComplexStructMarshall [RPCRT4.@]
2254 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2255 unsigned char *pMemory
,
2256 PFORMAT_STRING pFormat
)
2258 PFORMAT_STRING conf_array
= NULL
;
2259 PFORMAT_STRING pointer_desc
= NULL
;
2260 unsigned char *OldMemory
= pStubMsg
->Memory
;
2261 int pointer_buffer_mark_set
= 0;
2263 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2265 if (!pStubMsg
->PointerBufferMark
)
2267 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2268 /* save buffer length */
2269 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2271 /* get the buffer pointer after complex array data, but before
2273 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- pStubMsg
->BufferStart
;
2274 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2275 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
2276 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2278 /* save it for use by embedded pointer code later */
2279 pStubMsg
->PointerBufferMark
= pStubMsg
->BufferStart
+ pStubMsg
->BufferLength
;
2280 TRACE("difference = 0x%x\n", pStubMsg
->PointerBufferMark
- pStubMsg
->Buffer
);
2281 pointer_buffer_mark_set
= 1;
2283 /* restore the original buffer length */
2284 pStubMsg
->BufferLength
= saved_buffer_length
;
2287 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2290 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2292 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2295 pStubMsg
->Memory
= pMemory
;
2297 ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2300 NdrConformantArrayMarshall(pStubMsg
, pMemory
, conf_array
);
2302 pStubMsg
->Memory
= OldMemory
;
2304 if (pointer_buffer_mark_set
)
2306 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2307 pStubMsg
->PointerBufferMark
= NULL
;
2310 STD_OVERFLOW_CHECK(pStubMsg
);
2315 /***********************************************************************
2316 * NdrComplexStructUnmarshall [RPCRT4.@]
2318 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2319 unsigned char **ppMemory
,
2320 PFORMAT_STRING pFormat
,
2321 unsigned char fMustAlloc
)
2323 unsigned size
= *(const WORD
*)(pFormat
+2);
2324 PFORMAT_STRING conf_array
= NULL
;
2325 PFORMAT_STRING pointer_desc
= NULL
;
2326 unsigned char *pMemory
;
2327 int pointer_buffer_mark_set
= 0;
2329 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2331 if (!pStubMsg
->PointerBufferMark
)
2333 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2334 /* save buffer pointer */
2335 unsigned char *saved_buffer
= pStubMsg
->Buffer
;
2337 /* get the buffer pointer after complex array data, but before
2339 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2340 NdrComplexStructMemorySize(pStubMsg
, pFormat
);
2341 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2343 /* save it for use by embedded pointer code later */
2344 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2345 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->PointerBufferMark
- saved_buffer
));
2346 pointer_buffer_mark_set
= 1;
2348 /* restore the original buffer */
2349 pStubMsg
->Buffer
= saved_buffer
;
2352 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2354 if (fMustAlloc
|| !*ppMemory
)
2356 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2357 memset(*ppMemory
, 0, size
);
2361 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2363 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2366 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
);
2369 NdrConformantArrayUnmarshall(pStubMsg
, &pMemory
, conf_array
, fMustAlloc
);
2371 if (pointer_buffer_mark_set
)
2373 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2374 pStubMsg
->PointerBufferMark
= NULL
;
2380 /***********************************************************************
2381 * NdrComplexStructBufferSize [RPCRT4.@]
2383 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2384 unsigned char *pMemory
,
2385 PFORMAT_STRING pFormat
)
2387 PFORMAT_STRING conf_array
= NULL
;
2388 PFORMAT_STRING pointer_desc
= NULL
;
2389 unsigned char *OldMemory
= pStubMsg
->Memory
;
2390 int pointer_length_set
= 0;
2392 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2394 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
2396 if(!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
2398 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2399 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2401 /* get the buffer length after complex struct data, but before
2403 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2404 NdrComplexStructBufferSize(pStubMsg
, pMemory
, pFormat
);
2405 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2407 /* save it for use by embedded pointer code later */
2408 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2409 pointer_length_set
= 1;
2410 TRACE("difference = 0x%lx\n", pStubMsg
->PointerLength
- saved_buffer_length
);
2412 /* restore the original buffer length */
2413 pStubMsg
->BufferLength
= saved_buffer_length
;
2417 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2419 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2422 pStubMsg
->Memory
= pMemory
;
2424 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2427 NdrConformantArrayBufferSize(pStubMsg
, pMemory
, conf_array
);
2429 pStubMsg
->Memory
= OldMemory
;
2431 if(pointer_length_set
)
2433 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
2434 pStubMsg
->PointerLength
= 0;
2439 /***********************************************************************
2440 * NdrComplexStructMemorySize [RPCRT4.@]
2442 ULONG WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2443 PFORMAT_STRING pFormat
)
2445 unsigned size
= *(const WORD
*)(pFormat
+2);
2446 PFORMAT_STRING conf_array
= NULL
;
2447 PFORMAT_STRING pointer_desc
= NULL
;
2449 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2451 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2454 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2456 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2459 ComplexStructMemorySize(pStubMsg
, pFormat
);
2462 NdrConformantArrayMemorySize(pStubMsg
, conf_array
);
2467 /***********************************************************************
2468 * NdrComplexStructFree [RPCRT4.@]
2470 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
2471 unsigned char *pMemory
,
2472 PFORMAT_STRING pFormat
)
2474 PFORMAT_STRING conf_array
= NULL
;
2475 PFORMAT_STRING pointer_desc
= NULL
;
2476 unsigned char *OldMemory
= pStubMsg
->Memory
;
2478 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2481 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2483 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2486 pStubMsg
->Memory
= pMemory
;
2488 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2491 NdrConformantArrayFree(pStubMsg
, pMemory
, conf_array
);
2493 pStubMsg
->Memory
= OldMemory
;
2496 /***********************************************************************
2497 * NdrConformantArrayMarshall [RPCRT4.@]
2499 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2500 unsigned char *pMemory
,
2501 PFORMAT_STRING pFormat
)
2503 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
2504 unsigned char alignment
= pFormat
[1] + 1;
2506 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2507 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2509 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2511 WriteConformance(pStubMsg
);
2513 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2515 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2516 memcpy(pStubMsg
->Buffer
, pMemory
, size
);
2517 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2518 pStubMsg
->Buffer
+= size
;
2520 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2522 STD_OVERFLOW_CHECK(pStubMsg
);
2527 /***********************************************************************
2528 * NdrConformantArrayUnmarshall [RPCRT4.@]
2530 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2531 unsigned char **ppMemory
,
2532 PFORMAT_STRING pFormat
,
2533 unsigned char fMustAlloc
)
2535 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
2536 unsigned char alignment
= pFormat
[1] + 1;
2538 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2539 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2541 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2543 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2545 if (fMustAlloc
|| !*ppMemory
)
2546 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2548 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2550 memcpy(*ppMemory
, pStubMsg
->Buffer
, size
);
2552 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2553 pStubMsg
->Buffer
+= size
;
2555 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2560 /***********************************************************************
2561 * NdrConformantArrayBufferSize [RPCRT4.@]
2563 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2564 unsigned char *pMemory
,
2565 PFORMAT_STRING pFormat
)
2567 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
2568 unsigned char alignment
= pFormat
[1] + 1;
2570 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2571 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2573 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2575 SizeConformance(pStubMsg
);
2577 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
2579 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2580 /* conformance value plus array */
2581 pStubMsg
->BufferLength
+= size
;
2583 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
2586 /***********************************************************************
2587 * NdrConformantArrayMemorySize [RPCRT4.@]
2589 ULONG WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2590 PFORMAT_STRING pFormat
)
2592 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
2593 unsigned char alignment
= pFormat
[1] + 1;
2595 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2596 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2598 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2599 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2600 pStubMsg
->MemorySize
+= size
;
2602 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2603 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2604 pStubMsg
->Buffer
+= size
;
2606 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2608 return pStubMsg
->MemorySize
;
2611 /***********************************************************************
2612 * NdrConformantArrayFree [RPCRT4.@]
2614 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
2615 unsigned char *pMemory
,
2616 PFORMAT_STRING pFormat
)
2618 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2619 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2621 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2623 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2627 /***********************************************************************
2628 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2630 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2631 unsigned char* pMemory
,
2632 PFORMAT_STRING pFormat
)
2635 unsigned char alignment
= pFormat
[1] + 1;
2636 DWORD esize
= *(const WORD
*)(pFormat
+2);
2638 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
2640 if (pFormat
[0] != RPC_FC_CVARRAY
)
2642 ERR("invalid format type %x\n", pFormat
[0]);
2643 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2647 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2648 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2650 WriteConformance(pStubMsg
);
2651 WriteVariance(pStubMsg
);
2653 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2655 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2657 memcpy(pStubMsg
->Buffer
, pMemory
+ pStubMsg
->Offset
, bufsize
);
2658 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2659 pStubMsg
->Buffer
+= bufsize
;
2661 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2663 STD_OVERFLOW_CHECK(pStubMsg
);
2669 /***********************************************************************
2670 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2672 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2673 unsigned char** ppMemory
,
2674 PFORMAT_STRING pFormat
,
2675 unsigned char fMustAlloc
)
2677 ULONG bufsize
, memsize
;
2678 unsigned char alignment
= pFormat
[1] + 1;
2679 DWORD esize
= *(const WORD
*)(pFormat
+2);
2681 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2683 if (pFormat
[0] != RPC_FC_CVARRAY
)
2685 ERR("invalid format type %x\n", pFormat
[0]);
2686 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2690 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2691 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2693 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2695 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2696 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2698 if (!*ppMemory
|| fMustAlloc
)
2699 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2700 memcpy(*ppMemory
+ pStubMsg
->Offset
, pStubMsg
->Buffer
, bufsize
);
2701 pStubMsg
->Buffer
+= bufsize
;
2703 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2709 /***********************************************************************
2710 * NdrConformantVaryingArrayFree [RPCRT4.@]
2712 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
2713 unsigned char* pMemory
,
2714 PFORMAT_STRING pFormat
)
2716 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2718 if (pFormat
[0] != RPC_FC_CVARRAY
)
2720 ERR("invalid format type %x\n", pFormat
[0]);
2721 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2725 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2726 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2728 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2732 /***********************************************************************
2733 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2735 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
2736 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
2738 unsigned char alignment
= pFormat
[1] + 1;
2739 DWORD esize
= *(const WORD
*)(pFormat
+2);
2741 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
2743 if (pFormat
[0] != RPC_FC_CVARRAY
)
2745 ERR("invalid format type %x\n", pFormat
[0]);
2746 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2751 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2752 /* compute length */
2753 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2755 SizeConformance(pStubMsg
);
2756 SizeVariance(pStubMsg
);
2758 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
2760 pStubMsg
->BufferLength
+= safe_multiply(esize
, pStubMsg
->ActualCount
);
2762 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
2766 /***********************************************************************
2767 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2769 ULONG WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
2770 PFORMAT_STRING pFormat
)
2777 /***********************************************************************
2778 * NdrComplexArrayMarshall [RPCRT4.@]
2780 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2781 unsigned char *pMemory
,
2782 PFORMAT_STRING pFormat
)
2784 ULONG i
, count
, def
;
2785 BOOL variance_present
;
2786 unsigned char alignment
;
2787 int pointer_buffer_mark_set
= 0;
2789 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2791 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
2793 ERR("invalid format type %x\n", pFormat
[0]);
2794 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2798 alignment
= pFormat
[1] + 1;
2800 if (!pStubMsg
->PointerBufferMark
)
2802 /* save buffer fields that may be changed by buffer sizer functions
2803 * and that may be needed later on */
2804 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2805 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2806 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
2807 unsigned long saved_offset
= pStubMsg
->Offset
;
2808 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
2810 /* get the buffer pointer after complex array data, but before
2812 pStubMsg
->BufferLength
= pStubMsg
->Buffer
- pStubMsg
->BufferStart
;
2813 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2814 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
2815 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2817 /* save it for use by embedded pointer code later */
2818 pStubMsg
->PointerBufferMark
= pStubMsg
->BufferStart
+ pStubMsg
->BufferLength
;
2819 TRACE("difference = 0x%x\n", pStubMsg
->Buffer
- pStubMsg
->BufferStart
);
2820 pointer_buffer_mark_set
= 1;
2822 /* restore fields */
2823 pStubMsg
->ActualCount
= saved_actual_count
;
2824 pStubMsg
->Offset
= saved_offset
;
2825 pStubMsg
->MaxCount
= saved_max_count
;
2826 pStubMsg
->BufferLength
= saved_buffer_length
;
2829 def
= *(const WORD
*)&pFormat
[2];
2832 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
2833 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
2835 variance_present
= IsConformanceOrVariancePresent(pFormat
);
2836 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
2837 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
2839 WriteConformance(pStubMsg
);
2840 if (variance_present
)
2841 WriteVariance(pStubMsg
);
2843 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2845 count
= pStubMsg
->ActualCount
;
2846 for (i
= 0; i
< count
; i
++)
2847 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
2849 STD_OVERFLOW_CHECK(pStubMsg
);
2851 if (pointer_buffer_mark_set
)
2853 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2854 pStubMsg
->PointerBufferMark
= NULL
;
2860 /***********************************************************************
2861 * NdrComplexArrayUnmarshall [RPCRT4.@]
2863 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2864 unsigned char **ppMemory
,
2865 PFORMAT_STRING pFormat
,
2866 unsigned char fMustAlloc
)
2868 ULONG i
, count
, size
;
2869 unsigned char alignment
;
2870 unsigned char *pMemory
;
2871 unsigned char *saved_buffer
;
2872 int pointer_buffer_mark_set
= 0;
2873 int saved_ignore_embedded
;
2875 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2877 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
2879 ERR("invalid format type %x\n", pFormat
[0]);
2880 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2884 alignment
= pFormat
[1] + 1;
2886 saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2887 /* save buffer pointer */
2888 saved_buffer
= pStubMsg
->Buffer
;
2889 /* get the buffer pointer after complex array data, but before
2891 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2892 pStubMsg
->MemorySize
= 0;
2893 NdrComplexArrayMemorySize(pStubMsg
, pFormat
);
2894 size
= pStubMsg
->MemorySize
;
2895 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2897 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg
->Buffer
- saved_buffer
));
2898 if (!pStubMsg
->PointerBufferMark
)
2900 /* save it for use by embedded pointer code later */
2901 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
2902 pointer_buffer_mark_set
= 1;
2904 /* restore the original buffer */
2905 pStubMsg
->Buffer
= saved_buffer
;
2909 pFormat
= ReadConformance(pStubMsg
, pFormat
);
2910 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2912 if (fMustAlloc
|| !*ppMemory
)
2914 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2915 memset(*ppMemory
, 0, size
);
2918 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2920 pMemory
= *ppMemory
;
2921 count
= pStubMsg
->ActualCount
;
2922 for (i
= 0; i
< count
; i
++)
2923 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
2925 if (pointer_buffer_mark_set
)
2927 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
2928 pStubMsg
->PointerBufferMark
= NULL
;
2934 /***********************************************************************
2935 * NdrComplexArrayBufferSize [RPCRT4.@]
2937 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2938 unsigned char *pMemory
,
2939 PFORMAT_STRING pFormat
)
2941 ULONG i
, count
, def
;
2942 unsigned char alignment
;
2943 BOOL variance_present
;
2944 int pointer_length_set
= 0;
2946 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2948 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
2950 ERR("invalid format type %x\n", pFormat
[0]);
2951 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2955 alignment
= pFormat
[1] + 1;
2957 if (!pStubMsg
->IgnoreEmbeddedPointers
&& !pStubMsg
->PointerLength
)
2959 /* save buffer fields that may be changed by buffer sizer functions
2960 * and that may be needed later on */
2961 int saved_ignore_embedded
= pStubMsg
->IgnoreEmbeddedPointers
;
2962 unsigned long saved_buffer_length
= pStubMsg
->BufferLength
;
2963 unsigned long saved_max_count
= pStubMsg
->MaxCount
;
2964 unsigned long saved_offset
= pStubMsg
->Offset
;
2965 unsigned long saved_actual_count
= pStubMsg
->ActualCount
;
2967 /* get the buffer pointer after complex array data, but before
2969 pStubMsg
->IgnoreEmbeddedPointers
= 1;
2970 NdrComplexArrayBufferSize(pStubMsg
, pMemory
, pFormat
);
2971 pStubMsg
->IgnoreEmbeddedPointers
= saved_ignore_embedded
;
2973 /* save it for use by embedded pointer code later */
2974 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
2975 pointer_length_set
= 1;
2977 /* restore fields */
2978 pStubMsg
->ActualCount
= saved_actual_count
;
2979 pStubMsg
->Offset
= saved_offset
;
2980 pStubMsg
->MaxCount
= saved_max_count
;
2981 pStubMsg
->BufferLength
= saved_buffer_length
;
2983 def
= *(const WORD
*)&pFormat
[2];
2986 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
2987 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
2988 SizeConformance(pStubMsg
);
2990 variance_present
= IsConformanceOrVariancePresent(pFormat
);
2991 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
2992 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
2994 if (variance_present
)
2995 SizeVariance(pStubMsg
);
2997 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
2999 count
= pStubMsg
->ActualCount
;
3000 for (i
= 0; i
< count
; i
++)
3001 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
3003 if(pointer_length_set
)
3005 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3006 pStubMsg
->PointerLength
= 0;
3010 /***********************************************************************
3011 * NdrComplexArrayMemorySize [RPCRT4.@]
3013 ULONG WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3014 PFORMAT_STRING pFormat
)
3016 ULONG i
, count
, esize
, SavedMemorySize
, MemorySize
;
3017 unsigned char alignment
;
3018 unsigned char *Buffer
;
3020 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3022 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3024 ERR("invalid format type %x\n", pFormat
[0]);
3025 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3029 alignment
= pFormat
[1] + 1;
3033 pFormat
= ReadConformance(pStubMsg
, pFormat
);
3034 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
3036 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3038 SavedMemorySize
= pStubMsg
->MemorySize
;
3040 Buffer
= pStubMsg
->Buffer
;
3041 pStubMsg
->MemorySize
= 0;
3042 esize
= ComplexStructMemorySize(pStubMsg
, pFormat
);
3043 pStubMsg
->Buffer
= Buffer
;
3045 MemorySize
= safe_multiply(pStubMsg
->MaxCount
, esize
);
3047 count
= pStubMsg
->ActualCount
;
3048 for (i
= 0; i
< count
; i
++)
3049 ComplexStructMemorySize(pStubMsg
, pFormat
);
3051 pStubMsg
->MemorySize
= SavedMemorySize
;
3053 pStubMsg
->MemorySize
+= MemorySize
;
3057 /***********************************************************************
3058 * NdrComplexArrayFree [RPCRT4.@]
3060 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3061 unsigned char *pMemory
,
3062 PFORMAT_STRING pFormat
)
3064 ULONG i
, count
, def
;
3066 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3068 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
3070 ERR("invalid format type %x\n", pFormat
[0]);
3071 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3075 def
= *(const WORD
*)&pFormat
[2];
3078 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
3079 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
3081 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
3082 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
3084 count
= pStubMsg
->ActualCount
;
3085 for (i
= 0; i
< count
; i
++)
3086 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
3089 static ULONG
UserMarshalFlags(PMIDL_STUB_MESSAGE pStubMsg
)
3091 return MAKELONG(pStubMsg
->dwDestContext
,
3092 pStubMsg
->RpcMsg
->DataRepresentation
);
3095 #define USER_MARSHAL_PTR_PREFIX \
3096 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3097 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3099 /***********************************************************************
3100 * NdrUserMarshalMarshall [RPCRT4.@]
3102 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3103 unsigned char *pMemory
,
3104 PFORMAT_STRING pFormat
)
3106 unsigned flags
= pFormat
[1];
3107 unsigned index
= *(const WORD
*)&pFormat
[2];
3108 unsigned char *saved_buffer
= NULL
;
3109 ULONG uflag
= UserMarshalFlags(pStubMsg
);
3110 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3111 TRACE("index=%d\n", index
);
3113 if (flags
& USER_MARSHAL_POINTER
)
3115 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3116 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, USER_MARSHAL_PTR_PREFIX
);
3117 pStubMsg
->Buffer
+= 4;
3118 if (pStubMsg
->PointerBufferMark
)
3120 saved_buffer
= pStubMsg
->Buffer
;
3121 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3122 pStubMsg
->PointerBufferMark
= NULL
;
3124 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3127 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3130 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
3131 &uflag
, pStubMsg
->Buffer
, pMemory
);
3135 STD_OVERFLOW_CHECK(pStubMsg
);
3136 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3137 pStubMsg
->Buffer
= saved_buffer
;
3140 STD_OVERFLOW_CHECK(pStubMsg
);
3145 /***********************************************************************
3146 * NdrUserMarshalUnmarshall [RPCRT4.@]
3148 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3149 unsigned char **ppMemory
,
3150 PFORMAT_STRING pFormat
,
3151 unsigned char fMustAlloc
)
3153 unsigned flags
= pFormat
[1];
3154 unsigned index
= *(const WORD
*)&pFormat
[2];
3155 DWORD memsize
= *(const WORD
*)&pFormat
[4];
3156 unsigned char *saved_buffer
= NULL
;
3157 ULONG uflag
= UserMarshalFlags(pStubMsg
);
3158 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3159 TRACE("index=%d\n", index
);
3161 if (flags
& USER_MARSHAL_POINTER
)
3163 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3164 /* skip pointer prefix */
3165 pStubMsg
->Buffer
+= 4;
3166 if (pStubMsg
->PointerBufferMark
)
3168 saved_buffer
= pStubMsg
->Buffer
;
3169 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
3170 pStubMsg
->PointerBufferMark
= NULL
;
3172 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3175 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3177 if (fMustAlloc
|| !*ppMemory
)
3178 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
3181 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
3182 &uflag
, pStubMsg
->Buffer
, *ppMemory
);
3186 STD_OVERFLOW_CHECK(pStubMsg
);
3187 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
3188 pStubMsg
->Buffer
= saved_buffer
;
3194 /***********************************************************************
3195 * NdrUserMarshalBufferSize [RPCRT4.@]
3197 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3198 unsigned char *pMemory
,
3199 PFORMAT_STRING pFormat
)
3201 unsigned flags
= pFormat
[1];
3202 unsigned index
= *(const WORD
*)&pFormat
[2];
3203 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
3204 ULONG uflag
= UserMarshalFlags(pStubMsg
);
3205 unsigned long saved_buffer_length
= 0;
3206 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3207 TRACE("index=%d\n", index
);
3209 if (flags
& USER_MARSHAL_POINTER
)
3211 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
3212 /* skip pointer prefix */
3213 pStubMsg
->BufferLength
+= 4;
3214 if (pStubMsg
->IgnoreEmbeddedPointers
)
3216 if (pStubMsg
->PointerLength
)
3218 saved_buffer_length
= pStubMsg
->BufferLength
;
3219 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
3220 pStubMsg
->PointerLength
= 0;
3222 ALIGN_LENGTH(pStubMsg
->BufferLength
, 8);
3225 ALIGN_LENGTH(pStubMsg
->BufferLength
, (flags
& 0xf) + 1);
3228 TRACE("size=%d\n", bufsize
);
3229 pStubMsg
->BufferLength
+= bufsize
;
3232 pStubMsg
->BufferLength
=
3233 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
3234 &uflag
, pStubMsg
->BufferLength
, pMemory
);
3236 if (saved_buffer_length
)
3238 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
3239 pStubMsg
->BufferLength
= saved_buffer_length
;
3244 /***********************************************************************
3245 * NdrUserMarshalMemorySize [RPCRT4.@]
3247 ULONG WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3248 PFORMAT_STRING pFormat
)
3250 unsigned flags
= pFormat
[1];
3251 unsigned index
= *(const WORD
*)&pFormat
[2];
3252 DWORD memsize
= *(const WORD
*)&pFormat
[4];
3253 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
3255 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
3256 TRACE("index=%d\n", index
);
3258 pStubMsg
->MemorySize
+= memsize
;
3260 if (flags
& USER_MARSHAL_POINTER
)
3262 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
3263 /* skip pointer prefix */
3264 pStubMsg
->Buffer
+= 4;
3265 if (pStubMsg
->IgnoreEmbeddedPointers
)
3266 return pStubMsg
->MemorySize
;
3267 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
3270 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
3273 FIXME("not implemented for varying buffer size\n");
3275 pStubMsg
->Buffer
+= bufsize
;
3277 return pStubMsg
->MemorySize
;
3280 /***********************************************************************
3281 * NdrUserMarshalFree [RPCRT4.@]
3283 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
3284 unsigned char *pMemory
,
3285 PFORMAT_STRING pFormat
)
3287 /* unsigned flags = pFormat[1]; */
3288 unsigned index
= *(const WORD
*)&pFormat
[2];
3289 ULONG uflag
= UserMarshalFlags(pStubMsg
);
3290 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
3291 TRACE("index=%d\n", index
);
3293 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
3297 /***********************************************************************
3298 * NdrClearOutParameters [RPCRT4.@]
3300 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
3301 PFORMAT_STRING pFormat
,
3304 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
3307 /***********************************************************************
3308 * NdrConvert [RPCRT4.@]
3310 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
3312 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
3313 /* FIXME: since this stub doesn't do any converting, the proper behavior
3314 is to raise an exception */
3317 /***********************************************************************
3318 * NdrConvert2 [RPCRT4.@]
3320 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, LONG NumberParams
)
3322 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3323 pStubMsg
, pFormat
, NumberParams
);
3324 /* FIXME: since this stub doesn't do any converting, the proper behavior
3325 is to raise an exception */
3328 #include "pshpack1.h"
3329 typedef struct _NDR_CSTRUCT_FORMAT
3332 unsigned char alignment
;
3333 unsigned short memory_size
;
3334 short offset_to_array_description
;
3335 } NDR_CSTRUCT_FORMAT
, NDR_CVSTRUCT_FORMAT
;
3336 #include "poppack.h"
3338 /***********************************************************************
3339 * NdrConformantStructMarshall [RPCRT4.@]
3341 unsigned char * WINAPI
NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3342 unsigned char *pMemory
,
3343 PFORMAT_STRING pFormat
)
3345 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3346 PFORMAT_STRING pCArrayFormat
;
3347 ULONG esize
, bufsize
;
3349 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3351 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3352 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3354 ERR("invalid format type %x\n", pCStructFormat
->type
);
3355 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3359 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3360 pCStructFormat
->offset_to_array_description
;
3361 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3363 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3364 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3367 esize
= *(const WORD
*)(pCArrayFormat
+2);
3369 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
3370 pCArrayFormat
+ 4, 0);
3372 WriteConformance(pStubMsg
);
3374 ALIGN_POINTER(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
3376 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3378 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3379 /* copy constant sized part of struct */
3380 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3381 memcpy(pStubMsg
->Buffer
, pMemory
, pCStructFormat
->memory_size
+ bufsize
);
3382 pStubMsg
->Buffer
+= pCStructFormat
->memory_size
+ bufsize
;
3384 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3385 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3387 STD_OVERFLOW_CHECK(pStubMsg
);
3392 /***********************************************************************
3393 * NdrConformantStructUnmarshall [RPCRT4.@]
3395 unsigned char * WINAPI
NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3396 unsigned char **ppMemory
,
3397 PFORMAT_STRING pFormat
,
3398 unsigned char fMustAlloc
)
3400 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3401 PFORMAT_STRING pCArrayFormat
;
3402 ULONG esize
, bufsize
;
3404 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3406 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3407 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3409 ERR("invalid format type %x\n", pCStructFormat
->type
);
3410 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3413 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3414 pCStructFormat
->offset_to_array_description
;
3415 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3417 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3418 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3421 esize
= *(const WORD
*)(pCArrayFormat
+2);
3423 pCArrayFormat
= ReadConformance(pStubMsg
, pCArrayFormat
+ 4);
3425 ALIGN_POINTER(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
3427 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3429 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3430 /* work out how much memory to allocate if we need to do so */
3431 if (!*ppMemory
|| fMustAlloc
)
3433 SIZE_T size
= pCStructFormat
->memory_size
+ bufsize
;
3434 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3437 /* now copy the data */
3438 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3439 memcpy(*ppMemory
, pStubMsg
->Buffer
, pCStructFormat
->memory_size
+ bufsize
);
3440 pStubMsg
->Buffer
+= pCStructFormat
->memory_size
+ bufsize
;
3442 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3443 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3448 /***********************************************************************
3449 * NdrConformantStructBufferSize [RPCRT4.@]
3451 void WINAPI
NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3452 unsigned char *pMemory
,
3453 PFORMAT_STRING pFormat
)
3455 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3456 PFORMAT_STRING pCArrayFormat
;
3459 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3461 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3462 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3464 ERR("invalid format type %x\n", pCStructFormat
->type
);
3465 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3468 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3469 pCStructFormat
->offset_to_array_description
;
3470 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3472 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3473 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3476 esize
= *(const WORD
*)(pCArrayFormat
+2);
3478 pCArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
, pCArrayFormat
+4, 0);
3479 SizeConformance(pStubMsg
);
3481 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCStructFormat
->alignment
+ 1);
3483 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3485 pStubMsg
->BufferLength
+= pCStructFormat
->memory_size
+
3486 safe_multiply(pStubMsg
->MaxCount
, esize
);
3488 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3489 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3492 /***********************************************************************
3493 * NdrConformantStructMemorySize [RPCRT4.@]
3495 ULONG WINAPI
NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3496 PFORMAT_STRING pFormat
)
3502 /***********************************************************************
3503 * NdrConformantStructFree [RPCRT4.@]
3505 void WINAPI
NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3506 unsigned char *pMemory
,
3507 PFORMAT_STRING pFormat
)
3512 /***********************************************************************
3513 * NdrConformantVaryingStructMarshall [RPCRT4.@]
3515 unsigned char * WINAPI
NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3516 unsigned char *pMemory
,
3517 PFORMAT_STRING pFormat
)
3519 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3520 PFORMAT_STRING pCVArrayFormat
;
3521 ULONG esize
, bufsize
;
3523 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3525 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3526 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3528 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3529 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3533 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3534 pCVStructFormat
->offset_to_array_description
;
3535 switch (*pCVArrayFormat
)
3537 case RPC_FC_CVARRAY
:
3538 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3540 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3541 pCVArrayFormat
+ 4, 0);
3542 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3545 case RPC_FC_C_CSTRING
:
3546 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
3547 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
3548 esize
= sizeof(char);
3549 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3550 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3551 pCVArrayFormat
+ 2, 0);
3553 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3555 case RPC_FC_C_WSTRING
:
3556 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
3557 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
3558 esize
= sizeof(WCHAR
);
3559 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3560 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3561 pCVArrayFormat
+ 2, 0);
3563 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3566 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3567 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3571 WriteConformance(pStubMsg
);
3573 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
3575 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3577 /* write constant sized part */
3578 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3579 memcpy(pStubMsg
->Buffer
, pMemory
, pCVStructFormat
->memory_size
);
3580 pStubMsg
->Buffer
+= pCVStructFormat
->memory_size
;
3582 WriteVariance(pStubMsg
);
3584 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3586 /* write array part */
3587 memcpy(pStubMsg
->Buffer
, pMemory
+ pCVStructFormat
->memory_size
, bufsize
);
3588 pStubMsg
->Buffer
+= bufsize
;
3590 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3592 STD_OVERFLOW_CHECK(pStubMsg
);
3597 /***********************************************************************
3598 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3600 unsigned char * WINAPI
NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3601 unsigned char **ppMemory
,
3602 PFORMAT_STRING pFormat
,
3603 unsigned char fMustAlloc
)
3605 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3606 PFORMAT_STRING pCVArrayFormat
;
3607 ULONG esize
, bufsize
;
3608 unsigned char cvarray_type
;
3610 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3612 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3613 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3615 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3616 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3620 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3621 pCVStructFormat
->offset_to_array_description
;
3622 cvarray_type
= *pCVArrayFormat
;
3623 switch (cvarray_type
)
3625 case RPC_FC_CVARRAY
:
3626 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3627 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 4);
3629 case RPC_FC_C_CSTRING
:
3630 esize
= sizeof(char);
3631 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3632 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3634 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3636 case RPC_FC_C_WSTRING
:
3637 esize
= sizeof(WCHAR
);
3638 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3639 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3641 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3644 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3645 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3649 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
3651 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3653 /* work out how much memory to allocate if we need to do so */
3654 if (!*ppMemory
|| fMustAlloc
)
3656 SIZE_T size
= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->MaxCount
);
3657 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3660 /* copy the constant data */
3661 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3662 memcpy(*ppMemory
, pStubMsg
->Buffer
, pCVStructFormat
->memory_size
);
3663 pStubMsg
->Buffer
+= pCVStructFormat
->memory_size
;
3665 pCVArrayFormat
= ReadVariance(pStubMsg
, pCVArrayFormat
, pStubMsg
->MaxCount
);
3667 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3669 if ((cvarray_type
== RPC_FC_C_CSTRING
) ||
3670 (cvarray_type
== RPC_FC_C_WSTRING
))
3673 /* strings must always have null terminating bytes */
3674 if (bufsize
< esize
)
3676 ERR("invalid string length of %d\n", pStubMsg
->ActualCount
);
3677 RpcRaiseException(RPC_S_INVALID_BOUND
);
3680 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
3681 if (pStubMsg
->Buffer
[i
] != 0)
3683 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
3684 i
, pStubMsg
->Buffer
[i
]);
3685 RpcRaiseException(RPC_S_INVALID_BOUND
);
3690 /* copy the array data */
3691 memcpy(*ppMemory
+ pCVStructFormat
->memory_size
, pStubMsg
->Buffer
,
3693 pStubMsg
->Buffer
+= bufsize
;
3695 if (cvarray_type
== RPC_FC_C_CSTRING
)
3696 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory
+ pCVStructFormat
->memory_size
)));
3697 else if (cvarray_type
== RPC_FC_C_WSTRING
)
3698 TRACE("string=%s\n", debugstr_w((WCHAR
*)(*ppMemory
+ pCVStructFormat
->memory_size
)));
3700 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3705 /***********************************************************************
3706 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3708 void WINAPI
NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3709 unsigned char *pMemory
,
3710 PFORMAT_STRING pFormat
)
3712 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3713 PFORMAT_STRING pCVArrayFormat
;
3716 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3718 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3719 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3721 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3722 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3726 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3727 pCVStructFormat
->offset_to_array_description
;
3728 switch (*pCVArrayFormat
)
3730 case RPC_FC_CVARRAY
:
3731 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3733 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3734 pCVArrayFormat
+ 4, 0);
3735 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3738 case RPC_FC_C_CSTRING
:
3739 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
3740 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
3741 esize
= sizeof(char);
3742 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3743 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3744 pCVArrayFormat
+ 2, 0);
3746 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3748 case RPC_FC_C_WSTRING
:
3749 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
3750 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
3751 esize
= sizeof(WCHAR
);
3752 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3753 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3754 pCVArrayFormat
+ 2, 0);
3756 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3759 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3760 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3764 SizeConformance(pStubMsg
);
3766 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCVStructFormat
->alignment
+ 1);
3768 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3770 pStubMsg
->BufferLength
+= pCVStructFormat
->memory_size
;
3771 SizeVariance(pStubMsg
);
3772 pStubMsg
->BufferLength
+= safe_multiply(pStubMsg
->MaxCount
, esize
);
3774 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3777 /***********************************************************************
3778 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
3780 ULONG WINAPI
NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3781 PFORMAT_STRING pFormat
)
3783 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3784 PFORMAT_STRING pCVArrayFormat
;
3786 unsigned char cvarray_type
;
3788 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
3790 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3791 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3793 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3794 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3798 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3799 pCVStructFormat
->offset_to_array_description
;
3800 cvarray_type
= *pCVArrayFormat
;
3801 switch (cvarray_type
)
3803 case RPC_FC_CVARRAY
:
3804 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3805 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 4);
3807 case RPC_FC_C_CSTRING
:
3808 esize
= sizeof(char);
3809 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3810 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3812 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3814 case RPC_FC_C_WSTRING
:
3815 esize
= sizeof(WCHAR
);
3816 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3817 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3819 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3822 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3823 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3827 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
3829 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3831 pStubMsg
->Buffer
+= pCVStructFormat
->memory_size
;
3832 pCVArrayFormat
= ReadVariance(pStubMsg
, pCVArrayFormat
, pStubMsg
->MaxCount
);
3833 pStubMsg
->Buffer
+= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->ActualCount
);
3835 pStubMsg
->MemorySize
+= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->MaxCount
);
3837 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
3839 return pCVStructFormat
->memory_size
+ pStubMsg
->MaxCount
* esize
;
3842 /***********************************************************************
3843 * NdrConformantVaryingStructFree [RPCRT4.@]
3845 void WINAPI
NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3846 unsigned char *pMemory
,
3847 PFORMAT_STRING pFormat
)
3849 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3850 PFORMAT_STRING pCVArrayFormat
;
3853 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3855 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3856 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3858 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3859 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3863 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3864 pCVStructFormat
->offset_to_array_description
;
3865 switch (*pCVArrayFormat
)
3867 case RPC_FC_CVARRAY
:
3868 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3870 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3871 pCVArrayFormat
+ 4, 0);
3872 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3875 case RPC_FC_C_CSTRING
:
3876 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
3877 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
3878 esize
= sizeof(char);
3879 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3880 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3881 pCVArrayFormat
+ 2, 0);
3883 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3885 case RPC_FC_C_WSTRING
:
3886 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
3887 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
3888 esize
= sizeof(WCHAR
);
3889 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3890 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3891 pCVArrayFormat
+ 2, 0);
3893 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3896 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3897 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3901 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3903 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
3906 #include "pshpack1.h"
3910 unsigned char alignment
;
3911 unsigned short total_size
;
3912 } NDR_SMFARRAY_FORMAT
;
3917 unsigned char alignment
;
3918 unsigned long total_size
;
3919 } NDR_LGFARRAY_FORMAT
;
3920 #include "poppack.h"
3922 /***********************************************************************
3923 * NdrFixedArrayMarshall [RPCRT4.@]
3925 unsigned char * WINAPI
NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3926 unsigned char *pMemory
,
3927 PFORMAT_STRING pFormat
)
3929 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
3930 unsigned long total_size
;
3932 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3934 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
3935 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
3937 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
3938 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3942 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
3944 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
3946 total_size
= pSmFArrayFormat
->total_size
;
3947 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
3951 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
3952 total_size
= pLgFArrayFormat
->total_size
;
3953 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
3956 memcpy(pStubMsg
->Buffer
, pMemory
, total_size
);
3957 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3958 pStubMsg
->Buffer
+= total_size
;
3960 pFormat
= EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3965 /***********************************************************************
3966 * NdrFixedArrayUnmarshall [RPCRT4.@]
3968 unsigned char * WINAPI
NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3969 unsigned char **ppMemory
,
3970 PFORMAT_STRING pFormat
,
3971 unsigned char fMustAlloc
)
3973 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
3974 unsigned long total_size
;
3976 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3978 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
3979 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
3981 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
3982 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3986 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
3988 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
3990 total_size
= pSmFArrayFormat
->total_size
;
3991 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
3995 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
3996 total_size
= pLgFArrayFormat
->total_size
;
3997 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4000 if (fMustAlloc
|| !*ppMemory
)
4001 *ppMemory
= NdrAllocate(pStubMsg
, total_size
);
4002 memcpy(*ppMemory
, pStubMsg
->Buffer
, total_size
);
4003 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4004 pStubMsg
->Buffer
+= total_size
;
4006 pFormat
= EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4011 /***********************************************************************
4012 * NdrFixedArrayBufferSize [RPCRT4.@]
4014 void WINAPI
NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4015 unsigned char *pMemory
,
4016 PFORMAT_STRING pFormat
)
4018 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4019 unsigned long total_size
;
4021 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4023 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4024 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4026 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4027 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4031 ALIGN_LENGTH(pStubMsg
->BufferLength
, pSmFArrayFormat
->alignment
+ 1);
4033 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4035 total_size
= pSmFArrayFormat
->total_size
;
4036 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4040 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4041 total_size
= pLgFArrayFormat
->total_size
;
4042 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4044 pStubMsg
->BufferLength
+= total_size
;
4046 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4049 /***********************************************************************
4050 * NdrFixedArrayMemorySize [RPCRT4.@]
4052 ULONG WINAPI
NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4053 PFORMAT_STRING pFormat
)
4055 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4058 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4060 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4061 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4063 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4064 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4068 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
4070 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4072 total_size
= pSmFArrayFormat
->total_size
;
4073 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4077 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4078 total_size
= pLgFArrayFormat
->total_size
;
4079 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4081 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4082 pStubMsg
->Buffer
+= total_size
;
4083 pStubMsg
->MemorySize
+= total_size
;
4085 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4090 /***********************************************************************
4091 * NdrFixedArrayFree [RPCRT4.@]
4093 void WINAPI
NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4094 unsigned char *pMemory
,
4095 PFORMAT_STRING pFormat
)
4097 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
4099 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4101 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
4102 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
4104 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
4105 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4109 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
4110 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
4113 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
4114 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
4117 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4120 /***********************************************************************
4121 * NdrVaryingArrayMarshall [RPCRT4.@]
4123 unsigned char * WINAPI
NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4124 unsigned char *pMemory
,
4125 PFORMAT_STRING pFormat
)
4127 unsigned char alignment
;
4128 DWORD elements
, esize
;
4131 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4133 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4134 (pFormat
[0] != RPC_FC_LGVARRAY
))
4136 ERR("invalid format type %x\n", pFormat
[0]);
4137 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4141 alignment
= pFormat
[1] + 1;
4143 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4146 pFormat
+= sizeof(WORD
);
4147 elements
= *(const WORD
*)pFormat
;
4148 pFormat
+= sizeof(WORD
);
4153 pFormat
+= sizeof(DWORD
);
4154 elements
= *(const DWORD
*)pFormat
;
4155 pFormat
+= sizeof(DWORD
);
4158 esize
= *(const WORD
*)pFormat
;
4159 pFormat
+= sizeof(WORD
);
4161 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4162 if ((pStubMsg
->ActualCount
> elements
) ||
4163 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4165 RpcRaiseException(RPC_S_INVALID_BOUND
);
4169 WriteVariance(pStubMsg
);
4171 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4173 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4174 memcpy(pStubMsg
->Buffer
, pMemory
+ pStubMsg
->Offset
, bufsize
);
4175 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
4176 pStubMsg
->Buffer
+= bufsize
;
4178 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
4180 STD_OVERFLOW_CHECK(pStubMsg
);
4185 /***********************************************************************
4186 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4188 unsigned char * WINAPI
NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4189 unsigned char **ppMemory
,
4190 PFORMAT_STRING pFormat
,
4191 unsigned char fMustAlloc
)
4193 unsigned char alignment
;
4194 DWORD size
, elements
, esize
;
4197 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4199 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4200 (pFormat
[0] != RPC_FC_LGVARRAY
))
4202 ERR("invalid format type %x\n", pFormat
[0]);
4203 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4207 alignment
= pFormat
[1] + 1;
4209 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4212 size
= *(const WORD
*)pFormat
;
4213 pFormat
+= sizeof(WORD
);
4214 elements
= *(const WORD
*)pFormat
;
4215 pFormat
+= sizeof(WORD
);
4220 size
= *(const DWORD
*)pFormat
;
4221 pFormat
+= sizeof(DWORD
);
4222 elements
= *(const DWORD
*)pFormat
;
4223 pFormat
+= sizeof(DWORD
);
4226 esize
= *(const WORD
*)pFormat
;
4227 pFormat
+= sizeof(WORD
);
4229 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
4231 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4233 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
4235 if (!*ppMemory
|| fMustAlloc
)
4236 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4237 memcpy(*ppMemory
+ pStubMsg
->Offset
, pStubMsg
->Buffer
, bufsize
);
4238 pStubMsg
->Buffer
+= bufsize
;
4240 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4245 /***********************************************************************
4246 * NdrVaryingArrayBufferSize [RPCRT4.@]
4248 void WINAPI
NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4249 unsigned char *pMemory
,
4250 PFORMAT_STRING pFormat
)
4252 unsigned char alignment
;
4253 DWORD elements
, esize
;
4255 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4257 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4258 (pFormat
[0] != RPC_FC_LGVARRAY
))
4260 ERR("invalid format type %x\n", pFormat
[0]);
4261 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4265 alignment
= pFormat
[1] + 1;
4267 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4270 pFormat
+= sizeof(WORD
);
4271 elements
= *(const WORD
*)pFormat
;
4272 pFormat
+= sizeof(WORD
);
4277 pFormat
+= sizeof(DWORD
);
4278 elements
= *(const DWORD
*)pFormat
;
4279 pFormat
+= sizeof(DWORD
);
4282 esize
= *(const WORD
*)pFormat
;
4283 pFormat
+= sizeof(WORD
);
4285 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4286 if ((pStubMsg
->ActualCount
> elements
) ||
4287 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4289 RpcRaiseException(RPC_S_INVALID_BOUND
);
4293 SizeVariance(pStubMsg
);
4295 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
4297 pStubMsg
->BufferLength
+= safe_multiply(esize
, pStubMsg
->ActualCount
);
4299 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
4302 /***********************************************************************
4303 * NdrVaryingArrayMemorySize [RPCRT4.@]
4305 ULONG WINAPI
NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4306 PFORMAT_STRING pFormat
)
4308 unsigned char alignment
;
4309 DWORD size
, elements
, esize
;
4311 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
4313 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4314 (pFormat
[0] != RPC_FC_LGVARRAY
))
4316 ERR("invalid format type %x\n", pFormat
[0]);
4317 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4321 alignment
= pFormat
[1] + 1;
4323 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4326 size
= *(const WORD
*)pFormat
;
4327 pFormat
+= sizeof(WORD
);
4328 elements
= *(const WORD
*)pFormat
;
4329 pFormat
+= sizeof(WORD
);
4334 size
= *(const DWORD
*)pFormat
;
4335 pFormat
+= sizeof(DWORD
);
4336 elements
= *(const DWORD
*)pFormat
;
4337 pFormat
+= sizeof(DWORD
);
4340 esize
= *(const WORD
*)pFormat
;
4341 pFormat
+= sizeof(WORD
);
4343 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
4345 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
4347 pStubMsg
->Buffer
+= safe_multiply(esize
, pStubMsg
->ActualCount
);
4348 pStubMsg
->MemorySize
+= size
;
4350 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
4352 return pStubMsg
->MemorySize
;
4355 /***********************************************************************
4356 * NdrVaryingArrayFree [RPCRT4.@]
4358 void WINAPI
NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
4359 unsigned char *pMemory
,
4360 PFORMAT_STRING pFormat
)
4362 unsigned char alignment
;
4365 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4367 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
4368 (pFormat
[0] != RPC_FC_LGVARRAY
))
4370 ERR("invalid format type %x\n", pFormat
[0]);
4371 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
4375 alignment
= pFormat
[1] + 1;
4377 if (pFormat
[0] == RPC_FC_SMVARRAY
)
4380 pFormat
+= sizeof(WORD
);
4381 elements
= *(const WORD
*)pFormat
;
4382 pFormat
+= sizeof(WORD
);
4387 pFormat
+= sizeof(DWORD
);
4388 elements
= *(const DWORD
*)pFormat
;
4389 pFormat
+= sizeof(DWORD
);
4392 pFormat
+= sizeof(WORD
);
4394 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4395 if ((pStubMsg
->ActualCount
> elements
) ||
4396 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4398 RpcRaiseException(RPC_S_INVALID_BOUND
);
4402 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4405 static ULONG
get_discriminant(unsigned char fc
, unsigned char *pMemory
)
4413 return *(UCHAR
*)pMemory
;
4418 return *(USHORT
*)pMemory
;
4422 return *(ULONG
*)pMemory
;
4424 FIXME("Unhandled base type: 0x%02x\n", fc
);
4429 static PFORMAT_STRING
get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg
,
4430 unsigned long discriminant
,
4431 PFORMAT_STRING pFormat
)
4433 unsigned short num_arms
, arm
, type
;
4435 num_arms
= *(const SHORT
*)pFormat
& 0x0fff;
4437 for(arm
= 0; arm
< num_arms
; arm
++)
4439 if(discriminant
== *(const ULONG
*)pFormat
)
4447 type
= *(const unsigned short*)pFormat
;
4448 TRACE("type %04x\n", type
);
4449 if(arm
== num_arms
) /* default arm extras */
4453 ERR("no arm for 0x%lx and no default case\n", discriminant
);
4454 RpcRaiseException(RPC_S_INVALID_TAG
);
4459 TRACE("falling back to empty default case for 0x%lx\n", discriminant
);
4466 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
, ULONG discriminant
, PFORMAT_STRING pFormat
)
4468 unsigned short type
;
4472 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4476 type
= *(const unsigned short*)pFormat
;
4477 if((type
& 0xff00) == 0x8000)
4479 unsigned char basetype
= LOBYTE(type
);
4480 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &basetype
);
4484 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4485 NDR_MARSHALL m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
4488 unsigned char *saved_buffer
= NULL
;
4489 int pointer_buffer_mark_set
= 0;
4496 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4497 saved_buffer
= pStubMsg
->Buffer
;
4498 if (pStubMsg
->PointerBufferMark
)
4500 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4501 pStubMsg
->PointerBufferMark
= NULL
;
4502 pointer_buffer_mark_set
= 1;
4505 pStubMsg
->Buffer
+= 4; /* for pointer ID */
4507 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char **)pMemory
, desc
);
4508 if (pointer_buffer_mark_set
)
4510 STD_OVERFLOW_CHECK(pStubMsg
);
4511 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4512 pStubMsg
->Buffer
= saved_buffer
+ 4;
4516 m(pStubMsg
, pMemory
, desc
);
4519 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4524 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4525 unsigned char **ppMemory
,
4527 PFORMAT_STRING pFormat
,
4528 unsigned char fMustAlloc
)
4530 unsigned short type
;
4534 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4538 type
= *(const unsigned short*)pFormat
;
4539 if((type
& 0xff00) == 0x8000)
4541 unsigned char basetype
= LOBYTE(type
);
4542 return NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &basetype
, fMustAlloc
);
4546 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4547 NDR_UNMARSHALL m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
4550 unsigned char *saved_buffer
= NULL
;
4551 int pointer_buffer_mark_set
= 0;
4558 **(void***)ppMemory
= NULL
;
4559 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4560 saved_buffer
= pStubMsg
->Buffer
;
4561 if (pStubMsg
->PointerBufferMark
)
4563 pStubMsg
->Buffer
= pStubMsg
->PointerBufferMark
;
4564 pStubMsg
->PointerBufferMark
= NULL
;
4565 pointer_buffer_mark_set
= 1;
4568 pStubMsg
->Buffer
+= 4; /* for pointer ID */
4570 PointerUnmarshall(pStubMsg
, saved_buffer
, *(unsigned char ***)ppMemory
, desc
, fMustAlloc
);
4571 if (pointer_buffer_mark_set
)
4573 STD_OVERFLOW_CHECK(pStubMsg
);
4574 pStubMsg
->PointerBufferMark
= pStubMsg
->Buffer
;
4575 pStubMsg
->Buffer
= saved_buffer
+ 4;
4579 m(pStubMsg
, ppMemory
, desc
, fMustAlloc
);
4582 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4587 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg
,
4588 unsigned char *pMemory
,
4590 PFORMAT_STRING pFormat
)
4592 unsigned short type
;
4596 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4600 type
= *(const unsigned short*)pFormat
;
4601 if((type
& 0xff00) == 0x8000)
4603 unsigned char basetype
= LOBYTE(type
);
4604 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &basetype
);
4608 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4609 NDR_BUFFERSIZE m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
4618 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
4619 pStubMsg
->BufferLength
+= 4; /* for pointer ID */
4620 if (!pStubMsg
->IgnoreEmbeddedPointers
)
4622 int saved_buffer_length
= pStubMsg
->BufferLength
;
4623 pStubMsg
->BufferLength
= pStubMsg
->PointerLength
;
4624 pStubMsg
->PointerLength
= 0;
4625 if(!pStubMsg
->BufferLength
)
4626 ERR("BufferLength == 0??\n");
4627 PointerBufferSize(pStubMsg
, *(unsigned char **)pMemory
, desc
);
4628 pStubMsg
->PointerLength
= pStubMsg
->BufferLength
;
4629 pStubMsg
->BufferLength
= saved_buffer_length
;
4633 m(pStubMsg
, pMemory
, desc
);
4636 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
4640 static ULONG
union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg
,
4642 PFORMAT_STRING pFormat
)
4644 unsigned short type
, size
;
4646 size
= *(const unsigned short*)pFormat
;
4647 pStubMsg
->Memory
+= size
;
4650 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4654 type
= *(const unsigned short*)pFormat
;
4655 if((type
& 0xff00) == 0x8000)
4657 return NdrBaseTypeMemorySize(pStubMsg
, pFormat
);
4661 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4662 NDR_MEMORYSIZE m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
4663 unsigned char *saved_buffer
;
4672 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4673 saved_buffer
= pStubMsg
->Buffer
;
4674 pStubMsg
->Buffer
+= 4;
4675 ALIGN_LENGTH(pStubMsg
->MemorySize
, 4);
4676 pStubMsg
->MemorySize
+= 4;
4677 if (!pStubMsg
->IgnoreEmbeddedPointers
)
4678 PointerMemorySize(pStubMsg
, saved_buffer
, pFormat
);
4681 return m(pStubMsg
, desc
);
4684 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4687 TRACE("size %d\n", size
);
4691 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg
,
4692 unsigned char *pMemory
,
4694 PFORMAT_STRING pFormat
)
4696 unsigned short type
;
4700 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4704 type
= *(const unsigned short*)pFormat
;
4705 if((type
& 0xff00) != 0x8000)
4707 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4708 NDR_FREE m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
4717 PointerFree(pStubMsg
, *(unsigned char **)pMemory
, desc
);
4720 m(pStubMsg
, pMemory
, desc
);
4723 else FIXME("no freer for embedded type %02x\n", *desc
);
4727 /***********************************************************************
4728 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
4730 unsigned char * WINAPI
NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4731 unsigned char *pMemory
,
4732 PFORMAT_STRING pFormat
)
4734 unsigned char switch_type
;
4735 unsigned char increment
;
4738 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4741 switch_type
= *pFormat
& 0xf;
4742 increment
= (*pFormat
& 0xf0) >> 4;
4745 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
4747 switch_value
= get_discriminant(switch_type
, pMemory
);
4748 TRACE("got switch value 0x%x\n", switch_value
);
4750 NdrBaseTypeMarshall(pStubMsg
, pMemory
, &switch_type
);
4751 pMemory
+= increment
;
4753 return union_arm_marshall(pStubMsg
, pMemory
, switch_value
, pFormat
);
4756 /***********************************************************************
4757 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
4759 unsigned char * WINAPI
NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4760 unsigned char **ppMemory
,
4761 PFORMAT_STRING pFormat
,
4762 unsigned char fMustAlloc
)
4764 unsigned char switch_type
;
4765 unsigned char increment
;
4767 unsigned short size
;
4768 unsigned char *pMemoryArm
;
4770 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4773 switch_type
= *pFormat
& 0xf;
4774 increment
= (*pFormat
& 0xf0) >> 4;
4777 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
4778 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
4779 TRACE("got switch value 0x%x\n", switch_value
);
4781 size
= *(const unsigned short*)pFormat
+ increment
;
4782 if(!*ppMemory
|| fMustAlloc
)
4783 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4785 NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &switch_type
, FALSE
);
4786 pMemoryArm
= *ppMemory
+ increment
;
4788 return union_arm_unmarshall(pStubMsg
, &pMemoryArm
, switch_value
, pFormat
, fMustAlloc
);
4791 /***********************************************************************
4792 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
4794 void WINAPI
NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4795 unsigned char *pMemory
,
4796 PFORMAT_STRING pFormat
)
4798 unsigned char switch_type
;
4799 unsigned char increment
;
4802 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4805 switch_type
= *pFormat
& 0xf;
4806 increment
= (*pFormat
& 0xf0) >> 4;
4809 ALIGN_LENGTH(pStubMsg
->BufferLength
, increment
);
4810 switch_value
= get_discriminant(switch_type
, pMemory
);
4811 TRACE("got switch value 0x%x\n", switch_value
);
4813 /* Add discriminant size */
4814 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&switch_value
, &switch_type
);
4815 pMemory
+= increment
;
4817 union_arm_buffer_size(pStubMsg
, pMemory
, switch_value
, pFormat
);
4820 /***********************************************************************
4821 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
4823 ULONG WINAPI
NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4824 PFORMAT_STRING pFormat
)
4826 unsigned char switch_type
;
4827 unsigned char increment
;
4830 switch_type
= *pFormat
& 0xf;
4831 increment
= (*pFormat
& 0xf0) >> 4;
4834 ALIGN_POINTER(pStubMsg
->Buffer
, increment
);
4835 switch_value
= get_discriminant(switch_type
, pStubMsg
->Buffer
);
4836 TRACE("got switch value 0x%x\n", switch_value
);
4838 pStubMsg
->Memory
+= increment
;
4840 return increment
+ union_arm_memory_size(pStubMsg
, switch_value
, pFormat
+ *(const SHORT
*)pFormat
);
4843 /***********************************************************************
4844 * NdrEncapsulatedUnionFree [RPCRT4.@]
4846 void WINAPI
NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
4847 unsigned char *pMemory
,
4848 PFORMAT_STRING pFormat
)
4850 unsigned char switch_type
;
4851 unsigned char increment
;
4854 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4857 switch_type
= *pFormat
& 0xf;
4858 increment
= (*pFormat
& 0xf0) >> 4;
4861 switch_value
= get_discriminant(switch_type
, pMemory
);
4862 TRACE("got switch value 0x%x\n", switch_value
);
4864 pMemory
+= increment
;
4866 return union_arm_free(pStubMsg
, pMemory
, switch_value
, pFormat
);
4869 /***********************************************************************
4870 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
4872 unsigned char * WINAPI
NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4873 unsigned char *pMemory
,
4874 PFORMAT_STRING pFormat
)
4876 unsigned char switch_type
;
4878 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4881 switch_type
= *pFormat
;
4884 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
4885 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
4886 /* Marshall discriminant */
4887 NdrBaseTypeMarshall(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
4889 return union_arm_marshall(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
4892 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg
,
4893 PFORMAT_STRING
*ppFormat
)
4895 long discriminant
= 0;
4903 discriminant
= *(UCHAR
*)pStubMsg
->Buffer
;
4904 pStubMsg
->Buffer
+= sizeof(UCHAR
);
4909 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
4910 discriminant
= *(USHORT
*)pStubMsg
->Buffer
;
4911 pStubMsg
->Buffer
+= sizeof(USHORT
);
4915 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
4916 discriminant
= *(ULONG
*)pStubMsg
->Buffer
;
4917 pStubMsg
->Buffer
+= sizeof(ULONG
);
4920 FIXME("Unhandled base type: 0x%02x\n", **ppFormat
);
4924 if (pStubMsg
->fHasNewCorrDesc
)
4928 return discriminant
;
4931 /**********************************************************************
4932 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
4934 unsigned char * WINAPI
NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4935 unsigned char **ppMemory
,
4936 PFORMAT_STRING pFormat
,
4937 unsigned char fMustAlloc
)
4940 unsigned short size
;
4942 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4945 /* Unmarshall discriminant */
4946 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
4947 TRACE("unmarshalled discriminant %lx\n", discriminant
);
4949 pFormat
+= *(const SHORT
*)pFormat
;
4951 size
= *(const unsigned short*)pFormat
;
4953 if(!*ppMemory
|| fMustAlloc
)
4954 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4956 return union_arm_unmarshall(pStubMsg
, ppMemory
, discriminant
, pFormat
, fMustAlloc
);
4959 /***********************************************************************
4960 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
4962 void WINAPI
NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4963 unsigned char *pMemory
,
4964 PFORMAT_STRING pFormat
)
4966 unsigned char switch_type
;
4968 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4971 switch_type
= *pFormat
;
4974 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
4975 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
4976 /* Add discriminant size */
4977 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
4979 union_arm_buffer_size(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
4982 /***********************************************************************
4983 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
4985 ULONG WINAPI
NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4986 PFORMAT_STRING pFormat
)
4991 /* Unmarshall discriminant */
4992 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
4993 TRACE("unmarshalled discriminant 0x%x\n", discriminant
);
4995 return union_arm_memory_size(pStubMsg
, discriminant
, pFormat
+ *(const SHORT
*)pFormat
);
4998 /***********************************************************************
4999 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5001 void WINAPI
NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
5002 unsigned char *pMemory
,
5003 PFORMAT_STRING pFormat
)
5005 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
5009 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
5010 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
5012 return union_arm_free(pStubMsg
, pMemory
, pStubMsg
->MaxCount
, pFormat
+ *(const SHORT
*)pFormat
);
5015 /***********************************************************************
5016 * NdrByteCountPointerMarshall [RPCRT4.@]
5018 unsigned char * WINAPI
NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5019 unsigned char *pMemory
,
5020 PFORMAT_STRING pFormat
)
5026 /***********************************************************************
5027 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5029 unsigned char * WINAPI
NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5030 unsigned char **ppMemory
,
5031 PFORMAT_STRING pFormat
,
5032 unsigned char fMustAlloc
)
5038 /***********************************************************************
5039 * NdrByteCountPointerBufferSize [RPCRT4.@]
5041 void WINAPI
NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5042 unsigned char *pMemory
,
5043 PFORMAT_STRING pFormat
)
5048 /***********************************************************************
5049 * NdrByteCountPointerMemorySize [RPCRT4.@]
5051 ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5052 PFORMAT_STRING pFormat
)
5058 /***********************************************************************
5059 * NdrByteCountPointerFree [RPCRT4.@]
5061 void WINAPI
NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
5062 unsigned char *pMemory
,
5063 PFORMAT_STRING pFormat
)
5068 /***********************************************************************
5069 * NdrXmitOrRepAsMarshall [RPCRT4.@]
5071 unsigned char * WINAPI
NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5072 unsigned char *pMemory
,
5073 PFORMAT_STRING pFormat
)
5079 /***********************************************************************
5080 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
5082 unsigned char * WINAPI
NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5083 unsigned char **ppMemory
,
5084 PFORMAT_STRING pFormat
,
5085 unsigned char fMustAlloc
)
5091 /***********************************************************************
5092 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
5094 void WINAPI
NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
5095 unsigned char *pMemory
,
5096 PFORMAT_STRING pFormat
)
5101 /***********************************************************************
5102 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
5104 ULONG WINAPI
NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
5105 PFORMAT_STRING pFormat
)
5111 /***********************************************************************
5112 * NdrXmitOrRepAsFree [RPCRT4.@]
5114 void WINAPI
NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg
,
5115 unsigned char *pMemory
,
5116 PFORMAT_STRING pFormat
)
5121 #include "pshpack1.h"
5125 unsigned char flags_type
; /* flags in upper nibble, type in lower nibble */
5129 #include "poppack.h"
5131 /***********************************************************************
5132 * NdrRangeMarshall [internal]
5134 unsigned char *WINAPI
NdrRangeMarshall(
5135 PMIDL_STUB_MESSAGE pStubMsg
,
5136 unsigned char *pMemory
,
5137 PFORMAT_STRING pFormat
)
5139 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5140 unsigned char base_type
;
5142 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5144 if (pRange
->type
!= RPC_FC_RANGE
)
5146 ERR("invalid format type %x\n", pRange
->type
);
5147 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5151 base_type
= pRange
->flags_type
& 0xf;
5153 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &base_type
);
5156 /***********************************************************************
5157 * NdrRangeUnmarshall
5159 unsigned char *WINAPI
NdrRangeUnmarshall(
5160 PMIDL_STUB_MESSAGE pStubMsg
,
5161 unsigned char **ppMemory
,
5162 PFORMAT_STRING pFormat
,
5163 unsigned char fMustAlloc
)
5165 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5166 unsigned char base_type
;
5168 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
5170 if (pRange
->type
!= RPC_FC_RANGE
)
5172 ERR("invalid format type %x\n", pRange
->type
);
5173 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5176 base_type
= pRange
->flags_type
& 0xf;
5178 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5179 base_type
, pRange
->low_value
, pRange
->high_value
);
5181 #define RANGE_UNMARSHALL(type, format_spec) \
5184 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5185 if (fMustAlloc || !*ppMemory) \
5186 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5187 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5188 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5190 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5191 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5192 (type)pRange->high_value); \
5193 RpcRaiseException(RPC_S_INVALID_BOUND); \
5196 TRACE("*ppMemory: %p\n", *ppMemory); \
5197 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5198 pStubMsg->Buffer += sizeof(type); \
5205 RANGE_UNMARSHALL(UCHAR
, "%d");
5206 TRACE("value: 0x%02x\n", **(UCHAR
**)ppMemory
);
5210 RANGE_UNMARSHALL(CHAR
, "%u");
5211 TRACE("value: 0x%02x\n", **(UCHAR
**)ppMemory
);
5213 case RPC_FC_WCHAR
: /* FIXME: valid? */
5215 RANGE_UNMARSHALL(USHORT
, "%u");
5216 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5219 RANGE_UNMARSHALL(SHORT
, "%d");
5220 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5223 RANGE_UNMARSHALL(LONG
, "%d");
5224 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5227 RANGE_UNMARSHALL(ULONG
, "%u");
5228 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5232 FIXME("Unhandled enum type\n");
5234 case RPC_FC_ERROR_STATUS_T
: /* FIXME: valid? */
5239 ERR("invalid range base type: 0x%02x\n", base_type
);
5240 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5246 /***********************************************************************
5247 * NdrRangeBufferSize [internal]
5249 void WINAPI
NdrRangeBufferSize(
5250 PMIDL_STUB_MESSAGE pStubMsg
,
5251 unsigned char *pMemory
,
5252 PFORMAT_STRING pFormat
)
5254 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5255 unsigned char base_type
;
5257 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5259 if (pRange
->type
!= RPC_FC_RANGE
)
5261 ERR("invalid format type %x\n", pRange
->type
);
5262 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5264 base_type
= pRange
->flags_type
& 0xf;
5266 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &base_type
);
5269 /***********************************************************************
5270 * NdrRangeMemorySize [internal]
5272 ULONG WINAPI
NdrRangeMemorySize(
5273 PMIDL_STUB_MESSAGE pStubMsg
,
5274 PFORMAT_STRING pFormat
)
5276 NDR_RANGE
*pRange
= (NDR_RANGE
*)pFormat
;
5277 unsigned char base_type
;
5279 if (pRange
->type
!= RPC_FC_RANGE
)
5281 ERR("invalid format type %x\n", pRange
->type
);
5282 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5285 base_type
= pRange
->flags_type
& 0xf;
5287 return NdrBaseTypeMemorySize(pStubMsg
, &base_type
);
5290 /***********************************************************************
5291 * NdrRangeFree [internal]
5293 void WINAPI
NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg
,
5294 unsigned char *pMemory
,
5295 PFORMAT_STRING pFormat
)
5297 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5302 /***********************************************************************
5303 * NdrBaseTypeMarshall [internal]
5305 static unsigned char *WINAPI
NdrBaseTypeMarshall(
5306 PMIDL_STUB_MESSAGE pStubMsg
,
5307 unsigned char *pMemory
,
5308 PFORMAT_STRING pFormat
)
5310 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5318 *(UCHAR
*)pStubMsg
->Buffer
= *(UCHAR
*)pMemory
;
5319 pStubMsg
->Buffer
+= sizeof(UCHAR
);
5320 TRACE("value: 0x%02x\n", *(UCHAR
*)pMemory
);
5325 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5326 *(USHORT
*)pStubMsg
->Buffer
= *(USHORT
*)pMemory
;
5327 pStubMsg
->Buffer
+= sizeof(USHORT
);
5328 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
5332 case RPC_FC_ERROR_STATUS_T
:
5334 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
5335 *(ULONG
*)pStubMsg
->Buffer
= *(ULONG
*)pMemory
;
5336 pStubMsg
->Buffer
+= sizeof(ULONG
);
5337 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
5340 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(float));
5341 *(float *)pStubMsg
->Buffer
= *(float *)pMemory
;
5342 pStubMsg
->Buffer
+= sizeof(float);
5345 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(double));
5346 *(double *)pStubMsg
->Buffer
= *(double *)pMemory
;
5347 pStubMsg
->Buffer
+= sizeof(double);
5350 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONGLONG
));
5351 *(ULONGLONG
*)pStubMsg
->Buffer
= *(ULONGLONG
*)pMemory
;
5352 pStubMsg
->Buffer
+= sizeof(ULONGLONG
);
5353 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
5356 /* only 16-bits on the wire, so do a sanity check */
5357 if (*(UINT
*)pMemory
> USHRT_MAX
)
5358 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
5359 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5360 *(USHORT
*)pStubMsg
->Buffer
= *(UINT
*)pMemory
;
5361 pStubMsg
->Buffer
+= sizeof(USHORT
);
5362 TRACE("value: 0x%04x\n", *(UINT
*)pMemory
);
5365 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5368 STD_OVERFLOW_CHECK(pStubMsg
);
5370 /* FIXME: what is the correct return value? */
5374 /***********************************************************************
5375 * NdrBaseTypeUnmarshall [internal]
5377 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(
5378 PMIDL_STUB_MESSAGE pStubMsg
,
5379 unsigned char **ppMemory
,
5380 PFORMAT_STRING pFormat
,
5381 unsigned char fMustAlloc
)
5383 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
5385 #define BASE_TYPE_UNMARSHALL(type) \
5386 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5387 if (fMustAlloc || !*ppMemory) \
5388 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5389 TRACE("*ppMemory: %p\n", *ppMemory); \
5390 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5391 pStubMsg->Buffer += sizeof(type);
5399 BASE_TYPE_UNMARSHALL(UCHAR
);
5400 TRACE("value: 0x%02x\n", **(UCHAR
**)ppMemory
);
5405 BASE_TYPE_UNMARSHALL(USHORT
);
5406 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
5410 case RPC_FC_ERROR_STATUS_T
:
5412 BASE_TYPE_UNMARSHALL(ULONG
);
5413 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
5416 BASE_TYPE_UNMARSHALL(float);
5417 TRACE("value: %f\n", **(float **)ppMemory
);
5420 BASE_TYPE_UNMARSHALL(double);
5421 TRACE("value: %f\n", **(double **)ppMemory
);
5424 BASE_TYPE_UNMARSHALL(ULONGLONG
);
5425 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG
**)ppMemory
));
5428 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
5429 if (fMustAlloc
|| !*ppMemory
)
5430 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT
));
5431 TRACE("*ppMemory: %p\n", *ppMemory
);
5432 /* 16-bits on the wire, but int in memory */
5433 **(UINT
**)ppMemory
= *(USHORT
*)pStubMsg
->Buffer
;
5434 pStubMsg
->Buffer
+= sizeof(USHORT
);
5435 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
5438 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5440 #undef BASE_TYPE_UNMARSHALL
5442 /* FIXME: what is the correct return value? */
5447 /***********************************************************************
5448 * NdrBaseTypeBufferSize [internal]
5450 static void WINAPI
NdrBaseTypeBufferSize(
5451 PMIDL_STUB_MESSAGE pStubMsg
,
5452 unsigned char *pMemory
,
5453 PFORMAT_STRING pFormat
)
5455 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5463 pStubMsg
->BufferLength
+= sizeof(UCHAR
);
5469 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(USHORT
));
5470 pStubMsg
->BufferLength
+= sizeof(USHORT
);
5475 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONG
));
5476 pStubMsg
->BufferLength
+= sizeof(ULONG
);
5479 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(float));
5480 pStubMsg
->BufferLength
+= sizeof(float);
5483 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(double));
5484 pStubMsg
->BufferLength
+= sizeof(double);
5487 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONGLONG
));
5488 pStubMsg
->BufferLength
+= sizeof(ULONGLONG
);
5490 case RPC_FC_ERROR_STATUS_T
:
5491 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(error_status_t
));
5492 pStubMsg
->BufferLength
+= sizeof(error_status_t
);
5495 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5499 /***********************************************************************
5500 * NdrBaseTypeMemorySize [internal]
5502 static ULONG WINAPI
NdrBaseTypeMemorySize(
5503 PMIDL_STUB_MESSAGE pStubMsg
,
5504 PFORMAT_STRING pFormat
)
5512 pStubMsg
->Buffer
+= sizeof(UCHAR
);
5513 pStubMsg
->MemorySize
+= sizeof(UCHAR
);
5514 return sizeof(UCHAR
);
5518 pStubMsg
->Buffer
+= sizeof(USHORT
);
5519 pStubMsg
->MemorySize
+= sizeof(USHORT
);
5520 return sizeof(USHORT
);
5523 pStubMsg
->Buffer
+= sizeof(ULONG
);
5524 pStubMsg
->MemorySize
+= sizeof(ULONG
);
5525 return sizeof(ULONG
);
5527 pStubMsg
->Buffer
+= sizeof(float);
5528 pStubMsg
->MemorySize
+= sizeof(float);
5529 return sizeof(float);
5531 pStubMsg
->Buffer
+= sizeof(double);
5532 pStubMsg
->MemorySize
+= sizeof(double);
5533 return sizeof(double);
5535 pStubMsg
->Buffer
+= sizeof(ULONGLONG
);
5536 pStubMsg
->MemorySize
+= sizeof(ULONGLONG
);
5537 return sizeof(ULONGLONG
);
5538 case RPC_FC_ERROR_STATUS_T
:
5539 pStubMsg
->Buffer
+= sizeof(error_status_t
);
5540 pStubMsg
->MemorySize
+= sizeof(error_status_t
);
5541 return sizeof(error_status_t
);
5544 pStubMsg
->Buffer
+= sizeof(INT
);
5545 pStubMsg
->MemorySize
+= sizeof(INT
);
5548 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
5553 /***********************************************************************
5554 * NdrBaseTypeFree [internal]
5556 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg
,
5557 unsigned char *pMemory
,
5558 PFORMAT_STRING pFormat
)
5560 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5565 /***********************************************************************
5566 * NdrContextHandleBufferSize [internal]
5568 static void WINAPI
NdrContextHandleBufferSize(
5569 PMIDL_STUB_MESSAGE pStubMsg
,
5570 unsigned char *pMemory
,
5571 PFORMAT_STRING pFormat
)
5573 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5575 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
5577 ERR("invalid format type %x\n", *pFormat
);
5578 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5580 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
5581 pStubMsg
->BufferLength
+= cbNDRContext
;
5584 /***********************************************************************
5585 * NdrContextHandleMarshall [internal]
5587 static unsigned char *WINAPI
NdrContextHandleMarshall(
5588 PMIDL_STUB_MESSAGE pStubMsg
,
5589 unsigned char *pMemory
,
5590 PFORMAT_STRING pFormat
)
5592 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
5594 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
5596 ERR("invalid format type %x\n", *pFormat
);
5597 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5600 if (pFormat
[1] & 0x80)
5601 NdrClientContextMarshall(pStubMsg
, *(NDR_CCONTEXT
**)pMemory
, FALSE
);
5603 NdrClientContextMarshall(pStubMsg
, (NDR_CCONTEXT
*)pMemory
, FALSE
);
5608 /***********************************************************************
5609 * NdrContextHandleUnmarshall [internal]
5611 static unsigned char *WINAPI
NdrContextHandleUnmarshall(
5612 PMIDL_STUB_MESSAGE pStubMsg
,
5613 unsigned char **ppMemory
,
5614 PFORMAT_STRING pFormat
,
5615 unsigned char fMustAlloc
)
5617 if (*pFormat
!= RPC_FC_BIND_CONTEXT
)
5619 ERR("invalid format type %x\n", *pFormat
);
5620 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
5623 **(NDR_CCONTEXT
**)ppMemory
= NULL
;
5624 NdrClientContextUnmarshall(pStubMsg
, *(NDR_CCONTEXT
**)ppMemory
, pStubMsg
->RpcMsg
->Handle
);
5629 /***********************************************************************
5630 * NdrClientContextMarshall [RPCRT4.@]
5632 void WINAPI
NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5633 NDR_CCONTEXT ContextHandle
,
5636 TRACE("(%p, %p, %d)\n", pStubMsg
, ContextHandle
, fCheck
);
5638 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5640 /* FIXME: what does fCheck do? */
5641 NDRCContextMarshall(ContextHandle
,
5644 pStubMsg
->Buffer
+= cbNDRContext
;
5647 /***********************************************************************
5648 * NdrClientContextUnmarshall [RPCRT4.@]
5650 void WINAPI
NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5651 NDR_CCONTEXT
* pContextHandle
,
5652 RPC_BINDING_HANDLE BindHandle
)
5654 TRACE("(%p, %p, %p)\n", pStubMsg
, pContextHandle
, BindHandle
);
5656 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
5658 NDRCContextUnmarshall(pContextHandle
,
5661 pStubMsg
->RpcMsg
->DataRepresentation
);
5663 pStubMsg
->Buffer
+= cbNDRContext
;
5666 void WINAPI
NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5667 NDR_SCONTEXT ContextHandle
,
5668 NDR_RUNDOWN RundownRoutine
)
5670 FIXME("(%p, %p, %p): stub\n", pStubMsg
, ContextHandle
, RundownRoutine
);
5673 NDR_SCONTEXT WINAPI
NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
)
5675 FIXME("(%p): stub\n", pStubMsg
);
5679 void WINAPI
NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg
,
5680 unsigned char* pMemory
,
5681 PFORMAT_STRING pFormat
)
5683 FIXME("(%p, %p, %p): stub\n", pStubMsg
, pMemory
, pFormat
);
5686 NDR_SCONTEXT WINAPI
NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg
,
5687 PFORMAT_STRING pFormat
)
5689 FIXME("(%p, %p): stub\n", pStubMsg
, pFormat
);
5693 void WINAPI
NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5694 NDR_SCONTEXT ContextHandle
,
5695 NDR_RUNDOWN RundownRoutine
,
5696 PFORMAT_STRING pFormat
)
5698 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg
, ContextHandle
, RundownRoutine
, pFormat
);
5701 NDR_SCONTEXT WINAPI
NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
5702 PFORMAT_STRING pFormat
)
5704 FIXME("(%p, %p): stub\n", pStubMsg
, pFormat
);
5708 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
5710 typedef struct ndr_context_handle
5714 } ndr_context_handle
;
5716 struct context_handle_entry
5720 RPC_BINDING_HANDLE handle
;
5721 ndr_context_handle wire_data
;
5724 static struct list context_handle_list
= LIST_INIT(context_handle_list
);
5726 static CRITICAL_SECTION ndr_context_cs
;
5727 static CRITICAL_SECTION_DEBUG ndr_context_debug
=
5729 0, 0, &ndr_context_cs
,
5730 { &ndr_context_debug
.ProcessLocksList
, &ndr_context_debug
.ProcessLocksList
},
5731 0, 0, { (DWORD_PTR
)(__FILE__
": ndr_context") }
5733 static CRITICAL_SECTION ndr_context_cs
= { &ndr_context_debug
, -1, 0, 0, 0, 0 };
5735 static struct context_handle_entry
*get_context_entry(NDR_CCONTEXT CContext
)
5737 struct context_handle_entry
*che
= (struct context_handle_entry
*) CContext
;
5739 if (che
->magic
!= NDR_CONTEXT_HANDLE_MAGIC
)
5744 static struct context_handle_entry
*context_entry_from_guid(LPGUID uuid
)
5746 struct context_handle_entry
*che
;
5747 LIST_FOR_EACH_ENTRY(che
, &context_handle_list
, struct context_handle_entry
, entry
)
5748 if (IsEqualGUID(&che
->wire_data
.uuid
, uuid
))
5753 RPC_BINDING_HANDLE WINAPI
NDRCContextBinding(NDR_CCONTEXT CContext
)
5755 struct context_handle_entry
*che
;
5756 RPC_BINDING_HANDLE handle
= NULL
;
5758 TRACE("%p\n", CContext
);
5760 EnterCriticalSection(&ndr_context_cs
);
5761 che
= get_context_entry(CContext
);
5763 handle
= che
->handle
;
5764 LeaveCriticalSection(&ndr_context_cs
);
5767 RpcRaiseException(ERROR_INVALID_HANDLE
);
5771 void WINAPI
NDRCContextMarshall(NDR_CCONTEXT CContext
, void *pBuff
)
5773 struct context_handle_entry
*che
;
5775 TRACE("%p %p\n", CContext
, pBuff
);
5779 EnterCriticalSection(&ndr_context_cs
);
5780 che
= get_context_entry(CContext
);
5781 memcpy(pBuff
, &che
->wire_data
, sizeof (ndr_context_handle
));
5782 LeaveCriticalSection(&ndr_context_cs
);
5786 ndr_context_handle
*wire_data
= (ndr_context_handle
*)pBuff
;
5787 wire_data
->attributes
= 0;
5788 wire_data
->uuid
= GUID_NULL
;
5792 static UINT
ndr_update_context_handle(NDR_CCONTEXT
*CContext
,
5793 RPC_BINDING_HANDLE hBinding
,
5794 ndr_context_handle
*chi
)
5796 struct context_handle_entry
*che
= NULL
;
5798 /* a null UUID means we should free the context handle */
5799 if (IsEqualGUID(&chi
->uuid
, &GUID_NULL
))
5803 che
= get_context_entry(*CContext
);
5805 return ERROR_INVALID_HANDLE
;
5806 list_remove(&che
->entry
);
5807 RpcBindingFree(&che
->handle
);
5808 HeapFree(GetProcessHeap(), 0, che
);
5812 /* if there's no existing entry matching the GUID, allocate one */
5813 else if (!(che
= context_entry_from_guid(&chi
->uuid
)))
5815 che
= HeapAlloc(GetProcessHeap(), 0, sizeof *che
);
5817 return ERROR_NOT_ENOUGH_MEMORY
;
5818 che
->magic
= NDR_CONTEXT_HANDLE_MAGIC
;
5819 RpcBindingCopy(hBinding
, &che
->handle
);
5820 list_add_tail(&context_handle_list
, &che
->entry
);
5821 memcpy(&che
->wire_data
, chi
, sizeof *chi
);
5826 return ERROR_SUCCESS
;
5829 /***********************************************************************
5830 * NDRCContextUnmarshall [RPCRT4.@]
5832 void WINAPI
NDRCContextUnmarshall(NDR_CCONTEXT
*CContext
,
5833 RPC_BINDING_HANDLE hBinding
,
5834 void *pBuff
, ULONG DataRepresentation
)
5838 TRACE("*%p=(%p) %p %p %08x\n",
5839 CContext
, *CContext
, hBinding
, pBuff
, DataRepresentation
);
5841 EnterCriticalSection(&ndr_context_cs
);
5842 r
= ndr_update_context_handle(CContext
, hBinding
, pBuff
);
5843 LeaveCriticalSection(&ndr_context_cs
);
5845 RpcRaiseException(r
);
5848 /***********************************************************************
5849 * NDRSContextMarshall [RPCRT4.@]
5851 void WINAPI
NDRSContextMarshall(NDR_SCONTEXT CContext
,
5853 NDR_RUNDOWN userRunDownIn
)
5855 FIXME("(%p %p %p): stub\n", CContext
, pBuff
, userRunDownIn
);
5858 /***********************************************************************
5859 * NDRSContextMarshallEx [RPCRT4.@]
5861 void WINAPI
NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding
,
5862 NDR_SCONTEXT CContext
,
5864 NDR_RUNDOWN userRunDownIn
)
5866 FIXME("(%p %p %p %p): stub\n", hBinding
, CContext
, pBuff
, userRunDownIn
);
5869 /***********************************************************************
5870 * NDRSContextMarshall2 [RPCRT4.@]
5872 void WINAPI
NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding
,
5873 NDR_SCONTEXT CContext
,
5875 NDR_RUNDOWN userRunDownIn
,
5876 void *CtxGuard
, ULONG Flags
)
5878 FIXME("(%p %p %p %p %p %u): stub\n",
5879 hBinding
, CContext
, pBuff
, userRunDownIn
, CtxGuard
, Flags
);
5882 /***********************************************************************
5883 * NDRSContextUnmarshall [RPCRT4.@]
5885 NDR_SCONTEXT WINAPI
NDRSContextUnmarshall(void *pBuff
,
5886 ULONG DataRepresentation
)
5888 FIXME("(%p %08x): stub\n", pBuff
, DataRepresentation
);
5892 /***********************************************************************
5893 * NDRSContextUnmarshallEx [RPCRT4.@]
5895 NDR_SCONTEXT WINAPI
NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding
,
5897 ULONG DataRepresentation
)
5899 FIXME("(%p %p %08x): stub\n", hBinding
, pBuff
, DataRepresentation
);
5903 /***********************************************************************
5904 * NDRSContextUnmarshall2 [RPCRT4.@]
5906 NDR_SCONTEXT WINAPI
NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding
,
5908 ULONG DataRepresentation
,
5909 void *CtxGuard
, ULONG Flags
)
5911 FIXME("(%p %p %08x %p %u): stub\n",
5912 hBinding
, pBuff
, DataRepresentation
, CtxGuard
, Flags
);