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/%ld\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 unsigned long 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 %ld\n", pStubMsg
->Offset
);
348 pStubMsg
->ActualCount
= NDR_LOCAL_UINT32_READ(pStubMsg
->Buffer
);
349 pStubMsg
->Buffer
+= 4;
350 TRACE("variance is %ld\n", pStubMsg
->ActualCount
);
352 if ((pStubMsg
->ActualCount
> MaxValue
) ||
353 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> MaxValue
))
355 ERR("invalid array bound(s): ActualCount = %ld, Offset = %ld, MaxValue = %ld\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
*pCount
)
404 BYTE dtype
= pFormat
[0] & 0xf;
405 short ofs
= *(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=%ld\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 %ld\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 unsigned long WINAPI
NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
649 PFORMAT_STRING pFormat
)
651 unsigned long rslt
= 0;
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(" --> %lu\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 %ld\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 %ld, 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 unsigned long 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 /***********************************************************************
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];
805 unsigned long pointer_id
;
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
= (unsigned long)Pointer
;
829 TRACE("writing 0x%08lx 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%08lx 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 /***********************************************************************
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%08lx\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%08lx\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%08lx\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 /***********************************************************************
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
;
949 unsigned long pointer_id
;
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 [RPCRT4.@]
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 [RPCRT4.@]
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
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
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 unsigned long 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 unsigned long WINAPI
NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1618 PFORMAT_STRING pFormat
)
1620 unsigned short size
= *(LPWORD
)(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 return *(const WORD
*)&pFormat
[2];
1656 case RPC_FC_USER_MARSHAL
:
1657 return *(const WORD
*)&pFormat
[4];
1658 case RPC_FC_NON_ENCAPSULATED_UNION
:
1660 if (pStubMsg
->fHasNewCorrDesc
)
1665 pFormat
+= *(const SHORT
*)pFormat
;
1666 return *(const SHORT
*)pFormat
;
1668 return sizeof(void *);
1670 FIXME("unhandled embedded type %02x\n", *pFormat
);
1676 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1677 PFORMAT_STRING pFormat
)
1679 NDR_MEMORYSIZE m
= NdrMemorySizer
[*pFormat
& NDR_TABLE_MASK
];
1683 FIXME("no memorysizer for data type=%02x\n", *pFormat
);
1687 return m(pStubMsg
, pFormat
);
1691 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1692 unsigned char *pMemory
,
1693 PFORMAT_STRING pFormat
,
1694 PFORMAT_STRING pPointer
)
1696 PFORMAT_STRING desc
;
1700 while (*pFormat
!= RPC_FC_END
) {
1706 TRACE("byte=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
1707 memcpy(pStubMsg
->Buffer
, pMemory
, 1);
1708 pStubMsg
->Buffer
+= 1;
1714 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
1715 memcpy(pStubMsg
->Buffer
, pMemory
, 2);
1716 pStubMsg
->Buffer
+= 2;
1722 TRACE("long=%ld <= %p\n", *(DWORD
*)pMemory
, pMemory
);
1723 memcpy(pStubMsg
->Buffer
, pMemory
, 4);
1724 pStubMsg
->Buffer
+= 4;
1728 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
1729 memcpy(pStubMsg
->Buffer
, pMemory
, 8);
1730 pStubMsg
->Buffer
+= 8;
1733 case RPC_FC_POINTER
:
1734 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
1735 NdrPointerMarshall(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
1739 case RPC_FC_ALIGNM4
:
1740 ALIGN_POINTER(pMemory
, 4);
1742 case RPC_FC_ALIGNM8
:
1743 ALIGN_POINTER(pMemory
, 8);
1745 case RPC_FC_STRUCTPAD1
:
1746 case RPC_FC_STRUCTPAD2
:
1747 case RPC_FC_STRUCTPAD3
:
1748 case RPC_FC_STRUCTPAD4
:
1749 case RPC_FC_STRUCTPAD5
:
1750 case RPC_FC_STRUCTPAD6
:
1751 case RPC_FC_STRUCTPAD7
:
1752 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
1754 case RPC_FC_EMBEDDED_COMPLEX
:
1755 pMemory
+= pFormat
[1];
1757 desc
= pFormat
+ *(const SHORT
*)pFormat
;
1758 size
= EmbeddedComplexSize(pStubMsg
, desc
);
1759 TRACE("embedded complex (size=%ld) <= %p\n", size
, pMemory
);
1760 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
1761 if (m
) m(pStubMsg
, pMemory
, desc
);
1762 else FIXME("no marshaller for embedded type %02x\n", *desc
);
1769 FIXME("unhandled format 0x%02x\n", *pFormat
);
1777 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1778 unsigned char *pMemory
,
1779 PFORMAT_STRING pFormat
,
1780 PFORMAT_STRING pPointer
)
1782 PFORMAT_STRING desc
;
1786 while (*pFormat
!= RPC_FC_END
) {
1792 memcpy(pMemory
, pStubMsg
->Buffer
, 1);
1793 TRACE("byte=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
1794 pStubMsg
->Buffer
+= 1;
1800 memcpy(pMemory
, pStubMsg
->Buffer
, 2);
1801 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
1802 pStubMsg
->Buffer
+= 2;
1808 memcpy(pMemory
, pStubMsg
->Buffer
, 4);
1809 TRACE("long=%ld => %p\n", *(DWORD
*)pMemory
, pMemory
);
1810 pStubMsg
->Buffer
+= 4;
1814 memcpy(pMemory
, pStubMsg
->Buffer
, 8);
1815 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
1816 pStubMsg
->Buffer
+= 8;
1819 case RPC_FC_POINTER
:
1820 TRACE("pointer => %p\n", pMemory
);
1821 NdrPointerUnmarshall(pStubMsg
, (unsigned char**)pMemory
, pPointer
, TRUE
);
1825 case RPC_FC_ALIGNM4
:
1826 ALIGN_POINTER(pMemory
, 4);
1828 case RPC_FC_ALIGNM8
:
1829 ALIGN_POINTER(pMemory
, 8);
1831 case RPC_FC_STRUCTPAD1
:
1832 case RPC_FC_STRUCTPAD2
:
1833 case RPC_FC_STRUCTPAD3
:
1834 case RPC_FC_STRUCTPAD4
:
1835 case RPC_FC_STRUCTPAD5
:
1836 case RPC_FC_STRUCTPAD6
:
1837 case RPC_FC_STRUCTPAD7
:
1838 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
1840 case RPC_FC_EMBEDDED_COMPLEX
:
1841 pMemory
+= pFormat
[1];
1843 desc
= pFormat
+ *(const SHORT
*)pFormat
;
1844 size
= EmbeddedComplexSize(pStubMsg
, desc
);
1845 TRACE("embedded complex (size=%ld) => %p\n", size
, pMemory
);
1846 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
1847 memset(pMemory
, 0, size
); /* just in case */
1848 if (m
) m(pStubMsg
, &pMemory
, desc
, FALSE
);
1849 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
1856 FIXME("unhandled format %d\n", *pFormat
);
1864 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1865 unsigned char *pMemory
,
1866 PFORMAT_STRING pFormat
,
1867 PFORMAT_STRING pPointer
)
1869 PFORMAT_STRING desc
;
1873 while (*pFormat
!= RPC_FC_END
) {
1879 pStubMsg
->BufferLength
+= 1;
1885 pStubMsg
->BufferLength
+= 2;
1891 pStubMsg
->BufferLength
+= 4;
1895 pStubMsg
->BufferLength
+= 8;
1898 case RPC_FC_POINTER
:
1899 NdrPointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
1903 case RPC_FC_ALIGNM4
:
1904 ALIGN_POINTER(pMemory
, 4);
1906 case RPC_FC_ALIGNM8
:
1907 ALIGN_POINTER(pMemory
, 8);
1909 case RPC_FC_STRUCTPAD1
:
1910 case RPC_FC_STRUCTPAD2
:
1911 case RPC_FC_STRUCTPAD3
:
1912 case RPC_FC_STRUCTPAD4
:
1913 case RPC_FC_STRUCTPAD5
:
1914 case RPC_FC_STRUCTPAD6
:
1915 case RPC_FC_STRUCTPAD7
:
1916 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
1918 case RPC_FC_EMBEDDED_COMPLEX
:
1919 pMemory
+= pFormat
[1];
1921 desc
= pFormat
+ *(const SHORT
*)pFormat
;
1922 size
= EmbeddedComplexSize(pStubMsg
, desc
);
1923 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
1924 if (m
) m(pStubMsg
, pMemory
, desc
);
1925 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
1932 FIXME("unhandled format 0x%02x\n", *pFormat
);
1940 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
1941 unsigned char *pMemory
,
1942 PFORMAT_STRING pFormat
,
1943 PFORMAT_STRING pPointer
)
1945 PFORMAT_STRING desc
;
1949 while (*pFormat
!= RPC_FC_END
) {
1970 case RPC_FC_POINTER
:
1971 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
1975 case RPC_FC_ALIGNM4
:
1976 ALIGN_POINTER(pMemory
, 4);
1978 case RPC_FC_ALIGNM8
:
1979 ALIGN_POINTER(pMemory
, 8);
1981 case RPC_FC_STRUCTPAD1
:
1982 case RPC_FC_STRUCTPAD2
:
1983 case RPC_FC_STRUCTPAD3
:
1984 case RPC_FC_STRUCTPAD4
:
1985 case RPC_FC_STRUCTPAD5
:
1986 case RPC_FC_STRUCTPAD6
:
1987 case RPC_FC_STRUCTPAD7
:
1988 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
1990 case RPC_FC_EMBEDDED_COMPLEX
:
1991 pMemory
+= pFormat
[1];
1993 desc
= pFormat
+ *(const SHORT
*)pFormat
;
1994 size
= EmbeddedComplexSize(pStubMsg
, desc
);
1995 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
1996 if (m
) m(pStubMsg
, pMemory
, desc
);
1997 else FIXME("no freer for embedded type %02x\n", *desc
);
2004 FIXME("unhandled format 0x%02x\n", *pFormat
);
2012 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2013 PFORMAT_STRING pFormat
)
2015 PFORMAT_STRING desc
;
2016 unsigned long size
= 0;
2018 while (*pFormat
!= RPC_FC_END
) {
2025 pStubMsg
->Buffer
+= 1;
2031 pStubMsg
->Buffer
+= 2;
2037 pStubMsg
->Buffer
+= 4;
2041 pStubMsg
->Buffer
+= 8;
2043 case RPC_FC_POINTER
:
2045 pStubMsg
->Buffer
+= 4;
2047 case RPC_FC_ALIGNM4
:
2048 ALIGN_LENGTH(size
, 4);
2049 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2051 case RPC_FC_ALIGNM8
:
2052 ALIGN_LENGTH(size
, 8);
2053 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
2055 case RPC_FC_STRUCTPAD1
:
2056 case RPC_FC_STRUCTPAD2
:
2057 case RPC_FC_STRUCTPAD3
:
2058 case RPC_FC_STRUCTPAD4
:
2059 case RPC_FC_STRUCTPAD5
:
2060 case RPC_FC_STRUCTPAD6
:
2061 case RPC_FC_STRUCTPAD7
:
2062 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2064 case RPC_FC_EMBEDDED_COMPLEX
:
2067 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2068 size
+= EmbeddedComplexMemorySize(pStubMsg
, desc
);
2074 FIXME("unhandled format 0x%02x\n", *pFormat
);
2082 /***********************************************************************
2083 * NdrComplexStructMarshall [RPCRT4.@]
2085 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2086 unsigned char *pMemory
,
2087 PFORMAT_STRING pFormat
)
2089 PFORMAT_STRING conf_array
= NULL
;
2090 PFORMAT_STRING pointer_desc
= NULL
;
2091 unsigned char *OldMemory
= pStubMsg
->Memory
;
2093 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2095 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2098 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2100 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2103 pStubMsg
->Memory
= pMemory
;
2105 ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2108 NdrConformantArrayMarshall(pStubMsg
, pMemory
, conf_array
);
2110 pStubMsg
->Memory
= OldMemory
;
2112 STD_OVERFLOW_CHECK(pStubMsg
);
2117 /***********************************************************************
2118 * NdrComplexStructUnmarshall [RPCRT4.@]
2120 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2121 unsigned char **ppMemory
,
2122 PFORMAT_STRING pFormat
,
2123 unsigned char fMustAlloc
)
2125 unsigned size
= *(const WORD
*)(pFormat
+2);
2126 PFORMAT_STRING conf_array
= NULL
;
2127 PFORMAT_STRING pointer_desc
= NULL
;
2128 unsigned char *pMemory
;
2130 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2132 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2134 if (fMustAlloc
|| !*ppMemory
)
2136 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2137 memset(*ppMemory
, 0, size
);
2141 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2143 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2146 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
);
2149 NdrConformantArrayUnmarshall(pStubMsg
, &pMemory
, conf_array
, fMustAlloc
);
2154 /***********************************************************************
2155 * NdrComplexStructBufferSize [RPCRT4.@]
2157 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2158 unsigned char *pMemory
,
2159 PFORMAT_STRING pFormat
)
2161 PFORMAT_STRING conf_array
= NULL
;
2162 PFORMAT_STRING pointer_desc
= NULL
;
2163 unsigned char *OldMemory
= pStubMsg
->Memory
;
2165 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2167 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
2170 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2172 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2175 pStubMsg
->Memory
= pMemory
;
2177 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2180 NdrConformantArrayBufferSize(pStubMsg
, pMemory
, conf_array
);
2182 pStubMsg
->Memory
= OldMemory
;
2185 /***********************************************************************
2186 * NdrComplexStructMemorySize [RPCRT4.@]
2188 unsigned long WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2189 PFORMAT_STRING pFormat
)
2191 unsigned size
= *(const WORD
*)(pFormat
+2);
2192 PFORMAT_STRING conf_array
= NULL
;
2193 PFORMAT_STRING pointer_desc
= NULL
;
2195 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2197 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2200 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2202 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2205 ComplexStructMemorySize(pStubMsg
, pFormat
);
2208 NdrConformantArrayMemorySize(pStubMsg
, conf_array
);
2213 /***********************************************************************
2214 * NdrComplexStructFree [RPCRT4.@]
2216 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
2217 unsigned char *pMemory
,
2218 PFORMAT_STRING pFormat
)
2220 PFORMAT_STRING conf_array
= NULL
;
2221 PFORMAT_STRING pointer_desc
= NULL
;
2222 unsigned char *OldMemory
= pStubMsg
->Memory
;
2224 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2227 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2229 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2232 pStubMsg
->Memory
= pMemory
;
2234 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2237 NdrConformantArrayFree(pStubMsg
, pMemory
, conf_array
);
2239 pStubMsg
->Memory
= OldMemory
;
2242 /***********************************************************************
2243 * NdrConformantArrayMarshall [RPCRT4.@]
2245 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2246 unsigned char *pMemory
,
2247 PFORMAT_STRING pFormat
)
2249 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
2250 unsigned char alignment
= pFormat
[1] + 1;
2252 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2253 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2255 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2257 WriteConformance(pStubMsg
);
2259 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2261 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2262 memcpy(pStubMsg
->Buffer
, pMemory
, size
);
2263 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2264 pStubMsg
->Buffer
+= size
;
2266 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2268 STD_OVERFLOW_CHECK(pStubMsg
);
2273 /***********************************************************************
2274 * NdrConformantArrayUnmarshall [RPCRT4.@]
2276 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2277 unsigned char **ppMemory
,
2278 PFORMAT_STRING pFormat
,
2279 unsigned char fMustAlloc
)
2281 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
2282 unsigned char alignment
= pFormat
[1] + 1;
2284 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2285 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2287 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2289 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2291 if (fMustAlloc
|| !*ppMemory
)
2292 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2294 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2296 memcpy(*ppMemory
, pStubMsg
->Buffer
, size
);
2298 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2299 pStubMsg
->Buffer
+= size
;
2301 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2306 /***********************************************************************
2307 * NdrConformantArrayBufferSize [RPCRT4.@]
2309 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2310 unsigned char *pMemory
,
2311 PFORMAT_STRING pFormat
)
2313 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
2314 unsigned char alignment
= pFormat
[1] + 1;
2316 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2317 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2319 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2321 SizeConformance(pStubMsg
);
2323 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
2325 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2326 /* conformance value plus array */
2327 pStubMsg
->BufferLength
+= size
;
2329 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
2332 /***********************************************************************
2333 * NdrConformantArrayMemorySize [RPCRT4.@]
2335 unsigned long WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2336 PFORMAT_STRING pFormat
)
2338 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
2339 unsigned char alignment
= pFormat
[1] + 1;
2341 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2342 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2344 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2345 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2346 pStubMsg
->MemorySize
+= size
;
2348 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2349 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2350 pStubMsg
->Buffer
+= size
;
2352 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2354 return pStubMsg
->MemorySize
;
2357 /***********************************************************************
2358 * NdrConformantArrayFree [RPCRT4.@]
2360 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
2361 unsigned char *pMemory
,
2362 PFORMAT_STRING pFormat
)
2364 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2365 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2367 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2371 /***********************************************************************
2372 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2374 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2375 unsigned char* pMemory
,
2376 PFORMAT_STRING pFormat
)
2379 unsigned char alignment
= pFormat
[1] + 1;
2380 DWORD esize
= *(const WORD
*)(pFormat
+2);
2382 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
2384 if (pFormat
[0] != RPC_FC_CVARRAY
)
2386 ERR("invalid format type %x\n", pFormat
[0]);
2387 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2391 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2392 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2394 WriteConformance(pStubMsg
);
2395 WriteVariance(pStubMsg
);
2397 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2399 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2401 memcpy(pStubMsg
->Buffer
, pMemory
+ pStubMsg
->Offset
, bufsize
);
2402 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2403 pStubMsg
->Buffer
+= bufsize
;
2405 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2407 STD_OVERFLOW_CHECK(pStubMsg
);
2413 /***********************************************************************
2414 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2416 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2417 unsigned char** ppMemory
,
2418 PFORMAT_STRING pFormat
,
2419 unsigned char fMustAlloc
)
2421 ULONG bufsize
, memsize
;
2422 unsigned char alignment
= pFormat
[1] + 1;
2423 DWORD esize
= *(const WORD
*)(pFormat
+2);
2425 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2427 if (pFormat
[0] != RPC_FC_CVARRAY
)
2429 ERR("invalid format type %x\n", pFormat
[0]);
2430 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2434 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2435 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2437 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2439 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2440 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2442 if (!*ppMemory
|| fMustAlloc
)
2443 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2444 memcpy(*ppMemory
+ pStubMsg
->Offset
, pStubMsg
->Buffer
, bufsize
);
2445 pStubMsg
->Buffer
+= bufsize
;
2447 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2453 /***********************************************************************
2454 * NdrConformantVaryingArrayFree [RPCRT4.@]
2456 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
2457 unsigned char* pMemory
,
2458 PFORMAT_STRING pFormat
)
2460 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2462 if (pFormat
[0] != RPC_FC_CVARRAY
)
2464 ERR("invalid format type %x\n", pFormat
[0]);
2465 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2469 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2470 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2472 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2476 /***********************************************************************
2477 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2479 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
2480 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
2482 unsigned char alignment
= pFormat
[1] + 1;
2483 DWORD esize
= *(const WORD
*)(pFormat
+2);
2485 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
2487 if (pFormat
[0] != RPC_FC_CVARRAY
)
2489 ERR("invalid format type %x\n", pFormat
[0]);
2490 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2495 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2496 /* compute length */
2497 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2499 SizeConformance(pStubMsg
);
2500 SizeVariance(pStubMsg
);
2502 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
2504 pStubMsg
->BufferLength
+= safe_multiply(esize
, pStubMsg
->ActualCount
);
2506 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
2510 /***********************************************************************
2511 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2513 unsigned long WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
2514 PFORMAT_STRING pFormat
)
2521 /***********************************************************************
2522 * NdrComplexArrayMarshall [RPCRT4.@]
2524 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2525 unsigned char *pMemory
,
2526 PFORMAT_STRING pFormat
)
2528 ULONG i
, count
, def
;
2529 BOOL variance_present
;
2530 unsigned char alignment
;
2532 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2534 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
2536 ERR("invalid format type %x\n", pFormat
[0]);
2537 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2541 alignment
= pFormat
[1] + 1;
2543 def
= *(const WORD
*)&pFormat
[2];
2546 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
2547 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
2549 variance_present
= IsConformanceOrVariancePresent(pFormat
);
2550 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
2551 TRACE("variance = %ld\n", pStubMsg
->ActualCount
);
2553 WriteConformance(pStubMsg
);
2554 if (variance_present
)
2555 WriteVariance(pStubMsg
);
2557 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2559 count
= pStubMsg
->ActualCount
;
2560 for (i
= 0; i
< count
; i
++)
2561 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
2563 STD_OVERFLOW_CHECK(pStubMsg
);
2568 /***********************************************************************
2569 * NdrComplexArrayUnmarshall [RPCRT4.@]
2571 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2572 unsigned char **ppMemory
,
2573 PFORMAT_STRING pFormat
,
2574 unsigned char fMustAlloc
)
2576 ULONG i
, count
, esize
, memsize
;
2577 unsigned char alignment
;
2578 unsigned char *pMemory
;
2579 unsigned char *Buffer
;
2581 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2583 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
2585 ERR("invalid format type %x\n", pFormat
[0]);
2586 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2590 alignment
= pFormat
[1] + 1;
2594 pFormat
= ReadConformance(pStubMsg
, pFormat
);
2595 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2597 Buffer
= pStubMsg
->Buffer
;
2598 pStubMsg
->MemorySize
= 0;
2599 esize
= ComplexStructMemorySize(pStubMsg
, pFormat
);
2600 pStubMsg
->Buffer
= Buffer
;
2602 /* do multiply here instead of inside if block to verify MaxCount */
2603 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2604 if (fMustAlloc
|| !*ppMemory
)
2606 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2607 memset(*ppMemory
, 0, memsize
);
2610 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2612 pMemory
= *ppMemory
;
2613 count
= pStubMsg
->ActualCount
;
2614 for (i
= 0; i
< count
; i
++)
2615 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
2620 /***********************************************************************
2621 * NdrComplexArrayBufferSize [RPCRT4.@]
2623 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2624 unsigned char *pMemory
,
2625 PFORMAT_STRING pFormat
)
2627 ULONG i
, count
, def
;
2628 unsigned char alignment
;
2629 BOOL variance_present
;
2631 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2633 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
2635 ERR("invalid format type %x\n", pFormat
[0]);
2636 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2640 alignment
= pFormat
[1] + 1;
2642 def
= *(const WORD
*)&pFormat
[2];
2645 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
2646 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
2647 SizeConformance(pStubMsg
);
2649 variance_present
= IsConformanceOrVariancePresent(pFormat
);
2650 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
2651 TRACE("variance = %ld\n", pStubMsg
->ActualCount
);
2653 if (variance_present
)
2654 SizeVariance(pStubMsg
);
2656 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
2658 count
= pStubMsg
->ActualCount
;
2659 for (i
= 0; i
< count
; i
++)
2660 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
2663 /***********************************************************************
2664 * NdrComplexArrayMemorySize [RPCRT4.@]
2666 unsigned long WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2667 PFORMAT_STRING pFormat
)
2669 ULONG i
, count
, esize
;
2670 unsigned char alignment
;
2671 unsigned char *Buffer
;
2672 unsigned long SavedMemorySize
;
2673 unsigned long MemorySize
;
2675 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2677 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
2679 ERR("invalid format type %x\n", pFormat
[0]);
2680 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2684 alignment
= pFormat
[1] + 1;
2688 pFormat
= ReadConformance(pStubMsg
, pFormat
);
2689 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2691 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2693 SavedMemorySize
= pStubMsg
->MemorySize
;
2695 Buffer
= pStubMsg
->Buffer
;
2696 pStubMsg
->MemorySize
= 0;
2697 esize
= ComplexStructMemorySize(pStubMsg
, pFormat
);
2698 pStubMsg
->Buffer
= Buffer
;
2700 MemorySize
= safe_multiply(pStubMsg
->MaxCount
, esize
);
2702 count
= pStubMsg
->ActualCount
;
2703 for (i
= 0; i
< count
; i
++)
2704 ComplexStructMemorySize(pStubMsg
, pFormat
);
2706 pStubMsg
->MemorySize
= SavedMemorySize
;
2708 pStubMsg
->MemorySize
+= MemorySize
;
2712 /***********************************************************************
2713 * NdrComplexArrayFree [RPCRT4.@]
2715 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
2716 unsigned char *pMemory
,
2717 PFORMAT_STRING pFormat
)
2719 ULONG i
, count
, def
;
2721 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2723 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
2725 ERR("invalid format type %x\n", pFormat
[0]);
2726 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2730 def
= *(const WORD
*)&pFormat
[2];
2733 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
2734 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
2736 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
2737 TRACE("variance = %ld\n", pStubMsg
->ActualCount
);
2739 count
= pStubMsg
->ActualCount
;
2740 for (i
= 0; i
< count
; i
++)
2741 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
2744 static unsigned long UserMarshalFlags(PMIDL_STUB_MESSAGE pStubMsg
)
2746 return MAKELONG(pStubMsg
->dwDestContext
,
2747 pStubMsg
->RpcMsg
->DataRepresentation
);
2750 #define USER_MARSHAL_PTR_PREFIX \
2751 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
2752 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
2754 /***********************************************************************
2755 * NdrUserMarshalMarshall [RPCRT4.@]
2757 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2758 unsigned char *pMemory
,
2759 PFORMAT_STRING pFormat
)
2761 unsigned flags
= pFormat
[1];
2762 unsigned index
= *(const WORD
*)&pFormat
[2];
2763 unsigned long uflag
= UserMarshalFlags(pStubMsg
);
2764 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2765 TRACE("index=%d\n", index
);
2767 if (flags
& USER_MARSHAL_POINTER
)
2769 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2770 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, USER_MARSHAL_PTR_PREFIX
);
2771 pStubMsg
->Buffer
+= 4;
2772 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
2775 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
2778 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
2779 &uflag
, pStubMsg
->Buffer
, pMemory
);
2781 STD_OVERFLOW_CHECK(pStubMsg
);
2786 /***********************************************************************
2787 * NdrUserMarshalUnmarshall [RPCRT4.@]
2789 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2790 unsigned char **ppMemory
,
2791 PFORMAT_STRING pFormat
,
2792 unsigned char fMustAlloc
)
2794 unsigned flags
= pFormat
[1];
2795 unsigned index
= *(const WORD
*)&pFormat
[2];
2796 DWORD memsize
= *(const WORD
*)&pFormat
[4];
2797 unsigned long uflag
= UserMarshalFlags(pStubMsg
);
2798 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2799 TRACE("index=%d\n", index
);
2801 if (flags
& USER_MARSHAL_POINTER
)
2803 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2804 /* skip pointer prefix */
2805 pStubMsg
->Buffer
+= 4;
2806 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
2809 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
2811 if (fMustAlloc
|| !*ppMemory
)
2812 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2815 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
2816 &uflag
, pStubMsg
->Buffer
, *ppMemory
);
2821 /***********************************************************************
2822 * NdrUserMarshalBufferSize [RPCRT4.@]
2824 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2825 unsigned char *pMemory
,
2826 PFORMAT_STRING pFormat
)
2828 unsigned flags
= pFormat
[1];
2829 unsigned index
= *(const WORD
*)&pFormat
[2];
2830 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
2831 unsigned long uflag
= UserMarshalFlags(pStubMsg
);
2832 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2833 TRACE("index=%d\n", index
);
2835 if (flags
& USER_MARSHAL_POINTER
)
2837 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
2838 /* skip pointer prefix */
2839 pStubMsg
->BufferLength
+= 4;
2840 ALIGN_LENGTH(pStubMsg
->BufferLength
, 8);
2843 ALIGN_LENGTH(pStubMsg
->BufferLength
, (flags
& 0xf) + 1);
2846 TRACE("size=%ld\n", bufsize
);
2847 pStubMsg
->BufferLength
+= bufsize
;
2851 pStubMsg
->BufferLength
=
2852 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
2853 &uflag
, pStubMsg
->BufferLength
, pMemory
);
2856 /***********************************************************************
2857 * NdrUserMarshalMemorySize [RPCRT4.@]
2859 unsigned long WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2860 PFORMAT_STRING pFormat
)
2862 unsigned flags
= pFormat
[1];
2863 unsigned index
= *(const WORD
*)&pFormat
[2];
2864 DWORD memsize
= *(const WORD
*)&pFormat
[4];
2865 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
2867 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2868 TRACE("index=%d\n", index
);
2870 pStubMsg
->MemorySize
+= memsize
;
2872 if (flags
& USER_MARSHAL_POINTER
)
2874 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2875 /* skip pointer prefix */
2876 pStubMsg
->Buffer
+= 4;
2877 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
2880 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
2882 pStubMsg
->Buffer
+= bufsize
;
2884 return pStubMsg
->MemorySize
;
2887 /***********************************************************************
2888 * NdrUserMarshalFree [RPCRT4.@]
2890 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
2891 unsigned char *pMemory
,
2892 PFORMAT_STRING pFormat
)
2894 /* unsigned flags = pFormat[1]; */
2895 unsigned index
= *(const WORD
*)&pFormat
[2];
2896 unsigned long uflag
= UserMarshalFlags(pStubMsg
);
2897 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2898 TRACE("index=%d\n", index
);
2900 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
2904 /***********************************************************************
2905 * NdrClearOutParameters [RPCRT4.@]
2907 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
2908 PFORMAT_STRING pFormat
,
2911 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
2914 /***********************************************************************
2915 * NdrConvert [RPCRT4.@]
2917 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
2919 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
2920 /* FIXME: since this stub doesn't do any converting, the proper behavior
2921 is to raise an exception */
2924 /***********************************************************************
2925 * NdrConvert2 [RPCRT4.@]
2927 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, long NumberParams
)
2929 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %ld): stub.\n",
2930 pStubMsg
, pFormat
, NumberParams
);
2931 /* FIXME: since this stub doesn't do any converting, the proper behavior
2932 is to raise an exception */
2935 typedef struct _NDR_CSTRUCT_FORMAT
2938 unsigned char alignment
;
2939 unsigned short memory_size
;
2940 short offset_to_array_description
;
2941 } NDR_CSTRUCT_FORMAT
, NDR_CVSTRUCT_FORMAT
;
2943 /***********************************************************************
2944 * NdrConformantStructMarshall [RPCRT4.@]
2946 unsigned char * WINAPI
NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2947 unsigned char *pMemory
,
2948 PFORMAT_STRING pFormat
)
2950 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (NDR_CSTRUCT_FORMAT
*)pFormat
;
2951 PFORMAT_STRING pCArrayFormat
;
2952 ULONG esize
, bufsize
;
2954 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
2956 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
2957 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
2959 ERR("invalid format type %x\n", pCStructFormat
->type
);
2960 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2964 pCArrayFormat
= (unsigned char*)&pCStructFormat
->offset_to_array_description
+
2965 pCStructFormat
->offset_to_array_description
;
2966 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
2968 ERR("invalid array format type %x\n", pCStructFormat
->type
);
2969 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2972 esize
= *(const WORD
*)(pCArrayFormat
+2);
2974 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
2975 pCArrayFormat
+ 4, 0);
2977 WriteConformance(pStubMsg
);
2979 ALIGN_POINTER(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
2981 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
2983 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2984 /* copy constant sized part of struct */
2985 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2986 memcpy(pStubMsg
->Buffer
, pMemory
, pCStructFormat
->memory_size
+ bufsize
);
2987 pStubMsg
->Buffer
+= pCStructFormat
->memory_size
+ bufsize
;
2989 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
2990 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2992 STD_OVERFLOW_CHECK(pStubMsg
);
2997 /***********************************************************************
2998 * NdrConformantStructUnmarshall [RPCRT4.@]
3000 unsigned char * WINAPI
NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3001 unsigned char **ppMemory
,
3002 PFORMAT_STRING pFormat
,
3003 unsigned char fMustAlloc
)
3005 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (NDR_CSTRUCT_FORMAT
*)pFormat
;
3006 PFORMAT_STRING pCArrayFormat
;
3007 ULONG esize
, bufsize
;
3009 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3011 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3012 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3014 ERR("invalid format type %x\n", pCStructFormat
->type
);
3015 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3018 pCArrayFormat
= (unsigned char*)&pCStructFormat
->offset_to_array_description
+
3019 pCStructFormat
->offset_to_array_description
;
3020 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3022 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3023 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3026 esize
= *(const WORD
*)(pCArrayFormat
+2);
3028 pCArrayFormat
= ReadConformance(pStubMsg
, pCArrayFormat
+ 4);
3030 ALIGN_POINTER(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
3032 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3034 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3035 /* work out how much memory to allocate if we need to do so */
3036 if (!*ppMemory
|| fMustAlloc
)
3038 SIZE_T size
= pCStructFormat
->memory_size
+ bufsize
;
3039 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3042 /* now copy the data */
3043 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3044 memcpy(*ppMemory
, pStubMsg
->Buffer
, pCStructFormat
->memory_size
+ bufsize
);
3045 pStubMsg
->Buffer
+= pCStructFormat
->memory_size
+ bufsize
;
3047 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3048 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3053 /***********************************************************************
3054 * NdrConformantStructBufferSize [RPCRT4.@]
3056 void WINAPI
NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3057 unsigned char *pMemory
,
3058 PFORMAT_STRING pFormat
)
3060 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (NDR_CSTRUCT_FORMAT
*)pFormat
;
3061 PFORMAT_STRING pCArrayFormat
;
3064 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3066 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3067 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3069 ERR("invalid format type %x\n", pCStructFormat
->type
);
3070 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3073 pCArrayFormat
= (unsigned char*)&pCStructFormat
->offset_to_array_description
+
3074 pCStructFormat
->offset_to_array_description
;
3075 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3077 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3078 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3081 esize
= *(const WORD
*)(pCArrayFormat
+2);
3083 pCArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
, pCArrayFormat
+4, 0);
3084 SizeConformance(pStubMsg
);
3086 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCStructFormat
->alignment
+ 1);
3088 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3090 pStubMsg
->BufferLength
+= pCStructFormat
->memory_size
+
3091 safe_multiply(pStubMsg
->MaxCount
, esize
);
3093 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3094 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3097 /***********************************************************************
3098 * NdrConformantStructMemorySize [RPCRT4.@]
3100 unsigned long WINAPI
NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3101 PFORMAT_STRING pFormat
)
3107 /***********************************************************************
3108 * NdrConformantStructFree [RPCRT4.@]
3110 void WINAPI
NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3111 unsigned char *pMemory
,
3112 PFORMAT_STRING pFormat
)
3117 /***********************************************************************
3118 * NdrConformantVaryingStructMarshall [RPCRT4.@]
3120 unsigned char * WINAPI
NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3121 unsigned char *pMemory
,
3122 PFORMAT_STRING pFormat
)
3124 const NDR_CVSTRUCT_FORMAT
* pCVStructFormat
= (NDR_CVSTRUCT_FORMAT
*)pFormat
;
3125 PFORMAT_STRING pCVArrayFormat
;
3126 ULONG esize
, bufsize
;
3128 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3130 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3131 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3133 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3134 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3138 pCVArrayFormat
= (unsigned char*)&pCVStructFormat
->offset_to_array_description
+
3139 pCVStructFormat
->offset_to_array_description
;
3140 switch (*pCVArrayFormat
)
3142 case RPC_FC_CVARRAY
:
3143 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3145 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3146 pCVArrayFormat
+ 4, 0);
3147 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3150 case RPC_FC_C_CSTRING
:
3151 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
3152 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
3153 esize
= sizeof(char);
3154 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3155 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3156 pCVArrayFormat
+ 2, 0);
3158 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3160 case RPC_FC_C_WSTRING
:
3161 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
3162 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
3163 esize
= sizeof(WCHAR
);
3164 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3165 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3166 pCVArrayFormat
+ 2, 0);
3168 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3171 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3172 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3176 WriteConformance(pStubMsg
);
3178 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
3180 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3182 /* write constant sized part */
3183 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3184 memcpy(pStubMsg
->Buffer
, pMemory
, pCVStructFormat
->memory_size
);
3185 pStubMsg
->Buffer
+= pCVStructFormat
->memory_size
;
3187 WriteVariance(pStubMsg
);
3189 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3191 /* write array part */
3192 memcpy(pStubMsg
->Buffer
, pMemory
+ pCVStructFormat
->memory_size
, bufsize
);
3193 pStubMsg
->Buffer
+= bufsize
;
3195 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3197 STD_OVERFLOW_CHECK(pStubMsg
);
3202 /***********************************************************************
3203 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3205 unsigned char * WINAPI
NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3206 unsigned char **ppMemory
,
3207 PFORMAT_STRING pFormat
,
3208 unsigned char fMustAlloc
)
3210 const NDR_CVSTRUCT_FORMAT
* pCVStructFormat
= (NDR_CVSTRUCT_FORMAT
*)pFormat
;
3211 PFORMAT_STRING pCVArrayFormat
;
3212 ULONG esize
, bufsize
;
3213 unsigned char cvarray_type
;
3215 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3217 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3218 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3220 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3221 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3225 pCVArrayFormat
= (unsigned char*)&pCVStructFormat
->offset_to_array_description
+
3226 pCVStructFormat
->offset_to_array_description
;
3227 cvarray_type
= *pCVArrayFormat
;
3228 switch (cvarray_type
)
3230 case RPC_FC_CVARRAY
:
3231 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3232 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 4);
3234 case RPC_FC_C_CSTRING
:
3235 esize
= sizeof(char);
3236 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3237 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3239 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3241 case RPC_FC_C_WSTRING
:
3242 esize
= sizeof(WCHAR
);
3243 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3244 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3246 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3249 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3250 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3254 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
3256 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3258 /* work out how much memory to allocate if we need to do so */
3259 if (!*ppMemory
|| fMustAlloc
)
3261 SIZE_T size
= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->MaxCount
);
3262 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3265 /* copy the constant data */
3266 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3267 memcpy(*ppMemory
, pStubMsg
->Buffer
, pCVStructFormat
->memory_size
);
3268 pStubMsg
->Buffer
+= pCVStructFormat
->memory_size
;
3270 pCVArrayFormat
= ReadVariance(pStubMsg
, pCVArrayFormat
, pStubMsg
->MaxCount
);
3272 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3274 if ((cvarray_type
== RPC_FC_C_CSTRING
) ||
3275 (cvarray_type
== RPC_FC_C_WSTRING
))
3278 /* strings must always have null terminating bytes */
3279 if (bufsize
< esize
)
3281 ERR("invalid string length of %ld\n", pStubMsg
->ActualCount
);
3282 RpcRaiseException(RPC_S_INVALID_BOUND
);
3285 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
3286 if (pStubMsg
->Buffer
[i
] != 0)
3288 ERR("string not null-terminated at byte position %ld, data is 0x%x\n",
3289 i
, pStubMsg
->Buffer
[i
]);
3290 RpcRaiseException(RPC_S_INVALID_BOUND
);
3295 /* copy the array data */
3296 memcpy(*ppMemory
+ pCVStructFormat
->memory_size
, pStubMsg
->Buffer
,
3298 pStubMsg
->Buffer
+= bufsize
;
3300 if (cvarray_type
== RPC_FC_C_CSTRING
)
3301 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory
+ pCVStructFormat
->memory_size
)));
3302 else if (cvarray_type
== RPC_FC_C_WSTRING
)
3303 TRACE("string=%s\n", debugstr_w((WCHAR
*)(*ppMemory
+ pCVStructFormat
->memory_size
)));
3305 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3310 /***********************************************************************
3311 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3313 void WINAPI
NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3314 unsigned char *pMemory
,
3315 PFORMAT_STRING pFormat
)
3317 const NDR_CVSTRUCT_FORMAT
* pCVStructFormat
= (NDR_CVSTRUCT_FORMAT
*)pFormat
;
3318 PFORMAT_STRING pCVArrayFormat
;
3321 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3323 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3324 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3326 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3327 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3331 pCVArrayFormat
= (unsigned char*)&pCVStructFormat
->offset_to_array_description
+
3332 pCVStructFormat
->offset_to_array_description
;
3333 switch (*pCVArrayFormat
)
3335 case RPC_FC_CVARRAY
:
3336 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3338 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3339 pCVArrayFormat
+ 4, 0);
3340 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3343 case RPC_FC_C_CSTRING
:
3344 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
3345 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
3346 esize
= sizeof(char);
3347 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3348 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3349 pCVArrayFormat
+ 2, 0);
3351 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3353 case RPC_FC_C_WSTRING
:
3354 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
3355 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
3356 esize
= sizeof(WCHAR
);
3357 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3358 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3359 pCVArrayFormat
+ 2, 0);
3361 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3364 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3365 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3369 SizeConformance(pStubMsg
);
3371 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCVStructFormat
->alignment
+ 1);
3373 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3375 pStubMsg
->BufferLength
+= pCVStructFormat
->memory_size
;
3376 SizeVariance(pStubMsg
);
3377 pStubMsg
->BufferLength
+= safe_multiply(pStubMsg
->MaxCount
, esize
);
3379 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3382 /***********************************************************************
3383 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
3385 unsigned long WINAPI
NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3386 PFORMAT_STRING pFormat
)
3388 const NDR_CVSTRUCT_FORMAT
* pCVStructFormat
= (NDR_CVSTRUCT_FORMAT
*)pFormat
;
3389 PFORMAT_STRING pCVArrayFormat
;
3391 unsigned char cvarray_type
;
3393 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
3395 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3396 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3398 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3399 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3403 pCVArrayFormat
= (unsigned char*)&pCVStructFormat
->offset_to_array_description
+
3404 pCVStructFormat
->offset_to_array_description
;
3405 cvarray_type
= *pCVArrayFormat
;
3406 switch (cvarray_type
)
3408 case RPC_FC_CVARRAY
:
3409 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3410 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 4);
3412 case RPC_FC_C_CSTRING
:
3413 esize
= sizeof(char);
3414 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3415 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3417 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3419 case RPC_FC_C_WSTRING
:
3420 esize
= sizeof(WCHAR
);
3421 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3422 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3424 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3427 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3428 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3432 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
3434 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3436 pStubMsg
->Buffer
+= pCVStructFormat
->memory_size
;
3437 pCVArrayFormat
= ReadVariance(pStubMsg
, pCVArrayFormat
, pStubMsg
->MaxCount
);
3438 pStubMsg
->Buffer
+= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->ActualCount
);
3440 pStubMsg
->MemorySize
+= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->MaxCount
);
3442 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
3444 return pCVStructFormat
->memory_size
+ pStubMsg
->MaxCount
* esize
;
3447 /***********************************************************************
3448 * NdrConformantVaryingStructFree [RPCRT4.@]
3450 void WINAPI
NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3451 unsigned char *pMemory
,
3452 PFORMAT_STRING pFormat
)
3454 const NDR_CVSTRUCT_FORMAT
* pCVStructFormat
= (NDR_CVSTRUCT_FORMAT
*)pFormat
;
3455 PFORMAT_STRING pCVArrayFormat
;
3458 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3460 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3461 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3463 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3464 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3468 pCVArrayFormat
= (unsigned char*)&pCVStructFormat
->offset_to_array_description
+
3469 pCVStructFormat
->offset_to_array_description
;
3470 switch (*pCVArrayFormat
)
3472 case RPC_FC_CVARRAY
:
3473 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3475 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3476 pCVArrayFormat
+ 4, 0);
3477 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3480 case RPC_FC_C_CSTRING
:
3481 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
3482 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
3483 esize
= sizeof(char);
3484 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3485 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3486 pCVArrayFormat
+ 2, 0);
3488 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3490 case RPC_FC_C_WSTRING
:
3491 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
3492 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
3493 esize
= sizeof(WCHAR
);
3494 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3495 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3496 pCVArrayFormat
+ 2, 0);
3498 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3501 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3502 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3506 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3508 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
3514 unsigned char alignment
;
3515 unsigned short total_size
;
3516 } NDR_SMFARRAY_FORMAT
;
3521 unsigned char alignment
;
3522 unsigned long total_size
;
3523 } NDR_LGFARRAY_FORMAT
;
3525 /***********************************************************************
3526 * NdrFixedArrayMarshall [RPCRT4.@]
3528 unsigned char * WINAPI
NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3529 unsigned char *pMemory
,
3530 PFORMAT_STRING pFormat
)
3532 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
3533 unsigned long total_size
;
3535 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3537 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
3538 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
3540 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
3541 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3545 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
3547 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
3549 total_size
= pSmFArrayFormat
->total_size
;
3550 pFormat
= (unsigned char *)(pSmFArrayFormat
+ 1);
3554 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
3555 total_size
= pLgFArrayFormat
->total_size
;
3556 pFormat
= (unsigned char *)(pLgFArrayFormat
+ 1);
3558 memcpy(pStubMsg
->Buffer
, pMemory
, total_size
);
3559 pStubMsg
->Buffer
+= total_size
;
3561 pFormat
= EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3566 /***********************************************************************
3567 * NdrFixedArrayUnmarshall [RPCRT4.@]
3569 unsigned char * WINAPI
NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3570 unsigned char **ppMemory
,
3571 PFORMAT_STRING pFormat
,
3572 unsigned char fMustAlloc
)
3574 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
3575 unsigned long total_size
;
3577 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3579 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
3580 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
3582 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
3583 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3587 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
3589 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
3591 total_size
= pSmFArrayFormat
->total_size
;
3592 pFormat
= (unsigned char *)(pSmFArrayFormat
+ 1);
3596 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
3597 total_size
= pLgFArrayFormat
->total_size
;
3598 pFormat
= (unsigned char *)(pLgFArrayFormat
+ 1);
3601 if (fMustAlloc
|| !*ppMemory
)
3602 *ppMemory
= NdrAllocate(pStubMsg
, total_size
);
3603 memcpy(*ppMemory
, pStubMsg
->Buffer
, total_size
);
3604 pStubMsg
->Buffer
+= total_size
;
3606 pFormat
= EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3611 /***********************************************************************
3612 * NdrFixedArrayBufferSize [RPCRT4.@]
3614 void WINAPI
NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3615 unsigned char *pMemory
,
3616 PFORMAT_STRING pFormat
)
3618 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
3619 unsigned long total_size
;
3621 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3623 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
3624 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
3626 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
3627 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3631 ALIGN_LENGTH(pStubMsg
->BufferLength
, pSmFArrayFormat
->alignment
+ 1);
3633 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
3635 total_size
= pSmFArrayFormat
->total_size
;
3636 pFormat
= (unsigned char *)(pSmFArrayFormat
+ 1);
3640 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
3641 total_size
= pLgFArrayFormat
->total_size
;
3642 pFormat
= (unsigned char *)(pLgFArrayFormat
+ 1);
3644 pStubMsg
->BufferLength
+= total_size
;
3646 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3649 /***********************************************************************
3650 * NdrFixedArrayMemorySize [RPCRT4.@]
3652 unsigned long WINAPI
NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3653 PFORMAT_STRING pFormat
)
3655 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
3656 unsigned long total_size
;
3658 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
3660 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
3661 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
3663 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
3664 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3668 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
3670 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
3672 total_size
= pSmFArrayFormat
->total_size
;
3673 pFormat
= (unsigned char *)(pSmFArrayFormat
+ 1);
3677 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
3678 total_size
= pLgFArrayFormat
->total_size
;
3679 pFormat
= (unsigned char *)(pLgFArrayFormat
+ 1);
3681 pStubMsg
->Buffer
+= total_size
;
3682 pStubMsg
->MemorySize
+= total_size
;
3684 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
3689 /***********************************************************************
3690 * NdrFixedArrayFree [RPCRT4.@]
3692 void WINAPI
NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3693 unsigned char *pMemory
,
3694 PFORMAT_STRING pFormat
)
3696 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
3698 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3700 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
3701 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
3703 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
3704 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3708 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
3709 pFormat
= (unsigned char *)(pSmFArrayFormat
+ 1);
3712 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
3713 pFormat
= (unsigned char *)(pLgFArrayFormat
+ 1);
3716 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
3719 /***********************************************************************
3720 * NdrVaryingArrayMarshall [RPCRT4.@]
3722 unsigned char * WINAPI
NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3723 unsigned char *pMemory
,
3724 PFORMAT_STRING pFormat
)
3726 unsigned char alignment
;
3727 DWORD elements
, esize
;
3730 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3732 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
3733 (pFormat
[0] != RPC_FC_LGVARRAY
))
3735 ERR("invalid format type %x\n", pFormat
[0]);
3736 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3740 alignment
= pFormat
[1] + 1;
3742 if (pFormat
[0] == RPC_FC_SMVARRAY
)
3745 pFormat
+= sizeof(WORD
);
3746 elements
= *(const WORD
*)pFormat
;
3747 pFormat
+= sizeof(WORD
);
3752 pFormat
+= sizeof(DWORD
);
3753 elements
= *(const DWORD
*)pFormat
;
3754 pFormat
+= sizeof(DWORD
);
3757 esize
= *(const WORD
*)pFormat
;
3758 pFormat
+= sizeof(WORD
);
3760 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
3761 if ((pStubMsg
->ActualCount
> elements
) ||
3762 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
3764 RpcRaiseException(RPC_S_INVALID_BOUND
);
3768 WriteVariance(pStubMsg
);
3770 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3772 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3773 memcpy(pStubMsg
->Buffer
, pMemory
+ pStubMsg
->Offset
, bufsize
);
3774 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3775 pStubMsg
->Buffer
+= bufsize
;
3777 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3779 STD_OVERFLOW_CHECK(pStubMsg
);
3784 /***********************************************************************
3785 * NdrVaryingArrayUnmarshall [RPCRT4.@]
3787 unsigned char * WINAPI
NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3788 unsigned char **ppMemory
,
3789 PFORMAT_STRING pFormat
,
3790 unsigned char fMustAlloc
)
3792 unsigned char alignment
;
3793 DWORD size
, elements
, esize
;
3796 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3798 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
3799 (pFormat
[0] != RPC_FC_LGVARRAY
))
3801 ERR("invalid format type %x\n", pFormat
[0]);
3802 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3806 alignment
= pFormat
[1] + 1;
3808 if (pFormat
[0] == RPC_FC_SMVARRAY
)
3811 size
= *(const WORD
*)pFormat
;
3812 pFormat
+= sizeof(WORD
);
3813 elements
= *(const WORD
*)pFormat
;
3814 pFormat
+= sizeof(WORD
);
3819 size
= *(const DWORD
*)pFormat
;
3820 pFormat
+= sizeof(DWORD
);
3821 elements
= *(const DWORD
*)pFormat
;
3822 pFormat
+= sizeof(DWORD
);
3825 esize
= *(const WORD
*)pFormat
;
3826 pFormat
+= sizeof(WORD
);
3828 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
3830 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3832 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3834 if (!*ppMemory
|| fMustAlloc
)
3835 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3836 memcpy(*ppMemory
+ pStubMsg
->Offset
, pStubMsg
->Buffer
, bufsize
);
3837 pStubMsg
->Buffer
+= bufsize
;
3839 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3844 /***********************************************************************
3845 * NdrVaryingArrayBufferSize [RPCRT4.@]
3847 void WINAPI
NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3848 unsigned char *pMemory
,
3849 PFORMAT_STRING pFormat
)
3851 unsigned char alignment
;
3852 DWORD elements
, esize
;
3854 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3856 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
3857 (pFormat
[0] != RPC_FC_LGVARRAY
))
3859 ERR("invalid format type %x\n", pFormat
[0]);
3860 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3864 alignment
= pFormat
[1] + 1;
3866 if (pFormat
[0] == RPC_FC_SMVARRAY
)
3869 pFormat
+= sizeof(WORD
);
3870 elements
= *(const WORD
*)pFormat
;
3871 pFormat
+= sizeof(WORD
);
3876 pFormat
+= sizeof(DWORD
);
3877 elements
= *(const DWORD
*)pFormat
;
3878 pFormat
+= sizeof(DWORD
);
3881 esize
= *(const WORD
*)pFormat
;
3882 pFormat
+= sizeof(WORD
);
3884 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
3885 if ((pStubMsg
->ActualCount
> elements
) ||
3886 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
3888 RpcRaiseException(RPC_S_INVALID_BOUND
);
3892 SizeVariance(pStubMsg
);
3894 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
3896 pStubMsg
->BufferLength
+= safe_multiply(esize
, pStubMsg
->ActualCount
);
3898 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3901 /***********************************************************************
3902 * NdrVaryingArrayMemorySize [RPCRT4.@]
3904 unsigned long WINAPI
NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3905 PFORMAT_STRING pFormat
)
3907 unsigned char alignment
;
3908 DWORD size
, elements
, esize
;
3910 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
3912 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
3913 (pFormat
[0] != RPC_FC_LGVARRAY
))
3915 ERR("invalid format type %x\n", pFormat
[0]);
3916 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3920 alignment
= pFormat
[1] + 1;
3922 if (pFormat
[0] == RPC_FC_SMVARRAY
)
3925 size
= *(const WORD
*)pFormat
;
3926 pFormat
+= sizeof(WORD
);
3927 elements
= *(const WORD
*)pFormat
;
3928 pFormat
+= sizeof(WORD
);
3933 size
= *(const DWORD
*)pFormat
;
3934 pFormat
+= sizeof(DWORD
);
3935 elements
= *(const DWORD
*)pFormat
;
3936 pFormat
+= sizeof(DWORD
);
3939 esize
= *(const WORD
*)pFormat
;
3940 pFormat
+= sizeof(WORD
);
3942 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
3944 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3946 pStubMsg
->Buffer
+= safe_multiply(esize
, pStubMsg
->ActualCount
);
3947 pStubMsg
->MemorySize
+= size
;
3949 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
3951 return pStubMsg
->MemorySize
;
3954 /***********************************************************************
3955 * NdrVaryingArrayFree [RPCRT4.@]
3957 void WINAPI
NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3958 unsigned char *pMemory
,
3959 PFORMAT_STRING pFormat
)
3961 unsigned char alignment
;
3964 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3966 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
3967 (pFormat
[0] != RPC_FC_LGVARRAY
))
3969 ERR("invalid format type %x\n", pFormat
[0]);
3970 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3974 alignment
= pFormat
[1] + 1;
3976 if (pFormat
[0] == RPC_FC_SMVARRAY
)
3979 pFormat
+= sizeof(WORD
);
3980 elements
= *(const WORD
*)pFormat
;
3981 pFormat
+= sizeof(WORD
);
3986 pFormat
+= sizeof(DWORD
);
3987 elements
= *(const DWORD
*)pFormat
;
3988 pFormat
+= sizeof(DWORD
);
3991 pFormat
+= sizeof(WORD
);
3993 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
3994 if ((pStubMsg
->ActualCount
> elements
) ||
3995 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
3997 RpcRaiseException(RPC_S_INVALID_BOUND
);
4001 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4004 /***********************************************************************
4005 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
4007 unsigned char * WINAPI
NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4008 unsigned char *pMemory
,
4009 PFORMAT_STRING pFormat
)
4015 /***********************************************************************
4016 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
4018 unsigned char * WINAPI
NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4019 unsigned char **ppMemory
,
4020 PFORMAT_STRING pFormat
,
4021 unsigned char fMustAlloc
)
4027 /***********************************************************************
4028 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
4030 void WINAPI
NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4031 unsigned char *pMemory
,
4032 PFORMAT_STRING pFormat
)
4037 /***********************************************************************
4038 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
4040 unsigned long WINAPI
NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4041 PFORMAT_STRING pFormat
)
4047 /***********************************************************************
4048 * NdrEncapsulatedUnionFree [RPCRT4.@]
4050 void WINAPI
NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
4051 unsigned char *pMemory
,
4052 PFORMAT_STRING pFormat
)
4057 static PFORMAT_STRING
get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg
,
4058 unsigned long discriminant
,
4059 PFORMAT_STRING pFormat
)
4061 unsigned short num_arms
, arm
, type
;
4063 num_arms
= *(const SHORT
*)pFormat
& 0x0fff;
4065 for(arm
= 0; arm
< num_arms
; arm
++)
4067 if(discriminant
== *(const ULONG
*)pFormat
)
4075 type
= *(const unsigned short*)pFormat
;
4076 TRACE("type %04x\n", type
);
4077 if(arm
== num_arms
) /* default arm extras */
4081 ERR("no arm for 0x%lx and no default case\n", discriminant
);
4082 RpcRaiseException(RPC_S_INVALID_TAG
);
4087 TRACE("falling back to empty default case for 0x%lx\n", discriminant
);
4094 static PFORMAT_STRING
get_non_encapsulated_union_arm(PMIDL_STUB_MESSAGE pStubMsg
,
4096 PFORMAT_STRING pFormat
)
4098 pFormat
+= *(const SHORT
*)pFormat
;
4101 return get_arm_offset_from_union_arm_selector(pStubMsg
, value
, pFormat
);
4104 /***********************************************************************
4105 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
4107 unsigned char * WINAPI
NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4108 unsigned char *pMemory
,
4109 PFORMAT_STRING pFormat
)
4111 unsigned short type
;
4112 unsigned char switch_type
;
4114 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4117 switch_type
= *pFormat
;
4120 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
4121 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
4122 /* Marshall discriminant */
4123 NdrBaseTypeMarshall(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
4125 pFormat
= get_non_encapsulated_union_arm(pStubMsg
, pStubMsg
->MaxCount
, pFormat
);
4129 type
= *(const unsigned short*)pFormat
;
4130 if((type
& 0xff00) == 0x8000)
4132 unsigned char basetype
= LOBYTE(type
);
4133 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &basetype
);
4137 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4138 NDR_MARSHALL m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
4141 unsigned char *saved_buffer
= NULL
;
4148 saved_buffer
= pStubMsg
->Buffer
;
4149 pStubMsg
->Buffer
+= 4; /* for pointer ID */
4150 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char **)pMemory
, desc
);
4153 m(pStubMsg
, pMemory
, desc
);
4156 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4161 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg
,
4162 PFORMAT_STRING
*ppFormat
)
4164 long discriminant
= 0;
4172 discriminant
= *(UCHAR
*)pStubMsg
->Buffer
;
4173 pStubMsg
->Buffer
+= sizeof(UCHAR
);
4178 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
4179 discriminant
= *(USHORT
*)pStubMsg
->Buffer
;
4180 pStubMsg
->Buffer
+= sizeof(USHORT
);
4184 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
4185 discriminant
= *(ULONG
*)pStubMsg
->Buffer
;
4186 pStubMsg
->Buffer
+= sizeof(ULONG
);
4189 FIXME("Unhandled base type: 0x%02x\n", **ppFormat
);
4193 if (pStubMsg
->fHasNewCorrDesc
)
4197 return discriminant
;
4200 /**********************************************************************
4201 * NdrNonEncapsulatedUnionUnmarshall[RPCRT4.@]
4203 unsigned char * WINAPI
NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4204 unsigned char **ppMemory
,
4205 PFORMAT_STRING pFormat
,
4206 unsigned char fMustAlloc
)
4209 unsigned short type
, size
;
4211 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4214 /* Unmarshall discriminant */
4215 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
4216 TRACE("unmarshalled discriminant %lx\n", discriminant
);
4218 pFormat
+= *(const SHORT
*)pFormat
;
4220 size
= *(const unsigned short*)pFormat
;
4223 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4227 if(!*ppMemory
|| fMustAlloc
)
4228 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4230 type
= *(const unsigned short*)pFormat
;
4231 if((type
& 0xff00) == 0x8000)
4233 unsigned char basetype
= LOBYTE(type
);
4234 return NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &basetype
, fMustAlloc
);
4238 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4239 NDR_UNMARSHALL m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
4242 unsigned char *saved_buffer
= NULL
;
4249 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4250 saved_buffer
= pStubMsg
->Buffer
;
4251 pStubMsg
->Buffer
+= 4; /* for pointer ID */
4252 PointerUnmarshall(pStubMsg
, saved_buffer
, *(unsigned char ***)ppMemory
, desc
, TRUE
);
4255 m(pStubMsg
, ppMemory
, desc
, fMustAlloc
);
4258 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4263 /***********************************************************************
4264 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
4266 void WINAPI
NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4267 unsigned char *pMemory
,
4268 PFORMAT_STRING pFormat
)
4270 unsigned short type
;
4271 unsigned char switch_type
;
4273 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4276 switch_type
= *pFormat
;
4279 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
4280 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
4281 /* Add discriminant size */
4282 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
4284 pFormat
= get_non_encapsulated_union_arm(pStubMsg
, pStubMsg
->MaxCount
, pFormat
);
4288 type
= *(const unsigned short*)pFormat
;
4289 if((type
& 0xff00) == 0x8000)
4291 unsigned char basetype
= LOBYTE(type
);
4292 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &basetype
);
4296 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4297 NDR_BUFFERSIZE m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
4306 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
4307 pStubMsg
->BufferLength
+= 4; /* for pointer ID */
4308 PointerBufferSize(pStubMsg
, *(unsigned char **)pMemory
, desc
);
4311 m(pStubMsg
, pMemory
, desc
);
4314 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
4319 /***********************************************************************
4320 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
4322 unsigned long WINAPI
NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4323 PFORMAT_STRING pFormat
)
4325 unsigned long discriminant
;
4326 unsigned short type
, size
;
4329 /* Unmarshall discriminant */
4330 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
4331 TRACE("unmarshalled discriminant 0x%lx\n", discriminant
);
4333 pFormat
+= *(const SHORT
*)pFormat
;
4335 size
= *(const unsigned short*)pFormat
;
4338 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4342 pStubMsg
->Memory
+= size
;
4344 type
= *(const unsigned short*)pFormat
;
4345 if((type
& 0xff00) == 0x8000)
4347 return NdrBaseTypeMemorySize(pStubMsg
, pFormat
);
4351 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4352 NDR_MEMORYSIZE m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
4353 unsigned char *saved_buffer
;
4362 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4363 saved_buffer
= pStubMsg
->Buffer
;
4364 pStubMsg
->Buffer
+= 4;
4365 ALIGN_LENGTH(pStubMsg
->MemorySize
, 4);
4366 pStubMsg
->MemorySize
+= 4;
4367 PointerMemorySize(pStubMsg
, saved_buffer
, pFormat
);
4370 return m(pStubMsg
, desc
);
4373 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4376 TRACE("size %d\n", size
);
4380 /***********************************************************************
4381 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
4383 void WINAPI
NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
4384 unsigned char *pMemory
,
4385 PFORMAT_STRING pFormat
)
4390 /***********************************************************************
4391 * NdrByteCountPointerMarshall [RPCRT4.@]
4393 unsigned char * WINAPI
NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4394 unsigned char *pMemory
,
4395 PFORMAT_STRING pFormat
)
4401 /***********************************************************************
4402 * NdrByteCountPointerUnmarshall [RPCRT4.@]
4404 unsigned char * WINAPI
NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4405 unsigned char **ppMemory
,
4406 PFORMAT_STRING pFormat
,
4407 unsigned char fMustAlloc
)
4413 /***********************************************************************
4414 * NdrByteCountPointerBufferSize [RPCRT4.@]
4416 void WINAPI
NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4417 unsigned char *pMemory
,
4418 PFORMAT_STRING pFormat
)
4423 /***********************************************************************
4424 * NdrByteCountPointerMemorySize [RPCRT4.@]
4426 unsigned long WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4427 PFORMAT_STRING pFormat
)
4433 /***********************************************************************
4434 * NdrByteCountPointerFree [RPCRT4.@]
4436 void WINAPI
NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
4437 unsigned char *pMemory
,
4438 PFORMAT_STRING pFormat
)
4443 /***********************************************************************
4444 * NdrXmitOrRepAsMarshall [RPCRT4.@]
4446 unsigned char * WINAPI
NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4447 unsigned char *pMemory
,
4448 PFORMAT_STRING pFormat
)
4454 /***********************************************************************
4455 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
4457 unsigned char * WINAPI
NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4458 unsigned char **ppMemory
,
4459 PFORMAT_STRING pFormat
,
4460 unsigned char fMustAlloc
)
4466 /***********************************************************************
4467 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
4469 void WINAPI
NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4470 unsigned char *pMemory
,
4471 PFORMAT_STRING pFormat
)
4476 /***********************************************************************
4477 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
4479 unsigned long WINAPI
NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4480 PFORMAT_STRING pFormat
)
4486 /***********************************************************************
4487 * NdrXmitOrRepAsFree [RPCRT4.@]
4489 void WINAPI
NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg
,
4490 unsigned char *pMemory
,
4491 PFORMAT_STRING pFormat
)
4496 /***********************************************************************
4497 * NdrBaseTypeMarshall [internal]
4499 static unsigned char *WINAPI
NdrBaseTypeMarshall(
4500 PMIDL_STUB_MESSAGE pStubMsg
,
4501 unsigned char *pMemory
,
4502 PFORMAT_STRING pFormat
)
4504 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
4512 *(UCHAR
*)pStubMsg
->Buffer
= *(UCHAR
*)pMemory
;
4513 pStubMsg
->Buffer
+= sizeof(UCHAR
);
4514 TRACE("value: 0x%02x\n", *(UCHAR
*)pMemory
);
4519 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
4520 *(USHORT
*)pStubMsg
->Buffer
= *(USHORT
*)pMemory
;
4521 pStubMsg
->Buffer
+= sizeof(USHORT
);
4522 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
4526 case RPC_FC_ERROR_STATUS_T
:
4528 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
4529 *(ULONG
*)pStubMsg
->Buffer
= *(ULONG
*)pMemory
;
4530 pStubMsg
->Buffer
+= sizeof(ULONG
);
4531 TRACE("value: 0x%08lx\n", *(ULONG
*)pMemory
);
4534 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(float));
4535 *(float *)pStubMsg
->Buffer
= *(float *)pMemory
;
4536 pStubMsg
->Buffer
+= sizeof(float);
4539 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(double));
4540 *(double *)pStubMsg
->Buffer
= *(double *)pMemory
;
4541 pStubMsg
->Buffer
+= sizeof(double);
4544 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONGLONG
));
4545 *(ULONGLONG
*)pStubMsg
->Buffer
= *(ULONGLONG
*)pMemory
;
4546 pStubMsg
->Buffer
+= sizeof(ULONGLONG
);
4547 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
4550 /* only 16-bits on the wire, so do a sanity check */
4551 if (*(UINT
*)pMemory
> USHRT_MAX
)
4552 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
4553 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
4554 *(USHORT
*)pStubMsg
->Buffer
= *(UINT
*)pMemory
;
4555 pStubMsg
->Buffer
+= sizeof(USHORT
);
4556 TRACE("value: 0x%04x\n", *(UINT
*)pMemory
);
4559 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
4562 STD_OVERFLOW_CHECK(pStubMsg
);
4564 /* FIXME: what is the correct return value? */
4568 /***********************************************************************
4569 * NdrBaseTypeUnmarshall [internal]
4571 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(
4572 PMIDL_STUB_MESSAGE pStubMsg
,
4573 unsigned char **ppMemory
,
4574 PFORMAT_STRING pFormat
,
4575 unsigned char fMustAlloc
)
4577 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
4579 #define BASE_TYPE_UNMARSHALL(type) \
4580 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
4581 if (fMustAlloc || !*ppMemory) \
4582 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
4583 TRACE("*ppMemory: %p\n", *ppMemory); \
4584 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
4585 pStubMsg->Buffer += sizeof(type);
4593 BASE_TYPE_UNMARSHALL(UCHAR
);
4594 TRACE("value: 0x%02x\n", **(UCHAR
**)ppMemory
);
4599 BASE_TYPE_UNMARSHALL(USHORT
);
4600 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
4604 case RPC_FC_ERROR_STATUS_T
:
4606 BASE_TYPE_UNMARSHALL(ULONG
);
4607 TRACE("value: 0x%08lx\n", **(ULONG
**)ppMemory
);
4610 BASE_TYPE_UNMARSHALL(float);
4611 TRACE("value: %f\n", **(float **)ppMemory
);
4614 BASE_TYPE_UNMARSHALL(double);
4615 TRACE("value: %f\n", **(double **)ppMemory
);
4618 BASE_TYPE_UNMARSHALL(ULONGLONG
);
4619 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG
**)ppMemory
));
4622 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
4623 if (fMustAlloc
|| !*ppMemory
)
4624 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT
));
4625 TRACE("*ppMemory: %p\n", *ppMemory
);
4626 /* 16-bits on the wire, but int in memory */
4627 **(UINT
**)ppMemory
= *(USHORT
*)pStubMsg
->Buffer
;
4628 pStubMsg
->Buffer
+= sizeof(USHORT
);
4629 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
4632 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
4634 #undef BASE_TYPE_UNMARSHALL
4636 /* FIXME: what is the correct return value? */
4641 /***********************************************************************
4642 * NdrBaseTypeBufferSize [internal]
4644 static void WINAPI
NdrBaseTypeBufferSize(
4645 PMIDL_STUB_MESSAGE pStubMsg
,
4646 unsigned char *pMemory
,
4647 PFORMAT_STRING pFormat
)
4649 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
4657 pStubMsg
->BufferLength
+= sizeof(UCHAR
);
4663 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(USHORT
));
4664 pStubMsg
->BufferLength
+= sizeof(USHORT
);
4669 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONG
));
4670 pStubMsg
->BufferLength
+= sizeof(ULONG
);
4673 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(float));
4674 pStubMsg
->BufferLength
+= sizeof(float);
4677 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(double));
4678 pStubMsg
->BufferLength
+= sizeof(double);
4681 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONGLONG
));
4682 pStubMsg
->BufferLength
+= sizeof(ULONGLONG
);
4684 case RPC_FC_ERROR_STATUS_T
:
4685 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(error_status_t
));
4686 pStubMsg
->BufferLength
+= sizeof(error_status_t
);
4689 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
4693 /***********************************************************************
4694 * NdrBaseTypeMemorySize [internal]
4696 static unsigned long WINAPI
NdrBaseTypeMemorySize(
4697 PMIDL_STUB_MESSAGE pStubMsg
,
4698 PFORMAT_STRING pFormat
)
4706 pStubMsg
->Buffer
+= sizeof(UCHAR
);
4707 pStubMsg
->MemorySize
+= sizeof(UCHAR
);
4708 return sizeof(UCHAR
);
4712 pStubMsg
->Buffer
+= sizeof(USHORT
);
4713 pStubMsg
->MemorySize
+= sizeof(USHORT
);
4714 return sizeof(USHORT
);
4717 pStubMsg
->Buffer
+= sizeof(ULONG
);
4718 pStubMsg
->MemorySize
+= sizeof(ULONG
);
4719 return sizeof(ULONG
);
4721 pStubMsg
->Buffer
+= sizeof(float);
4722 pStubMsg
->MemorySize
+= sizeof(float);
4723 return sizeof(float);
4725 pStubMsg
->Buffer
+= sizeof(double);
4726 pStubMsg
->MemorySize
+= sizeof(double);
4727 return sizeof(double);
4729 pStubMsg
->Buffer
+= sizeof(ULONGLONG
);
4730 pStubMsg
->MemorySize
+= sizeof(ULONGLONG
);
4731 return sizeof(ULONGLONG
);
4732 case RPC_FC_ERROR_STATUS_T
:
4733 pStubMsg
->Buffer
+= sizeof(error_status_t
);
4734 pStubMsg
->MemorySize
+= sizeof(error_status_t
);
4735 return sizeof(error_status_t
);
4738 pStubMsg
->Buffer
+= sizeof(INT
);
4739 pStubMsg
->MemorySize
+= sizeof(INT
);
4742 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
4747 /***********************************************************************
4748 * NdrBaseTypeFree [internal]
4750 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg
,
4751 unsigned char *pMemory
,
4752 PFORMAT_STRING pFormat
)
4754 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
4759 /***********************************************************************
4760 * NdrClientContextMarshall
4762 void WINAPI
NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4763 NDR_CCONTEXT ContextHandle
,
4766 TRACE("(%p, %p, %d)\n", pStubMsg
, ContextHandle
, fCheck
);
4768 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4770 /* FIXME: what does fCheck do? */
4771 NDRCContextMarshall(ContextHandle
,
4774 pStubMsg
->Buffer
+= cbNDRContext
;
4777 /***********************************************************************
4778 * NdrClientContextUnmarshall
4780 void WINAPI
NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4781 NDR_CCONTEXT
* pContextHandle
,
4782 RPC_BINDING_HANDLE BindHandle
)
4784 TRACE("(%p, %p, %p)\n", pStubMsg
, pContextHandle
, BindHandle
);
4786 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4788 NDRCContextUnmarshall(pContextHandle
,
4791 pStubMsg
->RpcMsg
->DataRepresentation
);
4793 pStubMsg
->Buffer
+= cbNDRContext
;
4796 void WINAPI
NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4797 NDR_SCONTEXT ContextHandle
,
4798 NDR_RUNDOWN RundownRoutine
)
4800 FIXME("(%p, %p, %p): stub\n", pStubMsg
, ContextHandle
, RundownRoutine
);
4803 NDR_SCONTEXT WINAPI
NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
)
4805 FIXME("(%p): stub\n", pStubMsg
);
4809 void WINAPI
NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg
,
4810 unsigned char* pMemory
,
4811 PFORMAT_STRING pFormat
)
4813 FIXME("(%p, %p, %p): stub\n", pStubMsg
, pMemory
, pFormat
);
4816 NDR_SCONTEXT WINAPI
NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg
,
4817 PFORMAT_STRING pFormat
)
4819 FIXME("(%p, %p): stub\n", pStubMsg
, pFormat
);
4823 void WINAPI
NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4824 NDR_SCONTEXT ContextHandle
,
4825 NDR_RUNDOWN RundownRoutine
,
4826 PFORMAT_STRING pFormat
)
4828 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg
, ContextHandle
, RundownRoutine
, pFormat
);
4831 NDR_SCONTEXT WINAPI
NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4832 PFORMAT_STRING pFormat
)
4834 FIXME("(%p, %p): stub\n", pStubMsg
, pFormat
);
4838 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
4840 typedef struct ndr_context_handle
4844 } ndr_context_handle
;
4846 struct context_handle_entry
4850 RPC_BINDING_HANDLE handle
;
4851 ndr_context_handle wire_data
;
4854 static struct list context_handle_list
= LIST_INIT(context_handle_list
);
4856 static CRITICAL_SECTION ndr_context_cs
;
4857 static CRITICAL_SECTION_DEBUG ndr_context_debug
=
4859 0, 0, &ndr_context_cs
,
4860 { &ndr_context_debug
.ProcessLocksList
, &ndr_context_debug
.ProcessLocksList
},
4861 0, 0, { (DWORD_PTR
)(__FILE__
": ndr_context") }
4863 static CRITICAL_SECTION ndr_context_cs
= { &ndr_context_debug
, -1, 0, 0, 0, 0 };
4865 static struct context_handle_entry
*get_context_entry(NDR_CCONTEXT CContext
)
4867 struct context_handle_entry
*che
= (struct context_handle_entry
*) CContext
;
4869 if (che
->magic
!= NDR_CONTEXT_HANDLE_MAGIC
)
4874 static struct context_handle_entry
*context_entry_from_guid(LPGUID uuid
)
4876 struct context_handle_entry
*che
;
4877 LIST_FOR_EACH_ENTRY(che
, &context_handle_list
, struct context_handle_entry
, entry
)
4878 if (IsEqualGUID(&che
->wire_data
.uuid
, uuid
))
4883 RPC_BINDING_HANDLE WINAPI
NDRCContextBinding(NDR_CCONTEXT CContext
)
4885 struct context_handle_entry
*che
;
4886 RPC_BINDING_HANDLE handle
= NULL
;
4888 TRACE("%p\n", CContext
);
4890 EnterCriticalSection(&ndr_context_cs
);
4891 che
= get_context_entry(CContext
);
4893 handle
= che
->handle
;
4894 LeaveCriticalSection(&ndr_context_cs
);
4897 RpcRaiseException(ERROR_INVALID_HANDLE
);
4901 void WINAPI
NDRCContextMarshall(NDR_CCONTEXT CContext
, void *pBuff
)
4903 struct context_handle_entry
*che
;
4905 TRACE("%p %p\n", CContext
, pBuff
);
4909 EnterCriticalSection(&ndr_context_cs
);
4910 che
= get_context_entry(CContext
);
4911 memcpy(pBuff
, &che
->wire_data
, sizeof (ndr_context_handle
));
4912 LeaveCriticalSection(&ndr_context_cs
);
4916 ndr_context_handle
*wire_data
= (ndr_context_handle
*)pBuff
;
4917 wire_data
->attributes
= 0;
4918 wire_data
->uuid
= GUID_NULL
;
4922 static UINT
ndr_update_context_handle(NDR_CCONTEXT
*CContext
,
4923 RPC_BINDING_HANDLE hBinding
,
4924 ndr_context_handle
*chi
)
4926 struct context_handle_entry
*che
= NULL
;
4928 /* a null UUID means we should free the context handle */
4929 if (IsEqualGUID(&chi
->uuid
, &GUID_NULL
))
4933 che
= get_context_entry(*CContext
);
4935 return ERROR_INVALID_HANDLE
;
4936 list_remove(&che
->entry
);
4937 RpcBindingFree(&che
->handle
);
4938 HeapFree(GetProcessHeap(), 0, che
);
4942 /* if there's no existing entry matching the GUID, allocate one */
4943 else if (!(che
= context_entry_from_guid(&chi
->uuid
)))
4945 che
= HeapAlloc(GetProcessHeap(), 0, sizeof *che
);
4947 return ERROR_NOT_ENOUGH_MEMORY
;
4948 che
->magic
= NDR_CONTEXT_HANDLE_MAGIC
;
4949 RpcBindingCopy(hBinding
, &che
->handle
);
4950 list_add_tail(&context_handle_list
, &che
->entry
);
4951 memcpy(&che
->wire_data
, chi
, sizeof *chi
);
4956 return ERROR_SUCCESS
;
4959 void WINAPI
NDRCContextUnmarshall(NDR_CCONTEXT
*CContext
,
4960 RPC_BINDING_HANDLE hBinding
,
4962 unsigned long DataRepresentation
)
4966 TRACE("*%p=(%p) %p %p %08lx\n",
4967 CContext
, *CContext
, hBinding
, pBuff
, DataRepresentation
);
4969 EnterCriticalSection(&ndr_context_cs
);
4970 r
= ndr_update_context_handle(CContext
, hBinding
, pBuff
);
4971 LeaveCriticalSection(&ndr_context_cs
);
4973 RpcRaiseException(r
);
4976 void WINAPI
NDRSContextMarshall(NDR_SCONTEXT CContext
,
4978 NDR_RUNDOWN userRunDownIn
)
4980 FIXME("(%p %p %p): stub\n", CContext
, pBuff
, userRunDownIn
);
4983 void WINAPI
NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding
,
4984 NDR_SCONTEXT CContext
,
4986 NDR_RUNDOWN userRunDownIn
)
4988 FIXME("(%p %p %p %p): stub\n", hBinding
, CContext
, pBuff
, userRunDownIn
);
4991 void WINAPI
NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding
,
4992 NDR_SCONTEXT CContext
,
4994 NDR_RUNDOWN userRunDownIn
,
4996 unsigned long Flags
)
4998 FIXME("(%p %p %p %p %p %lu): stub\n",
4999 hBinding
, CContext
, pBuff
, userRunDownIn
, CtxGuard
, Flags
);
5002 NDR_SCONTEXT WINAPI
NDRSContextUnmarshall(void *pBuff
,
5003 unsigned long DataRepresentation
)
5005 FIXME("(%p %08lx): stub\n", pBuff
, DataRepresentation
);
5009 NDR_SCONTEXT WINAPI
NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding
,
5011 unsigned long DataRepresentation
)
5013 FIXME("(%p %p %08lx): stub\n", hBinding
, pBuff
, DataRepresentation
);
5017 NDR_SCONTEXT WINAPI
NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding
,
5019 unsigned long DataRepresentation
,
5021 unsigned long Flags
)
5023 FIXME("(%p %p %08lx %p %lu): stub\n",
5024 hBinding
, pBuff
, DataRepresentation
, CtxGuard
, Flags
);