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
= *(const short *)&pFormat
[2];
409 if (!IsConformanceOrVariancePresent(pFormat
)) {
410 /* null descriptor */
415 switch (pFormat
[0] & 0xf0) {
416 case RPC_FC_NORMAL_CONFORMANCE
:
417 TRACE("normal conformance, ofs=%d\n", ofs
);
420 case RPC_FC_POINTER_CONFORMANCE
:
421 TRACE("pointer conformance, ofs=%d\n", ofs
);
422 ptr
= pStubMsg
->Memory
;
424 case RPC_FC_TOP_LEVEL_CONFORMANCE
:
425 TRACE("toplevel conformance, ofs=%d\n", ofs
);
426 if (pStubMsg
->StackTop
) {
427 ptr
= pStubMsg
->StackTop
;
430 /* -Os mode, *pCount is already set */
434 case RPC_FC_CONSTANT_CONFORMANCE
:
435 data
= ofs
| ((DWORD
)pFormat
[1] << 16);
436 TRACE("constant conformance, val=%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
= *(const WORD
*)(pFormat
+2);
1622 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
1624 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
1625 pStubMsg
->MemorySize
+= size
;
1626 pStubMsg
->Buffer
+= size
;
1628 if (pFormat
[0] != RPC_FC_STRUCT
)
1629 EmbeddedPointerMemorySize(pStubMsg
, pFormat
+4);
1633 /***********************************************************************
1634 * NdrSimpleStructFree [RPCRT4.@]
1636 void WINAPI
NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
1637 unsigned char *pMemory
,
1638 PFORMAT_STRING pFormat
)
1640 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
1641 if (pFormat
[0] != RPC_FC_STRUCT
)
1642 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
+4);
1646 static unsigned long EmbeddedComplexSize(PMIDL_STUB_MESSAGE pStubMsg
,
1647 PFORMAT_STRING pFormat
)
1651 case RPC_FC_PSTRUCT
:
1652 case RPC_FC_CSTRUCT
:
1653 case RPC_FC_BOGUS_STRUCT
:
1654 case RPC_FC_SMFARRAY
:
1655 case RPC_FC_SMVARRAY
:
1656 return *(const WORD
*)&pFormat
[2];
1657 case RPC_FC_USER_MARSHAL
:
1658 return *(const WORD
*)&pFormat
[4];
1659 case RPC_FC_NON_ENCAPSULATED_UNION
:
1661 if (pStubMsg
->fHasNewCorrDesc
)
1666 pFormat
+= *(const SHORT
*)pFormat
;
1667 return *(const SHORT
*)pFormat
;
1669 return sizeof(void *);
1671 FIXME("unhandled embedded type %02x\n", *pFormat
);
1677 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
1678 PFORMAT_STRING pFormat
)
1680 NDR_MEMORYSIZE m
= NdrMemorySizer
[*pFormat
& NDR_TABLE_MASK
];
1684 FIXME("no memorysizer for data type=%02x\n", *pFormat
);
1688 return m(pStubMsg
, pFormat
);
1692 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1693 unsigned char *pMemory
,
1694 PFORMAT_STRING pFormat
,
1695 PFORMAT_STRING pPointer
)
1697 PFORMAT_STRING desc
;
1701 while (*pFormat
!= RPC_FC_END
) {
1707 TRACE("byte=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
1708 memcpy(pStubMsg
->Buffer
, pMemory
, 1);
1709 pStubMsg
->Buffer
+= 1;
1715 TRACE("short=%d <= %p\n", *(WORD
*)pMemory
, pMemory
);
1716 memcpy(pStubMsg
->Buffer
, pMemory
, 2);
1717 pStubMsg
->Buffer
+= 2;
1723 TRACE("long=%ld <= %p\n", *(DWORD
*)pMemory
, pMemory
);
1724 memcpy(pStubMsg
->Buffer
, pMemory
, 4);
1725 pStubMsg
->Buffer
+= 4;
1729 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
1730 memcpy(pStubMsg
->Buffer
, pMemory
, 8);
1731 pStubMsg
->Buffer
+= 8;
1734 case RPC_FC_POINTER
:
1735 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory
, pMemory
);
1736 NdrPointerMarshall(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
1740 case RPC_FC_ALIGNM4
:
1741 ALIGN_POINTER(pMemory
, 4);
1743 case RPC_FC_ALIGNM8
:
1744 ALIGN_POINTER(pMemory
, 8);
1746 case RPC_FC_STRUCTPAD1
:
1747 case RPC_FC_STRUCTPAD2
:
1748 case RPC_FC_STRUCTPAD3
:
1749 case RPC_FC_STRUCTPAD4
:
1750 case RPC_FC_STRUCTPAD5
:
1751 case RPC_FC_STRUCTPAD6
:
1752 case RPC_FC_STRUCTPAD7
:
1753 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
1755 case RPC_FC_EMBEDDED_COMPLEX
:
1756 pMemory
+= pFormat
[1];
1758 desc
= pFormat
+ *(const SHORT
*)pFormat
;
1759 size
= EmbeddedComplexSize(pStubMsg
, desc
);
1760 TRACE("embedded complex (size=%ld) <= %p\n", size
, pMemory
);
1761 m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
1762 if (m
) m(pStubMsg
, pMemory
, desc
);
1763 else FIXME("no marshaller for embedded type %02x\n", *desc
);
1770 FIXME("unhandled format 0x%02x\n", *pFormat
);
1778 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
1779 unsigned char *pMemory
,
1780 PFORMAT_STRING pFormat
,
1781 PFORMAT_STRING pPointer
)
1783 PFORMAT_STRING desc
;
1787 while (*pFormat
!= RPC_FC_END
) {
1793 memcpy(pMemory
, pStubMsg
->Buffer
, 1);
1794 TRACE("byte=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
1795 pStubMsg
->Buffer
+= 1;
1801 memcpy(pMemory
, pStubMsg
->Buffer
, 2);
1802 TRACE("short=%d => %p\n", *(WORD
*)pMemory
, pMemory
);
1803 pStubMsg
->Buffer
+= 2;
1809 memcpy(pMemory
, pStubMsg
->Buffer
, 4);
1810 TRACE("long=%ld => %p\n", *(DWORD
*)pMemory
, pMemory
);
1811 pStubMsg
->Buffer
+= 4;
1815 memcpy(pMemory
, pStubMsg
->Buffer
, 8);
1816 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
), pMemory
);
1817 pStubMsg
->Buffer
+= 8;
1820 case RPC_FC_POINTER
:
1821 TRACE("pointer => %p\n", pMemory
);
1822 NdrPointerUnmarshall(pStubMsg
, (unsigned char**)pMemory
, pPointer
, TRUE
);
1826 case RPC_FC_ALIGNM4
:
1827 ALIGN_POINTER(pMemory
, 4);
1829 case RPC_FC_ALIGNM8
:
1830 ALIGN_POINTER(pMemory
, 8);
1832 case RPC_FC_STRUCTPAD1
:
1833 case RPC_FC_STRUCTPAD2
:
1834 case RPC_FC_STRUCTPAD3
:
1835 case RPC_FC_STRUCTPAD4
:
1836 case RPC_FC_STRUCTPAD5
:
1837 case RPC_FC_STRUCTPAD6
:
1838 case RPC_FC_STRUCTPAD7
:
1839 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
1841 case RPC_FC_EMBEDDED_COMPLEX
:
1842 pMemory
+= pFormat
[1];
1844 desc
= pFormat
+ *(const SHORT
*)pFormat
;
1845 size
= EmbeddedComplexSize(pStubMsg
, desc
);
1846 TRACE("embedded complex (size=%ld) => %p\n", size
, pMemory
);
1847 m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
1848 memset(pMemory
, 0, size
); /* just in case */
1849 if (m
) m(pStubMsg
, &pMemory
, desc
, FALSE
);
1850 else FIXME("no unmarshaller for embedded type %02x\n", *desc
);
1857 FIXME("unhandled format %d\n", *pFormat
);
1865 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
1866 unsigned char *pMemory
,
1867 PFORMAT_STRING pFormat
,
1868 PFORMAT_STRING pPointer
)
1870 PFORMAT_STRING desc
;
1874 while (*pFormat
!= RPC_FC_END
) {
1880 pStubMsg
->BufferLength
+= 1;
1886 pStubMsg
->BufferLength
+= 2;
1892 pStubMsg
->BufferLength
+= 4;
1896 pStubMsg
->BufferLength
+= 8;
1899 case RPC_FC_POINTER
:
1900 NdrPointerBufferSize(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
1904 case RPC_FC_ALIGNM4
:
1905 ALIGN_POINTER(pMemory
, 4);
1907 case RPC_FC_ALIGNM8
:
1908 ALIGN_POINTER(pMemory
, 8);
1910 case RPC_FC_STRUCTPAD1
:
1911 case RPC_FC_STRUCTPAD2
:
1912 case RPC_FC_STRUCTPAD3
:
1913 case RPC_FC_STRUCTPAD4
:
1914 case RPC_FC_STRUCTPAD5
:
1915 case RPC_FC_STRUCTPAD6
:
1916 case RPC_FC_STRUCTPAD7
:
1917 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
1919 case RPC_FC_EMBEDDED_COMPLEX
:
1920 pMemory
+= pFormat
[1];
1922 desc
= pFormat
+ *(const SHORT
*)pFormat
;
1923 size
= EmbeddedComplexSize(pStubMsg
, desc
);
1924 m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
1925 if (m
) m(pStubMsg
, pMemory
, desc
);
1926 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
1933 FIXME("unhandled format 0x%02x\n", *pFormat
);
1941 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg
,
1942 unsigned char *pMemory
,
1943 PFORMAT_STRING pFormat
,
1944 PFORMAT_STRING pPointer
)
1946 PFORMAT_STRING desc
;
1950 while (*pFormat
!= RPC_FC_END
) {
1971 case RPC_FC_POINTER
:
1972 NdrPointerFree(pStubMsg
, *(unsigned char**)pMemory
, pPointer
);
1976 case RPC_FC_ALIGNM4
:
1977 ALIGN_POINTER(pMemory
, 4);
1979 case RPC_FC_ALIGNM8
:
1980 ALIGN_POINTER(pMemory
, 8);
1982 case RPC_FC_STRUCTPAD1
:
1983 case RPC_FC_STRUCTPAD2
:
1984 case RPC_FC_STRUCTPAD3
:
1985 case RPC_FC_STRUCTPAD4
:
1986 case RPC_FC_STRUCTPAD5
:
1987 case RPC_FC_STRUCTPAD6
:
1988 case RPC_FC_STRUCTPAD7
:
1989 pMemory
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
1991 case RPC_FC_EMBEDDED_COMPLEX
:
1992 pMemory
+= pFormat
[1];
1994 desc
= pFormat
+ *(const SHORT
*)pFormat
;
1995 size
= EmbeddedComplexSize(pStubMsg
, desc
);
1996 m
= NdrFreer
[*desc
& NDR_TABLE_MASK
];
1997 if (m
) m(pStubMsg
, pMemory
, desc
);
1998 else FIXME("no freer for embedded type %02x\n", *desc
);
2005 FIXME("unhandled format 0x%02x\n", *pFormat
);
2013 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2014 PFORMAT_STRING pFormat
)
2016 PFORMAT_STRING desc
;
2017 unsigned long size
= 0;
2019 while (*pFormat
!= RPC_FC_END
) {
2026 pStubMsg
->Buffer
+= 1;
2032 pStubMsg
->Buffer
+= 2;
2038 pStubMsg
->Buffer
+= 4;
2042 pStubMsg
->Buffer
+= 8;
2044 case RPC_FC_POINTER
:
2046 pStubMsg
->Buffer
+= 4;
2048 case RPC_FC_ALIGNM4
:
2049 ALIGN_LENGTH(size
, 4);
2050 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2052 case RPC_FC_ALIGNM8
:
2053 ALIGN_LENGTH(size
, 8);
2054 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
2056 case RPC_FC_STRUCTPAD1
:
2057 case RPC_FC_STRUCTPAD2
:
2058 case RPC_FC_STRUCTPAD3
:
2059 case RPC_FC_STRUCTPAD4
:
2060 case RPC_FC_STRUCTPAD5
:
2061 case RPC_FC_STRUCTPAD6
:
2062 case RPC_FC_STRUCTPAD7
:
2063 size
+= *pFormat
- RPC_FC_STRUCTPAD1
+ 1;
2065 case RPC_FC_EMBEDDED_COMPLEX
:
2068 desc
= pFormat
+ *(const SHORT
*)pFormat
;
2069 size
+= EmbeddedComplexMemorySize(pStubMsg
, desc
);
2075 FIXME("unhandled format 0x%02x\n", *pFormat
);
2083 /***********************************************************************
2084 * NdrComplexStructMarshall [RPCRT4.@]
2086 unsigned char * WINAPI
NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2087 unsigned char *pMemory
,
2088 PFORMAT_STRING pFormat
)
2090 PFORMAT_STRING conf_array
= NULL
;
2091 PFORMAT_STRING pointer_desc
= NULL
;
2092 unsigned char *OldMemory
= pStubMsg
->Memory
;
2094 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2096 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2099 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2101 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2104 pStubMsg
->Memory
= pMemory
;
2106 ComplexMarshall(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2109 NdrConformantArrayMarshall(pStubMsg
, pMemory
, conf_array
);
2111 pStubMsg
->Memory
= OldMemory
;
2113 STD_OVERFLOW_CHECK(pStubMsg
);
2118 /***********************************************************************
2119 * NdrComplexStructUnmarshall [RPCRT4.@]
2121 unsigned char * WINAPI
NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2122 unsigned char **ppMemory
,
2123 PFORMAT_STRING pFormat
,
2124 unsigned char fMustAlloc
)
2126 unsigned size
= *(const WORD
*)(pFormat
+2);
2127 PFORMAT_STRING conf_array
= NULL
;
2128 PFORMAT_STRING pointer_desc
= NULL
;
2129 unsigned char *pMemory
;
2131 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2133 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2135 if (fMustAlloc
|| !*ppMemory
)
2137 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2138 memset(*ppMemory
, 0, size
);
2142 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2144 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2147 pMemory
= ComplexUnmarshall(pStubMsg
, *ppMemory
, pFormat
, pointer_desc
);
2150 NdrConformantArrayUnmarshall(pStubMsg
, &pMemory
, conf_array
, fMustAlloc
);
2155 /***********************************************************************
2156 * NdrComplexStructBufferSize [RPCRT4.@]
2158 void WINAPI
NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2159 unsigned char *pMemory
,
2160 PFORMAT_STRING pFormat
)
2162 PFORMAT_STRING conf_array
= NULL
;
2163 PFORMAT_STRING pointer_desc
= NULL
;
2164 unsigned char *OldMemory
= pStubMsg
->Memory
;
2166 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2168 ALIGN_LENGTH(pStubMsg
->BufferLength
, pFormat
[1] + 1);
2171 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2173 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2176 pStubMsg
->Memory
= pMemory
;
2178 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2181 NdrConformantArrayBufferSize(pStubMsg
, pMemory
, conf_array
);
2183 pStubMsg
->Memory
= OldMemory
;
2186 /***********************************************************************
2187 * NdrComplexStructMemorySize [RPCRT4.@]
2189 unsigned long WINAPI
NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2190 PFORMAT_STRING pFormat
)
2192 unsigned size
= *(const WORD
*)(pFormat
+2);
2193 PFORMAT_STRING conf_array
= NULL
;
2194 PFORMAT_STRING pointer_desc
= NULL
;
2196 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2198 ALIGN_POINTER(pStubMsg
->Buffer
, pFormat
[1] + 1);
2201 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2203 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2206 ComplexStructMemorySize(pStubMsg
, pFormat
);
2209 NdrConformantArrayMemorySize(pStubMsg
, conf_array
);
2214 /***********************************************************************
2215 * NdrComplexStructFree [RPCRT4.@]
2217 void WINAPI
NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
2218 unsigned char *pMemory
,
2219 PFORMAT_STRING pFormat
)
2221 PFORMAT_STRING conf_array
= NULL
;
2222 PFORMAT_STRING pointer_desc
= NULL
;
2223 unsigned char *OldMemory
= pStubMsg
->Memory
;
2225 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2228 if (*(const WORD
*)pFormat
) conf_array
= pFormat
+ *(const WORD
*)pFormat
;
2230 if (*(const WORD
*)pFormat
) pointer_desc
= pFormat
+ *(const WORD
*)pFormat
;
2233 pStubMsg
->Memory
= pMemory
;
2235 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, pointer_desc
);
2238 NdrConformantArrayFree(pStubMsg
, pMemory
, conf_array
);
2240 pStubMsg
->Memory
= OldMemory
;
2243 /***********************************************************************
2244 * NdrConformantArrayMarshall [RPCRT4.@]
2246 unsigned char * WINAPI
NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2247 unsigned char *pMemory
,
2248 PFORMAT_STRING pFormat
)
2250 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
2251 unsigned char alignment
= pFormat
[1] + 1;
2253 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2254 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2256 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2258 WriteConformance(pStubMsg
);
2260 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2262 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2263 memcpy(pStubMsg
->Buffer
, pMemory
, size
);
2264 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2265 pStubMsg
->Buffer
+= size
;
2267 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2269 STD_OVERFLOW_CHECK(pStubMsg
);
2274 /***********************************************************************
2275 * NdrConformantArrayUnmarshall [RPCRT4.@]
2277 unsigned char * WINAPI
NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2278 unsigned char **ppMemory
,
2279 PFORMAT_STRING pFormat
,
2280 unsigned char fMustAlloc
)
2282 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
2283 unsigned char alignment
= pFormat
[1] + 1;
2285 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2286 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2288 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2290 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2292 if (fMustAlloc
|| !*ppMemory
)
2293 *ppMemory
= NdrAllocate(pStubMsg
, size
);
2295 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2297 memcpy(*ppMemory
, pStubMsg
->Buffer
, size
);
2299 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2300 pStubMsg
->Buffer
+= size
;
2302 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2307 /***********************************************************************
2308 * NdrConformantArrayBufferSize [RPCRT4.@]
2310 void WINAPI
NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2311 unsigned char *pMemory
,
2312 PFORMAT_STRING pFormat
)
2314 DWORD size
, esize
= *(const WORD
*)(pFormat
+2);
2315 unsigned char alignment
= pFormat
[1] + 1;
2317 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2318 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2320 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2322 SizeConformance(pStubMsg
);
2324 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
2326 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2327 /* conformance value plus array */
2328 pStubMsg
->BufferLength
+= size
;
2330 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
2333 /***********************************************************************
2334 * NdrConformantArrayMemorySize [RPCRT4.@]
2336 unsigned long WINAPI
NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2337 PFORMAT_STRING pFormat
)
2339 DWORD size
= 0, esize
= *(const WORD
*)(pFormat
+2);
2340 unsigned char alignment
= pFormat
[1] + 1;
2342 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2343 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2345 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2346 size
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2347 pStubMsg
->MemorySize
+= size
;
2349 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2350 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2351 pStubMsg
->Buffer
+= size
;
2353 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
2355 return pStubMsg
->MemorySize
;
2358 /***********************************************************************
2359 * NdrConformantArrayFree [RPCRT4.@]
2361 void WINAPI
NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
2362 unsigned char *pMemory
,
2363 PFORMAT_STRING pFormat
)
2365 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2366 if (pFormat
[0] != RPC_FC_CARRAY
) FIXME("format=%d\n", pFormat
[0]);
2368 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2370 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2374 /***********************************************************************
2375 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
2377 unsigned char* WINAPI
NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2378 unsigned char* pMemory
,
2379 PFORMAT_STRING pFormat
)
2382 unsigned char alignment
= pFormat
[1] + 1;
2383 DWORD esize
= *(const WORD
*)(pFormat
+2);
2385 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
2387 if (pFormat
[0] != RPC_FC_CVARRAY
)
2389 ERR("invalid format type %x\n", pFormat
[0]);
2390 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2394 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2395 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2397 WriteConformance(pStubMsg
);
2398 WriteVariance(pStubMsg
);
2400 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2402 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2404 memcpy(pStubMsg
->Buffer
, pMemory
+ pStubMsg
->Offset
, bufsize
);
2405 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2406 pStubMsg
->Buffer
+= bufsize
;
2408 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2410 STD_OVERFLOW_CHECK(pStubMsg
);
2416 /***********************************************************************
2417 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
2419 unsigned char* WINAPI
NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
,
2420 unsigned char** ppMemory
,
2421 PFORMAT_STRING pFormat
,
2422 unsigned char fMustAlloc
)
2424 ULONG bufsize
, memsize
;
2425 unsigned char alignment
= pFormat
[1] + 1;
2426 DWORD esize
= *(const WORD
*)(pFormat
+2);
2428 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2430 if (pFormat
[0] != RPC_FC_CVARRAY
)
2432 ERR("invalid format type %x\n", pFormat
[0]);
2433 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2437 pFormat
= ReadConformance(pStubMsg
, pFormat
+4);
2438 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2440 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2442 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
2443 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2445 if (!*ppMemory
|| fMustAlloc
)
2446 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2447 memcpy(*ppMemory
+ pStubMsg
->Offset
, pStubMsg
->Buffer
, bufsize
);
2448 pStubMsg
->Buffer
+= bufsize
;
2450 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2456 /***********************************************************************
2457 * NdrConformantVaryingArrayFree [RPCRT4.@]
2459 void WINAPI
NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg
,
2460 unsigned char* pMemory
,
2461 PFORMAT_STRING pFormat
)
2463 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2465 if (pFormat
[0] != RPC_FC_CVARRAY
)
2467 ERR("invalid format type %x\n", pFormat
[0]);
2468 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2472 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2473 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2475 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
2479 /***********************************************************************
2480 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
2482 void WINAPI
NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg
,
2483 unsigned char* pMemory
, PFORMAT_STRING pFormat
)
2485 unsigned char alignment
= pFormat
[1] + 1;
2486 DWORD esize
= *(const WORD
*)(pFormat
+2);
2488 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
2490 if (pFormat
[0] != RPC_FC_CVARRAY
)
2492 ERR("invalid format type %x\n", pFormat
[0]);
2493 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2498 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
+4, 0);
2499 /* compute length */
2500 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
2502 SizeConformance(pStubMsg
);
2503 SizeVariance(pStubMsg
);
2505 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
2507 pStubMsg
->BufferLength
+= safe_multiply(esize
, pStubMsg
->ActualCount
);
2509 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
2513 /***********************************************************************
2514 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
2516 unsigned long WINAPI
NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg
,
2517 PFORMAT_STRING pFormat
)
2524 /***********************************************************************
2525 * NdrComplexArrayMarshall [RPCRT4.@]
2527 unsigned char * WINAPI
NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2528 unsigned char *pMemory
,
2529 PFORMAT_STRING pFormat
)
2531 ULONG i
, count
, def
;
2532 BOOL variance_present
;
2533 unsigned char alignment
;
2535 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2537 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
2539 ERR("invalid format type %x\n", pFormat
[0]);
2540 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2544 alignment
= pFormat
[1] + 1;
2546 def
= *(const WORD
*)&pFormat
[2];
2549 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
2550 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
2552 variance_present
= IsConformanceOrVariancePresent(pFormat
);
2553 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
2554 TRACE("variance = %ld\n", pStubMsg
->ActualCount
);
2556 WriteConformance(pStubMsg
);
2557 if (variance_present
)
2558 WriteVariance(pStubMsg
);
2560 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2562 count
= pStubMsg
->ActualCount
;
2563 for (i
= 0; i
< count
; i
++)
2564 pMemory
= ComplexMarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
2566 STD_OVERFLOW_CHECK(pStubMsg
);
2571 /***********************************************************************
2572 * NdrComplexArrayUnmarshall [RPCRT4.@]
2574 unsigned char * WINAPI
NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2575 unsigned char **ppMemory
,
2576 PFORMAT_STRING pFormat
,
2577 unsigned char fMustAlloc
)
2579 ULONG i
, count
, esize
, memsize
;
2580 unsigned char alignment
;
2581 unsigned char *pMemory
;
2582 unsigned char *Buffer
;
2584 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2586 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
2588 ERR("invalid format type %x\n", pFormat
[0]);
2589 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2593 alignment
= pFormat
[1] + 1;
2597 pFormat
= ReadConformance(pStubMsg
, pFormat
);
2598 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2600 Buffer
= pStubMsg
->Buffer
;
2601 pStubMsg
->MemorySize
= 0;
2602 esize
= ComplexStructMemorySize(pStubMsg
, pFormat
);
2603 pStubMsg
->Buffer
= Buffer
;
2605 /* do multiply here instead of inside if block to verify MaxCount */
2606 memsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2607 if (fMustAlloc
|| !*ppMemory
)
2609 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2610 memset(*ppMemory
, 0, memsize
);
2613 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2615 pMemory
= *ppMemory
;
2616 count
= pStubMsg
->ActualCount
;
2617 for (i
= 0; i
< count
; i
++)
2618 pMemory
= ComplexUnmarshall(pStubMsg
, pMemory
, pFormat
, NULL
);
2623 /***********************************************************************
2624 * NdrComplexArrayBufferSize [RPCRT4.@]
2626 void WINAPI
NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2627 unsigned char *pMemory
,
2628 PFORMAT_STRING pFormat
)
2630 ULONG i
, count
, def
;
2631 unsigned char alignment
;
2632 BOOL variance_present
;
2634 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2636 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
2638 ERR("invalid format type %x\n", pFormat
[0]);
2639 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2643 alignment
= pFormat
[1] + 1;
2645 def
= *(const WORD
*)&pFormat
[2];
2648 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
2649 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
2650 SizeConformance(pStubMsg
);
2652 variance_present
= IsConformanceOrVariancePresent(pFormat
);
2653 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
2654 TRACE("variance = %ld\n", pStubMsg
->ActualCount
);
2656 if (variance_present
)
2657 SizeVariance(pStubMsg
);
2659 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
2661 count
= pStubMsg
->ActualCount
;
2662 for (i
= 0; i
< count
; i
++)
2663 pMemory
= ComplexBufferSize(pStubMsg
, pMemory
, pFormat
, NULL
);
2666 /***********************************************************************
2667 * NdrComplexArrayMemorySize [RPCRT4.@]
2669 unsigned long WINAPI
NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2670 PFORMAT_STRING pFormat
)
2672 ULONG i
, count
, esize
;
2673 unsigned char alignment
;
2674 unsigned char *Buffer
;
2675 unsigned long SavedMemorySize
;
2676 unsigned long MemorySize
;
2678 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2680 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
2682 ERR("invalid format type %x\n", pFormat
[0]);
2683 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2687 alignment
= pFormat
[1] + 1;
2691 pFormat
= ReadConformance(pStubMsg
, pFormat
);
2692 pFormat
= ReadVariance(pStubMsg
, pFormat
, pStubMsg
->MaxCount
);
2694 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
2696 SavedMemorySize
= pStubMsg
->MemorySize
;
2698 Buffer
= pStubMsg
->Buffer
;
2699 pStubMsg
->MemorySize
= 0;
2700 esize
= ComplexStructMemorySize(pStubMsg
, pFormat
);
2701 pStubMsg
->Buffer
= Buffer
;
2703 MemorySize
= safe_multiply(pStubMsg
->MaxCount
, esize
);
2705 count
= pStubMsg
->ActualCount
;
2706 for (i
= 0; i
< count
; i
++)
2707 ComplexStructMemorySize(pStubMsg
, pFormat
);
2709 pStubMsg
->MemorySize
= SavedMemorySize
;
2711 pStubMsg
->MemorySize
+= MemorySize
;
2715 /***********************************************************************
2716 * NdrComplexArrayFree [RPCRT4.@]
2718 void WINAPI
NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
2719 unsigned char *pMemory
,
2720 PFORMAT_STRING pFormat
)
2722 ULONG i
, count
, def
;
2724 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2726 if (pFormat
[0] != RPC_FC_BOGUS_ARRAY
)
2728 ERR("invalid format type %x\n", pFormat
[0]);
2729 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2733 def
= *(const WORD
*)&pFormat
[2];
2736 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, def
);
2737 TRACE("conformance = %ld\n", pStubMsg
->MaxCount
);
2739 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, pStubMsg
->MaxCount
);
2740 TRACE("variance = %ld\n", pStubMsg
->ActualCount
);
2742 count
= pStubMsg
->ActualCount
;
2743 for (i
= 0; i
< count
; i
++)
2744 pMemory
= ComplexFree(pStubMsg
, pMemory
, pFormat
, NULL
);
2747 static unsigned long UserMarshalFlags(PMIDL_STUB_MESSAGE pStubMsg
)
2749 return MAKELONG(pStubMsg
->dwDestContext
,
2750 pStubMsg
->RpcMsg
->DataRepresentation
);
2753 #define USER_MARSHAL_PTR_PREFIX \
2754 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
2755 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
2757 /***********************************************************************
2758 * NdrUserMarshalMarshall [RPCRT4.@]
2760 unsigned char * WINAPI
NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2761 unsigned char *pMemory
,
2762 PFORMAT_STRING pFormat
)
2764 unsigned flags
= pFormat
[1];
2765 unsigned index
= *(const WORD
*)&pFormat
[2];
2766 unsigned long uflag
= UserMarshalFlags(pStubMsg
);
2767 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2768 TRACE("index=%d\n", index
);
2770 if (flags
& USER_MARSHAL_POINTER
)
2772 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2773 NDR_LOCAL_UINT32_WRITE(pStubMsg
->Buffer
, USER_MARSHAL_PTR_PREFIX
);
2774 pStubMsg
->Buffer
+= 4;
2775 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
2778 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
2781 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnMarshall(
2782 &uflag
, pStubMsg
->Buffer
, pMemory
);
2784 STD_OVERFLOW_CHECK(pStubMsg
);
2789 /***********************************************************************
2790 * NdrUserMarshalUnmarshall [RPCRT4.@]
2792 unsigned char * WINAPI
NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2793 unsigned char **ppMemory
,
2794 PFORMAT_STRING pFormat
,
2795 unsigned char fMustAlloc
)
2797 unsigned flags
= pFormat
[1];
2798 unsigned index
= *(const WORD
*)&pFormat
[2];
2799 DWORD memsize
= *(const WORD
*)&pFormat
[4];
2800 unsigned long uflag
= UserMarshalFlags(pStubMsg
);
2801 TRACE("(%p,%p,%p,%d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
2802 TRACE("index=%d\n", index
);
2804 if (flags
& USER_MARSHAL_POINTER
)
2806 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2807 /* skip pointer prefix */
2808 pStubMsg
->Buffer
+= 4;
2809 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
2812 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
2814 if (fMustAlloc
|| !*ppMemory
)
2815 *ppMemory
= NdrAllocate(pStubMsg
, memsize
);
2818 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnUnmarshall(
2819 &uflag
, pStubMsg
->Buffer
, *ppMemory
);
2824 /***********************************************************************
2825 * NdrUserMarshalBufferSize [RPCRT4.@]
2827 void WINAPI
NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
2828 unsigned char *pMemory
,
2829 PFORMAT_STRING pFormat
)
2831 unsigned flags
= pFormat
[1];
2832 unsigned index
= *(const WORD
*)&pFormat
[2];
2833 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
2834 unsigned long uflag
= UserMarshalFlags(pStubMsg
);
2835 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2836 TRACE("index=%d\n", index
);
2838 if (flags
& USER_MARSHAL_POINTER
)
2840 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
2841 /* skip pointer prefix */
2842 pStubMsg
->BufferLength
+= 4;
2843 ALIGN_LENGTH(pStubMsg
->BufferLength
, 8);
2846 ALIGN_LENGTH(pStubMsg
->BufferLength
, (flags
& 0xf) + 1);
2849 TRACE("size=%ld\n", bufsize
);
2850 pStubMsg
->BufferLength
+= bufsize
;
2854 pStubMsg
->BufferLength
=
2855 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnBufferSize(
2856 &uflag
, pStubMsg
->BufferLength
, pMemory
);
2859 /***********************************************************************
2860 * NdrUserMarshalMemorySize [RPCRT4.@]
2862 unsigned long WINAPI
NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
2863 PFORMAT_STRING pFormat
)
2865 unsigned flags
= pFormat
[1];
2866 unsigned index
= *(const WORD
*)&pFormat
[2];
2867 DWORD memsize
= *(const WORD
*)&pFormat
[4];
2868 DWORD bufsize
= *(const WORD
*)&pFormat
[6];
2870 TRACE("(%p,%p)\n", pStubMsg
, pFormat
);
2871 TRACE("index=%d\n", index
);
2873 pStubMsg
->MemorySize
+= memsize
;
2875 if (flags
& USER_MARSHAL_POINTER
)
2877 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
2878 /* skip pointer prefix */
2879 pStubMsg
->Buffer
+= 4;
2880 ALIGN_POINTER(pStubMsg
->Buffer
, 8);
2883 ALIGN_POINTER(pStubMsg
->Buffer
, (flags
& 0xf) + 1);
2885 pStubMsg
->Buffer
+= bufsize
;
2887 return pStubMsg
->MemorySize
;
2890 /***********************************************************************
2891 * NdrUserMarshalFree [RPCRT4.@]
2893 void WINAPI
NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg
,
2894 unsigned char *pMemory
,
2895 PFORMAT_STRING pFormat
)
2897 /* unsigned flags = pFormat[1]; */
2898 unsigned index
= *(const WORD
*)&pFormat
[2];
2899 unsigned long uflag
= UserMarshalFlags(pStubMsg
);
2900 TRACE("(%p,%p,%p)\n", pStubMsg
, pMemory
, pFormat
);
2901 TRACE("index=%d\n", index
);
2903 pStubMsg
->StubDesc
->aUserMarshalQuadruple
[index
].pfnFree(
2907 /***********************************************************************
2908 * NdrClearOutParameters [RPCRT4.@]
2910 void WINAPI
NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg
,
2911 PFORMAT_STRING pFormat
,
2914 FIXME("(%p,%p,%p): stub\n", pStubMsg
, pFormat
, ArgAddr
);
2917 /***********************************************************************
2918 * NdrConvert [RPCRT4.@]
2920 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
2922 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
2923 /* FIXME: since this stub doesn't do any converting, the proper behavior
2924 is to raise an exception */
2927 /***********************************************************************
2928 * NdrConvert2 [RPCRT4.@]
2930 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, long NumberParams
)
2932 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %ld): stub.\n",
2933 pStubMsg
, pFormat
, NumberParams
);
2934 /* FIXME: since this stub doesn't do any converting, the proper behavior
2935 is to raise an exception */
2938 typedef struct _NDR_CSTRUCT_FORMAT
2941 unsigned char alignment
;
2942 unsigned short memory_size
;
2943 short offset_to_array_description
;
2944 } NDR_CSTRUCT_FORMAT
, NDR_CVSTRUCT_FORMAT
;
2946 /***********************************************************************
2947 * NdrConformantStructMarshall [RPCRT4.@]
2949 unsigned char * WINAPI
NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
2950 unsigned char *pMemory
,
2951 PFORMAT_STRING pFormat
)
2953 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
2954 PFORMAT_STRING pCArrayFormat
;
2955 ULONG esize
, bufsize
;
2957 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
2959 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
2960 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
2962 ERR("invalid format type %x\n", pCStructFormat
->type
);
2963 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2967 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
2968 pCStructFormat
->offset_to_array_description
;
2969 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
2971 ERR("invalid array format type %x\n", pCStructFormat
->type
);
2972 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
2975 esize
= *(const WORD
*)(pCArrayFormat
+2);
2977 ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
,
2978 pCArrayFormat
+ 4, 0);
2980 WriteConformance(pStubMsg
);
2982 ALIGN_POINTER(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
2984 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
2986 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
2987 /* copy constant sized part of struct */
2988 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
2989 memcpy(pStubMsg
->Buffer
, pMemory
, pCStructFormat
->memory_size
+ bufsize
);
2990 pStubMsg
->Buffer
+= pCStructFormat
->memory_size
+ bufsize
;
2992 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
2993 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
2995 STD_OVERFLOW_CHECK(pStubMsg
);
3000 /***********************************************************************
3001 * NdrConformantStructUnmarshall [RPCRT4.@]
3003 unsigned char * WINAPI
NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3004 unsigned char **ppMemory
,
3005 PFORMAT_STRING pFormat
,
3006 unsigned char fMustAlloc
)
3008 const NDR_CSTRUCT_FORMAT
*pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3009 PFORMAT_STRING pCArrayFormat
;
3010 ULONG esize
, bufsize
;
3012 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3014 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3015 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3017 ERR("invalid format type %x\n", pCStructFormat
->type
);
3018 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3021 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3022 pCStructFormat
->offset_to_array_description
;
3023 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3025 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3026 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3029 esize
= *(const WORD
*)(pCArrayFormat
+2);
3031 pCArrayFormat
= ReadConformance(pStubMsg
, pCArrayFormat
+ 4);
3033 ALIGN_POINTER(pStubMsg
->Buffer
, pCStructFormat
->alignment
+ 1);
3035 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3037 bufsize
= safe_multiply(esize
, pStubMsg
->MaxCount
);
3038 /* work out how much memory to allocate if we need to do so */
3039 if (!*ppMemory
|| fMustAlloc
)
3041 SIZE_T size
= pCStructFormat
->memory_size
+ bufsize
;
3042 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3045 /* now copy the data */
3046 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3047 memcpy(*ppMemory
, pStubMsg
->Buffer
, pCStructFormat
->memory_size
+ bufsize
);
3048 pStubMsg
->Buffer
+= pCStructFormat
->memory_size
+ bufsize
;
3050 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3051 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3056 /***********************************************************************
3057 * NdrConformantStructBufferSize [RPCRT4.@]
3059 void WINAPI
NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3060 unsigned char *pMemory
,
3061 PFORMAT_STRING pFormat
)
3063 const NDR_CSTRUCT_FORMAT
* pCStructFormat
= (const NDR_CSTRUCT_FORMAT
*)pFormat
;
3064 PFORMAT_STRING pCArrayFormat
;
3067 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3069 pFormat
+= sizeof(NDR_CSTRUCT_FORMAT
);
3070 if ((pCStructFormat
->type
!= RPC_FC_CPSTRUCT
) && (pCStructFormat
->type
!= RPC_FC_CSTRUCT
))
3072 ERR("invalid format type %x\n", pCStructFormat
->type
);
3073 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3076 pCArrayFormat
= (const unsigned char *)&pCStructFormat
->offset_to_array_description
+
3077 pCStructFormat
->offset_to_array_description
;
3078 if (*pCArrayFormat
!= RPC_FC_CARRAY
)
3080 ERR("invalid array format type %x\n", pCStructFormat
->type
);
3081 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3084 esize
= *(const WORD
*)(pCArrayFormat
+2);
3086 pCArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCStructFormat
->memory_size
, pCArrayFormat
+4, 0);
3087 SizeConformance(pStubMsg
);
3089 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCStructFormat
->alignment
+ 1);
3091 TRACE("memory_size = %d\n", pCStructFormat
->memory_size
);
3093 pStubMsg
->BufferLength
+= pCStructFormat
->memory_size
+
3094 safe_multiply(pStubMsg
->MaxCount
, esize
);
3096 if (pCStructFormat
->type
== RPC_FC_CPSTRUCT
)
3097 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3100 /***********************************************************************
3101 * NdrConformantStructMemorySize [RPCRT4.@]
3103 unsigned long WINAPI
NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3104 PFORMAT_STRING pFormat
)
3110 /***********************************************************************
3111 * NdrConformantStructFree [RPCRT4.@]
3113 void WINAPI
NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3114 unsigned char *pMemory
,
3115 PFORMAT_STRING pFormat
)
3120 /***********************************************************************
3121 * NdrConformantVaryingStructMarshall [RPCRT4.@]
3123 unsigned char * WINAPI
NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3124 unsigned char *pMemory
,
3125 PFORMAT_STRING pFormat
)
3127 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3128 PFORMAT_STRING pCVArrayFormat
;
3129 ULONG esize
, bufsize
;
3131 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3133 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3134 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3136 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3137 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3141 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3142 pCVStructFormat
->offset_to_array_description
;
3143 switch (*pCVArrayFormat
)
3145 case RPC_FC_CVARRAY
:
3146 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3148 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3149 pCVArrayFormat
+ 4, 0);
3150 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3153 case RPC_FC_C_CSTRING
:
3154 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
3155 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
3156 esize
= sizeof(char);
3157 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3158 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3159 pCVArrayFormat
+ 2, 0);
3161 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3163 case RPC_FC_C_WSTRING
:
3164 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
3165 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
3166 esize
= sizeof(WCHAR
);
3167 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3168 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3169 pCVArrayFormat
+ 2, 0);
3171 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3174 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3175 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3179 WriteConformance(pStubMsg
);
3181 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
3183 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3185 /* write constant sized part */
3186 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3187 memcpy(pStubMsg
->Buffer
, pMemory
, pCVStructFormat
->memory_size
);
3188 pStubMsg
->Buffer
+= pCVStructFormat
->memory_size
;
3190 WriteVariance(pStubMsg
);
3192 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3194 /* write array part */
3195 memcpy(pStubMsg
->Buffer
, pMemory
+ pCVStructFormat
->memory_size
, bufsize
);
3196 pStubMsg
->Buffer
+= bufsize
;
3198 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3200 STD_OVERFLOW_CHECK(pStubMsg
);
3205 /***********************************************************************
3206 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
3208 unsigned char * WINAPI
NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3209 unsigned char **ppMemory
,
3210 PFORMAT_STRING pFormat
,
3211 unsigned char fMustAlloc
)
3213 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3214 PFORMAT_STRING pCVArrayFormat
;
3215 ULONG esize
, bufsize
;
3216 unsigned char cvarray_type
;
3218 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3220 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3221 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3223 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3224 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3228 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3229 pCVStructFormat
->offset_to_array_description
;
3230 cvarray_type
= *pCVArrayFormat
;
3231 switch (cvarray_type
)
3233 case RPC_FC_CVARRAY
:
3234 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3235 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 4);
3237 case RPC_FC_C_CSTRING
:
3238 esize
= sizeof(char);
3239 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3240 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3242 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3244 case RPC_FC_C_WSTRING
:
3245 esize
= sizeof(WCHAR
);
3246 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3247 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3249 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3252 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3253 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3257 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
3259 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3261 /* work out how much memory to allocate if we need to do so */
3262 if (!*ppMemory
|| fMustAlloc
)
3264 SIZE_T size
= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->MaxCount
);
3265 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3268 /* copy the constant data */
3269 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3270 memcpy(*ppMemory
, pStubMsg
->Buffer
, pCVStructFormat
->memory_size
);
3271 pStubMsg
->Buffer
+= pCVStructFormat
->memory_size
;
3273 pCVArrayFormat
= ReadVariance(pStubMsg
, pCVArrayFormat
, pStubMsg
->MaxCount
);
3275 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3277 if ((cvarray_type
== RPC_FC_C_CSTRING
) ||
3278 (cvarray_type
== RPC_FC_C_WSTRING
))
3281 /* strings must always have null terminating bytes */
3282 if (bufsize
< esize
)
3284 ERR("invalid string length of %ld\n", pStubMsg
->ActualCount
);
3285 RpcRaiseException(RPC_S_INVALID_BOUND
);
3288 for (i
= bufsize
- esize
; i
< bufsize
; i
++)
3289 if (pStubMsg
->Buffer
[i
] != 0)
3291 ERR("string not null-terminated at byte position %ld, data is 0x%x\n",
3292 i
, pStubMsg
->Buffer
[i
]);
3293 RpcRaiseException(RPC_S_INVALID_BOUND
);
3298 /* copy the array data */
3299 memcpy(*ppMemory
+ pCVStructFormat
->memory_size
, pStubMsg
->Buffer
,
3301 pStubMsg
->Buffer
+= bufsize
;
3303 if (cvarray_type
== RPC_FC_C_CSTRING
)
3304 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory
+ pCVStructFormat
->memory_size
)));
3305 else if (cvarray_type
== RPC_FC_C_WSTRING
)
3306 TRACE("string=%s\n", debugstr_w((WCHAR
*)(*ppMemory
+ pCVStructFormat
->memory_size
)));
3308 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3313 /***********************************************************************
3314 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
3316 void WINAPI
NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3317 unsigned char *pMemory
,
3318 PFORMAT_STRING pFormat
)
3320 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3321 PFORMAT_STRING pCVArrayFormat
;
3324 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3326 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3327 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3329 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3330 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3334 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3335 pCVStructFormat
->offset_to_array_description
;
3336 switch (*pCVArrayFormat
)
3338 case RPC_FC_CVARRAY
:
3339 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3341 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3342 pCVArrayFormat
+ 4, 0);
3343 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3346 case RPC_FC_C_CSTRING
:
3347 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
3348 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
3349 esize
= sizeof(char);
3350 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3351 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3352 pCVArrayFormat
+ 2, 0);
3354 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3356 case RPC_FC_C_WSTRING
:
3357 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
3358 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
3359 esize
= sizeof(WCHAR
);
3360 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3361 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3362 pCVArrayFormat
+ 2, 0);
3364 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3367 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3368 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3372 SizeConformance(pStubMsg
);
3374 ALIGN_LENGTH(pStubMsg
->BufferLength
, pCVStructFormat
->alignment
+ 1);
3376 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3378 pStubMsg
->BufferLength
+= pCVStructFormat
->memory_size
;
3379 SizeVariance(pStubMsg
);
3380 pStubMsg
->BufferLength
+= safe_multiply(pStubMsg
->MaxCount
, esize
);
3382 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3385 /***********************************************************************
3386 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
3388 unsigned long WINAPI
NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3389 PFORMAT_STRING pFormat
)
3391 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3392 PFORMAT_STRING pCVArrayFormat
;
3394 unsigned char cvarray_type
;
3396 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
3398 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3399 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3401 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3402 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3406 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3407 pCVStructFormat
->offset_to_array_description
;
3408 cvarray_type
= *pCVArrayFormat
;
3409 switch (cvarray_type
)
3411 case RPC_FC_CVARRAY
:
3412 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3413 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 4);
3415 case RPC_FC_C_CSTRING
:
3416 esize
= sizeof(char);
3417 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3418 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3420 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3422 case RPC_FC_C_WSTRING
:
3423 esize
= sizeof(WCHAR
);
3424 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3425 pCVArrayFormat
= ReadConformance(pStubMsg
, pCVArrayFormat
+ 2);
3427 pCVArrayFormat
= ReadConformance(pStubMsg
, NULL
);
3430 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3431 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3435 ALIGN_POINTER(pStubMsg
->Buffer
, pCVStructFormat
->alignment
+ 1);
3437 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3439 pStubMsg
->Buffer
+= pCVStructFormat
->memory_size
;
3440 pCVArrayFormat
= ReadVariance(pStubMsg
, pCVArrayFormat
, pStubMsg
->MaxCount
);
3441 pStubMsg
->Buffer
+= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->ActualCount
);
3443 pStubMsg
->MemorySize
+= pCVStructFormat
->memory_size
+ safe_multiply(esize
, pStubMsg
->MaxCount
);
3445 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
3447 return pCVStructFormat
->memory_size
+ pStubMsg
->MaxCount
* esize
;
3450 /***********************************************************************
3451 * NdrConformantVaryingStructFree [RPCRT4.@]
3453 void WINAPI
NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg
,
3454 unsigned char *pMemory
,
3455 PFORMAT_STRING pFormat
)
3457 const NDR_CVSTRUCT_FORMAT
*pCVStructFormat
= (const NDR_CVSTRUCT_FORMAT
*)pFormat
;
3458 PFORMAT_STRING pCVArrayFormat
;
3461 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3463 pFormat
+= sizeof(NDR_CVSTRUCT_FORMAT
);
3464 if (pCVStructFormat
->type
!= RPC_FC_CVSTRUCT
)
3466 ERR("invalid format type %x\n", pCVStructFormat
->type
);
3467 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3471 pCVArrayFormat
= (const unsigned char *)&pCVStructFormat
->offset_to_array_description
+
3472 pCVStructFormat
->offset_to_array_description
;
3473 switch (*pCVArrayFormat
)
3475 case RPC_FC_CVARRAY
:
3476 esize
= *(const WORD
*)(pCVArrayFormat
+2);
3478 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3479 pCVArrayFormat
+ 4, 0);
3480 pCVArrayFormat
= ComputeVariance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3483 case RPC_FC_C_CSTRING
:
3484 TRACE("string=%s\n", debugstr_a((char*)pMemory
+ pCVStructFormat
->memory_size
));
3485 pStubMsg
->ActualCount
= strlen((char*)pMemory
+ pCVStructFormat
->memory_size
)+1;
3486 esize
= sizeof(char);
3487 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3488 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3489 pCVArrayFormat
+ 2, 0);
3491 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3493 case RPC_FC_C_WSTRING
:
3494 TRACE("string=%s\n", debugstr_w((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
));
3495 pStubMsg
->ActualCount
= strlenW((LPWSTR
)pMemory
+ pCVStructFormat
->memory_size
)+1;
3496 esize
= sizeof(WCHAR
);
3497 if (pCVArrayFormat
[1] == RPC_FC_STRING_SIZED
)
3498 pCVArrayFormat
= ComputeConformance(pStubMsg
, pMemory
+ pCVStructFormat
->memory_size
,
3499 pCVArrayFormat
+ 2, 0);
3501 pStubMsg
->MaxCount
= pStubMsg
->ActualCount
;
3504 ERR("invalid array format type %x\n", *pCVArrayFormat
);
3505 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3509 TRACE("memory_size = %d\n", pCVStructFormat
->memory_size
);
3511 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
3517 unsigned char alignment
;
3518 unsigned short total_size
;
3519 } NDR_SMFARRAY_FORMAT
;
3524 unsigned char alignment
;
3525 unsigned long total_size
;
3526 } NDR_LGFARRAY_FORMAT
;
3528 /***********************************************************************
3529 * NdrFixedArrayMarshall [RPCRT4.@]
3531 unsigned char * WINAPI
NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3532 unsigned char *pMemory
,
3533 PFORMAT_STRING pFormat
)
3535 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
3536 unsigned long total_size
;
3538 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3540 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
3541 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
3543 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
3544 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3548 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
3550 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
3552 total_size
= pSmFArrayFormat
->total_size
;
3553 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
3557 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
3558 total_size
= pLgFArrayFormat
->total_size
;
3559 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
3562 memcpy(pStubMsg
->Buffer
, pMemory
, total_size
);
3563 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3564 pStubMsg
->Buffer
+= total_size
;
3566 pFormat
= EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3571 /***********************************************************************
3572 * NdrFixedArrayUnmarshall [RPCRT4.@]
3574 unsigned char * WINAPI
NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3575 unsigned char **ppMemory
,
3576 PFORMAT_STRING pFormat
,
3577 unsigned char fMustAlloc
)
3579 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
3580 unsigned long total_size
;
3582 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3584 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
3585 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
3587 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
3588 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3592 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
3594 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
3596 total_size
= pSmFArrayFormat
->total_size
;
3597 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
3601 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
3602 total_size
= pLgFArrayFormat
->total_size
;
3603 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
3606 if (fMustAlloc
|| !*ppMemory
)
3607 *ppMemory
= NdrAllocate(pStubMsg
, total_size
);
3608 memcpy(*ppMemory
, pStubMsg
->Buffer
, total_size
);
3609 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3610 pStubMsg
->Buffer
+= total_size
;
3612 pFormat
= EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3617 /***********************************************************************
3618 * NdrFixedArrayBufferSize [RPCRT4.@]
3620 void WINAPI
NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3621 unsigned char *pMemory
,
3622 PFORMAT_STRING pFormat
)
3624 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
3625 unsigned long total_size
;
3627 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3629 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
3630 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
3632 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
3633 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3637 ALIGN_LENGTH(pStubMsg
->BufferLength
, pSmFArrayFormat
->alignment
+ 1);
3639 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
3641 total_size
= pSmFArrayFormat
->total_size
;
3642 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
3646 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
3647 total_size
= pLgFArrayFormat
->total_size
;
3648 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
3650 pStubMsg
->BufferLength
+= total_size
;
3652 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3655 /***********************************************************************
3656 * NdrFixedArrayMemorySize [RPCRT4.@]
3658 unsigned long WINAPI
NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3659 PFORMAT_STRING pFormat
)
3661 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
3662 unsigned long total_size
;
3664 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
3666 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
3667 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
3669 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
3670 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3674 ALIGN_POINTER(pStubMsg
->Buffer
, pSmFArrayFormat
->alignment
+ 1);
3676 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
3678 total_size
= pSmFArrayFormat
->total_size
;
3679 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
3683 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
3684 total_size
= pLgFArrayFormat
->total_size
;
3685 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
3687 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3688 pStubMsg
->Buffer
+= total_size
;
3689 pStubMsg
->MemorySize
+= total_size
;
3691 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
3696 /***********************************************************************
3697 * NdrFixedArrayFree [RPCRT4.@]
3699 void WINAPI
NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3700 unsigned char *pMemory
,
3701 PFORMAT_STRING pFormat
)
3703 const NDR_SMFARRAY_FORMAT
*pSmFArrayFormat
= (const NDR_SMFARRAY_FORMAT
*)pFormat
;
3705 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3707 if ((pSmFArrayFormat
->type
!= RPC_FC_SMFARRAY
) &&
3708 (pSmFArrayFormat
->type
!= RPC_FC_LGFARRAY
))
3710 ERR("invalid format type %x\n", pSmFArrayFormat
->type
);
3711 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3715 if (pSmFArrayFormat
->type
== RPC_FC_SMFARRAY
)
3716 pFormat
= (const unsigned char *)(pSmFArrayFormat
+ 1);
3719 const NDR_LGFARRAY_FORMAT
*pLgFArrayFormat
= (const NDR_LGFARRAY_FORMAT
*)pFormat
;
3720 pFormat
= (const unsigned char *)(pLgFArrayFormat
+ 1);
3723 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
3726 /***********************************************************************
3727 * NdrVaryingArrayMarshall [RPCRT4.@]
3729 unsigned char * WINAPI
NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3730 unsigned char *pMemory
,
3731 PFORMAT_STRING pFormat
)
3733 unsigned char alignment
;
3734 DWORD elements
, esize
;
3737 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3739 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
3740 (pFormat
[0] != RPC_FC_LGVARRAY
))
3742 ERR("invalid format type %x\n", pFormat
[0]);
3743 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3747 alignment
= pFormat
[1] + 1;
3749 if (pFormat
[0] == RPC_FC_SMVARRAY
)
3752 pFormat
+= sizeof(WORD
);
3753 elements
= *(const WORD
*)pFormat
;
3754 pFormat
+= sizeof(WORD
);
3759 pFormat
+= sizeof(DWORD
);
3760 elements
= *(const DWORD
*)pFormat
;
3761 pFormat
+= sizeof(DWORD
);
3764 esize
= *(const WORD
*)pFormat
;
3765 pFormat
+= sizeof(WORD
);
3767 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
3768 if ((pStubMsg
->ActualCount
> elements
) ||
3769 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
3771 RpcRaiseException(RPC_S_INVALID_BOUND
);
3775 WriteVariance(pStubMsg
);
3777 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3779 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3780 memcpy(pStubMsg
->Buffer
, pMemory
+ pStubMsg
->Offset
, bufsize
);
3781 pStubMsg
->BufferMark
= pStubMsg
->Buffer
;
3782 pStubMsg
->Buffer
+= bufsize
;
3784 EmbeddedPointerMarshall(pStubMsg
, pMemory
, pFormat
);
3786 STD_OVERFLOW_CHECK(pStubMsg
);
3791 /***********************************************************************
3792 * NdrVaryingArrayUnmarshall [RPCRT4.@]
3794 unsigned char * WINAPI
NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
3795 unsigned char **ppMemory
,
3796 PFORMAT_STRING pFormat
,
3797 unsigned char fMustAlloc
)
3799 unsigned char alignment
;
3800 DWORD size
, elements
, esize
;
3803 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3805 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
3806 (pFormat
[0] != RPC_FC_LGVARRAY
))
3808 ERR("invalid format type %x\n", pFormat
[0]);
3809 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3813 alignment
= pFormat
[1] + 1;
3815 if (pFormat
[0] == RPC_FC_SMVARRAY
)
3818 size
= *(const WORD
*)pFormat
;
3819 pFormat
+= sizeof(WORD
);
3820 elements
= *(const WORD
*)pFormat
;
3821 pFormat
+= sizeof(WORD
);
3826 size
= *(const DWORD
*)pFormat
;
3827 pFormat
+= sizeof(DWORD
);
3828 elements
= *(const DWORD
*)pFormat
;
3829 pFormat
+= sizeof(DWORD
);
3832 esize
= *(const WORD
*)pFormat
;
3833 pFormat
+= sizeof(WORD
);
3835 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
3837 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3839 bufsize
= safe_multiply(esize
, pStubMsg
->ActualCount
);
3841 if (!*ppMemory
|| fMustAlloc
)
3842 *ppMemory
= NdrAllocate(pStubMsg
, size
);
3843 memcpy(*ppMemory
+ pStubMsg
->Offset
, pStubMsg
->Buffer
, bufsize
);
3844 pStubMsg
->Buffer
+= bufsize
;
3846 EmbeddedPointerUnmarshall(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
3851 /***********************************************************************
3852 * NdrVaryingArrayBufferSize [RPCRT4.@]
3854 void WINAPI
NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
3855 unsigned char *pMemory
,
3856 PFORMAT_STRING pFormat
)
3858 unsigned char alignment
;
3859 DWORD elements
, esize
;
3861 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3863 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
3864 (pFormat
[0] != RPC_FC_LGVARRAY
))
3866 ERR("invalid format type %x\n", pFormat
[0]);
3867 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3871 alignment
= pFormat
[1] + 1;
3873 if (pFormat
[0] == RPC_FC_SMVARRAY
)
3876 pFormat
+= sizeof(WORD
);
3877 elements
= *(const WORD
*)pFormat
;
3878 pFormat
+= sizeof(WORD
);
3883 pFormat
+= sizeof(DWORD
);
3884 elements
= *(const DWORD
*)pFormat
;
3885 pFormat
+= sizeof(DWORD
);
3888 esize
= *(const WORD
*)pFormat
;
3889 pFormat
+= sizeof(WORD
);
3891 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
3892 if ((pStubMsg
->ActualCount
> elements
) ||
3893 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
3895 RpcRaiseException(RPC_S_INVALID_BOUND
);
3899 SizeVariance(pStubMsg
);
3901 ALIGN_LENGTH(pStubMsg
->BufferLength
, alignment
);
3903 pStubMsg
->BufferLength
+= safe_multiply(esize
, pStubMsg
->ActualCount
);
3905 EmbeddedPointerBufferSize(pStubMsg
, pMemory
, pFormat
);
3908 /***********************************************************************
3909 * NdrVaryingArrayMemorySize [RPCRT4.@]
3911 unsigned long WINAPI
NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
3912 PFORMAT_STRING pFormat
)
3914 unsigned char alignment
;
3915 DWORD size
, elements
, esize
;
3917 TRACE("(%p, %p)\n", pStubMsg
, pFormat
);
3919 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
3920 (pFormat
[0] != RPC_FC_LGVARRAY
))
3922 ERR("invalid format type %x\n", pFormat
[0]);
3923 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3927 alignment
= pFormat
[1] + 1;
3929 if (pFormat
[0] == RPC_FC_SMVARRAY
)
3932 size
= *(const WORD
*)pFormat
;
3933 pFormat
+= sizeof(WORD
);
3934 elements
= *(const WORD
*)pFormat
;
3935 pFormat
+= sizeof(WORD
);
3940 size
= *(const DWORD
*)pFormat
;
3941 pFormat
+= sizeof(DWORD
);
3942 elements
= *(const DWORD
*)pFormat
;
3943 pFormat
+= sizeof(DWORD
);
3946 esize
= *(const WORD
*)pFormat
;
3947 pFormat
+= sizeof(WORD
);
3949 pFormat
= ReadVariance(pStubMsg
, pFormat
, elements
);
3951 ALIGN_POINTER(pStubMsg
->Buffer
, alignment
);
3953 pStubMsg
->Buffer
+= safe_multiply(esize
, pStubMsg
->ActualCount
);
3954 pStubMsg
->MemorySize
+= size
;
3956 EmbeddedPointerMemorySize(pStubMsg
, pFormat
);
3958 return pStubMsg
->MemorySize
;
3961 /***********************************************************************
3962 * NdrVaryingArrayFree [RPCRT4.@]
3964 void WINAPI
NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg
,
3965 unsigned char *pMemory
,
3966 PFORMAT_STRING pFormat
)
3968 unsigned char alignment
;
3971 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
3973 if ((pFormat
[0] != RPC_FC_SMVARRAY
) &&
3974 (pFormat
[0] != RPC_FC_LGVARRAY
))
3976 ERR("invalid format type %x\n", pFormat
[0]);
3977 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
3981 alignment
= pFormat
[1] + 1;
3983 if (pFormat
[0] == RPC_FC_SMVARRAY
)
3986 pFormat
+= sizeof(WORD
);
3987 elements
= *(const WORD
*)pFormat
;
3988 pFormat
+= sizeof(WORD
);
3993 pFormat
+= sizeof(DWORD
);
3994 elements
= *(const DWORD
*)pFormat
;
3995 pFormat
+= sizeof(DWORD
);
3998 pFormat
+= sizeof(WORD
);
4000 pFormat
= ComputeVariance(pStubMsg
, pMemory
, pFormat
, 0);
4001 if ((pStubMsg
->ActualCount
> elements
) ||
4002 (pStubMsg
->ActualCount
+ pStubMsg
->Offset
> elements
))
4004 RpcRaiseException(RPC_S_INVALID_BOUND
);
4008 EmbeddedPointerFree(pStubMsg
, pMemory
, pFormat
);
4011 /***********************************************************************
4012 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
4014 unsigned char * WINAPI
NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4015 unsigned char *pMemory
,
4016 PFORMAT_STRING pFormat
)
4022 /***********************************************************************
4023 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
4025 unsigned char * WINAPI
NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4026 unsigned char **ppMemory
,
4027 PFORMAT_STRING pFormat
,
4028 unsigned char fMustAlloc
)
4034 /***********************************************************************
4035 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
4037 void WINAPI
NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4038 unsigned char *pMemory
,
4039 PFORMAT_STRING pFormat
)
4044 /***********************************************************************
4045 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
4047 unsigned long WINAPI
NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4048 PFORMAT_STRING pFormat
)
4054 /***********************************************************************
4055 * NdrEncapsulatedUnionFree [RPCRT4.@]
4057 void WINAPI
NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
4058 unsigned char *pMemory
,
4059 PFORMAT_STRING pFormat
)
4064 static PFORMAT_STRING
get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg
,
4065 unsigned long discriminant
,
4066 PFORMAT_STRING pFormat
)
4068 unsigned short num_arms
, arm
, type
;
4070 num_arms
= *(const SHORT
*)pFormat
& 0x0fff;
4072 for(arm
= 0; arm
< num_arms
; arm
++)
4074 if(discriminant
== *(const ULONG
*)pFormat
)
4082 type
= *(const unsigned short*)pFormat
;
4083 TRACE("type %04x\n", type
);
4084 if(arm
== num_arms
) /* default arm extras */
4088 ERR("no arm for 0x%lx and no default case\n", discriminant
);
4089 RpcRaiseException(RPC_S_INVALID_TAG
);
4094 TRACE("falling back to empty default case for 0x%lx\n", discriminant
);
4101 static PFORMAT_STRING
get_non_encapsulated_union_arm(PMIDL_STUB_MESSAGE pStubMsg
,
4103 PFORMAT_STRING pFormat
)
4105 pFormat
+= *(const SHORT
*)pFormat
;
4108 return get_arm_offset_from_union_arm_selector(pStubMsg
, value
, pFormat
);
4111 /***********************************************************************
4112 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
4114 unsigned char * WINAPI
NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4115 unsigned char *pMemory
,
4116 PFORMAT_STRING pFormat
)
4118 unsigned short type
;
4119 unsigned char switch_type
;
4121 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4124 switch_type
= *pFormat
;
4127 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
4128 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
4129 /* Marshall discriminant */
4130 NdrBaseTypeMarshall(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
4132 pFormat
= get_non_encapsulated_union_arm(pStubMsg
, pStubMsg
->MaxCount
, pFormat
);
4136 type
= *(const unsigned short*)pFormat
;
4137 if((type
& 0xff00) == 0x8000)
4139 unsigned char basetype
= LOBYTE(type
);
4140 return NdrBaseTypeMarshall(pStubMsg
, pMemory
, &basetype
);
4144 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4145 NDR_MARSHALL m
= NdrMarshaller
[*desc
& NDR_TABLE_MASK
];
4148 unsigned char *saved_buffer
= NULL
;
4155 saved_buffer
= pStubMsg
->Buffer
;
4156 pStubMsg
->Buffer
+= 4; /* for pointer ID */
4157 PointerMarshall(pStubMsg
, saved_buffer
, *(unsigned char **)pMemory
, desc
);
4160 m(pStubMsg
, pMemory
, desc
);
4163 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4168 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg
,
4169 PFORMAT_STRING
*ppFormat
)
4171 long discriminant
= 0;
4179 discriminant
= *(UCHAR
*)pStubMsg
->Buffer
;
4180 pStubMsg
->Buffer
+= sizeof(UCHAR
);
4185 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
4186 discriminant
= *(USHORT
*)pStubMsg
->Buffer
;
4187 pStubMsg
->Buffer
+= sizeof(USHORT
);
4191 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
4192 discriminant
= *(ULONG
*)pStubMsg
->Buffer
;
4193 pStubMsg
->Buffer
+= sizeof(ULONG
);
4196 FIXME("Unhandled base type: 0x%02x\n", **ppFormat
);
4200 if (pStubMsg
->fHasNewCorrDesc
)
4204 return discriminant
;
4207 /**********************************************************************
4208 * NdrNonEncapsulatedUnionUnmarshall[RPCRT4.@]
4210 unsigned char * WINAPI
NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4211 unsigned char **ppMemory
,
4212 PFORMAT_STRING pFormat
,
4213 unsigned char fMustAlloc
)
4216 unsigned short type
, size
;
4218 TRACE("(%p, %p, %p, %d)\n", pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
4221 /* Unmarshall discriminant */
4222 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
4223 TRACE("unmarshalled discriminant %lx\n", discriminant
);
4225 pFormat
+= *(const SHORT
*)pFormat
;
4227 size
= *(const unsigned short*)pFormat
;
4230 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4234 if(!*ppMemory
|| fMustAlloc
)
4235 *ppMemory
= NdrAllocate(pStubMsg
, size
);
4237 type
= *(const unsigned short*)pFormat
;
4238 if((type
& 0xff00) == 0x8000)
4240 unsigned char basetype
= LOBYTE(type
);
4241 return NdrBaseTypeUnmarshall(pStubMsg
, ppMemory
, &basetype
, fMustAlloc
);
4245 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4246 NDR_UNMARSHALL m
= NdrUnmarshaller
[*desc
& NDR_TABLE_MASK
];
4249 unsigned char *saved_buffer
= NULL
;
4256 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4257 saved_buffer
= pStubMsg
->Buffer
;
4258 pStubMsg
->Buffer
+= 4; /* for pointer ID */
4259 PointerUnmarshall(pStubMsg
, saved_buffer
, *(unsigned char ***)ppMemory
, desc
, TRUE
);
4262 m(pStubMsg
, ppMemory
, desc
, fMustAlloc
);
4265 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4270 /***********************************************************************
4271 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
4273 void WINAPI
NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4274 unsigned char *pMemory
,
4275 PFORMAT_STRING pFormat
)
4277 unsigned short type
;
4278 unsigned char switch_type
;
4280 TRACE("(%p, %p, %p)\n", pStubMsg
, pMemory
, pFormat
);
4283 switch_type
= *pFormat
;
4286 pFormat
= ComputeConformance(pStubMsg
, pMemory
, pFormat
, 0);
4287 TRACE("got switch value 0x%lx\n", pStubMsg
->MaxCount
);
4288 /* Add discriminant size */
4289 NdrBaseTypeBufferSize(pStubMsg
, (unsigned char *)&pStubMsg
->MaxCount
, &switch_type
);
4291 pFormat
= get_non_encapsulated_union_arm(pStubMsg
, pStubMsg
->MaxCount
, pFormat
);
4295 type
= *(const unsigned short*)pFormat
;
4296 if((type
& 0xff00) == 0x8000)
4298 unsigned char basetype
= LOBYTE(type
);
4299 NdrBaseTypeBufferSize(pStubMsg
, pMemory
, &basetype
);
4303 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4304 NDR_BUFFERSIZE m
= NdrBufferSizer
[*desc
& NDR_TABLE_MASK
];
4313 ALIGN_LENGTH(pStubMsg
->BufferLength
, 4);
4314 pStubMsg
->BufferLength
+= 4; /* for pointer ID */
4315 PointerBufferSize(pStubMsg
, *(unsigned char **)pMemory
, desc
);
4318 m(pStubMsg
, pMemory
, desc
);
4321 else FIXME("no buffersizer for embedded type %02x\n", *desc
);
4326 /***********************************************************************
4327 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
4329 unsigned long WINAPI
NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4330 PFORMAT_STRING pFormat
)
4332 unsigned long discriminant
;
4333 unsigned short type
, size
;
4336 /* Unmarshall discriminant */
4337 discriminant
= unmarshall_discriminant(pStubMsg
, &pFormat
);
4338 TRACE("unmarshalled discriminant 0x%lx\n", discriminant
);
4340 pFormat
+= *(const SHORT
*)pFormat
;
4342 size
= *(const unsigned short*)pFormat
;
4345 pFormat
= get_arm_offset_from_union_arm_selector(pStubMsg
, discriminant
, pFormat
);
4349 pStubMsg
->Memory
+= size
;
4351 type
= *(const unsigned short*)pFormat
;
4352 if((type
& 0xff00) == 0x8000)
4354 return NdrBaseTypeMemorySize(pStubMsg
, pFormat
);
4358 PFORMAT_STRING desc
= pFormat
+ *(const SHORT
*)pFormat
;
4359 NDR_MEMORYSIZE m
= NdrMemorySizer
[*desc
& NDR_TABLE_MASK
];
4360 unsigned char *saved_buffer
;
4369 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4370 saved_buffer
= pStubMsg
->Buffer
;
4371 pStubMsg
->Buffer
+= 4;
4372 ALIGN_LENGTH(pStubMsg
->MemorySize
, 4);
4373 pStubMsg
->MemorySize
+= 4;
4374 PointerMemorySize(pStubMsg
, saved_buffer
, pFormat
);
4377 return m(pStubMsg
, desc
);
4380 else FIXME("no marshaller for embedded type %02x\n", *desc
);
4383 TRACE("size %d\n", size
);
4387 /***********************************************************************
4388 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
4390 void WINAPI
NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg
,
4391 unsigned char *pMemory
,
4392 PFORMAT_STRING pFormat
)
4397 /***********************************************************************
4398 * NdrByteCountPointerMarshall [RPCRT4.@]
4400 unsigned char * WINAPI
NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4401 unsigned char *pMemory
,
4402 PFORMAT_STRING pFormat
)
4408 /***********************************************************************
4409 * NdrByteCountPointerUnmarshall [RPCRT4.@]
4411 unsigned char * WINAPI
NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4412 unsigned char **ppMemory
,
4413 PFORMAT_STRING pFormat
,
4414 unsigned char fMustAlloc
)
4420 /***********************************************************************
4421 * NdrByteCountPointerBufferSize [RPCRT4.@]
4423 void WINAPI
NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4424 unsigned char *pMemory
,
4425 PFORMAT_STRING pFormat
)
4430 /***********************************************************************
4431 * NdrByteCountPointerMemorySize [RPCRT4.@]
4433 unsigned long WINAPI
NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4434 PFORMAT_STRING pFormat
)
4440 /***********************************************************************
4441 * NdrByteCountPointerFree [RPCRT4.@]
4443 void WINAPI
NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg
,
4444 unsigned char *pMemory
,
4445 PFORMAT_STRING pFormat
)
4450 /***********************************************************************
4451 * NdrXmitOrRepAsMarshall [RPCRT4.@]
4453 unsigned char * WINAPI
NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4454 unsigned char *pMemory
,
4455 PFORMAT_STRING pFormat
)
4461 /***********************************************************************
4462 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
4464 unsigned char * WINAPI
NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4465 unsigned char **ppMemory
,
4466 PFORMAT_STRING pFormat
,
4467 unsigned char fMustAlloc
)
4473 /***********************************************************************
4474 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
4476 void WINAPI
NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg
,
4477 unsigned char *pMemory
,
4478 PFORMAT_STRING pFormat
)
4483 /***********************************************************************
4484 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
4486 unsigned long WINAPI
NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg
,
4487 PFORMAT_STRING pFormat
)
4493 /***********************************************************************
4494 * NdrXmitOrRepAsFree [RPCRT4.@]
4496 void WINAPI
NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg
,
4497 unsigned char *pMemory
,
4498 PFORMAT_STRING pFormat
)
4503 /***********************************************************************
4504 * NdrBaseTypeMarshall [internal]
4506 static unsigned char *WINAPI
NdrBaseTypeMarshall(
4507 PMIDL_STUB_MESSAGE pStubMsg
,
4508 unsigned char *pMemory
,
4509 PFORMAT_STRING pFormat
)
4511 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
4519 *(UCHAR
*)pStubMsg
->Buffer
= *(UCHAR
*)pMemory
;
4520 pStubMsg
->Buffer
+= sizeof(UCHAR
);
4521 TRACE("value: 0x%02x\n", *(UCHAR
*)pMemory
);
4526 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
4527 *(USHORT
*)pStubMsg
->Buffer
= *(USHORT
*)pMemory
;
4528 pStubMsg
->Buffer
+= sizeof(USHORT
);
4529 TRACE("value: 0x%04x\n", *(USHORT
*)pMemory
);
4533 case RPC_FC_ERROR_STATUS_T
:
4535 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONG
));
4536 *(ULONG
*)pStubMsg
->Buffer
= *(ULONG
*)pMemory
;
4537 pStubMsg
->Buffer
+= sizeof(ULONG
);
4538 TRACE("value: 0x%08lx\n", *(ULONG
*)pMemory
);
4541 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(float));
4542 *(float *)pStubMsg
->Buffer
= *(float *)pMemory
;
4543 pStubMsg
->Buffer
+= sizeof(float);
4546 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(double));
4547 *(double *)pStubMsg
->Buffer
= *(double *)pMemory
;
4548 pStubMsg
->Buffer
+= sizeof(double);
4551 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(ULONGLONG
));
4552 *(ULONGLONG
*)pStubMsg
->Buffer
= *(ULONGLONG
*)pMemory
;
4553 pStubMsg
->Buffer
+= sizeof(ULONGLONG
);
4554 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG
*)pMemory
));
4557 /* only 16-bits on the wire, so do a sanity check */
4558 if (*(UINT
*)pMemory
> USHRT_MAX
)
4559 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE
);
4560 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
4561 *(USHORT
*)pStubMsg
->Buffer
= *(UINT
*)pMemory
;
4562 pStubMsg
->Buffer
+= sizeof(USHORT
);
4563 TRACE("value: 0x%04x\n", *(UINT
*)pMemory
);
4566 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
4569 STD_OVERFLOW_CHECK(pStubMsg
);
4571 /* FIXME: what is the correct return value? */
4575 /***********************************************************************
4576 * NdrBaseTypeUnmarshall [internal]
4578 static unsigned char *WINAPI
NdrBaseTypeUnmarshall(
4579 PMIDL_STUB_MESSAGE pStubMsg
,
4580 unsigned char **ppMemory
,
4581 PFORMAT_STRING pFormat
,
4582 unsigned char fMustAlloc
)
4584 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg
, ppMemory
, *pFormat
, fMustAlloc
? "true" : "false");
4586 #define BASE_TYPE_UNMARSHALL(type) \
4587 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
4588 if (fMustAlloc || !*ppMemory) \
4589 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
4590 TRACE("*ppMemory: %p\n", *ppMemory); \
4591 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
4592 pStubMsg->Buffer += sizeof(type);
4600 BASE_TYPE_UNMARSHALL(UCHAR
);
4601 TRACE("value: 0x%02x\n", **(UCHAR
**)ppMemory
);
4606 BASE_TYPE_UNMARSHALL(USHORT
);
4607 TRACE("value: 0x%04x\n", **(USHORT
**)ppMemory
);
4611 case RPC_FC_ERROR_STATUS_T
:
4613 BASE_TYPE_UNMARSHALL(ULONG
);
4614 TRACE("value: 0x%08lx\n", **(ULONG
**)ppMemory
);
4617 BASE_TYPE_UNMARSHALL(float);
4618 TRACE("value: %f\n", **(float **)ppMemory
);
4621 BASE_TYPE_UNMARSHALL(double);
4622 TRACE("value: %f\n", **(double **)ppMemory
);
4625 BASE_TYPE_UNMARSHALL(ULONGLONG
);
4626 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG
**)ppMemory
));
4629 ALIGN_POINTER(pStubMsg
->Buffer
, sizeof(USHORT
));
4630 if (fMustAlloc
|| !*ppMemory
)
4631 *ppMemory
= NdrAllocate(pStubMsg
, sizeof(UINT
));
4632 TRACE("*ppMemory: %p\n", *ppMemory
);
4633 /* 16-bits on the wire, but int in memory */
4634 **(UINT
**)ppMemory
= *(USHORT
*)pStubMsg
->Buffer
;
4635 pStubMsg
->Buffer
+= sizeof(USHORT
);
4636 TRACE("value: 0x%08x\n", **(UINT
**)ppMemory
);
4639 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
4641 #undef BASE_TYPE_UNMARSHALL
4643 /* FIXME: what is the correct return value? */
4648 /***********************************************************************
4649 * NdrBaseTypeBufferSize [internal]
4651 static void WINAPI
NdrBaseTypeBufferSize(
4652 PMIDL_STUB_MESSAGE pStubMsg
,
4653 unsigned char *pMemory
,
4654 PFORMAT_STRING pFormat
)
4656 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
4664 pStubMsg
->BufferLength
+= sizeof(UCHAR
);
4670 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(USHORT
));
4671 pStubMsg
->BufferLength
+= sizeof(USHORT
);
4676 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONG
));
4677 pStubMsg
->BufferLength
+= sizeof(ULONG
);
4680 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(float));
4681 pStubMsg
->BufferLength
+= sizeof(float);
4684 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(double));
4685 pStubMsg
->BufferLength
+= sizeof(double);
4688 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(ULONGLONG
));
4689 pStubMsg
->BufferLength
+= sizeof(ULONGLONG
);
4691 case RPC_FC_ERROR_STATUS_T
:
4692 ALIGN_LENGTH(pStubMsg
->BufferLength
, sizeof(error_status_t
));
4693 pStubMsg
->BufferLength
+= sizeof(error_status_t
);
4696 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
4700 /***********************************************************************
4701 * NdrBaseTypeMemorySize [internal]
4703 static unsigned long WINAPI
NdrBaseTypeMemorySize(
4704 PMIDL_STUB_MESSAGE pStubMsg
,
4705 PFORMAT_STRING pFormat
)
4713 pStubMsg
->Buffer
+= sizeof(UCHAR
);
4714 pStubMsg
->MemorySize
+= sizeof(UCHAR
);
4715 return sizeof(UCHAR
);
4719 pStubMsg
->Buffer
+= sizeof(USHORT
);
4720 pStubMsg
->MemorySize
+= sizeof(USHORT
);
4721 return sizeof(USHORT
);
4724 pStubMsg
->Buffer
+= sizeof(ULONG
);
4725 pStubMsg
->MemorySize
+= sizeof(ULONG
);
4726 return sizeof(ULONG
);
4728 pStubMsg
->Buffer
+= sizeof(float);
4729 pStubMsg
->MemorySize
+= sizeof(float);
4730 return sizeof(float);
4732 pStubMsg
->Buffer
+= sizeof(double);
4733 pStubMsg
->MemorySize
+= sizeof(double);
4734 return sizeof(double);
4736 pStubMsg
->Buffer
+= sizeof(ULONGLONG
);
4737 pStubMsg
->MemorySize
+= sizeof(ULONGLONG
);
4738 return sizeof(ULONGLONG
);
4739 case RPC_FC_ERROR_STATUS_T
:
4740 pStubMsg
->Buffer
+= sizeof(error_status_t
);
4741 pStubMsg
->MemorySize
+= sizeof(error_status_t
);
4742 return sizeof(error_status_t
);
4745 pStubMsg
->Buffer
+= sizeof(INT
);
4746 pStubMsg
->MemorySize
+= sizeof(INT
);
4749 FIXME("Unhandled base type: 0x%02x\n", *pFormat
);
4754 /***********************************************************************
4755 * NdrBaseTypeFree [internal]
4757 static void WINAPI
NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg
,
4758 unsigned char *pMemory
,
4759 PFORMAT_STRING pFormat
)
4761 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg
, pMemory
, *pFormat
);
4766 /***********************************************************************
4767 * NdrClientContextMarshall
4769 void WINAPI
NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4770 NDR_CCONTEXT ContextHandle
,
4773 TRACE("(%p, %p, %d)\n", pStubMsg
, ContextHandle
, fCheck
);
4775 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4777 /* FIXME: what does fCheck do? */
4778 NDRCContextMarshall(ContextHandle
,
4781 pStubMsg
->Buffer
+= cbNDRContext
;
4784 /***********************************************************************
4785 * NdrClientContextUnmarshall
4787 void WINAPI
NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4788 NDR_CCONTEXT
* pContextHandle
,
4789 RPC_BINDING_HANDLE BindHandle
)
4791 TRACE("(%p, %p, %p)\n", pStubMsg
, pContextHandle
, BindHandle
);
4793 ALIGN_POINTER(pStubMsg
->Buffer
, 4);
4795 NDRCContextUnmarshall(pContextHandle
,
4798 pStubMsg
->RpcMsg
->DataRepresentation
);
4800 pStubMsg
->Buffer
+= cbNDRContext
;
4803 void WINAPI
NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4804 NDR_SCONTEXT ContextHandle
,
4805 NDR_RUNDOWN RundownRoutine
)
4807 FIXME("(%p, %p, %p): stub\n", pStubMsg
, ContextHandle
, RundownRoutine
);
4810 NDR_SCONTEXT WINAPI
NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
)
4812 FIXME("(%p): stub\n", pStubMsg
);
4816 void WINAPI
NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg
,
4817 unsigned char* pMemory
,
4818 PFORMAT_STRING pFormat
)
4820 FIXME("(%p, %p, %p): stub\n", pStubMsg
, pMemory
, pFormat
);
4823 NDR_SCONTEXT WINAPI
NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg
,
4824 PFORMAT_STRING pFormat
)
4826 FIXME("(%p, %p): stub\n", pStubMsg
, pFormat
);
4830 void WINAPI
NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4831 NDR_SCONTEXT ContextHandle
,
4832 NDR_RUNDOWN RundownRoutine
,
4833 PFORMAT_STRING pFormat
)
4835 FIXME("(%p, %p, %p, %p): stub\n", pStubMsg
, ContextHandle
, RundownRoutine
, pFormat
);
4838 NDR_SCONTEXT WINAPI
NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
,
4839 PFORMAT_STRING pFormat
)
4841 FIXME("(%p, %p): stub\n", pStubMsg
, pFormat
);
4845 #define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e
4847 typedef struct ndr_context_handle
4851 } ndr_context_handle
;
4853 struct context_handle_entry
4857 RPC_BINDING_HANDLE handle
;
4858 ndr_context_handle wire_data
;
4861 static struct list context_handle_list
= LIST_INIT(context_handle_list
);
4863 static CRITICAL_SECTION ndr_context_cs
;
4864 static CRITICAL_SECTION_DEBUG ndr_context_debug
=
4866 0, 0, &ndr_context_cs
,
4867 { &ndr_context_debug
.ProcessLocksList
, &ndr_context_debug
.ProcessLocksList
},
4868 0, 0, { (DWORD_PTR
)(__FILE__
": ndr_context") }
4870 static CRITICAL_SECTION ndr_context_cs
= { &ndr_context_debug
, -1, 0, 0, 0, 0 };
4872 static struct context_handle_entry
*get_context_entry(NDR_CCONTEXT CContext
)
4874 struct context_handle_entry
*che
= (struct context_handle_entry
*) CContext
;
4876 if (che
->magic
!= NDR_CONTEXT_HANDLE_MAGIC
)
4881 static struct context_handle_entry
*context_entry_from_guid(LPGUID uuid
)
4883 struct context_handle_entry
*che
;
4884 LIST_FOR_EACH_ENTRY(che
, &context_handle_list
, struct context_handle_entry
, entry
)
4885 if (IsEqualGUID(&che
->wire_data
.uuid
, uuid
))
4890 RPC_BINDING_HANDLE WINAPI
NDRCContextBinding(NDR_CCONTEXT CContext
)
4892 struct context_handle_entry
*che
;
4893 RPC_BINDING_HANDLE handle
= NULL
;
4895 TRACE("%p\n", CContext
);
4897 EnterCriticalSection(&ndr_context_cs
);
4898 che
= get_context_entry(CContext
);
4900 handle
= che
->handle
;
4901 LeaveCriticalSection(&ndr_context_cs
);
4904 RpcRaiseException(ERROR_INVALID_HANDLE
);
4908 void WINAPI
NDRCContextMarshall(NDR_CCONTEXT CContext
, void *pBuff
)
4910 struct context_handle_entry
*che
;
4912 TRACE("%p %p\n", CContext
, pBuff
);
4916 EnterCriticalSection(&ndr_context_cs
);
4917 che
= get_context_entry(CContext
);
4918 memcpy(pBuff
, &che
->wire_data
, sizeof (ndr_context_handle
));
4919 LeaveCriticalSection(&ndr_context_cs
);
4923 ndr_context_handle
*wire_data
= (ndr_context_handle
*)pBuff
;
4924 wire_data
->attributes
= 0;
4925 wire_data
->uuid
= GUID_NULL
;
4929 static UINT
ndr_update_context_handle(NDR_CCONTEXT
*CContext
,
4930 RPC_BINDING_HANDLE hBinding
,
4931 ndr_context_handle
*chi
)
4933 struct context_handle_entry
*che
= NULL
;
4935 /* a null UUID means we should free the context handle */
4936 if (IsEqualGUID(&chi
->uuid
, &GUID_NULL
))
4940 che
= get_context_entry(*CContext
);
4942 return ERROR_INVALID_HANDLE
;
4943 list_remove(&che
->entry
);
4944 RpcBindingFree(&che
->handle
);
4945 HeapFree(GetProcessHeap(), 0, che
);
4949 /* if there's no existing entry matching the GUID, allocate one */
4950 else if (!(che
= context_entry_from_guid(&chi
->uuid
)))
4952 che
= HeapAlloc(GetProcessHeap(), 0, sizeof *che
);
4954 return ERROR_NOT_ENOUGH_MEMORY
;
4955 che
->magic
= NDR_CONTEXT_HANDLE_MAGIC
;
4956 RpcBindingCopy(hBinding
, &che
->handle
);
4957 list_add_tail(&context_handle_list
, &che
->entry
);
4958 memcpy(&che
->wire_data
, chi
, sizeof *chi
);
4963 return ERROR_SUCCESS
;
4966 void WINAPI
NDRCContextUnmarshall(NDR_CCONTEXT
*CContext
,
4967 RPC_BINDING_HANDLE hBinding
,
4969 unsigned long DataRepresentation
)
4973 TRACE("*%p=(%p) %p %p %08lx\n",
4974 CContext
, *CContext
, hBinding
, pBuff
, DataRepresentation
);
4976 EnterCriticalSection(&ndr_context_cs
);
4977 r
= ndr_update_context_handle(CContext
, hBinding
, pBuff
);
4978 LeaveCriticalSection(&ndr_context_cs
);
4980 RpcRaiseException(r
);
4983 void WINAPI
NDRSContextMarshall(NDR_SCONTEXT CContext
,
4985 NDR_RUNDOWN userRunDownIn
)
4987 FIXME("(%p %p %p): stub\n", CContext
, pBuff
, userRunDownIn
);
4990 void WINAPI
NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding
,
4991 NDR_SCONTEXT CContext
,
4993 NDR_RUNDOWN userRunDownIn
)
4995 FIXME("(%p %p %p %p): stub\n", hBinding
, CContext
, pBuff
, userRunDownIn
);
4998 void WINAPI
NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding
,
4999 NDR_SCONTEXT CContext
,
5001 NDR_RUNDOWN userRunDownIn
,
5003 unsigned long Flags
)
5005 FIXME("(%p %p %p %p %p %lu): stub\n",
5006 hBinding
, CContext
, pBuff
, userRunDownIn
, CtxGuard
, Flags
);
5009 NDR_SCONTEXT WINAPI
NDRSContextUnmarshall(void *pBuff
,
5010 unsigned long DataRepresentation
)
5012 FIXME("(%p %08lx): stub\n", pBuff
, DataRepresentation
);
5016 NDR_SCONTEXT WINAPI
NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding
,
5018 unsigned long DataRepresentation
)
5020 FIXME("(%p %p %08lx): stub\n", hBinding
, pBuff
, DataRepresentation
);
5024 NDR_SCONTEXT WINAPI
NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding
,
5026 unsigned long DataRepresentation
,
5028 unsigned long Flags
)
5030 FIXME("(%p %p %08lx %p %lu): stub\n",
5031 hBinding
, pBuff
, DataRepresentation
, CtxGuard
, Flags
);