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
47 #include "wine/unicode.h"
48 #include "wine/rpcfc.h"
50 #include "wine/debug.h"
51 #include "wine/list.h"
53 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
56 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
57 (*((UINT32 *)(pchar)) = (uint32))
59 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
60 (*((UINT32 *)(pchar)))
62 /* these would work for i386 too, but less efficient */
63 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
64 (*(pchar) = LOBYTE(LOWORD(uint32)), \
65 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
66 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
67 *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
68 (uint32)) /* allow as r-value */
70 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
72 MAKEWORD(*(pchar), *((pchar)+1)), \
73 MAKEWORD(*((pchar)+2), *((pchar)+3))))
76 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
77 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
78 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
79 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
80 *(pchar) = HIBYTE(HIWORD(uint32)), \
81 (uint32)) /* allow as r-value */
83 #define BIG_ENDIAN_UINT32_READ(pchar) \
85 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
86 MAKEWORD(*((pchar)+1), *(pchar))))
88 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
89 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
90 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
91 # define NDR_LOCAL_UINT32_READ(pchar) \
92 BIG_ENDIAN_UINT32_READ(pchar)
94 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
95 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
96 # define NDR_LOCAL_UINT32_READ(pchar) \
97 LITTLE_ENDIAN_UINT32_READ(pchar)
100 /* _Align must be the desired alignment,
101 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
102 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
103 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
104 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
105 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
107 #define STD_OVERFLOW_CHECK(_Msg) do { \
108 TRACE("buffer=%d/%d\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
109 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
110 ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
113 #define NDR_TABLE_SIZE 128
114 #define NDR_TABLE_MASK 127
116 static unsigned char *WINAPI
NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
117 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE
, unsigned char **, PFORMAT_STRING
, unsigned char);
118 static void WINAPI
NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
119 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE
, unsigned char *, PFORMAT_STRING
);
120 static ULONG WINAPI
NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE
, PFORMAT_STRING
);
122 const NDR_MARSHALL NdrMarshaller
[NDR_TABLE_SIZE
] = {
124 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
125 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
126 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
127 NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
, NdrBaseTypeMarshall
,
131 NdrPointerMarshall
, NdrPointerMarshall
,
132 NdrPointerMarshall
, NdrPointerMarshall
,
134 NdrSimpleStructMarshall
, NdrSimpleStructMarshall
,
135 NdrConformantStructMarshall
, NdrConformantStructMarshall
,
136 NdrConformantVaryingStructMarshall
,
137 NdrComplexStructMarshall
,
139 NdrConformantArrayMarshall
,
140 NdrConformantVaryingArrayMarshall
,
141 NdrFixedArrayMarshall
, NdrFixedArrayMarshall
,
142 NdrVaryingArrayMarshall
, NdrVaryingArrayMarshall
,
143 NdrComplexArrayMarshall
,
145 NdrConformantStringMarshall
, 0, 0,
146 NdrConformantStringMarshall
,
147 NdrNonConformantStringMarshall
, 0, 0, 0,
149 NdrEncapsulatedUnionMarshall
,
150 NdrNonEncapsulatedUnionMarshall
,
151 NdrByteCountPointerMarshall
,
152 NdrXmitOrRepAsMarshall
, NdrXmitOrRepAsMarshall
,
154 NdrInterfacePointerMarshall
,
157 NdrUserMarshalMarshall
159 const NDR_UNMARSHALL NdrUnmarshaller
[NDR_TABLE_SIZE
] = {
161 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
162 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
163 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
164 NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
, NdrBaseTypeUnmarshall
,
166 NdrBaseTypeUnmarshall
,
168 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
169 NdrPointerUnmarshall
, NdrPointerUnmarshall
,
171 NdrSimpleStructUnmarshall
, NdrSimpleStructUnmarshall
,
172 NdrConformantStructUnmarshall
, NdrConformantStructUnmarshall
,
173 NdrConformantVaryingStructUnmarshall
,
174 NdrComplexStructUnmarshall
,
176 NdrConformantArrayUnmarshall
,
177 NdrConformantVaryingArrayUnmarshall
,
178 NdrFixedArrayUnmarshall
, NdrFixedArrayUnmarshall
,
179 NdrVaryingArrayUnmarshall
, NdrVaryingArrayUnmarshall
,
180 NdrComplexArrayUnmarshall
,
182 NdrConformantStringUnmarshall
, 0, 0,
183 NdrConformantStringUnmarshall
,
184 NdrNonConformantStringUnmarshall
, 0, 0, 0,
186 NdrEncapsulatedUnionUnmarshall
,
187 NdrNonEncapsulatedUnionUnmarshall
,
188 NdrByteCountPointerUnmarshall
,
189 NdrXmitOrRepAsUnmarshall
, NdrXmitOrRepAsUnmarshall
,
191 NdrInterfacePointerUnmarshall
,
194 NdrUserMarshalUnmarshall
196 const NDR_BUFFERSIZE NdrBufferSizer
[NDR_TABLE_SIZE
] = {
198 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
199 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
200 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
201 NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
, NdrBaseTypeBufferSize
,
203 NdrBaseTypeBufferSize
,
205 NdrPointerBufferSize
, NdrPointerBufferSize
,
206 NdrPointerBufferSize
, NdrPointerBufferSize
,
208 NdrSimpleStructBufferSize
, NdrSimpleStructBufferSize
,
209 NdrConformantStructBufferSize
, NdrConformantStructBufferSize
,
210 NdrConformantVaryingStructBufferSize
,
211 NdrComplexStructBufferSize
,
213 NdrConformantArrayBufferSize
,
214 NdrConformantVaryingArrayBufferSize
,
215 NdrFixedArrayBufferSize
, NdrFixedArrayBufferSize
,
216 NdrVaryingArrayBufferSize
, NdrVaryingArrayBufferSize
,
217 NdrComplexArrayBufferSize
,
219 NdrConformantStringBufferSize
, 0, 0,
220 NdrConformantStringBufferSize
,
221 NdrNonConformantStringBufferSize
, 0, 0, 0,
223 NdrEncapsulatedUnionBufferSize
,
224 NdrNonEncapsulatedUnionBufferSize
,
225 NdrByteCountPointerBufferSize
,
226 NdrXmitOrRepAsBufferSize
, NdrXmitOrRepAsBufferSize
,
228 NdrInterfacePointerBufferSize
,
231 NdrUserMarshalBufferSize
233 const NDR_MEMORYSIZE NdrMemorySizer
[NDR_TABLE_SIZE
] = {
235 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
236 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
237 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
238 NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
, NdrBaseTypeMemorySize
,
240 NdrBaseTypeMemorySize
,
242 NdrPointerMemorySize
, NdrPointerMemorySize
,
243 NdrPointerMemorySize
, NdrPointerMemorySize
,
245 NdrSimpleStructMemorySize
, NdrSimpleStructMemorySize
,
246 NdrConformantStructMemorySize
, NdrConformantStructMemorySize
,
247 NdrConformantVaryingStructMemorySize
,
248 NdrComplexStructMemorySize
,
250 NdrConformantArrayMemorySize
,
251 NdrConformantVaryingArrayMemorySize
,
252 NdrFixedArrayMemorySize
, NdrFixedArrayMemorySize
,
253 NdrVaryingArrayMemorySize
, NdrVaryingArrayMemorySize
,
254 NdrComplexArrayMemorySize
,
256 NdrConformantStringMemorySize
, 0, 0,
257 NdrConformantStringMemorySize
,
258 NdrNonConformantStringMemorySize
, 0, 0, 0,
260 NdrEncapsulatedUnionMemorySize
,
261 NdrNonEncapsulatedUnionMemorySize
,
262 NdrByteCountPointerMemorySize
,
263 NdrXmitOrRepAsMemorySize
, NdrXmitOrRepAsMemorySize
,
265 NdrInterfacePointerMemorySize
,
268 NdrUserMarshalMemorySize
270 const NDR_FREE NdrFreer
[NDR_TABLE_SIZE
] = {
272 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
273 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
274 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
275 NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
, NdrBaseTypeFree
,
279 NdrPointerFree
, NdrPointerFree
,
280 NdrPointerFree
, NdrPointerFree
,
282 NdrSimpleStructFree
, NdrSimpleStructFree
,
283 NdrConformantStructFree
, NdrConformantStructFree
,
284 NdrConformantVaryingStructFree
,
285 NdrComplexStructFree
,
287 NdrConformantArrayFree
,
288 NdrConformantVaryingArrayFree
,
289 NdrFixedArrayFree
, NdrFixedArrayFree
,
290 NdrVaryingArrayFree
, NdrVaryingArrayFree
,
296 NdrEncapsulatedUnionFree
,
297 NdrNonEncapsulatedUnionFree
,
299 NdrXmitOrRepAsFree
, NdrXmitOrRepAsFree
,
301 NdrInterfacePointerFree
,
307 void * WINAPI
NdrAllocate(MIDL_STUB_MESSAGE
*pStubMsg
, size_t len
)
309 /* hmm, this is probably supposed to do more? */
310 return pStubMsg
->pfnAllocate(len
);
313 static void WINAPI
NdrFree(MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *Pointer
)
315 pStubMsg
->pfnFree(Pointer
);
318 static inline BOOL
IsConformanceOrVariancePresent(PFORMAT_STRING pFormat
)
320 return (*(const ULONG
*)pFormat
!= -1);
323 static PFORMAT_STRING
ReadConformance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
)
325 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
326 pStubMsg
->MaxCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
327 pStubMsg
->Buffer
+= 4;
328 TRACE("unmarshalled conformance is %ld\n", pStubMsg
->MaxCount
);
329 if (pStubMsg
->fHasNewCorrDesc
)
335 static inline PFORMAT_STRING
ReadVariance(MIDL_STUB_MESSAGE
*pStubMsg
, PFORMAT_STRING pFormat
, ULONG MaxValue
)
337 if (pFormat
&& !IsConformanceOrVariancePresent(pFormat
))
339 pStubMsg
->Offset
= 0;
340 pStubMsg
->ActualCount
= pStubMsg
->MaxCount
;
344 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
345 pStubMsg
->Offset
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
346 pStubMsg
->Buffer
+= 4;
347 TRACE("offset is %d\n", pStubMsg
->Offset
);
348 pStubMsg
->ActualCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
349 pStubMsg
->Buffer
+= 4;
350 TRACE("variance is %d\n", pStubMsg
->ActualCount
);
352 if ((pStubMsg
->ActualCount
> MaxValue
) ||
353 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> MaxValue
))
355 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
356 pStubMsg
->ActualCount
, pStubMsg
->Offset
, MaxValue
);
357 RpcRaiseException(RPC_S_INVALID_BOUND
);
362 if (pStubMsg
->fHasNewCorrDesc
)
368 /* writes the conformance value to the buffer */
369 static inline void WriteConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
371 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
372 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->MaxCount
);
373 pStubMsg
->Buffer
+= 4;
376 /* writes the variance values to the buffer */
377 static inline void WriteVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
379 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
380 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->Offset
);
381 pStubMsg
->Buffer
+= 4;
382 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, pStubMsg
->ActualCount
);
383 pStubMsg
->Buffer
+= 4;
386 /* requests buffer space for the conformance value */
387 static inline void SizeConformance(MIDL_STUB_MESSAGE
*pStubMsg
)
389 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
390 pStubMsg
->BufferLength
+= 4;
393 /* requests buffer space for the variance values */
394 static inline void SizeVariance(MIDL_STUB_MESSAGE
*pStubMsg
)
396 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
397 pStubMsg
->BufferLength
+= 8;
400 PFORMAT_STRING
ComputeConformanceOrVariance(
401 MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *pMemory
,
402 PFORMAT_STRING pFormat
, ULONG_PTR def
, ULONG_PTR
*pCount
)
404 BYTE dtype
= pFormat
[0] & 0xf;
405 short ofs
= *(const short *)&pFormat
[2];
409 if (!IsConformanceOrVariancePresent(pFormat
)) {
410 /* null descriptor */
415 switch (pFormat
[0] & 0xf0) {
416 case RPC_FC_NORMAL_CONFORMANCE
:
417 TRACE("normal conformance, ofs=%d\n", ofs
);
420 case RPC_FC_POINTER_CONFORMANCE
:
421 TRACE("pointer conformance, ofs=%d\n", ofs
);
422 ptr
= pStubMsg
->Memory
;
424 case RPC_FC_TOP_LEVEL_CONFORMANCE
:
425 TRACE("toplevel conformance, ofs=%d\n", ofs
);
426 if (pStubMsg
->StackTop
) {
427 ptr
= pStubMsg
->StackTop
;
430 /* -Os mode, *pCount is already set */
434 case RPC_FC_CONSTANT_CONFORMANCE
:
435 data
= ofs
| ((DWORD
)pFormat
[1] << 16);
436 TRACE("constant conformance, val=%d\n", data
);
439 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE
:
440 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs
);
441 if (pStubMsg
->StackTop
) {
442 ptr
= pStubMsg
->StackTop
;
450 FIXME("unknown conformance type %x\n", pFormat
[0] & 0xf0);
453 switch (pFormat
[1]) {
454 case RPC_FC_DEREFERENCE
:
455 ptr
= *(LPVOID
*)((char *)ptr
+ ofs
);
457 case RPC_FC_CALLBACK
:
459 unsigned char *old_stack_top
= pStubMsg
->StackTop
;
460 pStubMsg
->StackTop
= ptr
;
462 /* ofs is index into StubDesc->apfnExprEval */
463 TRACE("callback conformance into apfnExprEval[%d]\n", ofs
);
464 pStubMsg
->StubDesc
->apfnExprEval
[ofs
](pStubMsg
);
466 pStubMsg
->StackTop
= old_stack_top
;
468 /* the callback function always stores the computed value in MaxCount */
469 *pCount
= pStubMsg
->MaxCount
;
473 ptr
= (char *)ptr
+ ofs
;
486 data
= *(USHORT
*)ptr
;
497 FIXME("unknown conformance data type %x\n", dtype
);
500 TRACE("dereferenced data type %x at %p, got %d\n", dtype
, ptr
, data
);
503 switch (pFormat
[1]) {
504 case RPC_FC_DEREFERENCE
: /* already handled */
521 FIXME("unknown conformance op %d\n", pFormat
[1]);
526 TRACE("resulting conformance is %ld\n", *pCount
);
527 if (pStubMsg
->fHasNewCorrDesc
)
533 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
534 * the result overflows 32-bits */
535 inline static ULONG
safe_multiply(ULONG a
, ULONG b
)
537 ULONGLONG ret
= (ULONGLONG
)a
* b
;
538 if (ret
> 0xffffffff)
540 RpcRaiseException(RPC_S_INVALID_BOUND
);
548 * NdrConformantString:
550 * What MS calls a ConformantString is, in DCE terminology,
551 * a Varying-Conformant String.
553 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
554 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
555 * into unmarshalled string)
556 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
558 * data: CHARTYPE[maxlen]
560 * ], where CHARTYPE is the appropriate character type (specified externally)
564 /***********************************************************************
565 * NdrConformantStringMarshall [RPCRT4.@]
567 unsigned char *WINAPI
NdrConformantStringMarshall(MIDL_STUB_MESSAGE
*pStubMsg
,
568 unsigned char *pszMessage
, PFORMAT_STRING pFormat
)
572 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg
, pszMessage
, pFormat
);
574 if (*pFormat
== RPC_FC_C_CSTRING
) {
575 TRACE("string=%s\n", debugstr_a((char*)pszMessage
));
576 pStubMsg
->ActualCount
= strlen((char*)pszMessage
)+1;
579 else if (*pFormat
== RPC_FC_C_WSTRING
) {
580 TRACE("string=%s\n", debugstr_w((LPWSTR
)pszMessage
));
581 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pszMessage
)+1;
585 ERR("Unhandled string type: %#x\n", *pFormat
);
586 /* FIXME: raise an exception. */
590 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
591 pFormat
= ComputeConformance(pStubMsg
, pszMessage
, pFormat
+ 2, 0);
593 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
594 pStubMsg
->Offset
= 0;
595 WriteConformance(pStubMsg
);
596 WriteVariance(pStubMsg
);
598 size
= safe_multiply(esize
, pStubMsg
->ActualCount
);
599 memcpy(pStubMsg
->Buffer
, pszMessage
, size
); /* the string itself */
600 pStubMsg
->Buffer
+= size
;
602 STD_OVERFLOW_CHECK(pStubMsg
);
605 return NULL
; /* is this always right? */
608 /***********************************************************************
609 * NdrConformantStringBufferSize [RPCRT4.@]
611 void WINAPI
NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
612 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
616 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
618 SizeConformance(pStubMsg
);
619 SizeVariance(pStubMsg
);
621 if (*pFormat
== RPC_FC_C_CSTRING
) {
622 TRACE("string=%s\n", debugstr_a((char*)pMemory
));
623 pStubMsg
->ActualCount
= strlen((char*)pMemory
)+1;
626 else if (*pFormat
== RPC_FC_C_WSTRING
) {
627 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
));
628 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
)+1;
632 ERR("Unhandled string type: %#x\n", *pFormat
);
633 /* FIXME: raise an exception */
637 if (pFormat
[1] == RPC_FC_STRING_SIZED
)
638 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+ 2, 0);
640 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
642 pStubMsg
->BufferLength
+= safe_multiply(esize
, pStubMsg
->ActualCount
);
645 /************************************************************************
646 * NdrConformantStringMemorySize [RPCRT4.@]
648 ULONG WINAPI
NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
649 PFORMAT_STRING pFormat
)
653 FIXME("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
655 assert(pStubMsg
&& pFormat
);
657 if (*pFormat
== RPC_FC_C_CSTRING
) {
658 rslt
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
); /* maxlen */
660 else if (*pFormat
== RPC_FC_C_WSTRING
) {
661 rslt
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
)*2; /* maxlen */
664 ERR("Unhandled string type: %#x\n", *pFormat
);
665 /* FIXME: raise an exception */
668 if (pFormat
[1] != RPC_FC_PAD
) {
669 FIXME("sized string format=%d\n", pFormat
[1]);
672 TRACE(" --> %u\n", rslt
);
676 /************************************************************************
677 * NdrConformantStringUnmarshall [RPCRT4.@]
679 unsigned char *WINAPI
NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
680 unsigned char** ppMemory
, PFORMAT_STRING pFormat
, unsigned char fMustAlloc
)
682 ULONG bufsize
, memsize
, esize
, i
;
684 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
685 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
687 assert(pFormat
&& ppMemory
&& pStubMsg
);
689 ReadConformance(pStubMsg
, NULL
);
690 ReadVariance(pStubMsg
, NULL
, pStubMsg
->MaxCount
);
692 if (*pFormat
== RPC_FC_C_CSTRING
) esize
= 1;
693 else if (*pFormat
== RPC_FC_C_WSTRING
) esize
= 2;
695 ERR("Unhandled string type: %#x\n", *pFormat
);
696 /* FIXME: raise an exception */
700 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
701 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
703 /* strings must always have null terminating bytes */
706 ERR("invalid string length of %d\n", pStubMsg
->ActualCount
);
707 RpcRaiseException(RPC_S_INVALID_BOUND
);
710 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
711 if (pStubMsg
->Buffer
[i
] != 0)
713 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
714 i
, pStubMsg
->Buffer
[i
]);
715 RpcRaiseException(RPC_S_INVALID_BOUND
);
719 if (fMustAlloc
|| !*ppMemory
)
720 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
722 memcpy(*ppMemory
, pStubMsg
->Buffer
, bufsize
);
724 pStubMsg
->Buffer
+= bufsize
;
726 if (*pFormat
== RPC_FC_C_CSTRING
) {
727 TRACE("string=%s\n", debugstr_a((char*)*ppMemory
));
729 else if (*pFormat
== RPC_FC_C_WSTRING
) {
730 TRACE("string=%s\n", debugstr_w((LPWSTR
)*ppMemory
));
733 return NULL
; /* FIXME: is this always right? */
736 /***********************************************************************
737 * NdrNonConformantStringMarshall [RPCRT4.@]
739 unsigned char * WINAPI
NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
740 unsigned char *pMemory
,
741 PFORMAT_STRING pFormat
)
747 /***********************************************************************
748 * NdrNonConformantStringUnmarshall [RPCRT4.@]
750 unsigned char * WINAPI
NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
751 unsigned char **ppMemory
,
752 PFORMAT_STRING pFormat
,
753 unsigned char fMustAlloc
)
759 /***********************************************************************
760 * NdrNonConformantStringBufferSize [RPCRT4.@]
762 void WINAPI
NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
763 unsigned char *pMemory
,
764 PFORMAT_STRING pFormat
)
769 /***********************************************************************
770 * NdrNonConformantStringMemorySize [RPCRT4.@]
772 ULONG WINAPI
NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
773 PFORMAT_STRING pFormat
)
779 static inline void dump_pointer_attr(unsigned char attr
)
781 if (attr
& RPC_FC_P_ALLOCALLNODES
)
782 TRACE(" RPC_FC_P_ALLOCALLNODES");
783 if (attr
& RPC_FC_P_DONTFREE
)
784 TRACE(" RPC_FC_P_DONTFREE");
785 if (attr
& RPC_FC_P_ONSTACK
)
786 TRACE(" RPC_FC_P_ONSTACK");
787 if (attr
& RPC_FC_P_SIMPLEPOINTER
)
788 TRACE(" RPC_FC_P_SIMPLEPOINTER");
789 if (attr
& RPC_FC_P_DEREF
)
790 TRACE(" RPC_FC_P_DEREF");
794 /***********************************************************************
795 * PointerMarshall [internal]
797 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
798 unsigned char *Buffer
,
799 unsigned char *Pointer
,
800 PFORMAT_STRING pFormat
)
802 unsigned type
= pFormat
[0], attr
= pFormat
[1];
806 int pointer_needs_marshaling
;
808 TRACE("(%p,%p,%p,%p)\n", pStubMsg
, Buffer
, Pointer
, pFormat
);
809 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
811 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
812 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
815 case RPC_FC_RP
: /* ref pointer (always non-null) */
816 #if 0 /* this causes problems for InstallShield so is disabled - we need more tests */
818 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
820 pointer_needs_marshaling
= 1;
822 case RPC_FC_UP
: /* unique pointer */
823 case RPC_FC_OP
: /* object pointer - same as unique here */
825 pointer_needs_marshaling
= 1;
827 pointer_needs_marshaling
= 0;
828 pointer_id
= (ULONG
)Pointer
;
829 TRACE("writing 0x%08x to buffer\n", pointer_id
);
830 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
833 pointer_needs_marshaling
= !NdrFullPointerQueryPointer(
834 pStubMsg
->FullPtrXlatTables
, Pointer
, 1, &pointer_id
);
835 TRACE("writing 0x%08x to buffer\n", pointer_id
);
836 NDR_LOCAL_UINT32_WRITE(Buffer
, pointer_id
);
839 FIXME("unhandled ptr type=%02x\n", type
);
840 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
844 TRACE("calling marshaller for type 0x%x\n", (int)*desc
);
846 if (pointer_needs_marshaling
) {
847 if (attr
& RPC_FC_P_DEREF
) {
848 Pointer
= *(unsigned char**)Pointer
;
849 TRACE("deref => %p\n", Pointer
);
851 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
852 if (m
) m(pStubMsg
, Pointer
, desc
);
853 else FIXME("no marshaller for data type=%02x\n", *desc
);
856 STD_OVERFLOW_CHECK(pStubMsg
);
859 /***********************************************************************
860 * PointerUnmarshall [internal]
862 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
863 unsigned char *Buffer
,
864 unsigned char **pPointer
,
865 PFORMAT_STRING pFormat
,
866 unsigned char fMustAlloc
)
868 unsigned type
= pFormat
[0], attr
= pFormat
[1];
871 DWORD pointer_id
= 0;
872 int pointer_needs_unmarshaling
;
874 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg
, Buffer
, pPointer
, pFormat
, fMustAlloc
);
875 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
877 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
878 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
881 case RPC_FC_RP
: /* ref pointer (always non-null) */
882 pointer_needs_unmarshaling
= 1;
884 case RPC_FC_UP
: /* unique pointer */
885 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
886 TRACE("pointer_id is 0x%08x\n", pointer_id
);
888 pointer_needs_unmarshaling
= 1;
891 pointer_needs_unmarshaling
= 0;
894 case RPC_FC_OP
: /* object pointer - we must free data before overwriting it */
895 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
896 TRACE("pointer_id is 0x%08x\n", pointer_id
);
897 if (!fMustAlloc
&& *pPointer
)
899 FIXME("free object pointer %p\n", *pPointer
);
903 pointer_needs_unmarshaling
= 1;
905 pointer_needs_unmarshaling
= 0;
908 pointer_id
= NDR_LOCAL_UINT32_READ(Buffer
);
909 TRACE("pointer_id is 0x%08x\n", pointer_id
);
910 pointer_needs_unmarshaling
= !NdrFullPointerQueryRefId(
911 pStubMsg
->FullPtrXlatTables
, pointer_id
, 1, (void **)pPointer
);
914 FIXME("unhandled ptr type=%02x\n", type
);
915 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
919 if (pointer_needs_unmarshaling
) {
920 if (attr
& RPC_FC_P_DEREF
) {
921 if (!*pPointer
|| fMustAlloc
)
922 *pPointer
= NdrAllocate(pStubMsg
, sizeof(void *));
923 pPointer
= *(unsigned char***)pPointer
;
924 TRACE("deref => %p\n", pPointer
);
926 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
927 if (m
) m(pStubMsg
, pPointer
, desc
, fMustAlloc
);
928 else FIXME("no unmarshaller for data type=%02x\n", *desc
);
930 if (type
== RPC_FC_FP
)
931 NdrFullPointerInsertRefId(pStubMsg
->FullPtrXlatTables
, pointer_id
,
935 TRACE("pointer=%p\n", *pPointer
);
938 /***********************************************************************
939 * PointerBufferSize [internal]
941 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
942 unsigned char *Pointer
,
943 PFORMAT_STRING pFormat
)
945 unsigned type
= pFormat
[0], attr
= pFormat
[1];
948 int pointer_needs_sizing
;
951 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
952 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
954 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
955 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
958 case RPC_FC_RP
: /* ref pointer (always non-null) */
962 /* NULL pointer has no further representation */
967 pointer_needs_sizing
= !NdrFullPointerQueryPointer(
968 pStubMsg
->FullPtrXlatTables
, Pointer
, 0, &pointer_id
);
969 if (!pointer_needs_sizing
)
973 FIXME("unhandled ptr type=%02x\n", type
);
974 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
978 if (attr
& RPC_FC_P_DEREF
) {
979 Pointer
= *(unsigned char**)Pointer
;
980 TRACE("deref => %p\n", Pointer
);
983 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
984 if (m
) m(pStubMsg
, Pointer
, desc
);
985 else FIXME("no buffersizer for data type=%02x\n", *desc
);
988 /***********************************************************************
989 * PointerMemorySize [internal]
991 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
992 unsigned char *Buffer
,
993 PFORMAT_STRING pFormat
)
995 unsigned type
= pFormat
[0], attr
= pFormat
[1];
999 FIXME("(%p,%p,%p): stub\n", pStubMsg
, Buffer
, pFormat
);
1000 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1002 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1003 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1006 case RPC_FC_RP
: /* ref pointer (always non-null) */
1009 FIXME("unhandled ptr type=%02x\n", type
);
1010 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1013 if (attr
& RPC_FC_P_DEREF
) {
1017 m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
1018 if (m
) m(pStubMsg
, desc
);
1019 else FIXME("no memorysizer for data type=%02x\n", *desc
);
1024 /***********************************************************************
1025 * PointerFree [internal]
1027 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1028 unsigned char *Pointer
,
1029 PFORMAT_STRING pFormat
)
1031 unsigned type
= pFormat
[0], attr
= pFormat
[1];
1032 PFORMAT_STRING desc
;
1035 TRACE("(%p,%p,%p)\n", pStubMsg
, Pointer
, pFormat
);
1036 TRACE("type=0x%x, attr=", type
); dump_pointer_attr(attr
);
1037 if (attr
& RPC_FC_P_DONTFREE
) return;
1039 if (attr
& RPC_FC_P_SIMPLEPOINTER
) desc
= pFormat
;
1040 else desc
= pFormat
+ *(const SHORT
*)pFormat
;
1042 if (!Pointer
) return;
1044 if (type
== RPC_FC_FP
) {
1045 int pointer_needs_freeing
= NdrFullPointerFree(
1046 pStubMsg
->FullPtrXlatTables
, Pointer
);
1047 if (!pointer_needs_freeing
)
1051 if (attr
& RPC_FC_P_DEREF
) {
1052 Pointer
= *(unsigned char**)Pointer
;
1053 TRACE("deref => %p\n", Pointer
);
1056 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
1057 if (m
) m(pStubMsg
, Pointer
, desc
);
1059 /* hmm... is this sensible?
1060 * perhaps we should check if the memory comes from NdrAllocate,
1061 * and deallocate only if so - checking if the pointer is between
1062 * BufferStart and BufferEnd is probably no good since the buffer
1063 * may be reallocated when the server wants to marshal the reply */
1065 case RPC_FC_BOGUS_STRUCT
:
1066 case RPC_FC_BOGUS_ARRAY
:
1067 case RPC_FC_USER_MARSHAL
:
1069 case RPC_FC_CVARRAY
:
1072 FIXME("unhandled data type=%02x\n", *desc
);
1074 case RPC_FC_C_CSTRING
:
1075 case RPC_FC_C_WSTRING
:
1076 if (pStubMsg
->ReuseBuffer
) goto notfree
;
1082 if (attr
& RPC_FC_P_ONSTACK
) {
1083 TRACE("not freeing stack ptr %p\n", Pointer
);
1086 TRACE("freeing %p\n", Pointer
);
1087 NdrFree(pStubMsg
, Pointer
);
1090 TRACE("not freeing %p\n", Pointer
);
1093 /***********************************************************************
1094 * EmbeddedPointerMarshall
1096 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1097 unsigned char *pMemory
,
1098 PFORMAT_STRING pFormat
)
1100 unsigned char *Mark
= pStubMsg
->BufferMark
;
1101 unsigned long Offset
= pStubMsg
->Offset
;
1102 unsigned ofs
, rep
, count
, stride
, xofs
;
1105 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1107 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1110 while (pFormat
[0] != RPC_FC_END
) {
1111 switch (pFormat
[0]) {
1113 FIXME("unknown repeat type %d\n", pFormat
[0]);
1114 case RPC_FC_NO_REPEAT
:
1122 case RPC_FC_FIXED_REPEAT
:
1123 rep
= *(const WORD
*)&pFormat
[2];
1124 stride
= *(const WORD
*)&pFormat
[4];
1125 ofs
= *(const WORD
*)&pFormat
[6];
1126 count
= *(const WORD
*)&pFormat
[8];
1130 case RPC_FC_VARIABLE_REPEAT
:
1131 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1132 stride
= *(const WORD
*)&pFormat
[2];
1133 ofs
= *(const WORD
*)&pFormat
[4];
1134 count
= *(const WORD
*)&pFormat
[6];
1135 xofs
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? Offset
* stride
: 0;
1139 for (i
= 0; i
< rep
; i
++) {
1140 PFORMAT_STRING info
= pFormat
;
1141 unsigned char *membase
= pMemory
+ (i
* stride
);
1142 unsigned char *bufbase
= Mark
+ (i
* stride
);
1144 /* ofs doesn't seem to matter in this context */
1145 for (u
=0; u
<count
; u
++,info
+=8) {
1146 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1147 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1148 unsigned char *saved_memory
= pStubMsg
->Memory
;
1150 pStubMsg
->Memory
= pMemory
;
1151 PointerMarshall(pStubMsg
, bufptr
, *(unsigned char**)memptr
, info
+4);
1152 pStubMsg
->Memory
= saved_memory
;
1155 pFormat
+= 8 * count
;
1158 STD_OVERFLOW_CHECK(pStubMsg
);
1163 /***********************************************************************
1164 * EmbeddedPointerUnmarshall
1166 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1167 unsigned char **ppMemory
,
1168 PFORMAT_STRING pFormat
,
1169 unsigned char fMustAlloc
)
1171 unsigned char *Mark
= pStubMsg
->BufferMark
;
1172 unsigned long Offset
= pStubMsg
->Offset
;
1173 unsigned ofs
, rep
, count
, stride
, xofs
;
1176 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1178 if (*pFormat
!= RPC_FC_PP
) return NULL
;
1181 while (pFormat
[0] != RPC_FC_END
) {
1182 TRACE("pFormat[0] = 0x%x\n", pFormat
[0]);
1183 switch (pFormat
[0]) {
1185 FIXME("unknown repeat type %d\n", pFormat
[0]);
1186 case RPC_FC_NO_REPEAT
:
1194 case RPC_FC_FIXED_REPEAT
:
1195 rep
= *(const WORD
*)&pFormat
[2];
1196 stride
= *(const WORD
*)&pFormat
[4];
1197 ofs
= *(const WORD
*)&pFormat
[6];
1198 count
= *(const WORD
*)&pFormat
[8];
1202 case RPC_FC_VARIABLE_REPEAT
:
1203 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1204 stride
= *(const WORD
*)&pFormat
[2];
1205 ofs
= *(const WORD
*)&pFormat
[4];
1206 count
= *(const WORD
*)&pFormat
[6];
1207 xofs
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? Offset
* stride
: 0;
1211 /* ofs doesn't seem to matter in this context */
1212 for (i
= 0; i
< rep
; i
++) {
1213 PFORMAT_STRING info
= pFormat
;
1214 unsigned char *membase
= *ppMemory
+ (i
* stride
);
1215 unsigned char *bufbase
= Mark
+ (i
* stride
);
1217 for (u
=0; u
<count
; u
++,info
+=8) {
1218 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1219 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1220 PointerUnmarshall(pStubMsg
, bufptr
, (unsigned char**)memptr
, info
+4, TRUE
);
1223 pFormat
+= 8 * count
;
1229 /***********************************************************************
1230 * EmbeddedPointerBufferSize
1232 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1233 unsigned char *pMemory
,
1234 PFORMAT_STRING pFormat
)
1236 unsigned long Offset
= pStubMsg
->Offset
;
1237 unsigned ofs
, rep
, count
, stride
, xofs
;
1240 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1242 if (pStubMsg
->IgnoreEmbeddedPointers
) return;
1244 if (*pFormat
!= RPC_FC_PP
) return;
1247 while (pFormat
[0] != RPC_FC_END
) {
1248 switch (pFormat
[0]) {
1250 FIXME("unknown repeat type %d\n", pFormat
[0]);
1251 case RPC_FC_NO_REPEAT
:
1259 case RPC_FC_FIXED_REPEAT
:
1260 rep
= *(const WORD
*)&pFormat
[2];
1261 stride
= *(const WORD
*)&pFormat
[4];
1262 ofs
= *(const WORD
*)&pFormat
[6];
1263 count
= *(const WORD
*)&pFormat
[8];
1267 case RPC_FC_VARIABLE_REPEAT
:
1268 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1269 stride
= *(const WORD
*)&pFormat
[2];
1270 ofs
= *(const WORD
*)&pFormat
[4];
1271 count
= *(const WORD
*)&pFormat
[6];
1272 xofs
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? Offset
* stride
: 0;
1276 /* ofs doesn't seem to matter in this context */
1277 for (i
= 0; i
< rep
; i
++) {
1278 PFORMAT_STRING info
= pFormat
;
1279 unsigned char *membase
= pMemory
+ (i
* stride
);
1281 for (u
=0; u
<count
; u
++,info
+=8) {
1282 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1283 unsigned char *saved_memory
= pStubMsg
->Memory
;
1285 pStubMsg
->Memory
= pMemory
;
1286 PointerBufferSize(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1287 pStubMsg
->Memory
= saved_memory
;
1290 pFormat
+= 8 * count
;
1294 /***********************************************************************
1295 * EmbeddedPointerMemorySize [internal]
1297 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1298 PFORMAT_STRING pFormat
)
1300 unsigned long Offset
= pStubMsg
->Offset
;
1301 unsigned char *Mark
= pStubMsg
->BufferMark
;
1302 unsigned ofs
, rep
, count
, stride
, xofs
;
1305 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1307 if (*pFormat
!= RPC_FC_PP
) return 0;
1310 while (pFormat
[0] != RPC_FC_END
) {
1311 switch (pFormat
[0]) {
1313 FIXME("unknown repeat type %d\n", pFormat
[0]);
1314 case RPC_FC_NO_REPEAT
:
1322 case RPC_FC_FIXED_REPEAT
:
1323 rep
= *(const WORD
*)&pFormat
[2];
1324 stride
= *(const WORD
*)&pFormat
[4];
1325 ofs
= *(const WORD
*)&pFormat
[6];
1326 count
= *(const WORD
*)&pFormat
[8];
1330 case RPC_FC_VARIABLE_REPEAT
:
1331 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1332 stride
= *(const WORD
*)&pFormat
[2];
1333 ofs
= *(const WORD
*)&pFormat
[4];
1334 count
= *(const WORD
*)&pFormat
[6];
1335 xofs
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? Offset
* stride
: 0;
1339 /* ofs doesn't seem to matter in this context */
1340 for (i
= 0; i
< rep
; i
++) {
1341 PFORMAT_STRING info
= pFormat
;
1342 unsigned char *bufbase
= Mark
+ (i
* stride
);
1344 for (u
=0; u
<count
; u
++,info
+=8) {
1345 unsigned char *bufptr
= bufbase
+ *(const SHORT
*)&info
[2];
1346 PointerMemorySize(pStubMsg
, bufptr
, info
+4);
1349 pFormat
+= 8 * count
;
1355 /***********************************************************************
1356 * EmbeddedPointerFree [internal]
1358 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1359 unsigned char *pMemory
,
1360 PFORMAT_STRING pFormat
)
1362 unsigned long Offset
= pStubMsg
->Offset
;
1363 unsigned ofs
, rep
, count
, stride
, xofs
;
1366 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1367 if (*pFormat
!= RPC_FC_PP
) return;
1370 while (pFormat
[0] != RPC_FC_END
) {
1371 switch (pFormat
[0]) {
1373 FIXME("unknown repeat type %d\n", pFormat
[0]);
1374 case RPC_FC_NO_REPEAT
:
1382 case RPC_FC_FIXED_REPEAT
:
1383 rep
= *(const WORD
*)&pFormat
[2];
1384 stride
= *(const WORD
*)&pFormat
[4];
1385 ofs
= *(const WORD
*)&pFormat
[6];
1386 count
= *(const WORD
*)&pFormat
[8];
1390 case RPC_FC_VARIABLE_REPEAT
:
1391 rep
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? pStubMsg
->ActualCount
: pStubMsg
->MaxCount
;
1392 stride
= *(const WORD
*)&pFormat
[2];
1393 ofs
= *(const WORD
*)&pFormat
[4];
1394 count
= *(const WORD
*)&pFormat
[6];
1395 xofs
= (pFormat
[1] == RPC_FC_VARIABLE_OFFSET
) ? Offset
* stride
: 0;
1399 /* ofs doesn't seem to matter in this context */
1400 for (i
= 0; i
< rep
; i
++) {
1401 PFORMAT_STRING info
= pFormat
;
1402 unsigned char *membase
= pMemory
+ (i
* stride
);
1404 for (u
=0; u
<count
; u
++,info
+=8) {
1405 unsigned char *memptr
= membase
+ *(const SHORT
*)&info
[0];
1406 unsigned char *saved_memory
= pStubMsg
->Memory
;
1408 pStubMsg
->Memory
= pMemory
;
1409 PointerFree(pStubMsg
, *(unsigned char**)memptr
, info
+4);
1410 pStubMsg
->Memory
= saved_memory
;
1413 pFormat
+= 8 * count
;
1417 /***********************************************************************
1418 * NdrPointerMarshall [RPCRT4.@]
1420 unsigned char * WINAPI
NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1421 unsigned char *pMemory
,
1422 PFORMAT_STRING pFormat
)
1424 unsigned char *Buffer
;
1426 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1428 /* incremement the buffer here instead of in PointerMarshall,
1429 * as that is used by embedded pointers which already handle the incrementing
1430 * the buffer, and shouldn't write any additional pointer data to the wire */
1431 if (*pFormat
!= RPC_FC_RP
)
1433 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1434 Buffer
= pStubMsg
->Buffer
;
1435 pStubMsg
->Buffer
+= 4;
1438 Buffer
= pStubMsg
->Buffer
;
1440 PointerMarshall(pStubMsg
, Buffer
, pMemory
, pFormat
);
1442 STD_OVERFLOW_CHECK(pStubMsg
);
1447 /***********************************************************************
1448 * NdrPointerUnmarshall [RPCRT4.@]
1450 unsigned char * WINAPI
NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1451 unsigned char **ppMemory
,
1452 PFORMAT_STRING pFormat
,
1453 unsigned char fMustAlloc
)
1455 unsigned char *Buffer
;
1457 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1459 /* incremement the buffer here instead of in PointerUnmarshall,
1460 * as that is used by embedded pointers which already handle the incrementing
1461 * the buffer, and shouldn't read any additional pointer data from the
1463 if (*pFormat
!= RPC_FC_RP
)
1465 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
1466 Buffer
= pStubMsg
->Buffer
;
1467 pStubMsg
->Buffer
+= 4;
1470 Buffer
= pStubMsg
->Buffer
;
1472 PointerUnmarshall(pStubMsg
, Buffer
, ppMemory
, pFormat
, fMustAlloc
);
1477 /***********************************************************************
1478 * NdrPointerBufferSize [RPCRT4.@]
1480 void WINAPI
NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1481 unsigned char *pMemory
,
1482 PFORMAT_STRING pFormat
)
1484 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1486 /* incremement the buffer length here instead of in PointerBufferSize,
1487 * as that is used by embedded pointers which already handle the buffer
1488 * length, and shouldn't write anything more to the wire */
1489 if (*pFormat
!= RPC_FC_RP
)
1491 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
1492 pStubMsg
->BufferLength
+= 4;
1495 PointerBufferSize(pStubMsg
, pMemory
, pFormat
);
1498 /***********************************************************************
1499 * NdrPointerMemorySize [RPCRT4.@]
1501 ULONG WINAPI
NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1502 PFORMAT_STRING pFormat
)
1504 /* unsigned size = *(LPWORD)(pFormat+2); */
1505 FIXME("(%p,%p): stub\n", pStubMsg
, pFormat
);
1506 PointerMemorySize(pStubMsg
, pStubMsg
->Buffer
, pFormat
);
1510 /***********************************************************************
1511 * NdrPointerFree [RPCRT4.@]
1513 void WINAPI
NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
1514 unsigned char *pMemory
,
1515 PFORMAT_STRING pFormat
)
1517 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1518 PointerFree(pStubMsg
, pMemory
, pFormat
);
1521 /***********************************************************************
1522 * NdrSimpleTypeMarshall [RPCRT4.@]
1524 void WINAPI
NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1525 unsigned char FormatChar
)
1530 /***********************************************************************
1531 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1533 void WINAPI
NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
,
1534 unsigned char FormatChar
)
1539 /***********************************************************************
1540 * NdrSimpleStructMarshall [RPCRT4.@]
1542 unsigned char * WINAPI
NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1543 unsigned char *pMemory
,
1544 PFORMAT_STRING pFormat
)
1546 unsigned size
= *(const WORD
*)(pFormat
+2);
1547 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1549 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1551 memcpy(pStubMsg
->Buffer
, pMemory
, size
);
1552 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1553 pStubMsg
->Buffer
+= size
;
1555 if (pFormat
[0] != RPC_FC_STRUCT
)
1556 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
+4);
1558 STD_OVERFLOW_CHECK(pStubMsg
);
1563 /***********************************************************************
1564 * NdrSimpleStructUnmarshall [RPCRT4.@]
1566 unsigned char * WINAPI
NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1567 unsigned char **ppMemory
,
1568 PFORMAT_STRING pFormat
,
1569 unsigned char fMustAlloc
)
1571 unsigned size
= *(const WORD
*)(pFormat
+2);
1572 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
1574 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1577 *ppMemory
= NdrAllocate(pStubMsg
, size
);
1578 memcpy(*ppMemory
, pStubMsg
->Buffer
, size
);
1580 if (!pStubMsg
->IsClient
&& !*ppMemory
)
1581 /* for servers, we just point straight into the RPC buffer */
1582 *ppMemory
= pStubMsg
->Buffer
;
1584 /* for clients, memory should be provided by caller */
1585 memcpy(*ppMemory
, pStubMsg
->Buffer
, size
);
1588 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
1589 pStubMsg
->Buffer
+= size
;
1591 if (pFormat
[0] != RPC_FC_STRUCT
)
1592 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
+4, fMustAlloc
);
1597 /***********************************************************************
1598 * NdrSimpleStructBufferSize [RPCRT4.@]
1600 void WINAPI
NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1601 unsigned char *pMemory
,
1602 PFORMAT_STRING pFormat
)
1604 unsigned size
= *(const WORD
*)(pFormat
+2);
1605 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1607 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
1609 pStubMsg
->BufferLength
+= size
;
1610 if (pFormat
[0] != RPC_FC_STRUCT
)
1611 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
+4);
1614 /***********************************************************************
1615 * NdrSimpleStructMemorySize [RPCRT4.@]
1617 ULONG WINAPI
NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1618 PFORMAT_STRING pFormat
)
1620 unsigned short size
= *(const WORD
*)(pFormat
+2);
1622 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1624 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1625 pStubMsg
->MemorySize
+= size
;
1626 pStubMsg
->Buffer
+= size
;
1628 if (pFormat
[0] != RPC_FC_STRUCT
)
1629 EmbeddedPointerMemorySize(pStubMsg
, pFormat
+4);
1633 /***********************************************************************
1634 * NdrSimpleStructFree [RPCRT4.@]
1636 void WINAPI
NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
1637 unsigned char *pMemory
,
1638 PFORMAT_STRING pFormat
)
1640 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1641 if (pFormat
[0] != RPC_FC_STRUCT
)
1642 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
+4);
1646 static unsigned long EmbeddedComplexSize(PMIDL_STUB_MESSAGE pStubMsg
,
1647 PFORMAT_STRING pFormat
)
1651 case RPC_FC_PSTRUCT
:
1652 case RPC_FC_CSTRUCT
:
1653 case RPC_FC_BOGUS_STRUCT
:
1654 case RPC_FC_SMFARRAY
:
1655 case RPC_FC_SMVARRAY
:
1656 return *(const WORD
*)&pFormat
[2];
1657 case RPC_FC_USER_MARSHAL
:
1658 return *(const WORD
*)&pFormat
[4];
1659 case RPC_FC_NON_ENCAPSULATED_UNION
:
1661 if (pStubMsg
->fHasNewCorrDesc
)
1666 pFormat
+= *(const SHORT
*)pFormat
;
1667 return *(const SHORT
*)pFormat
;
1669 return sizeof(void *);
1671 FIXME("unhandled embedded type %02x\n", *pFormat
);
1677 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1678 PFORMAT_STRING pFormat
)
1680 NDR_MEMORYSIZE m
= NdrMemorySizer
[*pFormat
& NDR_TABLE_MASK
];
1684 FIXME("no memorysizer for data type=%02x\n", *pFormat
);
1688 return m(pStubMsg
, pFormat
);
1692 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1693 unsigned char *pMemory
,
1694 PFORMAT_STRING pFormat
,
1695 PFORMAT_STRING pPointer
)
1697 PFORMAT_STRING desc
;
1701 while (*pFormat
!= RPC_FC_END
) {
1707 TRACE("byte=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
1708 memcpy(pStubMsg
->Buffer
, pMemory
, 1);
1709 pStubMsg
->Buffer
+= 1;
1715 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
1716 memcpy(pStubMsg
->Buffer
, pMemory
, 2);
1717 pStubMsg
->Buffer
+= 2;
1723 TRACE("long=%d <= %p\n", *(DWORD
*)pMemory
, pMemory
);
1724 memcpy(pStubMsg
->Buffer
, pMemory
, 4);
1725 pStubMsg
->Buffer
+= 4;
1729 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
1730 memcpy(pStubMsg
->Buffer
, pMemory
, 8);
1731 pStubMsg
->Buffer
+= 8;
1734 case RPC_FC_POINTER
:
1735 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
1736 NdrPointerMarshall(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
1740 case RPC_FC_ALIGNM4
:
1741 ALIGN_POINTER(pMemory
, 4);
1743 case RPC_FC_ALIGNM8
:
1744 ALIGN_POINTER(pMemory
, 8);
1746 case RPC_FC_STRUCTPAD1
:
1747 case RPC_FC_STRUCTPAD2
:
1748 case RPC_FC_STRUCTPAD3
:
1749 case RPC_FC_STRUCTPAD4
:
1750 case RPC_FC_STRUCTPAD5
:
1751 case RPC_FC_STRUCTPAD6
:
1752 case RPC_FC_STRUCTPAD7
:
1753 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
1755 case RPC_FC_EMBEDDED_COMPLEX
:
1756 pMemory
+= pFormat
[1];
1758 desc
= pFormat
+ *(const SHORT
*)pFormat
;
1759 size
= EmbeddedComplexSize(pStubMsg
, desc
);
1760 TRACE("embedded complex (size=%ld) <= %p\n", size
, pMemory
);
1761 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
1762 if (m
) m(pStubMsg
, pMemory
, desc
);
1763 else FIXME("no marshaller for embedded type %02x\n", *desc
);
1770 FIXME("unhandled format 0x%02x\n", *pFormat
);
1778 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1779 unsigned char *pMemory
,
1780 PFORMAT_STRING pFormat
,
1781 PFORMAT_STRING pPointer
)
1783 PFORMAT_STRING desc
;
1787 while (*pFormat
!= RPC_FC_END
) {
1793 memcpy(pMemory
, pStubMsg
->Buffer
, 1);
1794 TRACE("byte=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
1795 pStubMsg
->Buffer
+= 1;
1801 memcpy(pMemory
, pStubMsg
->Buffer
, 2);
1802 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
1803 pStubMsg
->Buffer
+= 2;
1809 memcpy(pMemory
, pStubMsg
->Buffer
, 4);
1810 TRACE("long=%d => %p\n", *(DWORD
*)pMemory
, pMemory
);
1811 pStubMsg
->Buffer
+= 4;
1815 memcpy(pMemory
, pStubMsg
->Buffer
, 8);
1816 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
1817 pStubMsg
->Buffer
+= 8;
1820 case RPC_FC_POINTER
:
1821 TRACE("pointer => %p\n", pMemory
);
1822 NdrPointerUnmarshall(pStubMsg
, (unsigned char**)pMemory
, pPointer
, TRUE
);
1826 case RPC_FC_ALIGNM4
:
1827 ALIGN_POINTER(pMemory
, 4);
1829 case RPC_FC_ALIGNM8
:
1830 ALIGN_POINTER(pMemory
, 8);
1832 case RPC_FC_STRUCTPAD1
:
1833 case RPC_FC_STRUCTPAD2
:
1834 case RPC_FC_STRUCTPAD3
:
1835 case RPC_FC_STRUCTPAD4
:
1836 case RPC_FC_STRUCTPAD5
:
1837 case RPC_FC_STRUCTPAD6
:
1838 case RPC_FC_STRUCTPAD7
:
1839 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
1841 case RPC_FC_EMBEDDED_COMPLEX
:
1842 pMemory
+= pFormat
[1];
1844 desc
= pFormat
+ *(const SHORT
*)pFormat
;
1845 size
= EmbeddedComplexSize(pStubMsg
, desc
);
1846 TRACE("embedded complex (size=%ld) => %p\n", size
, pMemory
);
1847 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
1848 memset(pMemory
, 0, size
); /* just in case */
1849 if (m
) m(pStubMsg
, &pMemory
, desc
, FALSE
);
1850 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
1857 FIXME("unhandled format %d\n", *pFormat
);
1865 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1866 unsigned char *pMemory
,
1867 PFORMAT_STRING pFormat
,
1868 PFORMAT_STRING pPointer
)
1870 PFORMAT_STRING desc
;
1874 while (*pFormat
!= RPC_FC_END
) {
1880 pStubMsg
->BufferLength
+= 1;
1886 pStubMsg
->BufferLength
+= 2;
1892 pStubMsg
->BufferLength
+= 4;
1896 pStubMsg
->BufferLength
+= 8;
1899 case RPC_FC_POINTER
:
1900 NdrPointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
1904 case RPC_FC_ALIGNM4
:
1905 ALIGN_POINTER(pMemory
, 4);
1907 case RPC_FC_ALIGNM8
:
1908 ALIGN_POINTER(pMemory
, 8);
1910 case RPC_FC_STRUCTPAD1
:
1911 case RPC_FC_STRUCTPAD2
:
1912 case RPC_FC_STRUCTPAD3
:
1913 case RPC_FC_STRUCTPAD4
:
1914 case RPC_FC_STRUCTPAD5
:
1915 case RPC_FC_STRUCTPAD6
:
1916 case RPC_FC_STRUCTPAD7
:
1917 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
1919 case RPC_FC_EMBEDDED_COMPLEX
:
1920 pMemory
+= pFormat
[1];
1922 desc
= pFormat
+ *(const SHORT
*)pFormat
;
1923 size
= EmbeddedComplexSize(pStubMsg
, desc
);
1924 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
1925 if (m
) m(pStubMsg
, pMemory
, desc
);
1926 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
1933 FIXME("unhandled format 0x%02x\n", *pFormat
);
1941 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
1942 unsigned char *pMemory
,
1943 PFORMAT_STRING pFormat
,
1944 PFORMAT_STRING pPointer
)
1946 PFORMAT_STRING desc
;
1950 while (*pFormat
!= RPC_FC_END
) {
1971 case RPC_FC_POINTER
:
1972 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
1976 case RPC_FC_ALIGNM4
:
1977 ALIGN_POINTER(pMemory
, 4);
1979 case RPC_FC_ALIGNM8
:
1980 ALIGN_POINTER(pMemory
, 8);
1982 case RPC_FC_STRUCTPAD1
:
1983 case RPC_FC_STRUCTPAD2
:
1984 case RPC_FC_STRUCTPAD3
:
1985 case RPC_FC_STRUCTPAD4
:
1986 case RPC_FC_STRUCTPAD5
:
1987 case RPC_FC_STRUCTPAD6
:
1988 case RPC_FC_STRUCTPAD7
:
1989 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
1991 case RPC_FC_EMBEDDED_COMPLEX
:
1992 pMemory
+= pFormat
[1];
1994 desc
= pFormat
+ *(const SHORT
*)pFormat
;
1995 size
= EmbeddedComplexSize(pStubMsg
, desc
);
1996 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
1997 if (m
) m(pStubMsg
, pMemory
, desc
);
1998 else FIXME("no freer for embedded type %02x\n", *desc
);
2005 FIXME("unhandled format 0x%02x\n", *pFormat
);
2013 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2014 PFORMAT_STRING pFormat
)
2016 PFORMAT_STRING desc
;
2017 unsigned long size
= 0;
2019 while (*pFormat
!= RPC_FC_END
) {
2026 pStubMsg
->Buffer
+= 1;
2032 pStubMsg
->Buffer
+= 2;
2038 pStubMsg
->Buffer
+= 4;
2042 pStubMsg
->Buffer
+= 8;
2044 case RPC_FC_POINTER
:
2046 pStubMsg
->Buffer
+= 4;
2048 case RPC_FC_ALIGNM4
:
2049 ALIGN_LENGTH(size
, 4);
2050 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2052 case RPC_FC_ALIGNM8
:
2053 ALIGN_LENGTH(size
, 8);
2054 ALIGN_POINTER(pStubMsg
->Buffer
, 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 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2065 case RPC_FC_EMBEDDED_COMPLEX
:
2068 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2069 size
+= EmbeddedComplexMemorySize(pStubMsg
, desc
);
2075 FIXME("unhandled format 0x%02x\n", *pFormat
);
2083 /***********************************************************************
2084 * NdrComplexStructMarshall [RPCRT4.@]
2086 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2087 unsigned char *pMemory
,
2088 PFORMAT_STRING pFormat
)
2090 PFORMAT_STRING conf_array
= NULL
;
2091 PFORMAT_STRING pointer_desc
= NULL
;
2092 unsigned char *OldMemory
= pStubMsg
->Memory
;
2094 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2096 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2099 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2101 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2104 pStubMsg
->Memory
= pMemory
;
2106 ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2109 NdrConformantArrayMarshall(pStubMsg
, pMemory
, conf_array
);
2111 pStubMsg
->Memory
= OldMemory
;
2113 STD_OVERFLOW_CHECK(pStubMsg
);
2118 /***********************************************************************
2119 * NdrComplexStructUnmarshall [RPCRT4.@]
2121 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2122 unsigned char **ppMemory
,
2123 PFORMAT_STRING pFormat
,
2124 unsigned char fMustAlloc
)
2126 unsigned size
= *(const WORD
*)(pFormat
+2);
2127 PFORMAT_STRING conf_array
= NULL
;
2128 PFORMAT_STRING pointer_desc
= NULL
;
2129 unsigned char *pMemory
;
2131 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2133 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2135 if (fMustAlloc
|| !*ppMemory
)
2137 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2138 memset(*ppMemory
, 0, size
);
2142 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2144 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2147 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
);
2150 NdrConformantArrayUnmarshall(pStubMsg
, &pMemory
, conf_array
, fMustAlloc
);
2155 /***********************************************************************
2156 * NdrComplexStructBufferSize [RPCRT4.@]
2158 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2159 unsigned char *pMemory
,
2160 PFORMAT_STRING pFormat
)
2162 PFORMAT_STRING conf_array
= NULL
;
2163 PFORMAT_STRING pointer_desc
= NULL
;
2164 unsigned char *OldMemory
= pStubMsg
->Memory
;
2166 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2168 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
2171 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2173 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2176 pStubMsg
->Memory
= pMemory
;
2178 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2181 NdrConformantArrayBufferSize(pStubMsg
, pMemory
, conf_array
);
2183 pStubMsg
->Memory
= OldMemory
;
2186 /***********************************************************************
2187 * NdrComplexStructMemorySize [RPCRT4.@]
2189 ULONG WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2190 PFORMAT_STRING pFormat
)
2192 unsigned size
= *(const WORD
*)(pFormat
+2);
2193 PFORMAT_STRING conf_array
= NULL
;
2194 PFORMAT_STRING pointer_desc
= NULL
;
2196 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2198 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2201 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2203 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2206 ComplexStructMemorySize(pStubMsg
, pFormat
);
2209 NdrConformantArrayMemorySize(pStubMsg
, conf_array
);
2214 /***********************************************************************
2215 * NdrComplexStructFree [RPCRT4.@]
2217 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
2218 unsigned char *pMemory
,
2219 PFORMAT_STRING pFormat
)
2221 PFORMAT_STRING conf_array
= NULL
;
2222 PFORMAT_STRING pointer_desc
= NULL
;
2223 unsigned char *OldMemory
= pStubMsg
->Memory
;
2225 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2228 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2230 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2233 pStubMsg
->Memory
= pMemory
;
2235 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2238 NdrConformantArrayFree(pStubMsg
, pMemory
, conf_array
);
2240 pStubMsg
->Memory
= OldMemory
;
2243 /***********************************************************************
2244 * NdrConformantArrayMarshall [RPCRT4.@]
2246 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2247 unsigned char *pMemory
,
2248 PFORMAT_STRING pFormat
)
2250 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
2251 unsigned char alignment
= pFormat
[1] + 1;
2253 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2254 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2256 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2258 WriteConformance(pStubMsg
);
2260 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2262 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2263 memcpy(pStubMsg
->Buffer
, pMemory
, size
);
2264 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2265 pStubMsg
->Buffer
+= size
;
2267 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2269 STD_OVERFLOW_CHECK(pStubMsg
);
2274 /***********************************************************************
2275 * NdrConformantArrayUnmarshall [RPCRT4.@]
2277 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2278 unsigned char **ppMemory
,
2279 PFORMAT_STRING pFormat
,
2280 unsigned char fMustAlloc
)
2282 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
2283 unsigned char alignment
= pFormat
[1] + 1;
2285 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2286 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2288 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2290 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2292 if (fMustAlloc
|| !*ppMemory
)
2293 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2295 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2297 memcpy(*ppMemory
, pStubMsg
->Buffer
, size
);
2299 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2300 pStubMsg
->Buffer
+= size
;
2302 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2307 /***********************************************************************
2308 * NdrConformantArrayBufferSize [RPCRT4.@]
2310 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2311 unsigned char *pMemory
,
2312 PFORMAT_STRING pFormat
)
2314 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
2315 unsigned char alignment
= pFormat
[1] + 1;
2317 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2318 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2320 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2322 SizeConformance(pStubMsg
);
2324 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
2326 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2327 /* conformance value plus array */
2328 pStubMsg
->BufferLength
+= size
;
2330 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
2333 /***********************************************************************
2334 * NdrConformantArrayMemorySize [RPCRT4.@]
2336 ULONG WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2337 PFORMAT_STRING pFormat
)
2339 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
2340 unsigned char alignment
= pFormat
[1] + 1;
2342 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2343 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2345 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2346 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2347 pStubMsg
->MemorySize
+= size
;
2349 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2350 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2351 pStubMsg
->Buffer
+= size
;
2353 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2355 return pStubMsg
->MemorySize
;
2358 /***********************************************************************
2359 * NdrConformantArrayFree [RPCRT4.@]
2361 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
2362 unsigned char *pMemory
,
2363 PFORMAT_STRING pFormat
)
2365 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2366 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2368 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2370 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2374 /***********************************************************************
2375 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2377 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2378 unsigned char* pMemory
,
2379 PFORMAT_STRING pFormat
)
2382 unsigned char alignment
= pFormat
[1] + 1;
2383 DWORD esize
= *(const WORD
*)(pFormat
+2);
2385 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
2387 if (pFormat
[0] != RPC_FC_CVARRAY
)
2389 ERR("invalid format type %x\n", pFormat
[0]);
2390 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2394 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2395 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2397 WriteConformance(pStubMsg
);
2398 WriteVariance(pStubMsg
);
2400 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2402 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2404 memcpy(pStubMsg
->Buffer
, pMemory
+ pStubMsg
->Offset
, bufsize
);
2405 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2406 pStubMsg
->Buffer
+= bufsize
;
2408 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2410 STD_OVERFLOW_CHECK(pStubMsg
);
2416 /***********************************************************************
2417 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2419 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2420 unsigned char** ppMemory
,
2421 PFORMAT_STRING pFormat
,
2422 unsigned char fMustAlloc
)
2424 ULONG bufsize
, memsize
;
2425 unsigned char alignment
= pFormat
[1] + 1;
2426 DWORD esize
= *(const WORD
*)(pFormat
+2);
2428 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2430 if (pFormat
[0] != RPC_FC_CVARRAY
)
2432 ERR("invalid format type %x\n", pFormat
[0]);
2433 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2437 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2438 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2440 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2442 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2443 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2445 if (!*ppMemory
|| fMustAlloc
)
2446 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2447 memcpy(*ppMemory
+ pStubMsg
->Offset
, pStubMsg
->Buffer
, bufsize
);
2448 pStubMsg
->Buffer
+= bufsize
;
2450 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2456 /***********************************************************************
2457 * NdrConformantVaryingArrayFree [RPCRT4.@]
2459 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
2460 unsigned char* pMemory
,
2461 PFORMAT_STRING pFormat
)
2463 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2465 if (pFormat
[0] != RPC_FC_CVARRAY
)
2467 ERR("invalid format type %x\n", pFormat
[0]);
2468 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2472 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2473 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2475 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2479 /***********************************************************************
2480 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2482 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
2483 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
2485 unsigned char alignment
= pFormat
[1] + 1;
2486 DWORD esize
= *(const WORD
*)(pFormat
+2);
2488 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
2490 if (pFormat
[0] != RPC_FC_CVARRAY
)
2492 ERR("invalid format type %x\n", pFormat
[0]);
2493 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2498 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2499 /* compute length */
2500 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2502 SizeConformance(pStubMsg
);
2503 SizeVariance(pStubMsg
);
2505 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
2507 pStubMsg
->BufferLength
+= safe_multiply(esize
, pStubMsg
->ActualCount
);
2509 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
2513 /***********************************************************************
2514 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2516 ULONG WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
2517 PFORMAT_STRING pFormat
)
2524 /***********************************************************************
2525 * NdrComplexArrayMarshall [RPCRT4.@]
2527 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2528 unsigned char *pMemory
,
2529 PFORMAT_STRING pFormat
)
2531 ULONG i
, count
, def
;
2532 BOOL variance_present
;
2533 unsigned char alignment
;
2535 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2537 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
2539 ERR("invalid format type %x\n", pFormat
[0]);
2540 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2544 alignment
= pFormat
[1] + 1;
2546 def
= *(const WORD
*)&pFormat
[2];
2549 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
2550 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
2552 variance_present
= IsConformanceOrVariancePresent(pFormat
);
2553 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
2554 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
2556 WriteConformance(pStubMsg
);
2557 if (variance_present
)
2558 WriteVariance(pStubMsg
);
2560 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2562 count
= pStubMsg
->ActualCount
;
2563 for (i
= 0; i
< count
; i
++)
2564 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
2566 STD_OVERFLOW_CHECK(pStubMsg
);
2571 /***********************************************************************
2572 * NdrComplexArrayUnmarshall [RPCRT4.@]
2574 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2575 unsigned char **ppMemory
,
2576 PFORMAT_STRING pFormat
,
2577 unsigned char fMustAlloc
)
2579 ULONG i
, count
, esize
, memsize
;
2580 unsigned char alignment
;
2581 unsigned char *pMemory
;
2582 unsigned char *Buffer
;
2584 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2586 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
2588 ERR("invalid format type %x\n", pFormat
[0]);
2589 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2593 alignment
= pFormat
[1] + 1;
2597 pFormat
= ReadConformance(pStubMsg
, pFormat
);
2598 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2600 Buffer
= pStubMsg
->Buffer
;
2601 pStubMsg
->MemorySize
= 0;
2602 esize
= ComplexStructMemorySize(pStubMsg
, pFormat
);
2603 pStubMsg
->Buffer
= Buffer
;
2605 /* do multiply here instead of inside if block to verify MaxCount */
2606 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2607 if (fMustAlloc
|| !*ppMemory
)
2609 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2610 memset(*ppMemory
, 0, memsize
);
2613 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2615 pMemory
= *ppMemory
;
2616 count
= pStubMsg
->ActualCount
;
2617 for (i
= 0; i
< count
; i
++)
2618 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
2623 /***********************************************************************
2624 * NdrComplexArrayBufferSize [RPCRT4.@]
2626 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2627 unsigned char *pMemory
,
2628 PFORMAT_STRING pFormat
)
2630 ULONG i
, count
, def
;
2631 unsigned char alignment
;
2632 BOOL variance_present
;
2634 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2636 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
2638 ERR("invalid format type %x\n", pFormat
[0]);
2639 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2643 alignment
= pFormat
[1] + 1;
2645 def
= *(const WORD
*)&pFormat
[2];
2648 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
2649 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
2650 SizeConformance(pStubMsg
);
2652 variance_present
= IsConformanceOrVariancePresent(pFormat
);
2653 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
2654 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
2656 if (variance_present
)
2657 SizeVariance(pStubMsg
);
2659 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
2661 count
= pStubMsg
->ActualCount
;
2662 for (i
= 0; i
< count
; i
++)
2663 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
2666 /***********************************************************************
2667 * NdrComplexArrayMemorySize [RPCRT4.@]
2669 ULONG WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2670 PFORMAT_STRING pFormat
)
2672 ULONG i
, count
, esize
, SavedMemorySize
, MemorySize
;
2673 unsigned char alignment
;
2674 unsigned char *Buffer
;
2676 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2678 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
2680 ERR("invalid format type %x\n", pFormat
[0]);
2681 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2685 alignment
= pFormat
[1] + 1;
2689 pFormat
= ReadConformance(pStubMsg
, pFormat
);
2690 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2692 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2694 SavedMemorySize
= pStubMsg
->MemorySize
;
2696 Buffer
= pStubMsg
->Buffer
;
2697 pStubMsg
->MemorySize
= 0;
2698 esize
= ComplexStructMemorySize(pStubMsg
, pFormat
);
2699 pStubMsg
->Buffer
= Buffer
;
2701 MemorySize
= safe_multiply(pStubMsg
->MaxCount
, esize
);
2703 count
= pStubMsg
->ActualCount
;
2704 for (i
= 0; i
< count
; i
++)
2705 ComplexStructMemorySize(pStubMsg
, pFormat
);
2707 pStubMsg
->MemorySize
= SavedMemorySize
;
2709 pStubMsg
->MemorySize
+= MemorySize
;
2713 /***********************************************************************
2714 * NdrComplexArrayFree [RPCRT4.@]
2716 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
2717 unsigned char *pMemory
,
2718 PFORMAT_STRING pFormat
)
2720 ULONG i
, count
, def
;
2722 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2724 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
2726 ERR("invalid format type %x\n", pFormat
[0]);
2727 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2731 def
= *(const WORD
*)&pFormat
[2];
2734 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
2735 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
2737 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
2738 TRACE("variance = %d\n", pStubMsg
->ActualCount
);
2740 count
= pStubMsg
->ActualCount
;
2741 for (i
= 0; i
< count
; i
++)
2742 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
2745 static ULONG
UserMarshalFlags(PMIDL_STUB_MESSAGE pStubMsg
)
2747 return MAKELONG(pStubMsg
->dwDestContext
,
2748 pStubMsg
->RpcMsg
->DataRepresentation
);
2751 #define USER_MARSHAL_PTR_PREFIX \
2752 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
2753 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
2755 /***********************************************************************
2756 * NdrUserMarshalMarshall [RPCRT4.@]
2758 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2759 unsigned char *pMemory
,
2760 PFORMAT_STRING pFormat
)
2762 unsigned flags
= pFormat
[1];
2763 unsigned index
= *(const WORD
*)&pFormat
[2];
2764 ULONG uflag
= UserMarshalFlags(pStubMsg
);
2765 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2766 TRACE("index=%d\n", index
);
2768 if (flags
& USER_MARSHAL_POINTER
)
2770 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2771 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, USER_MARSHAL_PTR_PREFIX
);
2772 pStubMsg
->Buffer
+= 4;
2773 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
2776 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
2779 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
2780 &uflag
, pStubMsg
->Buffer
, pMemory
);
2782 STD_OVERFLOW_CHECK(pStubMsg
);
2787 /***********************************************************************
2788 * NdrUserMarshalUnmarshall [RPCRT4.@]
2790 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2791 unsigned char **ppMemory
,
2792 PFORMAT_STRING pFormat
,
2793 unsigned char fMustAlloc
)
2795 unsigned flags
= pFormat
[1];
2796 unsigned index
= *(const WORD
*)&pFormat
[2];
2797 DWORD memsize
= *(const WORD
*)&pFormat
[4];
2798 ULONG uflag
= UserMarshalFlags(pStubMsg
);
2799 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2800 TRACE("index=%d\n", index
);
2802 if (flags
& USER_MARSHAL_POINTER
)
2804 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2805 /* skip pointer prefix */
2806 pStubMsg
->Buffer
+= 4;
2807 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
2810 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
2812 if (fMustAlloc
|| !*ppMemory
)
2813 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2816 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
2817 &uflag
, pStubMsg
->Buffer
, *ppMemory
);
2822 /***********************************************************************
2823 * NdrUserMarshalBufferSize [RPCRT4.@]
2825 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2826 unsigned char *pMemory
,
2827 PFORMAT_STRING pFormat
)
2829 unsigned flags
= pFormat
[1];
2830 unsigned index
= *(const WORD
*)&pFormat
[2];
2831 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
2832 ULONG uflag
= UserMarshalFlags(pStubMsg
);
2833 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2834 TRACE("index=%d\n", index
);
2836 if (flags
& USER_MARSHAL_POINTER
)
2838 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
2839 /* skip pointer prefix */
2840 pStubMsg
->BufferLength
+= 4;
2841 ALIGN_LENGTH(pStubMsg
->BufferLength
, 8);
2844 ALIGN_LENGTH(pStubMsg
->BufferLength
, (flags
& 0xf) + 1);
2847 TRACE("size=%d\n", bufsize
);
2848 pStubMsg
->BufferLength
+= bufsize
;
2852 pStubMsg
->BufferLength
=
2853 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
2854 &uflag
, pStubMsg
->BufferLength
, pMemory
);
2857 /***********************************************************************
2858 * NdrUserMarshalMemorySize [RPCRT4.@]
2860 ULONG WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2861 PFORMAT_STRING pFormat
)
2863 unsigned flags
= pFormat
[1];
2864 unsigned index
= *(const WORD
*)&pFormat
[2];
2865 DWORD memsize
= *(const WORD
*)&pFormat
[4];
2866 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
2868 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2869 TRACE("index=%d\n", index
);
2871 pStubMsg
->MemorySize
+= memsize
;
2873 if (flags
& USER_MARSHAL_POINTER
)
2875 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2876 /* skip pointer prefix */
2877 pStubMsg
->Buffer
+= 4;
2878 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
2881 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
2883 pStubMsg
->Buffer
+= bufsize
;
2885 return pStubMsg
->MemorySize
;
2888 /***********************************************************************
2889 * NdrUserMarshalFree [RPCRT4.@]
2891 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
2892 unsigned char *pMemory
,
2893 PFORMAT_STRING pFormat
)
2895 /* unsigned flags = pFormat[1]; */
2896 unsigned index
= *(const WORD
*)&pFormat
[2];
2897 ULONG uflag
= UserMarshalFlags(pStubMsg
);
2898 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2899 TRACE("index=%d\n", index
);
2901 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
2905 /***********************************************************************
2906 * NdrClearOutParameters [RPCRT4.@]
2908 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
2909 PFORMAT_STRING pFormat
,
2912 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
2915 /***********************************************************************
2916 * NdrConvert [RPCRT4.@]
2918 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
2920 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
2921 /* FIXME: since this stub doesn't do any converting, the proper behavior
2922 is to raise an exception */
2925 /***********************************************************************
2926 * NdrConvert2 [RPCRT4.@]
2928 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, LONG NumberParams
)
2930 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
2931 pStubMsg
, pFormat
, NumberParams
);
2932 /* FIXME: since this stub doesn't do any converting, the proper behavior
2933 is to raise an exception */
2936 typedef struct _NDR_CSTRUCT_FORMAT
2939 unsigned char alignment
;
2940 unsigned short memory_size
;
2941 short offset_to_array_description
;
2942 } NDR_CSTRUCT_FORMAT
, NDR_CVSTRUCT_FORMAT
;
2944 /***********************************************************************
2945 * NdrConformantStructMarshall [RPCRT4.@]
2947 unsigned char * WINAPI
NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2948 unsigned char *pMemory
,
2949 PFORMAT_STRING pFormat
)
2951 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
2952 PFORMAT_STRING pCArrayFormat
;
2953 ULONG esize
, bufsize
;
2955 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
2957 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
2958 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
2960 ERR("invalid format type %x\n", pCStructFormat
->type
);
2961 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2965 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
2966 pCStructFormat
->offset_to_array_description
;
2967 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
2969 ERR("invalid array format type %x\n", pCStructFormat
->type
);
2970 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2973 esize
= *(const WORD
*)(pCArrayFormat
+2);
2975 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
2976 pCArrayFormat
+ 4, 0);
2978 WriteConformance(pStubMsg
);
2980 ALIGN_POINTER(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
2982 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
2984 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2985 /* copy constant sized part of struct */
2986 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2987 memcpy(pStubMsg
->Buffer
, pMemory
, pCStructFormat
->memory_size
+ bufsize
);
2988 pStubMsg
->Buffer
+= pCStructFormat
->memory_size
+ bufsize
;
2990 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
2991 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2993 STD_OVERFLOW_CHECK(pStubMsg
);
2998 /***********************************************************************
2999 * NdrConformantStructUnmarshall [RPCRT4.@]
3001 unsigned char * WINAPI
NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3002 unsigned char **ppMemory
,
3003 PFORMAT_STRING pFormat
,
3004 unsigned char fMustAlloc
)
3006 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3007 PFORMAT_STRING pCArrayFormat
;
3008 ULONG esize
, bufsize
;
3010 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3012 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3013 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3015 ERR("invalid format type %x\n", pCStructFormat
->type
);
3016 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3019 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3020 pCStructFormat
->offset_to_array_description
;
3021 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3023 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3024 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3027 esize
= *(const WORD
*)(pCArrayFormat
+2);
3029 pCArrayFormat
= ReadConformance(pStubMsg
, pCArrayFormat
+ 4);
3031 ALIGN_POINTER(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
3033 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3035 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3036 /* work out how much memory to allocate if we need to do so */
3037 if (!*ppMemory
|| fMustAlloc
)
3039 SIZE_T size
= pCStructFormat
->memory_size
+ bufsize
;
3040 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3043 /* now copy the data */
3044 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3045 memcpy(*ppMemory
, pStubMsg
->Buffer
, pCStructFormat
->memory_size
+ bufsize
);
3046 pStubMsg
->Buffer
+= pCStructFormat
->memory_size
+ bufsize
;
3048 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3049 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3054 /***********************************************************************
3055 * NdrConformantStructBufferSize [RPCRT4.@]
3057 void WINAPI
NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3058 unsigned char *pMemory
,
3059 PFORMAT_STRING pFormat
)
3061 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3062 PFORMAT_STRING pCArrayFormat
;
3065 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3067 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3068 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3070 ERR("invalid format type %x\n", pCStructFormat
->type
);
3071 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3074 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3075 pCStructFormat
->offset_to_array_description
;
3076 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3078 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3079 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3082 esize
= *(const WORD
*)(pCArrayFormat
+2);
3084 pCArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
, pCArrayFormat
+4, 0);
3085 SizeConformance(pStubMsg
);
3087 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCStructFormat
->alignment
+ 1);
3089 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3091 pStubMsg
->BufferLength
+= pCStructFormat
->memory_size
+
3092 safe_multiply(pStubMsg
->MaxCount
, esize
);
3094 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3095 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3098 /***********************************************************************
3099 * NdrConformantStructMemorySize [RPCRT4.@]
3101 ULONG WINAPI
NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3102 PFORMAT_STRING pFormat
)
3108 /***********************************************************************
3109 * NdrConformantStructFree [RPCRT4.@]
3111 void WINAPI
NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3112 unsigned char *pMemory
,
3113 PFORMAT_STRING pFormat
)
3118 /***********************************************************************
3119 * NdrConformantVaryingStructMarshall [RPCRT4.@]
3121 unsigned char * WINAPI
NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3122 unsigned char *pMemory
,
3123 PFORMAT_STRING pFormat
)
3125 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3126 PFORMAT_STRING pCVArrayFormat
;
3127 ULONG esize
, bufsize
;
3129 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3131 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3132 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3134 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3135 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3139 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3140 pCVStructFormat
->offset_to_array_description
;
3141 switch (*pCVArrayFormat
)
3143 case RPC_FC_CVARRAY
:
3144 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3146 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3147 pCVArrayFormat
+ 4, 0);
3148 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3151 case RPC_FC_C_CSTRING
:
3152 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
3153 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
3154 esize
= sizeof(char);
3155 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3156 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3157 pCVArrayFormat
+ 2, 0);
3159 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3161 case RPC_FC_C_WSTRING
:
3162 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
3163 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
3164 esize
= sizeof(WCHAR
);
3165 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3166 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3167 pCVArrayFormat
+ 2, 0);
3169 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3172 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3173 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3177 WriteConformance(pStubMsg
);
3179 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
3181 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3183 /* write constant sized part */
3184 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3185 memcpy(pStubMsg
->Buffer
, pMemory
, pCVStructFormat
->memory_size
);
3186 pStubMsg
->Buffer
+= pCVStructFormat
->memory_size
;
3188 WriteVariance(pStubMsg
);
3190 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3192 /* write array part */
3193 memcpy(pStubMsg
->Buffer
, pMemory
+ pCVStructFormat
->memory_size
, bufsize
);
3194 pStubMsg
->Buffer
+= bufsize
;
3196 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3198 STD_OVERFLOW_CHECK(pStubMsg
);
3203 /***********************************************************************
3204 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3206 unsigned char * WINAPI
NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3207 unsigned char **ppMemory
,
3208 PFORMAT_STRING pFormat
,
3209 unsigned char fMustAlloc
)
3211 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3212 PFORMAT_STRING pCVArrayFormat
;
3213 ULONG esize
, bufsize
;
3214 unsigned char cvarray_type
;
3216 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3218 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3219 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3221 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3222 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3226 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3227 pCVStructFormat
->offset_to_array_description
;
3228 cvarray_type
= *pCVArrayFormat
;
3229 switch (cvarray_type
)
3231 case RPC_FC_CVARRAY
:
3232 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3233 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 4);
3235 case RPC_FC_C_CSTRING
:
3236 esize
= sizeof(char);
3237 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3238 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3240 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3242 case RPC_FC_C_WSTRING
:
3243 esize
= sizeof(WCHAR
);
3244 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3245 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3247 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3250 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3251 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3255 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
3257 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3259 /* work out how much memory to allocate if we need to do so */
3260 if (!*ppMemory
|| fMustAlloc
)
3262 SIZE_T size
= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->MaxCount
);
3263 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3266 /* copy the constant data */
3267 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3268 memcpy(*ppMemory
, pStubMsg
->Buffer
, pCVStructFormat
->memory_size
);
3269 pStubMsg
->Buffer
+= pCVStructFormat
->memory_size
;
3271 pCVArrayFormat
= ReadVariance(pStubMsg
, pCVArrayFormat
, pStubMsg
->MaxCount
);
3273 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3275 if ((cvarray_type
== RPC_FC_C_CSTRING
) ||
3276 (cvarray_type
== RPC_FC_C_WSTRING
))
3279 /* strings must always have null terminating bytes */
3280 if (bufsize
< esize
)
3282 ERR("invalid string length of %d\n", pStubMsg
->ActualCount
);
3283 RpcRaiseException(RPC_S_INVALID_BOUND
);
3286 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
3287 if (pStubMsg
->Buffer
[i
] != 0)
3289 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
3290 i
, pStubMsg
->Buffer
[i
]);
3291 RpcRaiseException(RPC_S_INVALID_BOUND
);
3296 /* copy the array data */
3297 memcpy(*ppMemory
+ pCVStructFormat
->memory_size
, pStubMsg
->Buffer
,
3299 pStubMsg
->Buffer
+= bufsize
;
3301 if (cvarray_type
== RPC_FC_C_CSTRING
)
3302 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory
+ pCVStructFormat
->memory_size
)));
3303 else if (cvarray_type
== RPC_FC_C_WSTRING
)
3304 TRACE("string=%s\n", debugstr_w((WCHAR
*)(*ppMemory
+ pCVStructFormat
->memory_size
)));
3306 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3311 /***********************************************************************
3312 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3314 void WINAPI
NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3315 unsigned char *pMemory
,
3316 PFORMAT_STRING pFormat
)
3318 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3319 PFORMAT_STRING pCVArrayFormat
;
3322 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3324 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3325 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3327 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3328 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3332 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3333 pCVStructFormat
->offset_to_array_description
;
3334 switch (*pCVArrayFormat
)
3336 case RPC_FC_CVARRAY
:
3337 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3339 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3340 pCVArrayFormat
+ 4, 0);
3341 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3344 case RPC_FC_C_CSTRING
:
3345 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
3346 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
3347 esize
= sizeof(char);
3348 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3349 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3350 pCVArrayFormat
+ 2, 0);
3352 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3354 case RPC_FC_C_WSTRING
:
3355 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
3356 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
3357 esize
= sizeof(WCHAR
);
3358 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3359 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3360 pCVArrayFormat
+ 2, 0);
3362 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3365 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3366 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3370 SizeConformance(pStubMsg
);
3372 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCVStructFormat
->alignment
+ 1);
3374 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3376 pStubMsg
->BufferLength
+= pCVStructFormat
->memory_size
;
3377 SizeVariance(pStubMsg
);
3378 pStubMsg
->BufferLength
+= safe_multiply(pStubMsg
->MaxCount
, esize
);
3380 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3383 /***********************************************************************
3384 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
3386 ULONG WINAPI
NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3387 PFORMAT_STRING pFormat
)
3389 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3390 PFORMAT_STRING pCVArrayFormat
;
3392 unsigned char cvarray_type
;
3394 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
3396 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3397 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3399 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3400 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3404 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3405 pCVStructFormat
->offset_to_array_description
;
3406 cvarray_type
= *pCVArrayFormat
;
3407 switch (cvarray_type
)
3409 case RPC_FC_CVARRAY
:
3410 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3411 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 4);
3413 case RPC_FC_C_CSTRING
:
3414 esize
= sizeof(char);
3415 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3416 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3418 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3420 case RPC_FC_C_WSTRING
:
3421 esize
= sizeof(WCHAR
);
3422 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3423 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3425 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3428 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3429 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3433 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
3435 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3437 pStubMsg
->Buffer
+= pCVStructFormat
->memory_size
;
3438 pCVArrayFormat
= ReadVariance(pStubMsg
, pCVArrayFormat
, pStubMsg
->MaxCount
);
3439 pStubMsg
->Buffer
+= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->ActualCount
);
3441 pStubMsg
->MemorySize
+= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->MaxCount
);
3443 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
3445 return pCVStructFormat
->memory_size
+ pStubMsg
->MaxCount
* esize
;
3448 /***********************************************************************
3449 * NdrConformantVaryingStructFree [RPCRT4.@]
3451 void WINAPI
NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3452 unsigned char *pMemory
,
3453 PFORMAT_STRING pFormat
)
3455 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3456 PFORMAT_STRING pCVArrayFormat
;
3459 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3461 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3462 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3464 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3465 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3469 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3470 pCVStructFormat
->offset_to_array_description
;
3471 switch (*pCVArrayFormat
)
3473 case RPC_FC_CVARRAY
:
3474 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3476 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3477 pCVArrayFormat
+ 4, 0);
3478 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3481 case RPC_FC_C_CSTRING
:
3482 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
3483 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
3484 esize
= sizeof(char);
3485 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3486 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3487 pCVArrayFormat
+ 2, 0);
3489 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3491 case RPC_FC_C_WSTRING
:
3492 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
3493 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
3494 esize
= sizeof(WCHAR
);
3495 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3496 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3497 pCVArrayFormat
+ 2, 0);
3499 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3502 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3503 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3507 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3509 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
3515 unsigned char alignment
;
3516 unsigned short total_size
;
3517 } NDR_SMFARRAY_FORMAT
;
3522 unsigned char alignment
;
3523 unsigned long total_size
;
3524 } NDR_LGFARRAY_FORMAT
;
3526 /***********************************************************************
3527 * NdrFixedArrayMarshall [RPCRT4.@]
3529 unsigned char * WINAPI
NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3530 unsigned char *pMemory
,
3531 PFORMAT_STRING pFormat
)
3533 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
3534 unsigned long total_size
;
3536 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3538 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
3539 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
3541 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
3542 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3546 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
3548 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
3550 total_size
= pSmFArrayFormat
->total_size
;
3551 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
3555 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
3556 total_size
= pLgFArrayFormat
->total_size
;
3557 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
3560 memcpy(pStubMsg
->Buffer
, pMemory
, total_size
);
3561 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3562 pStubMsg
->Buffer
+= total_size
;
3564 pFormat
= EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3569 /***********************************************************************
3570 * NdrFixedArrayUnmarshall [RPCRT4.@]
3572 unsigned char * WINAPI
NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3573 unsigned char **ppMemory
,
3574 PFORMAT_STRING pFormat
,
3575 unsigned char fMustAlloc
)
3577 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
3578 unsigned long total_size
;
3580 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3582 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
3583 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
3585 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
3586 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3590 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
3592 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
3594 total_size
= pSmFArrayFormat
->total_size
;
3595 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
3599 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
3600 total_size
= pLgFArrayFormat
->total_size
;
3601 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
3604 if (fMustAlloc
|| !*ppMemory
)
3605 *ppMemory
= NdrAllocate(pStubMsg
, total_size
);
3606 memcpy(*ppMemory
, pStubMsg
->Buffer
, total_size
);
3607 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3608 pStubMsg
->Buffer
+= total_size
;
3610 pFormat
= EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3615 /***********************************************************************
3616 * NdrFixedArrayBufferSize [RPCRT4.@]
3618 void WINAPI
NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3619 unsigned char *pMemory
,
3620 PFORMAT_STRING pFormat
)
3622 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
3623 unsigned long total_size
;
3625 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3627 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
3628 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
3630 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
3631 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3635 ALIGN_LENGTH(pStubMsg
->BufferLength
, pSmFArrayFormat
->alignment
+ 1);
3637 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
3639 total_size
= pSmFArrayFormat
->total_size
;
3640 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
3644 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
3645 total_size
= pLgFArrayFormat
->total_size
;
3646 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
3648 pStubMsg
->BufferLength
+= total_size
;
3650 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3653 /***********************************************************************
3654 * NdrFixedArrayMemorySize [RPCRT4.@]
3656 ULONG WINAPI
NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3657 PFORMAT_STRING pFormat
)
3659 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
3662 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
3664 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
3665 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
3667 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
3668 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3672 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
3674 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
3676 total_size
= pSmFArrayFormat
->total_size
;
3677 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
3681 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
3682 total_size
= pLgFArrayFormat
->total_size
;
3683 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
3685 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3686 pStubMsg
->Buffer
+= total_size
;
3687 pStubMsg
->MemorySize
+= total_size
;
3689 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
3694 /***********************************************************************
3695 * NdrFixedArrayFree [RPCRT4.@]
3697 void WINAPI
NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3698 unsigned char *pMemory
,
3699 PFORMAT_STRING pFormat
)
3701 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
3703 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3705 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
3706 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
3708 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
3709 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3713 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
3714 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
3717 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
3718 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
3721 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
3724 /***********************************************************************
3725 * NdrVaryingArrayMarshall [RPCRT4.@]
3727 unsigned char * WINAPI
NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3728 unsigned char *pMemory
,
3729 PFORMAT_STRING pFormat
)
3731 unsigned char alignment
;
3732 DWORD elements
, esize
;
3735 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3737 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
3738 (pFormat
[0] != RPC_FC_LGVARRAY
))
3740 ERR("invalid format type %x\n", pFormat
[0]);
3741 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3745 alignment
= pFormat
[1] + 1;
3747 if (pFormat
[0] == RPC_FC_SMVARRAY
)
3750 pFormat
+= sizeof(WORD
);
3751 elements
= *(const WORD
*)pFormat
;
3752 pFormat
+= sizeof(WORD
);
3757 pFormat
+= sizeof(DWORD
);
3758 elements
= *(const DWORD
*)pFormat
;
3759 pFormat
+= sizeof(DWORD
);
3762 esize
= *(const WORD
*)pFormat
;
3763 pFormat
+= sizeof(WORD
);
3765 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
3766 if ((pStubMsg
->ActualCount
> elements
) ||
3767 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
3769 RpcRaiseException(RPC_S_INVALID_BOUND
);
3773 WriteVariance(pStubMsg
);
3775 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3777 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3778 memcpy(pStubMsg
->Buffer
, pMemory
+ pStubMsg
->Offset
, bufsize
);
3779 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3780 pStubMsg
->Buffer
+= bufsize
;
3782 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3784 STD_OVERFLOW_CHECK(pStubMsg
);
3789 /***********************************************************************
3790 * NdrVaryingArrayUnmarshall [RPCRT4.@]
3792 unsigned char * WINAPI
NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3793 unsigned char **ppMemory
,
3794 PFORMAT_STRING pFormat
,
3795 unsigned char fMustAlloc
)
3797 unsigned char alignment
;
3798 DWORD size
, elements
, esize
;
3801 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3803 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
3804 (pFormat
[0] != RPC_FC_LGVARRAY
))
3806 ERR("invalid format type %x\n", pFormat
[0]);
3807 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3811 alignment
= pFormat
[1] + 1;
3813 if (pFormat
[0] == RPC_FC_SMVARRAY
)
3816 size
= *(const WORD
*)pFormat
;
3817 pFormat
+= sizeof(WORD
);
3818 elements
= *(const WORD
*)pFormat
;
3819 pFormat
+= sizeof(WORD
);
3824 size
= *(const DWORD
*)pFormat
;
3825 pFormat
+= sizeof(DWORD
);
3826 elements
= *(const DWORD
*)pFormat
;
3827 pFormat
+= sizeof(DWORD
);
3830 esize
= *(const WORD
*)pFormat
;
3831 pFormat
+= sizeof(WORD
);
3833 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
3835 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3837 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3839 if (!*ppMemory
|| fMustAlloc
)
3840 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3841 memcpy(*ppMemory
+ pStubMsg
->Offset
, pStubMsg
->Buffer
, bufsize
);
3842 pStubMsg
->Buffer
+= bufsize
;
3844 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3849 /***********************************************************************
3850 * NdrVaryingArrayBufferSize [RPCRT4.@]
3852 void WINAPI
NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3853 unsigned char *pMemory
,
3854 PFORMAT_STRING pFormat
)
3856 unsigned char alignment
;
3857 DWORD elements
, esize
;
3859 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3861 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
3862 (pFormat
[0] != RPC_FC_LGVARRAY
))
3864 ERR("invalid format type %x\n", pFormat
[0]);
3865 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3869 alignment
= pFormat
[1] + 1;
3871 if (pFormat
[0] == RPC_FC_SMVARRAY
)
3874 pFormat
+= sizeof(WORD
);
3875 elements
= *(const WORD
*)pFormat
;
3876 pFormat
+= sizeof(WORD
);
3881 pFormat
+= sizeof(DWORD
);
3882 elements
= *(const DWORD
*)pFormat
;
3883 pFormat
+= sizeof(DWORD
);
3886 esize
= *(const WORD
*)pFormat
;
3887 pFormat
+= sizeof(WORD
);
3889 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
3890 if ((pStubMsg
->ActualCount
> elements
) ||
3891 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
3893 RpcRaiseException(RPC_S_INVALID_BOUND
);
3897 SizeVariance(pStubMsg
);
3899 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
3901 pStubMsg
->BufferLength
+= safe_multiply(esize
, pStubMsg
->ActualCount
);
3903 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3906 /***********************************************************************
3907 * NdrVaryingArrayMemorySize [RPCRT4.@]
3909 ULONG WINAPI
NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3910 PFORMAT_STRING pFormat
)
3912 unsigned char alignment
;
3913 DWORD size
, elements
, esize
;
3915 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
3917 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
3918 (pFormat
[0] != RPC_FC_LGVARRAY
))
3920 ERR("invalid format type %x\n", pFormat
[0]);
3921 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3925 alignment
= pFormat
[1] + 1;
3927 if (pFormat
[0] == RPC_FC_SMVARRAY
)
3930 size
= *(const WORD
*)pFormat
;
3931 pFormat
+= sizeof(WORD
);
3932 elements
= *(const WORD
*)pFormat
;
3933 pFormat
+= sizeof(WORD
);
3938 size
= *(const DWORD
*)pFormat
;
3939 pFormat
+= sizeof(DWORD
);
3940 elements
= *(const DWORD
*)pFormat
;
3941 pFormat
+= sizeof(DWORD
);
3944 esize
= *(const WORD
*)pFormat
;
3945 pFormat
+= sizeof(WORD
);
3947 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
3949 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3951 pStubMsg
->Buffer
+= safe_multiply(esize
, pStubMsg
->ActualCount
);
3952 pStubMsg
->MemorySize
+= size
;
3954 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
3956 return pStubMsg
->MemorySize
;
3959 /***********************************************************************
3960 * NdrVaryingArrayFree [RPCRT4.@]
3962 void WINAPI
NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3963 unsigned char *pMemory
,
3964 PFORMAT_STRING pFormat
)
3966 unsigned char alignment
;
3969 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3971 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
3972 (pFormat
[0] != RPC_FC_LGVARRAY
))
3974 ERR("invalid format type %x\n", pFormat
[0]);
3975 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3979 alignment
= pFormat
[1] + 1;
3981 if (pFormat
[0] == RPC_FC_SMVARRAY
)
3984 pFormat
+= sizeof(WORD
);
3985 elements
= *(const WORD
*)pFormat
;
3986 pFormat
+= sizeof(WORD
);
3991 pFormat
+= sizeof(DWORD
);
3992 elements
= *(const DWORD
*)pFormat
;
3993 pFormat
+= sizeof(DWORD
);
3996 pFormat
+= sizeof(WORD
);
3998 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
3999 if ((pStubMsg
->ActualCount
> elements
) ||
4000 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4002 RpcRaiseException(RPC_S_INVALID_BOUND
);
4006 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4009 /***********************************************************************
4010 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
4012 unsigned char * WINAPI
NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4013 unsigned char *pMemory
,
4014 PFORMAT_STRING pFormat
)
4020 /***********************************************************************
4021 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
4023 unsigned char * WINAPI
NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4024 unsigned char **ppMemory
,
4025 PFORMAT_STRING pFormat
,
4026 unsigned char fMustAlloc
)
4032 /***********************************************************************
4033 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
4035 void WINAPI
NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4036 unsigned char *pMemory
,
4037 PFORMAT_STRING pFormat
)
4042 /***********************************************************************
4043 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
4045 ULONG WINAPI
NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4046 PFORMAT_STRING pFormat
)
4052 /***********************************************************************
4053 * NdrEncapsulatedUnionFree [RPCRT4.@]
4055 void WINAPI
NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
4056 unsigned char *pMemory
,
4057 PFORMAT_STRING pFormat
)
4062 static PFORMAT_STRING
get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg
,
4063 unsigned long discriminant
,
4064 PFORMAT_STRING pFormat
)
4066 unsigned short num_arms
, arm
, type
;
4068 num_arms
= *(const SHORT
*)pFormat
& 0x0fff;
4070 for(arm
= 0; arm
< num_arms
; arm
++)
4072 if(discriminant
== *(const ULONG
*)pFormat
)
4080 type
= *(const unsigned short*)pFormat
;
4081 TRACE("type %04x\n", type
);
4082 if(arm
== num_arms
) /* default arm extras */
4086 ERR("no arm for 0x%lx and no default case\n", discriminant
);
4087 RpcRaiseException(RPC_S_INVALID_TAG
);
4092 TRACE("falling back to empty default case for 0x%lx\n", discriminant
);
4099 static PFORMAT_STRING
get_non_encapsulated_union_arm(PMIDL_STUB_MESSAGE pStubMsg
,
4101 PFORMAT_STRING pFormat
)
4103 pFormat
+= *(const SHORT
*)pFormat
;
4106 return get_arm_offset_from_union_arm_selector(pStubMsg
, value
, pFormat
);
4109 /***********************************************************************
4110 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
4112 unsigned char * WINAPI
NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4113 unsigned char *pMemory
,
4114 PFORMAT_STRING pFormat
)
4116 unsigned short type
;
4117 unsigned char switch_type
;
4119 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4122 switch_type
= *pFormat
;
4125 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
4126 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
4127 /* Marshall discriminant */
4128 NdrBaseTypeMarshall(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
4130 pFormat
= get_non_encapsulated_union_arm(pStubMsg
, pStubMsg
->MaxCount
, pFormat
);
4134 type
= *(const unsigned short*)pFormat
;
4135 if((type
& 0xff00) == 0x8000)
4137 unsigned char basetype
= LOBYTE(type
);
4138 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &basetype
);
4142 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4143 NDR_MARSHALL m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
4146 unsigned char *saved_buffer
= NULL
;
4153 saved_buffer
= pStubMsg
->Buffer
;
4154 pStubMsg
->Buffer
+= 4; /* for pointer ID */
4155 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char **)pMemory
, desc
);
4158 m(pStubMsg
, pMemory
, desc
);
4161 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4166 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg
,
4167 PFORMAT_STRING
*ppFormat
)
4169 long discriminant
= 0;
4177 discriminant
= *(UCHAR
*)pStubMsg
->Buffer
;
4178 pStubMsg
->Buffer
+= sizeof(UCHAR
);
4183 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
4184 discriminant
= *(USHORT
*)pStubMsg
->Buffer
;
4185 pStubMsg
->Buffer
+= sizeof(USHORT
);
4189 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
4190 discriminant
= *(ULONG
*)pStubMsg
->Buffer
;
4191 pStubMsg
->Buffer
+= sizeof(ULONG
);
4194 FIXME("Unhandled base type: 0x%02x\n", **ppFormat
);
4198 if (pStubMsg
->fHasNewCorrDesc
)
4202 return discriminant
;
4205 /**********************************************************************
4206 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
4208 unsigned char * WINAPI
NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4209 unsigned char **ppMemory
,
4210 PFORMAT_STRING pFormat
,
4211 unsigned char fMustAlloc
)
4214 unsigned short type
, size
;
4216 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4219 /* Unmarshall discriminant */
4220 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
4221 TRACE("unmarshalled discriminant %lx\n", discriminant
);
4223 pFormat
+= *(const SHORT
*)pFormat
;
4225 size
= *(const unsigned short*)pFormat
;
4228 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4232 if(!*ppMemory
|| fMustAlloc
)
4233 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4235 type
= *(const unsigned short*)pFormat
;
4236 if((type
& 0xff00) == 0x8000)
4238 unsigned char basetype
= LOBYTE(type
);
4239 return NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &basetype
, fMustAlloc
);
4243 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4244 NDR_UNMARSHALL m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
4247 unsigned char *saved_buffer
= NULL
;
4254 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4255 saved_buffer
= pStubMsg
->Buffer
;
4256 pStubMsg
->Buffer
+= 4; /* for pointer ID */
4257 PointerUnmarshall(pStubMsg
, saved_buffer
, *(unsigned char ***)ppMemory
, desc
, TRUE
);
4260 m(pStubMsg
, ppMemory
, desc
, fMustAlloc
);
4263 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4268 /***********************************************************************
4269 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
4271 void WINAPI
NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4272 unsigned char *pMemory
,
4273 PFORMAT_STRING pFormat
)
4275 unsigned short type
;
4276 unsigned char switch_type
;
4278 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4281 switch_type
= *pFormat
;
4284 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
4285 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
4286 /* Add discriminant size */
4287 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
4289 pFormat
= get_non_encapsulated_union_arm(pStubMsg
, pStubMsg
->MaxCount
, pFormat
);
4293 type
= *(const unsigned short*)pFormat
;
4294 if((type
& 0xff00) == 0x8000)
4296 unsigned char basetype
= LOBYTE(type
);
4297 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &basetype
);
4301 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4302 NDR_BUFFERSIZE m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
4311 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
4312 pStubMsg
->BufferLength
+= 4; /* for pointer ID */
4313 PointerBufferSize(pStubMsg
, *(unsigned char **)pMemory
, desc
);
4316 m(pStubMsg
, pMemory
, desc
);
4319 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
4324 /***********************************************************************
4325 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
4327 ULONG WINAPI
NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4328 PFORMAT_STRING pFormat
)
4331 unsigned short type
, size
;
4334 /* Unmarshall discriminant */
4335 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
4336 TRACE("unmarshalled discriminant 0x%x\n", discriminant
);
4338 pFormat
+= *(const SHORT
*)pFormat
;
4340 size
= *(const unsigned short*)pFormat
;
4343 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4347 pStubMsg
->Memory
+= size
;
4349 type
= *(const unsigned short*)pFormat
;
4350 if((type
& 0xff00) == 0x8000)
4352 return NdrBaseTypeMemorySize(pStubMsg
, pFormat
);
4356 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4357 NDR_MEMORYSIZE m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
4358 unsigned char *saved_buffer
;
4367 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4368 saved_buffer
= pStubMsg
->Buffer
;
4369 pStubMsg
->Buffer
+= 4;
4370 ALIGN_LENGTH(pStubMsg
->MemorySize
, 4);
4371 pStubMsg
->MemorySize
+= 4;
4372 PointerMemorySize(pStubMsg
, saved_buffer
, pFormat
);
4375 return m(pStubMsg
, desc
);
4378 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4381 TRACE("size %d\n", size
);
4385 /***********************************************************************
4386 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
4388 void WINAPI
NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
4389 unsigned char *pMemory
,
4390 PFORMAT_STRING pFormat
)
4395 /***********************************************************************
4396 * NdrByteCountPointerMarshall [RPCRT4.@]
4398 unsigned char * WINAPI
NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4399 unsigned char *pMemory
,
4400 PFORMAT_STRING pFormat
)
4406 /***********************************************************************
4407 * NdrByteCountPointerUnmarshall [RPCRT4.@]
4409 unsigned char * WINAPI
NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4410 unsigned char **ppMemory
,
4411 PFORMAT_STRING pFormat
,
4412 unsigned char fMustAlloc
)
4418 /***********************************************************************
4419 * NdrByteCountPointerBufferSize [RPCRT4.@]
4421 void WINAPI
NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4422 unsigned char *pMemory
,
4423 PFORMAT_STRING pFormat
)
4428 /***********************************************************************
4429 * NdrByteCountPointerMemorySize [RPCRT4.@]
4431 ULONG WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4432 PFORMAT_STRING pFormat
)
4438 /***********************************************************************
4439 * NdrByteCountPointerFree [RPCRT4.@]
4441 void WINAPI
NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
4442 unsigned char *pMemory
,
4443 PFORMAT_STRING pFormat
)
4448 /***********************************************************************
4449 * NdrXmitOrRepAsMarshall [RPCRT4.@]
4451 unsigned char * WINAPI
NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4452 unsigned char *pMemory
,
4453 PFORMAT_STRING pFormat
)
4459 /***********************************************************************
4460 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
4462 unsigned char * WINAPI
NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4463 unsigned char **ppMemory
,
4464 PFORMAT_STRING pFormat
,
4465 unsigned char fMustAlloc
)
4471 /***********************************************************************
4472 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
4474 void WINAPI
NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4475 unsigned char *pMemory
,
4476 PFORMAT_STRING pFormat
)
4481 /***********************************************************************
4482 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
4484 ULONG WINAPI
NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4485 PFORMAT_STRING pFormat
)
4491 /***********************************************************************
4492 * NdrXmitOrRepAsFree [RPCRT4.@]
4494 void WINAPI
NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg
,
4495 unsigned char *pMemory
,
4496 PFORMAT_STRING pFormat
)
4501 /***********************************************************************
4502 * NdrBaseTypeMarshall [internal]
4504 static unsigned char *WINAPI
NdrBaseTypeMarshall(
4505 PMIDL_STUB_MESSAGE pStubMsg
,
4506 unsigned char *pMemory
,
4507 PFORMAT_STRING pFormat
)
4509 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
4517 *(UCHAR
*)pStubMsg
->Buffer
= *(UCHAR
*)pMemory
;
4518 pStubMsg
->Buffer
+= sizeof(UCHAR
);
4519 TRACE("value: 0x%02x\n", *(UCHAR
*)pMemory
);
4524 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
4525 *(USHORT
*)pStubMsg
->Buffer
= *(USHORT
*)pMemory
;
4526 pStubMsg
->Buffer
+= sizeof(USHORT
);
4527 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
4531 case RPC_FC_ERROR_STATUS_T
:
4533 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
4534 *(ULONG
*)pStubMsg
->Buffer
= *(ULONG
*)pMemory
;
4535 pStubMsg
->Buffer
+= sizeof(ULONG
);
4536 TRACE("value: 0x%08x\n", *(ULONG
*)pMemory
);
4539 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(float));
4540 *(float *)pStubMsg
->Buffer
= *(float *)pMemory
;
4541 pStubMsg
->Buffer
+= sizeof(float);
4544 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(double));
4545 *(double *)pStubMsg
->Buffer
= *(double *)pMemory
;
4546 pStubMsg
->Buffer
+= sizeof(double);
4549 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONGLONG
));
4550 *(ULONGLONG
*)pStubMsg
->Buffer
= *(ULONGLONG
*)pMemory
;
4551 pStubMsg
->Buffer
+= sizeof(ULONGLONG
);
4552 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
4555 /* only 16-bits on the wire, so do a sanity check */
4556 if (*(UINT
*)pMemory
> USHRT_MAX
)
4557 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
4558 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
4559 *(USHORT
*)pStubMsg
->Buffer
= *(UINT
*)pMemory
;
4560 pStubMsg
->Buffer
+= sizeof(USHORT
);
4561 TRACE("value: 0x%04x\n", *(UINT
*)pMemory
);
4564 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
4567 STD_OVERFLOW_CHECK(pStubMsg
);
4569 /* FIXME: what is the correct return value? */
4573 /***********************************************************************
4574 * NdrBaseTypeUnmarshall [internal]
4576 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(
4577 PMIDL_STUB_MESSAGE pStubMsg
,
4578 unsigned char **ppMemory
,
4579 PFORMAT_STRING pFormat
,
4580 unsigned char fMustAlloc
)
4582 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
4584 #define BASE_TYPE_UNMARSHALL(type) \
4585 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
4586 if (fMustAlloc || !*ppMemory) \
4587 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
4588 TRACE("*ppMemory: %p\n", *ppMemory); \
4589 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
4590 pStubMsg->Buffer += sizeof(type);
4598 BASE_TYPE_UNMARSHALL(UCHAR
);
4599 TRACE("value: 0x%02x\n", **(UCHAR
**)ppMemory
);
4604 BASE_TYPE_UNMARSHALL(USHORT
);
4605 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
4609 case RPC_FC_ERROR_STATUS_T
:
4611 BASE_TYPE_UNMARSHALL(ULONG
);
4612 TRACE("value: 0x%08x\n", **(ULONG
**)ppMemory
);
4615 BASE_TYPE_UNMARSHALL(float);
4616 TRACE("value: %f\n", **(float **)ppMemory
);
4619 BASE_TYPE_UNMARSHALL(double);
4620 TRACE("value: %f\n", **(double **)ppMemory
);
4623 BASE_TYPE_UNMARSHALL(ULONGLONG
);
4624 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG
**)ppMemory
));
4627 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
4628 if (fMustAlloc
|| !*ppMemory
)
4629 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT
));
4630 TRACE("*ppMemory: %p\n", *ppMemory
);
4631 /* 16-bits on the wire, but int in memory */
4632 **(UINT
**)ppMemory
= *(USHORT
*)pStubMsg
->Buffer
;
4633 pStubMsg
->Buffer
+= sizeof(USHORT
);
4634 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
4637 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
4639 #undef BASE_TYPE_UNMARSHALL
4641 /* FIXME: what is the correct return value? */
4646 /***********************************************************************
4647 * NdrBaseTypeBufferSize [internal]
4649 static void WINAPI
NdrBaseTypeBufferSize(
4650 PMIDL_STUB_MESSAGE pStubMsg
,
4651 unsigned char *pMemory
,
4652 PFORMAT_STRING pFormat
)
4654 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
4662 pStubMsg
->BufferLength
+= sizeof(UCHAR
);
4668 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(USHORT
));
4669 pStubMsg
->BufferLength
+= sizeof(USHORT
);
4674 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONG
));
4675 pStubMsg
->BufferLength
+= sizeof(ULONG
);
4678 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(float));
4679 pStubMsg
->BufferLength
+= sizeof(float);
4682 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(double));
4683 pStubMsg
->BufferLength
+= sizeof(double);
4686 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONGLONG
));
4687 pStubMsg
->BufferLength
+= sizeof(ULONGLONG
);
4689 case RPC_FC_ERROR_STATUS_T
:
4690 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(error_status_t
));
4691 pStubMsg
->BufferLength
+= sizeof(error_status_t
);
4694 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
4698 /***********************************************************************
4699 * NdrBaseTypeMemorySize [internal]
4701 static ULONG WINAPI
NdrBaseTypeMemorySize(
4702 PMIDL_STUB_MESSAGE pStubMsg
,
4703 PFORMAT_STRING pFormat
)
4711 pStubMsg
->Buffer
+= sizeof(UCHAR
);
4712 pStubMsg
->MemorySize
+= sizeof(UCHAR
);
4713 return sizeof(UCHAR
);
4717 pStubMsg
->Buffer
+= sizeof(USHORT
);
4718 pStubMsg
->MemorySize
+= sizeof(USHORT
);
4719 return sizeof(USHORT
);
4722 pStubMsg
->Buffer
+= sizeof(ULONG
);
4723 pStubMsg
->MemorySize
+= sizeof(ULONG
);
4724 return sizeof(ULONG
);
4726 pStubMsg
->Buffer
+= sizeof(float);
4727 pStubMsg
->MemorySize
+= sizeof(float);
4728 return sizeof(float);
4730 pStubMsg
->Buffer
+= sizeof(double);
4731 pStubMsg
->MemorySize
+= sizeof(double);
4732 return sizeof(double);
4734 pStubMsg
->Buffer
+= sizeof(ULONGLONG
);
4735 pStubMsg
->MemorySize
+= sizeof(ULONGLONG
);
4736 return sizeof(ULONGLONG
);
4737 case RPC_FC_ERROR_STATUS_T
:
4738 pStubMsg
->Buffer
+= sizeof(error_status_t
);
4739 pStubMsg
->MemorySize
+= sizeof(error_status_t
);
4740 return sizeof(error_status_t
);
4743 pStubMsg
->Buffer
+= sizeof(INT
);
4744 pStubMsg
->MemorySize
+= sizeof(INT
);
4747 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
4752 /***********************************************************************
4753 * NdrBaseTypeFree [internal]
4755 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg
,
4756 unsigned char *pMemory
,
4757 PFORMAT_STRING pFormat
)
4759 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
4764 /***********************************************************************
4765 * NdrClientContextMarshall [RPCRT4.@]
4767 void WINAPI
NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4768 NDR_CCONTEXT ContextHandle
,
4771 TRACE("(%p, %p, %d)\n", pStubMsg
, ContextHandle
, fCheck
);
4773 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4775 /* FIXME: what does fCheck do? */
4776 NDRCContextMarshall(ContextHandle
,
4779 pStubMsg
->Buffer
+= cbNDRContext
;
4782 /***********************************************************************
4783 * NdrClientContextUnmarshall [RPCRT4.@]
4785 void WINAPI
NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4786 NDR_CCONTEXT
* pContextHandle
,
4787 RPC_BINDING_HANDLE BindHandle
)
4789 TRACE("(%p, %p, %p)\n", pStubMsg
, pContextHandle
, BindHandle
);
4791 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4793 NDRCContextUnmarshall(pContextHandle
,
4796 pStubMsg
->RpcMsg
->DataRepresentation
);
4798 pStubMsg
->Buffer
+= cbNDRContext
;
4801 void WINAPI
NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4802 NDR_SCONTEXT ContextHandle
,
4803 NDR_RUNDOWN RundownRoutine
)
4805 FIXME("(%p, %p, %p): stub\n", pStubMsg
, ContextHandle
, RundownRoutine
);
4808 NDR_SCONTEXT WINAPI
NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
)
4810 FIXME("(%p): stub\n", pStubMsg
);
4814 void WINAPI
NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg
,
4815 unsigned char* pMemory
,
4816 PFORMAT_STRING pFormat
)
4818 FIXME("(%p, %p, %p): stub\n", pStubMsg
, pMemory
, pFormat
);
4821 NDR_SCONTEXT WINAPI
NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg
,
4822 PFORMAT_STRING pFormat
)
4824 FIXME("(%p, %p): stub\n", pStubMsg
, pFormat
);
4828 void WINAPI
NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4829 NDR_SCONTEXT ContextHandle
,
4830 NDR_RUNDOWN RundownRoutine
,
4831 PFORMAT_STRING pFormat
)
4833 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg
, ContextHandle
, RundownRoutine
, pFormat
);
4836 NDR_SCONTEXT WINAPI
NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4837 PFORMAT_STRING pFormat
)
4839 FIXME("(%p, %p): stub\n", pStubMsg
, pFormat
);
4843 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
4845 typedef struct ndr_context_handle
4849 } ndr_context_handle
;
4851 struct context_handle_entry
4855 RPC_BINDING_HANDLE handle
;
4856 ndr_context_handle wire_data
;
4859 static struct list context_handle_list
= LIST_INIT(context_handle_list
);
4861 static CRITICAL_SECTION ndr_context_cs
;
4862 static CRITICAL_SECTION_DEBUG ndr_context_debug
=
4864 0, 0, &ndr_context_cs
,
4865 { &ndr_context_debug
.ProcessLocksList
, &ndr_context_debug
.ProcessLocksList
},
4866 0, 0, { (DWORD_PTR
)(__FILE__
": ndr_context") }
4868 static CRITICAL_SECTION ndr_context_cs
= { &ndr_context_debug
, -1, 0, 0, 0, 0 };
4870 static struct context_handle_entry
*get_context_entry(NDR_CCONTEXT CContext
)
4872 struct context_handle_entry
*che
= (struct context_handle_entry
*) CContext
;
4874 if (che
->magic
!= NDR_CONTEXT_HANDLE_MAGIC
)
4879 static struct context_handle_entry
*context_entry_from_guid(LPGUID uuid
)
4881 struct context_handle_entry
*che
;
4882 LIST_FOR_EACH_ENTRY(che
, &context_handle_list
, struct context_handle_entry
, entry
)
4883 if (IsEqualGUID(&che
->wire_data
.uuid
, uuid
))
4888 RPC_BINDING_HANDLE WINAPI
NDRCContextBinding(NDR_CCONTEXT CContext
)
4890 struct context_handle_entry
*che
;
4891 RPC_BINDING_HANDLE handle
= NULL
;
4893 TRACE("%p\n", CContext
);
4895 EnterCriticalSection(&ndr_context_cs
);
4896 che
= get_context_entry(CContext
);
4898 handle
= che
->handle
;
4899 LeaveCriticalSection(&ndr_context_cs
);
4902 RpcRaiseException(ERROR_INVALID_HANDLE
);
4906 void WINAPI
NDRCContextMarshall(NDR_CCONTEXT CContext
, void *pBuff
)
4908 struct context_handle_entry
*che
;
4910 TRACE("%p %p\n", CContext
, pBuff
);
4914 EnterCriticalSection(&ndr_context_cs
);
4915 che
= get_context_entry(CContext
);
4916 memcpy(pBuff
, &che
->wire_data
, sizeof (ndr_context_handle
));
4917 LeaveCriticalSection(&ndr_context_cs
);
4921 ndr_context_handle
*wire_data
= (ndr_context_handle
*)pBuff
;
4922 wire_data
->attributes
= 0;
4923 wire_data
->uuid
= GUID_NULL
;
4927 static UINT
ndr_update_context_handle(NDR_CCONTEXT
*CContext
,
4928 RPC_BINDING_HANDLE hBinding
,
4929 ndr_context_handle
*chi
)
4931 struct context_handle_entry
*che
= NULL
;
4933 /* a null UUID means we should free the context handle */
4934 if (IsEqualGUID(&chi
->uuid
, &GUID_NULL
))
4938 che
= get_context_entry(*CContext
);
4940 return ERROR_INVALID_HANDLE
;
4941 list_remove(&che
->entry
);
4942 RpcBindingFree(&che
->handle
);
4943 HeapFree(GetProcessHeap(), 0, che
);
4947 /* if there's no existing entry matching the GUID, allocate one */
4948 else if (!(che
= context_entry_from_guid(&chi
->uuid
)))
4950 che
= HeapAlloc(GetProcessHeap(), 0, sizeof *che
);
4952 return ERROR_NOT_ENOUGH_MEMORY
;
4953 che
->magic
= NDR_CONTEXT_HANDLE_MAGIC
;
4954 RpcBindingCopy(hBinding
, &che
->handle
);
4955 list_add_tail(&context_handle_list
, &che
->entry
);
4956 memcpy(&che
->wire_data
, chi
, sizeof *chi
);
4961 return ERROR_SUCCESS
;
4964 /***********************************************************************
4965 * NDRCContextUnmarshall [RPCRT4.@]
4967 void WINAPI
NDRCContextUnmarshall(NDR_CCONTEXT
*CContext
,
4968 RPC_BINDING_HANDLE hBinding
,
4969 void *pBuff
, ULONG DataRepresentation
)
4973 TRACE("*%p=(%p) %p %p %08x\n",
4974 CContext
, *CContext
, hBinding
, pBuff
, DataRepresentation
);
4976 EnterCriticalSection(&ndr_context_cs
);
4977 r
= ndr_update_context_handle(CContext
, hBinding
, pBuff
);
4978 LeaveCriticalSection(&ndr_context_cs
);
4980 RpcRaiseException(r
);
4983 /***********************************************************************
4984 * NDRSContextMarshall [RPCRT4.@]
4986 void WINAPI
NDRSContextMarshall(NDR_SCONTEXT CContext
,
4988 NDR_RUNDOWN userRunDownIn
)
4990 FIXME("(%p %p %p): stub\n", CContext
, pBuff
, userRunDownIn
);
4993 /***********************************************************************
4994 * NDRSContextMarshallEx [RPCRT4.@]
4996 void WINAPI
NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding
,
4997 NDR_SCONTEXT CContext
,
4999 NDR_RUNDOWN userRunDownIn
)
5001 FIXME("(%p %p %p %p): stub\n", hBinding
, CContext
, pBuff
, userRunDownIn
);
5004 /***********************************************************************
5005 * NDRSContextMarshall2 [RPCRT4.@]
5007 void WINAPI
NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding
,
5008 NDR_SCONTEXT CContext
,
5010 NDR_RUNDOWN userRunDownIn
,
5011 void *CtxGuard
, ULONG Flags
)
5013 FIXME("(%p %p %p %p %p %u): stub\n",
5014 hBinding
, CContext
, pBuff
, userRunDownIn
, CtxGuard
, Flags
);
5017 /***********************************************************************
5018 * NDRSContextUnmarshall [RPCRT4.@]
5020 NDR_SCONTEXT WINAPI
NDRSContextUnmarshall(void *pBuff
,
5021 ULONG DataRepresentation
)
5023 FIXME("(%p %08x): stub\n", pBuff
, DataRepresentation
);
5027 /***********************************************************************
5028 * NDRSContextUnmarshallEx [RPCRT4.@]
5030 NDR_SCONTEXT WINAPI
NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding
,
5032 ULONG DataRepresentation
)
5034 FIXME("(%p %p %08x): stub\n", hBinding
, pBuff
, DataRepresentation
);
5038 /***********************************************************************
5039 * NDRSContextUnmarshall2 [RPCRT4.@]
5041 NDR_SCONTEXT WINAPI
NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding
,
5043 ULONG DataRepresentation
,
5044 void *CtxGuard
, ULONG Flags
)
5046 FIXME("(%p %p %08x %p %u): stub\n",
5047 hBinding
, pBuff
, DataRepresentation
, CtxGuard
, Flags
);