secur32: Move the detection of NULL credentials from AcquireCredentialsHandle to...
[wine/multimedia.git] / dlls / rpcrt4 / ndr_marshall.c
blob888b1503182b70f0455e9c00278913cb20e7db5e
1 /*
2 * NDR data marshalling
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
21 * TODO:
22 * - String structs
23 * - Byte count pointers
24 * - transmit_as/represent as
25 * - Multi-dimensional arrays
26 * - Conversion functions (NdrConvert)
27 * - Checks for integer addition overflow in base type and user marshall functions
30 #include <stdarg.h>
31 #include <stdio.h>
32 #include <string.h>
33 #include <assert.h>
34 #include <limits.h>
36 #include "windef.h"
37 #include "winbase.h"
38 #include "winerror.h"
40 #include "ndr_misc.h"
41 #include "rpcndr.h"
43 #include "wine/unicode.h"
44 #include "wine/rpcfc.h"
46 #include "wine/debug.h"
48 WINE_DEFAULT_DEBUG_CHANNEL(ole);
50 #if defined(__i386__)
51 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
52 (*((UINT32 *)(pchar)) = (uint32))
54 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
55 (*((UINT32 *)(pchar)))
56 #else
57 /* these would work for i386 too, but less efficient */
58 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
59 (*(pchar) = LOBYTE(LOWORD(uint32)), \
60 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
61 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
62 *((pchar)+3) = HIBYTE(HIWORD(uint32)), \
63 (uint32)) /* allow as r-value */
65 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
66 (MAKELONG( \
67 MAKEWORD(*(pchar), *((pchar)+1)), \
68 MAKEWORD(*((pchar)+2), *((pchar)+3))))
69 #endif
71 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
72 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
73 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
74 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
75 *(pchar) = HIBYTE(HIWORD(uint32)), \
76 (uint32)) /* allow as r-value */
78 #define BIG_ENDIAN_UINT32_READ(pchar) \
79 (MAKELONG( \
80 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
81 MAKEWORD(*((pchar)+1), *(pchar))))
83 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
84 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
85 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
86 # define NDR_LOCAL_UINT32_READ(pchar) \
87 BIG_ENDIAN_UINT32_READ(pchar)
88 #else
89 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
90 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
91 # define NDR_LOCAL_UINT32_READ(pchar) \
92 LITTLE_ENDIAN_UINT32_READ(pchar)
93 #endif
95 /* _Align must be the desired alignment,
96 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
97 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
98 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
99 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
100 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
101 #define ALIGN_POINTER_CLEAR(_Ptr, _Align) \
102 do { \
103 memset((_Ptr), 0, ((_Align) - (ULONG_PTR)(_Ptr)) & ((_Align) - 1)); \
104 ALIGN_POINTER(_Ptr, _Align); \
105 } while(0)
107 #define STD_OVERFLOW_CHECK(_Msg) do { \
108 TRACE("buffer=%d/%d\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
109 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
110 ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
111 } while (0)
113 #define NDR_TABLE_SIZE 128
114 #define NDR_TABLE_MASK 127
116 static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
117 static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
118 static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
119 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
120 static ULONG WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
122 static unsigned char *WINAPI NdrContextHandleMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
123 static void WINAPI NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
124 static unsigned char *WINAPI NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
126 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
128 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
129 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
130 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
131 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
132 /* 0x10 */
133 NdrBaseTypeMarshall,
134 /* 0x11 */
135 NdrPointerMarshall, NdrPointerMarshall,
136 NdrPointerMarshall, NdrPointerMarshall,
137 /* 0x15 */
138 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
139 NdrConformantStructMarshall, NdrConformantStructMarshall,
140 NdrConformantVaryingStructMarshall,
141 NdrComplexStructMarshall,
142 /* 0x1b */
143 NdrConformantArrayMarshall,
144 NdrConformantVaryingArrayMarshall,
145 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
146 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
147 NdrComplexArrayMarshall,
148 /* 0x22 */
149 NdrConformantStringMarshall, 0, 0,
150 NdrConformantStringMarshall,
151 NdrNonConformantStringMarshall, 0, 0, 0,
152 /* 0x2a */
153 NdrEncapsulatedUnionMarshall,
154 NdrNonEncapsulatedUnionMarshall,
155 NdrByteCountPointerMarshall,
156 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
157 /* 0x2f */
158 NdrInterfacePointerMarshall,
159 /* 0x30 */
160 NdrContextHandleMarshall,
161 /* 0xb1 */
162 0, 0, 0,
163 NdrUserMarshalMarshall,
164 0, 0,
165 /* 0xb7 */
166 NdrRangeMarshall
168 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
170 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
171 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
172 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
173 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
174 /* 0x10 */
175 NdrBaseTypeUnmarshall,
176 /* 0x11 */
177 NdrPointerUnmarshall, NdrPointerUnmarshall,
178 NdrPointerUnmarshall, NdrPointerUnmarshall,
179 /* 0x15 */
180 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
181 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
182 NdrConformantVaryingStructUnmarshall,
183 NdrComplexStructUnmarshall,
184 /* 0x1b */
185 NdrConformantArrayUnmarshall,
186 NdrConformantVaryingArrayUnmarshall,
187 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
188 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
189 NdrComplexArrayUnmarshall,
190 /* 0x22 */
191 NdrConformantStringUnmarshall, 0, 0,
192 NdrConformantStringUnmarshall,
193 NdrNonConformantStringUnmarshall, 0, 0, 0,
194 /* 0x2a */
195 NdrEncapsulatedUnionUnmarshall,
196 NdrNonEncapsulatedUnionUnmarshall,
197 NdrByteCountPointerUnmarshall,
198 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
199 /* 0x2f */
200 NdrInterfacePointerUnmarshall,
201 /* 0x30 */
202 NdrContextHandleUnmarshall,
203 /* 0xb1 */
204 0, 0, 0,
205 NdrUserMarshalUnmarshall,
206 0, 0,
207 /* 0xb7 */
208 NdrRangeUnmarshall
210 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
212 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
213 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
214 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
215 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
216 /* 0x10 */
217 NdrBaseTypeBufferSize,
218 /* 0x11 */
219 NdrPointerBufferSize, NdrPointerBufferSize,
220 NdrPointerBufferSize, NdrPointerBufferSize,
221 /* 0x15 */
222 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
223 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
224 NdrConformantVaryingStructBufferSize,
225 NdrComplexStructBufferSize,
226 /* 0x1b */
227 NdrConformantArrayBufferSize,
228 NdrConformantVaryingArrayBufferSize,
229 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
230 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
231 NdrComplexArrayBufferSize,
232 /* 0x22 */
233 NdrConformantStringBufferSize, 0, 0,
234 NdrConformantStringBufferSize,
235 NdrNonConformantStringBufferSize, 0, 0, 0,
236 /* 0x2a */
237 NdrEncapsulatedUnionBufferSize,
238 NdrNonEncapsulatedUnionBufferSize,
239 NdrByteCountPointerBufferSize,
240 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
241 /* 0x2f */
242 NdrInterfacePointerBufferSize,
243 /* 0x30 */
244 NdrContextHandleBufferSize,
245 /* 0xb1 */
246 0, 0, 0,
247 NdrUserMarshalBufferSize,
248 0, 0,
249 /* 0xb7 */
250 NdrRangeBufferSize
252 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
254 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
255 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
256 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
257 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
258 /* 0x10 */
259 NdrBaseTypeMemorySize,
260 /* 0x11 */
261 NdrPointerMemorySize, NdrPointerMemorySize,
262 NdrPointerMemorySize, NdrPointerMemorySize,
263 /* 0x15 */
264 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
265 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
266 NdrConformantVaryingStructMemorySize,
267 NdrComplexStructMemorySize,
268 /* 0x1b */
269 NdrConformantArrayMemorySize,
270 NdrConformantVaryingArrayMemorySize,
271 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
272 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
273 NdrComplexArrayMemorySize,
274 /* 0x22 */
275 NdrConformantStringMemorySize, 0, 0,
276 NdrConformantStringMemorySize,
277 NdrNonConformantStringMemorySize, 0, 0, 0,
278 /* 0x2a */
279 NdrEncapsulatedUnionMemorySize,
280 NdrNonEncapsulatedUnionMemorySize,
281 NdrByteCountPointerMemorySize,
282 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
283 /* 0x2f */
284 NdrInterfacePointerMemorySize,
285 /* 0x30 */
287 /* 0xb1 */
288 0, 0, 0,
289 NdrUserMarshalMemorySize,
290 0, 0,
291 /* 0xb7 */
292 NdrRangeMemorySize
294 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
296 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
297 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
298 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
299 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
300 /* 0x10 */
301 NdrBaseTypeFree,
302 /* 0x11 */
303 NdrPointerFree, NdrPointerFree,
304 NdrPointerFree, NdrPointerFree,
305 /* 0x15 */
306 NdrSimpleStructFree, NdrSimpleStructFree,
307 NdrConformantStructFree, NdrConformantStructFree,
308 NdrConformantVaryingStructFree,
309 NdrComplexStructFree,
310 /* 0x1b */
311 NdrConformantArrayFree,
312 NdrConformantVaryingArrayFree,
313 NdrFixedArrayFree, NdrFixedArrayFree,
314 NdrVaryingArrayFree, NdrVaryingArrayFree,
315 NdrComplexArrayFree,
316 /* 0x22 */
317 0, 0, 0,
318 0, 0, 0, 0, 0,
319 /* 0x2a */
320 NdrEncapsulatedUnionFree,
321 NdrNonEncapsulatedUnionFree,
323 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
324 /* 0x2f */
325 NdrInterfacePointerFree,
326 /* 0x30 */
328 /* 0xb1 */
329 0, 0, 0,
330 NdrUserMarshalFree,
331 0, 0,
332 /* 0xb7 */
333 NdrRangeFree
336 typedef struct _NDR_MEMORY_LIST
338 ULONG magic;
339 ULONG size;
340 ULONG reserved;
341 struct _NDR_MEMORY_LIST *next;
342 } NDR_MEMORY_LIST;
344 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
346 /***********************************************************************
347 * NdrAllocate [RPCRT4.@]
349 * Allocates a block of memory using pStubMsg->pfnAllocate.
351 * PARAMS
352 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
353 * len [I] Size of memory block to allocate.
355 * RETURNS
356 * The memory block of size len that was allocated.
358 * NOTES
359 * The memory block is always 8-byte aligned.
360 * If the function is unable to allocate memory an ERROR_OUTOFMEMORY
361 * exception is raised.
363 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, size_t len)
365 size_t aligned_len;
366 size_t adjusted_len;
367 void *p;
368 NDR_MEMORY_LIST *mem_list;
370 aligned_len = ALIGNED_LENGTH(len, 8);
371 adjusted_len = aligned_len + sizeof(NDR_MEMORY_LIST);
372 /* check for overflow */
373 if (adjusted_len < len)
375 ERR("overflow of adjusted_len %d, len %d\n", adjusted_len, len);
376 RpcRaiseException(RPC_X_BAD_STUB_DATA);
379 p = pStubMsg->pfnAllocate(adjusted_len);
380 if (!p) RpcRaiseException(ERROR_OUTOFMEMORY);
382 mem_list = (NDR_MEMORY_LIST *)((char *)p + aligned_len);
383 mem_list->magic = MEML_MAGIC;
384 mem_list->size = aligned_len;
385 mem_list->reserved = 0;
386 mem_list->next = pStubMsg->pMemoryList;
387 pStubMsg->pMemoryList = mem_list;
389 TRACE("-- %p\n", p);
390 return p;
393 static void WINAPI NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
395 TRACE("(%p, %p)\n", pStubMsg, Pointer);
397 pStubMsg->pfnFree(Pointer);
400 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
402 return (*(const ULONG *)pFormat != -1);
405 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
407 ALIGN_POINTER(pStubMsg->Buffer, 4);
408 if (pStubMsg->Buffer + 4 > pStubMsg->BufferEnd)
409 RpcRaiseException(RPC_X_BAD_STUB_DATA);
410 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
411 pStubMsg->Buffer += 4;
412 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
413 if (pStubMsg->fHasNewCorrDesc)
414 return pFormat+6;
415 else
416 return pFormat+4;
419 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue)
421 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
423 pStubMsg->Offset = 0;
424 pStubMsg->ActualCount = pStubMsg->MaxCount;
425 goto done;
428 ALIGN_POINTER(pStubMsg->Buffer, 4);
429 if (pStubMsg->Buffer + 8 > pStubMsg->BufferEnd)
430 RpcRaiseException(RPC_X_BAD_STUB_DATA);
431 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
432 pStubMsg->Buffer += 4;
433 TRACE("offset is %d\n", pStubMsg->Offset);
434 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
435 pStubMsg->Buffer += 4;
436 TRACE("variance is %d\n", pStubMsg->ActualCount);
438 if ((pStubMsg->ActualCount > MaxValue) ||
439 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
441 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
442 pStubMsg->ActualCount, pStubMsg->Offset, MaxValue);
443 RpcRaiseException(RPC_S_INVALID_BOUND);
444 return NULL;
447 done:
448 if (pStubMsg->fHasNewCorrDesc)
449 return pFormat+6;
450 else
451 return pFormat+4;
454 /* writes the conformance value to the buffer */
455 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
457 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
458 if (pStubMsg->Buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
459 RpcRaiseException(RPC_X_BAD_STUB_DATA);
460 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
461 pStubMsg->Buffer += 4;
464 /* writes the variance values to the buffer */
465 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
467 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
468 if (pStubMsg->Buffer + 8 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
469 RpcRaiseException(RPC_X_BAD_STUB_DATA);
470 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
471 pStubMsg->Buffer += 4;
472 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
473 pStubMsg->Buffer += 4;
476 /* requests buffer space for the conformance value */
477 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
479 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
480 if (pStubMsg->BufferLength + 4 < pStubMsg->BufferLength)
481 RpcRaiseException(RPC_X_BAD_STUB_DATA);
482 pStubMsg->BufferLength += 4;
485 /* requests buffer space for the variance values */
486 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
488 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
489 if (pStubMsg->BufferLength + 8 < pStubMsg->BufferLength)
490 RpcRaiseException(RPC_X_BAD_STUB_DATA);
491 pStubMsg->BufferLength += 8;
494 PFORMAT_STRING ComputeConformanceOrVariance(
495 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
496 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount)
498 BYTE dtype = pFormat[0] & 0xf;
499 short ofs = *(const short *)&pFormat[2];
500 LPVOID ptr = NULL;
501 DWORD data = 0;
503 if (!IsConformanceOrVariancePresent(pFormat)) {
504 /* null descriptor */
505 *pCount = def;
506 goto finish_conf;
509 switch (pFormat[0] & 0xf0) {
510 case RPC_FC_NORMAL_CONFORMANCE:
511 TRACE("normal conformance, ofs=%d\n", ofs);
512 ptr = pMemory;
513 break;
514 case RPC_FC_POINTER_CONFORMANCE:
515 TRACE("pointer conformance, ofs=%d\n", ofs);
516 ptr = pStubMsg->Memory;
517 break;
518 case RPC_FC_TOP_LEVEL_CONFORMANCE:
519 TRACE("toplevel conformance, ofs=%d\n", ofs);
520 if (pStubMsg->StackTop) {
521 ptr = pStubMsg->StackTop;
523 else {
524 /* -Os mode, *pCount is already set */
525 goto finish_conf;
527 break;
528 case RPC_FC_CONSTANT_CONFORMANCE:
529 data = ofs | ((DWORD)pFormat[1] << 16);
530 TRACE("constant conformance, val=%d\n", data);
531 *pCount = data;
532 goto finish_conf;
533 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
534 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
535 if (pStubMsg->StackTop) {
536 ptr = pStubMsg->StackTop;
538 else {
539 /* ? */
540 goto done_conf_grab;
542 break;
543 default:
544 FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);
547 switch (pFormat[1]) {
548 case RPC_FC_DEREFERENCE:
549 ptr = *(LPVOID*)((char *)ptr + ofs);
550 break;
551 case RPC_FC_CALLBACK:
553 unsigned char *old_stack_top = pStubMsg->StackTop;
554 pStubMsg->StackTop = ptr;
556 /* ofs is index into StubDesc->apfnExprEval */
557 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
558 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
560 pStubMsg->StackTop = old_stack_top;
562 /* the callback function always stores the computed value in MaxCount */
563 *pCount = pStubMsg->MaxCount;
564 goto finish_conf;
566 default:
567 ptr = (char *)ptr + ofs;
568 break;
571 switch (dtype) {
572 case RPC_FC_LONG:
573 case RPC_FC_ULONG:
574 data = *(DWORD*)ptr;
575 break;
576 case RPC_FC_SHORT:
577 data = *(SHORT*)ptr;
578 break;
579 case RPC_FC_USHORT:
580 data = *(USHORT*)ptr;
581 break;
582 case RPC_FC_CHAR:
583 case RPC_FC_SMALL:
584 data = *(CHAR*)ptr;
585 break;
586 case RPC_FC_BYTE:
587 case RPC_FC_USMALL:
588 data = *(UCHAR*)ptr;
589 break;
590 default:
591 FIXME("unknown conformance data type %x\n", dtype);
592 goto done_conf_grab;
594 TRACE("dereferenced data type %x at %p, got %d\n", dtype, ptr, data);
596 done_conf_grab:
597 switch (pFormat[1]) {
598 case RPC_FC_DEREFERENCE: /* already handled */
599 case 0: /* no op */
600 *pCount = data;
601 break;
602 case RPC_FC_ADD_1:
603 *pCount = data + 1;
604 break;
605 case RPC_FC_SUB_1:
606 *pCount = data - 1;
607 break;
608 case RPC_FC_MULT_2:
609 *pCount = data * 2;
610 break;
611 case RPC_FC_DIV_2:
612 *pCount = data / 2;
613 break;
614 default:
615 FIXME("unknown conformance op %d\n", pFormat[1]);
616 goto finish_conf;
619 finish_conf:
620 TRACE("resulting conformance is %ld\n", *pCount);
621 if (pStubMsg->fHasNewCorrDesc)
622 return pFormat+6;
623 else
624 return pFormat+4;
627 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
628 * the result overflows 32-bits */
629 static inline ULONG safe_multiply(ULONG a, ULONG b)
631 ULONGLONG ret = (ULONGLONG)a * b;
632 if (ret > 0xffffffff)
634 RpcRaiseException(RPC_S_INVALID_BOUND);
635 return 0;
637 return ret;
640 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
642 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
643 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
644 RpcRaiseException(RPC_X_BAD_STUB_DATA);
645 pStubMsg->Buffer += size;
648 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
650 if (pStubMsg->BufferLength + size < pStubMsg->BufferLength) /* integer overflow of pStubMsg->BufferSize */
652 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
653 pStubMsg->BufferLength, size);
654 RpcRaiseException(RPC_X_BAD_STUB_DATA);
656 pStubMsg->BufferLength += size;
659 /* copies data from the buffer, checking that there is enough data in the buffer
660 * to do so */
661 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE *pStubMsg, void *p, ULONG size)
663 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
664 (pStubMsg->Buffer + size > pStubMsg->BufferEnd))
666 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
667 pStubMsg->Buffer, pStubMsg->BufferEnd, size);
668 RpcRaiseException(RPC_X_BAD_STUB_DATA);
670 if (p == pStubMsg->Buffer)
671 ERR("pointer is the same as the buffer\n");
672 memcpy(p, pStubMsg->Buffer, size);
673 pStubMsg->Buffer += size;
676 /* copies data to the buffer, checking that there is enough space to do so */
677 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE *pStubMsg, const void *p, ULONG size)
679 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
680 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
682 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
683 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength,
684 size);
685 RpcRaiseException(RPC_X_BAD_STUB_DATA);
687 memcpy(pStubMsg->Buffer, p, size);
688 pStubMsg->Buffer += size;
692 * NdrConformantString:
694 * What MS calls a ConformantString is, in DCE terminology,
695 * a Varying-Conformant String.
697 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
698 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
699 * into unmarshalled string)
700 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
701 * [
702 * data: CHARTYPE[maxlen]
703 * ]
704 * ], where CHARTYPE is the appropriate character type (specified externally)
708 /***********************************************************************
709 * NdrConformantStringMarshall [RPCRT4.@]
711 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
712 unsigned char *pszMessage, PFORMAT_STRING pFormat)
714 ULONG esize, size;
716 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
718 if (*pFormat == RPC_FC_C_CSTRING) {
719 TRACE("string=%s\n", debugstr_a((char*)pszMessage));
720 pStubMsg->ActualCount = strlen((char*)pszMessage)+1;
721 esize = 1;
723 else if (*pFormat == RPC_FC_C_WSTRING) {
724 TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage));
725 pStubMsg->ActualCount = strlenW((LPWSTR)pszMessage)+1;
726 esize = 2;
728 else {
729 ERR("Unhandled string type: %#x\n", *pFormat);
730 /* FIXME: raise an exception. */
731 return NULL;
734 if (pFormat[1] == RPC_FC_STRING_SIZED)
735 pFormat = ComputeConformance(pStubMsg, pszMessage, pFormat + 2, 0);
736 else
737 pStubMsg->MaxCount = pStubMsg->ActualCount;
738 pStubMsg->Offset = 0;
739 WriteConformance(pStubMsg);
740 WriteVariance(pStubMsg);
742 size = safe_multiply(esize, pStubMsg->ActualCount);
743 safe_copy_to_buffer(pStubMsg, pszMessage, size); /* the string itself */
745 /* success */
746 return NULL; /* is this always right? */
749 /***********************************************************************
750 * NdrConformantStringBufferSize [RPCRT4.@]
752 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
753 unsigned char* pMemory, PFORMAT_STRING pFormat)
755 ULONG esize;
757 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
759 SizeConformance(pStubMsg);
760 SizeVariance(pStubMsg);
762 if (*pFormat == RPC_FC_C_CSTRING) {
763 TRACE("string=%s\n", debugstr_a((char*)pMemory));
764 pStubMsg->ActualCount = strlen((char*)pMemory)+1;
765 esize = 1;
767 else if (*pFormat == RPC_FC_C_WSTRING) {
768 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory));
769 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory)+1;
770 esize = 2;
772 else {
773 ERR("Unhandled string type: %#x\n", *pFormat);
774 /* FIXME: raise an exception */
775 return;
778 if (pFormat[1] == RPC_FC_STRING_SIZED)
779 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
780 else
781 pStubMsg->MaxCount = pStubMsg->ActualCount;
783 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
786 /************************************************************************
787 * NdrConformantStringMemorySize [RPCRT4.@]
789 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
790 PFORMAT_STRING pFormat )
792 ULONG bufsize, memsize, esize, i;
794 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
796 ReadConformance(pStubMsg, NULL);
797 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
799 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
801 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
802 pStubMsg->ActualCount, pStubMsg->MaxCount);
803 RpcRaiseException(RPC_S_INVALID_BOUND);
805 if (pStubMsg->Offset)
807 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
808 RpcRaiseException(RPC_S_INVALID_BOUND);
811 if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
812 else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
813 else {
814 ERR("Unhandled string type: %#x\n", *pFormat);
815 /* FIXME: raise an exception */
816 esize = 0;
819 memsize = safe_multiply(esize, pStubMsg->MaxCount);
820 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
822 /* strings must always have null terminating bytes */
823 if (bufsize < esize)
825 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
826 RpcRaiseException(RPC_S_INVALID_BOUND);
829 /* verify the buffer is safe to access */
830 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
831 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
833 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
834 pStubMsg->BufferEnd, pStubMsg->Buffer);
835 RpcRaiseException(RPC_X_BAD_STUB_DATA);
838 for (i = bufsize - esize; i < bufsize; i++)
839 if (pStubMsg->Buffer[i] != 0)
841 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
842 i, pStubMsg->Buffer[i]);
843 RpcRaiseException(RPC_S_INVALID_BOUND);
846 safe_buffer_increment(pStubMsg, bufsize);
847 pStubMsg->MemorySize += memsize;
849 return pStubMsg->MemorySize;
852 /************************************************************************
853 * NdrConformantStringUnmarshall [RPCRT4.@]
855 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
856 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
858 ULONG bufsize, memsize, esize, i;
860 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
861 pStubMsg, *ppMemory, pFormat, fMustAlloc);
863 assert(pFormat && ppMemory && pStubMsg);
865 ReadConformance(pStubMsg, NULL);
866 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
868 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
870 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
871 pStubMsg->ActualCount, pStubMsg->MaxCount);
872 RpcRaiseException(RPC_S_INVALID_BOUND);
873 return NULL;
875 if (pStubMsg->Offset)
877 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
878 RpcRaiseException(RPC_S_INVALID_BOUND);
879 return NULL;
882 if (*pFormat == RPC_FC_C_CSTRING) esize = 1;
883 else if (*pFormat == RPC_FC_C_WSTRING) esize = 2;
884 else {
885 ERR("Unhandled string type: %#x\n", *pFormat);
886 /* FIXME: raise an exception */
887 esize = 0;
890 memsize = safe_multiply(esize, pStubMsg->MaxCount);
891 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
893 /* strings must always have null terminating bytes */
894 if (bufsize < esize)
896 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
897 RpcRaiseException(RPC_S_INVALID_BOUND);
898 return NULL;
901 /* verify the buffer is safe to access */
902 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
903 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
905 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
906 pStubMsg->BufferEnd, pStubMsg->Buffer);
907 RpcRaiseException(RPC_X_BAD_STUB_DATA);
908 return NULL;
911 for (i = bufsize - esize; i < bufsize; i++)
912 if (pStubMsg->Buffer[i] != 0)
914 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
915 i, pStubMsg->Buffer[i]);
916 RpcRaiseException(RPC_S_INVALID_BOUND);
917 return NULL;
920 if (fMustAlloc)
921 *ppMemory = NdrAllocate(pStubMsg, memsize);
922 else
924 if (!pStubMsg->IsClient && !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount))
925 /* if the data in the RPC buffer is big enough, we just point straight
926 * into it */
927 *ppMemory = pStubMsg->Buffer;
928 else if (!*ppMemory)
929 *ppMemory = NdrAllocate(pStubMsg, memsize);
932 if (*ppMemory == pStubMsg->Buffer)
933 safe_buffer_increment(pStubMsg, bufsize);
934 else
935 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
937 if (*pFormat == RPC_FC_C_CSTRING) {
938 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
940 else if (*pFormat == RPC_FC_C_WSTRING) {
941 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
944 return NULL; /* FIXME: is this always right? */
947 /***********************************************************************
948 * NdrNonConformantStringMarshall [RPCRT4.@]
950 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
951 unsigned char *pMemory,
952 PFORMAT_STRING pFormat)
954 ULONG esize, size, maxsize;
956 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
958 maxsize = *(USHORT *)&pFormat[2];
960 if (*pFormat == RPC_FC_CSTRING)
962 ULONG i;
963 const char *str = (const char *)pMemory;
964 for (i = 0; i < maxsize && *str; i++, str++)
966 TRACE("string=%s\n", debugstr_an(str, i));
967 pStubMsg->ActualCount = i + 1;
968 esize = 1;
970 else if (*pFormat == RPC_FC_WSTRING)
972 ULONG i;
973 const WCHAR *str = (const WCHAR *)pMemory;
974 for (i = 0; i < maxsize && *str; i++, str++)
976 TRACE("string=%s\n", debugstr_wn(str, i));
977 pStubMsg->ActualCount = i + 1;
978 esize = 2;
980 else
982 ERR("Unhandled string type: %#x\n", *pFormat);
983 RpcRaiseException(RPC_X_BAD_STUB_DATA);
986 pStubMsg->Offset = 0;
987 WriteVariance(pStubMsg);
989 size = safe_multiply(esize, pStubMsg->ActualCount);
990 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
992 return NULL;
995 /***********************************************************************
996 * NdrNonConformantStringUnmarshall [RPCRT4.@]
998 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
999 unsigned char **ppMemory,
1000 PFORMAT_STRING pFormat,
1001 unsigned char fMustAlloc)
1003 ULONG bufsize, memsize, esize, i, maxsize;
1005 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
1006 pStubMsg, *ppMemory, pFormat, fMustAlloc);
1008 maxsize = *(USHORT *)&pFormat[2];
1010 ReadVariance(pStubMsg, NULL, maxsize);
1011 if (pStubMsg->Offset)
1013 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
1014 RpcRaiseException(RPC_S_INVALID_BOUND);
1017 if (*pFormat == RPC_FC_CSTRING) esize = 1;
1018 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
1019 else
1021 ERR("Unhandled string type: %#x\n", *pFormat);
1022 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1025 memsize = esize * maxsize;
1026 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
1028 if (bufsize < esize)
1030 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
1031 RpcRaiseException(RPC_S_INVALID_BOUND);
1032 return NULL;
1035 /* verify the buffer is safe to access */
1036 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
1037 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
1039 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
1040 pStubMsg->BufferEnd, pStubMsg->Buffer);
1041 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1042 return NULL;
1045 /* strings must always have null terminating bytes */
1046 for (i = bufsize - esize; i < bufsize; i++)
1047 if (pStubMsg->Buffer[i] != 0)
1049 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
1050 i, pStubMsg->Buffer[i]);
1051 RpcRaiseException(RPC_S_INVALID_BOUND);
1054 if (fMustAlloc || !*ppMemory)
1055 *ppMemory = NdrAllocate(pStubMsg, memsize);
1057 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
1059 if (*pFormat == RPC_FC_CSTRING) {
1060 TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount));
1062 else if (*pFormat == RPC_FC_WSTRING) {
1063 TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount));
1066 return NULL;
1069 /***********************************************************************
1070 * NdrNonConformantStringBufferSize [RPCRT4.@]
1072 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1073 unsigned char *pMemory,
1074 PFORMAT_STRING pFormat)
1076 ULONG esize, maxsize;
1078 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
1080 maxsize = *(USHORT *)&pFormat[2];
1082 SizeVariance(pStubMsg);
1084 if (*pFormat == RPC_FC_CSTRING)
1086 ULONG i;
1087 const char *str = (const char *)pMemory;
1088 for (i = 0; i < maxsize && *str; i++, str++)
1090 TRACE("string=%s\n", debugstr_an(str, i));
1091 pStubMsg->ActualCount = i + 1;
1092 esize = 1;
1094 else if (*pFormat == RPC_FC_WSTRING)
1096 ULONG i;
1097 const WCHAR *str = (const WCHAR *)pMemory;
1098 for (i = 0; i < maxsize && *str; i++, str++)
1100 TRACE("string=%s\n", debugstr_wn(str, i));
1101 pStubMsg->ActualCount = i + 1;
1102 esize = 2;
1104 else
1106 ERR("Unhandled string type: %#x\n", *pFormat);
1107 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1110 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
1113 /***********************************************************************
1114 * NdrNonConformantStringMemorySize [RPCRT4.@]
1116 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1117 PFORMAT_STRING pFormat)
1119 ULONG bufsize, memsize, esize, i, maxsize;
1121 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
1123 maxsize = *(USHORT *)&pFormat[2];
1125 ReadVariance(pStubMsg, NULL, maxsize);
1127 if (pStubMsg->Offset)
1129 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
1130 RpcRaiseException(RPC_S_INVALID_BOUND);
1133 if (*pFormat == RPC_FC_CSTRING) esize = 1;
1134 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
1135 else
1137 ERR("Unhandled string type: %#x\n", *pFormat);
1138 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1141 memsize = esize * maxsize;
1142 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
1144 /* strings must always have null terminating bytes */
1145 if (bufsize < esize)
1147 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
1148 RpcRaiseException(RPC_S_INVALID_BOUND);
1151 /* verify the buffer is safe to access */
1152 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
1153 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
1155 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
1156 pStubMsg->BufferEnd, pStubMsg->Buffer);
1157 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1160 for (i = bufsize - esize; i < bufsize; i++)
1161 if (pStubMsg->Buffer[i] != 0)
1163 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
1164 i, pStubMsg->Buffer[i]);
1165 RpcRaiseException(RPC_S_INVALID_BOUND);
1168 safe_buffer_increment(pStubMsg, bufsize);
1169 pStubMsg->MemorySize += memsize;
1171 return pStubMsg->MemorySize;
1174 static inline void dump_pointer_attr(unsigned char attr)
1176 if (attr & RPC_FC_P_ALLOCALLNODES)
1177 TRACE(" RPC_FC_P_ALLOCALLNODES");
1178 if (attr & RPC_FC_P_DONTFREE)
1179 TRACE(" RPC_FC_P_DONTFREE");
1180 if (attr & RPC_FC_P_ONSTACK)
1181 TRACE(" RPC_FC_P_ONSTACK");
1182 if (attr & RPC_FC_P_SIMPLEPOINTER)
1183 TRACE(" RPC_FC_P_SIMPLEPOINTER");
1184 if (attr & RPC_FC_P_DEREF)
1185 TRACE(" RPC_FC_P_DEREF");
1186 TRACE("\n");
1189 /***********************************************************************
1190 * PointerMarshall [internal]
1192 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1193 unsigned char *Buffer,
1194 unsigned char *Pointer,
1195 PFORMAT_STRING pFormat)
1197 unsigned type = pFormat[0], attr = pFormat[1];
1198 PFORMAT_STRING desc;
1199 NDR_MARSHALL m;
1200 ULONG pointer_id;
1201 int pointer_needs_marshaling;
1203 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
1204 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1205 pFormat += 2;
1206 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1207 else desc = pFormat + *(const SHORT*)pFormat;
1209 switch (type) {
1210 case RPC_FC_RP: /* ref pointer (always non-null) */
1211 if (!Pointer)
1213 ERR("NULL ref pointer is not allowed\n");
1214 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1216 pointer_needs_marshaling = 1;
1217 break;
1218 case RPC_FC_UP: /* unique pointer */
1219 case RPC_FC_OP: /* object pointer - same as unique here */
1220 if (Pointer)
1221 pointer_needs_marshaling = 1;
1222 else
1223 pointer_needs_marshaling = 0;
1224 pointer_id = (ULONG)Pointer;
1225 TRACE("writing 0x%08x to buffer\n", pointer_id);
1226 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
1227 break;
1228 case RPC_FC_FP:
1229 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
1230 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
1231 TRACE("writing 0x%08x to buffer\n", pointer_id);
1232 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
1233 break;
1234 default:
1235 FIXME("unhandled ptr type=%02x\n", type);
1236 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1237 return;
1240 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
1242 if (pointer_needs_marshaling) {
1243 if (attr & RPC_FC_P_DEREF) {
1244 Pointer = *(unsigned char**)Pointer;
1245 TRACE("deref => %p\n", Pointer);
1247 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
1248 if (m) m(pStubMsg, Pointer, desc);
1249 else FIXME("no marshaller for data type=%02x\n", *desc);
1252 STD_OVERFLOW_CHECK(pStubMsg);
1255 /***********************************************************************
1256 * PointerUnmarshall [internal]
1258 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1259 unsigned char *Buffer,
1260 unsigned char **pPointer,
1261 unsigned char *pSrcPointer,
1262 PFORMAT_STRING pFormat,
1263 unsigned char fMustAlloc)
1265 unsigned type = pFormat[0], attr = pFormat[1];
1266 PFORMAT_STRING desc;
1267 NDR_UNMARSHALL m;
1268 DWORD pointer_id = 0;
1269 int pointer_needs_unmarshaling;
1271 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pSrcPointer, pFormat, fMustAlloc);
1272 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1273 pFormat += 2;
1274 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1275 else desc = pFormat + *(const SHORT*)pFormat;
1277 switch (type) {
1278 case RPC_FC_RP: /* ref pointer (always non-null) */
1279 pointer_needs_unmarshaling = 1;
1280 break;
1281 case RPC_FC_UP: /* unique pointer */
1282 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1283 TRACE("pointer_id is 0x%08x\n", pointer_id);
1284 if (pointer_id)
1285 pointer_needs_unmarshaling = 1;
1286 else {
1287 *pPointer = NULL;
1288 pointer_needs_unmarshaling = 0;
1290 break;
1291 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1292 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1293 TRACE("pointer_id is 0x%08x\n", pointer_id);
1294 if (!fMustAlloc && pSrcPointer)
1296 FIXME("free object pointer %p\n", pSrcPointer);
1297 fMustAlloc = TRUE;
1299 if (pointer_id)
1300 pointer_needs_unmarshaling = 1;
1301 else
1302 pointer_needs_unmarshaling = 0;
1303 break;
1304 case RPC_FC_FP:
1305 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1306 TRACE("pointer_id is 0x%08x\n", pointer_id);
1307 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
1308 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
1309 break;
1310 default:
1311 FIXME("unhandled ptr type=%02x\n", type);
1312 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1313 return;
1316 if (pointer_needs_unmarshaling) {
1317 unsigned char *base_ptr_val = *pPointer;
1318 unsigned char **current_ptr = pPointer;
1319 if (pStubMsg->IsClient) {
1320 TRACE("client\n");
1321 /* if we aren't forcing allocation of memory then try to use the existing
1322 * (source) pointer to unmarshall the data into so that [in,out]
1323 * parameters behave correctly. it doesn't matter if the parameter is
1324 * [out] only since in that case the pointer will be NULL. we force
1325 * allocation when the source pointer is NULL here instead of in the type
1326 * unmarshalling routine for the benefit of the deref code below */
1327 if (!fMustAlloc) {
1328 if (pSrcPointer) {
1329 TRACE("setting *pPointer to %p\n", pSrcPointer);
1330 *pPointer = base_ptr_val = pSrcPointer;
1331 } else
1332 fMustAlloc = TRUE;
1334 } else {
1335 TRACE("server\n");
1336 /* the memory in a stub is never initialised, so we have to work out here
1337 * whether we have to initialise it so we can use the optimisation of
1338 * setting the pointer to the buffer, if possible, or set fMustAlloc to
1339 * TRUE. */
1340 if (attr & RPC_FC_P_DEREF) {
1341 fMustAlloc = TRUE;
1342 } else {
1343 base_ptr_val = NULL;
1344 *current_ptr = NULL;
1348 if (attr & RPC_FC_P_ALLOCALLNODES)
1349 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
1351 if (attr & RPC_FC_P_DEREF) {
1352 if (fMustAlloc) {
1353 base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *));
1354 *pPointer = base_ptr_val;
1355 current_ptr = (unsigned char **)base_ptr_val;
1356 } else
1357 current_ptr = *(unsigned char***)current_ptr;
1358 TRACE("deref => %p\n", current_ptr);
1359 if (!fMustAlloc && !*current_ptr) fMustAlloc = TRUE;
1361 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
1362 if (m) m(pStubMsg, current_ptr, desc, fMustAlloc);
1363 else FIXME("no unmarshaller for data type=%02x\n", *desc);
1365 if (type == RPC_FC_FP)
1366 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
1367 base_ptr_val);
1370 TRACE("pointer=%p\n", *pPointer);
1373 /***********************************************************************
1374 * PointerBufferSize [internal]
1376 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1377 unsigned char *Pointer,
1378 PFORMAT_STRING pFormat)
1380 unsigned type = pFormat[0], attr = pFormat[1];
1381 PFORMAT_STRING desc;
1382 NDR_BUFFERSIZE m;
1383 int pointer_needs_sizing;
1384 ULONG pointer_id;
1386 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1387 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1388 pFormat += 2;
1389 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1390 else desc = pFormat + *(const SHORT*)pFormat;
1392 switch (type) {
1393 case RPC_FC_RP: /* ref pointer (always non-null) */
1394 if (!Pointer)
1396 ERR("NULL ref pointer is not allowed\n");
1397 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1399 break;
1400 case RPC_FC_OP:
1401 case RPC_FC_UP:
1402 /* NULL pointer has no further representation */
1403 if (!Pointer)
1404 return;
1405 break;
1406 case RPC_FC_FP:
1407 pointer_needs_sizing = !NdrFullPointerQueryPointer(
1408 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
1409 if (!pointer_needs_sizing)
1410 return;
1411 break;
1412 default:
1413 FIXME("unhandled ptr type=%02x\n", type);
1414 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1415 return;
1418 if (attr & RPC_FC_P_DEREF) {
1419 Pointer = *(unsigned char**)Pointer;
1420 TRACE("deref => %p\n", Pointer);
1423 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
1424 if (m) m(pStubMsg, Pointer, desc);
1425 else FIXME("no buffersizer for data type=%02x\n", *desc);
1428 /***********************************************************************
1429 * PointerMemorySize [internal]
1431 static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1432 unsigned char *Buffer,
1433 PFORMAT_STRING pFormat)
1435 unsigned type = pFormat[0], attr = pFormat[1];
1436 PFORMAT_STRING desc;
1437 NDR_MEMORYSIZE m;
1438 DWORD pointer_id = 0;
1439 int pointer_needs_sizing;
1441 TRACE("(%p,%p,%p)\n", pStubMsg, Buffer, pFormat);
1442 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1443 pFormat += 2;
1444 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1445 else desc = pFormat + *(const SHORT*)pFormat;
1447 switch (type) {
1448 case RPC_FC_RP: /* ref pointer (always non-null) */
1449 pointer_needs_sizing = 1;
1450 break;
1451 case RPC_FC_UP: /* unique pointer */
1452 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1453 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1454 TRACE("pointer_id is 0x%08x\n", pointer_id);
1455 if (pointer_id)
1456 pointer_needs_sizing = 1;
1457 else
1458 pointer_needs_sizing = 0;
1459 break;
1460 case RPC_FC_FP:
1462 void *pointer;
1463 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1464 TRACE("pointer_id is 0x%08x\n", pointer_id);
1465 pointer_needs_sizing = !NdrFullPointerQueryRefId(
1466 pStubMsg->FullPtrXlatTables, pointer_id, 1, &pointer);
1467 break;
1469 default:
1470 FIXME("unhandled ptr type=%02x\n", type);
1471 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1472 return 0;
1475 if (attr & RPC_FC_P_DEREF) {
1476 TRACE("deref\n");
1479 if (pointer_needs_sizing) {
1480 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1481 if (m) m(pStubMsg, desc);
1482 else FIXME("no memorysizer for data type=%02x\n", *desc);
1485 return pStubMsg->MemorySize;
1488 /***********************************************************************
1489 * PointerFree [internal]
1491 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1492 unsigned char *Pointer,
1493 PFORMAT_STRING pFormat)
1495 unsigned type = pFormat[0], attr = pFormat[1];
1496 PFORMAT_STRING desc;
1497 NDR_FREE m;
1498 unsigned char *current_pointer = Pointer;
1500 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1501 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1502 if (attr & RPC_FC_P_DONTFREE) return;
1503 pFormat += 2;
1504 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1505 else desc = pFormat + *(const SHORT*)pFormat;
1507 if (!Pointer) return;
1509 if (type == RPC_FC_FP) {
1510 int pointer_needs_freeing = NdrFullPointerFree(
1511 pStubMsg->FullPtrXlatTables, Pointer);
1512 if (!pointer_needs_freeing)
1513 return;
1516 if (attr & RPC_FC_P_DEREF) {
1517 current_pointer = *(unsigned char**)Pointer;
1518 TRACE("deref => %p\n", current_pointer);
1521 m = NdrFreer[*desc & NDR_TABLE_MASK];
1522 if (m) m(pStubMsg, current_pointer, desc);
1524 /* this check stops us from trying to free buffer memory. we don't have to
1525 * worry about clients, since they won't call this function.
1526 * we don't have to check for the buffer being reallocated because
1527 * BufferStart and BufferEnd won't be reset when allocating memory for
1528 * sending the response. we don't have to check for the new buffer here as
1529 * it won't be used a type memory, only for buffer memory */
1530 if (Pointer >= pStubMsg->BufferStart && Pointer < pStubMsg->BufferEnd)
1531 goto notfree;
1533 if (attr & RPC_FC_P_ONSTACK) {
1534 TRACE("not freeing stack ptr %p\n", Pointer);
1535 return;
1537 TRACE("freeing %p\n", Pointer);
1538 NdrFree(pStubMsg, Pointer);
1539 return;
1540 notfree:
1541 TRACE("not freeing %p\n", Pointer);
1544 /***********************************************************************
1545 * EmbeddedPointerMarshall
1547 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1548 unsigned char *pMemory,
1549 PFORMAT_STRING pFormat)
1551 unsigned char *Mark = pStubMsg->BufferMark;
1552 unsigned rep, count, stride;
1553 unsigned i;
1554 unsigned char *saved_buffer = NULL;
1556 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1558 if (*pFormat != RPC_FC_PP) return NULL;
1559 pFormat += 2;
1561 if (pStubMsg->PointerBufferMark)
1563 saved_buffer = pStubMsg->Buffer;
1564 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1565 pStubMsg->PointerBufferMark = NULL;
1568 while (pFormat[0] != RPC_FC_END) {
1569 switch (pFormat[0]) {
1570 default:
1571 FIXME("unknown repeat type %d\n", pFormat[0]);
1572 case RPC_FC_NO_REPEAT:
1573 rep = 1;
1574 stride = 0;
1575 count = 1;
1576 pFormat += 2;
1577 break;
1578 case RPC_FC_FIXED_REPEAT:
1579 rep = *(const WORD*)&pFormat[2];
1580 stride = *(const WORD*)&pFormat[4];
1581 count = *(const WORD*)&pFormat[8];
1582 pFormat += 10;
1583 break;
1584 case RPC_FC_VARIABLE_REPEAT:
1585 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1586 stride = *(const WORD*)&pFormat[2];
1587 count = *(const WORD*)&pFormat[6];
1588 pFormat += 8;
1589 break;
1591 for (i = 0; i < rep; i++) {
1592 PFORMAT_STRING info = pFormat;
1593 unsigned char *membase = pMemory + (i * stride);
1594 unsigned char *bufbase = Mark + (i * stride);
1595 unsigned u;
1597 for (u=0; u<count; u++,info+=8) {
1598 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1599 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1600 unsigned char *saved_memory = pStubMsg->Memory;
1602 pStubMsg->Memory = pMemory;
1603 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1604 pStubMsg->Memory = saved_memory;
1607 pFormat += 8 * count;
1610 if (saved_buffer)
1612 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1613 pStubMsg->Buffer = saved_buffer;
1616 STD_OVERFLOW_CHECK(pStubMsg);
1618 return NULL;
1621 /***********************************************************************
1622 * EmbeddedPointerUnmarshall
1624 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1625 unsigned char *pDstMemoryPtrs,
1626 unsigned char *pSrcMemoryPtrs,
1627 PFORMAT_STRING pFormat,
1628 unsigned char fMustAlloc)
1630 unsigned char *Mark = pStubMsg->BufferMark;
1631 unsigned rep, count, stride;
1632 unsigned i;
1633 unsigned char *saved_buffer = NULL;
1635 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstMemoryPtrs, pSrcMemoryPtrs, pFormat, fMustAlloc);
1637 if (*pFormat != RPC_FC_PP) return NULL;
1638 pFormat += 2;
1640 if (pStubMsg->PointerBufferMark)
1642 saved_buffer = pStubMsg->Buffer;
1643 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1644 pStubMsg->PointerBufferMark = NULL;
1647 while (pFormat[0] != RPC_FC_END) {
1648 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1649 switch (pFormat[0]) {
1650 default:
1651 FIXME("unknown repeat type %d\n", pFormat[0]);
1652 case RPC_FC_NO_REPEAT:
1653 rep = 1;
1654 stride = 0;
1655 count = 1;
1656 pFormat += 2;
1657 break;
1658 case RPC_FC_FIXED_REPEAT:
1659 rep = *(const WORD*)&pFormat[2];
1660 stride = *(const WORD*)&pFormat[4];
1661 count = *(const WORD*)&pFormat[8];
1662 pFormat += 10;
1663 break;
1664 case RPC_FC_VARIABLE_REPEAT:
1665 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1666 stride = *(const WORD*)&pFormat[2];
1667 count = *(const WORD*)&pFormat[6];
1668 pFormat += 8;
1669 break;
1671 for (i = 0; i < rep; i++) {
1672 PFORMAT_STRING info = pFormat;
1673 unsigned char *memdstbase = pDstMemoryPtrs + (i * stride);
1674 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride);
1675 unsigned char *bufbase = Mark + (i * stride);
1676 unsigned u;
1678 for (u=0; u<count; u++,info+=8) {
1679 unsigned char **memdstptr = (unsigned char **)(memdstbase + *(const SHORT*)&info[0]);
1680 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]);
1681 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1682 PointerUnmarshall(pStubMsg, bufptr, memdstptr, *memsrcptr, info+4, fMustAlloc);
1685 pFormat += 8 * count;
1688 if (saved_buffer)
1690 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1691 pStubMsg->Buffer = saved_buffer;
1694 return NULL;
1697 /***********************************************************************
1698 * EmbeddedPointerBufferSize
1700 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1701 unsigned char *pMemory,
1702 PFORMAT_STRING pFormat)
1704 unsigned rep, count, stride;
1705 unsigned i;
1706 ULONG saved_buffer_length = 0;
1708 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1710 if (pStubMsg->IgnoreEmbeddedPointers) return;
1712 if (*pFormat != RPC_FC_PP) return;
1713 pFormat += 2;
1715 if (pStubMsg->PointerLength)
1717 saved_buffer_length = pStubMsg->BufferLength;
1718 pStubMsg->BufferLength = pStubMsg->PointerLength;
1719 pStubMsg->PointerLength = 0;
1722 while (pFormat[0] != RPC_FC_END) {
1723 switch (pFormat[0]) {
1724 default:
1725 FIXME("unknown repeat type %d\n", pFormat[0]);
1726 case RPC_FC_NO_REPEAT:
1727 rep = 1;
1728 stride = 0;
1729 count = 1;
1730 pFormat += 2;
1731 break;
1732 case RPC_FC_FIXED_REPEAT:
1733 rep = *(const WORD*)&pFormat[2];
1734 stride = *(const WORD*)&pFormat[4];
1735 count = *(const WORD*)&pFormat[8];
1736 pFormat += 10;
1737 break;
1738 case RPC_FC_VARIABLE_REPEAT:
1739 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1740 stride = *(const WORD*)&pFormat[2];
1741 count = *(const WORD*)&pFormat[6];
1742 pFormat += 8;
1743 break;
1745 for (i = 0; i < rep; i++) {
1746 PFORMAT_STRING info = pFormat;
1747 unsigned char *membase = pMemory + (i * stride);
1748 unsigned u;
1750 for (u=0; u<count; u++,info+=8) {
1751 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1752 unsigned char *saved_memory = pStubMsg->Memory;
1754 pStubMsg->Memory = pMemory;
1755 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1756 pStubMsg->Memory = saved_memory;
1759 pFormat += 8 * count;
1762 if (saved_buffer_length)
1764 pStubMsg->PointerLength = pStubMsg->BufferLength;
1765 pStubMsg->BufferLength = saved_buffer_length;
1769 /***********************************************************************
1770 * EmbeddedPointerMemorySize [internal]
1772 static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1773 PFORMAT_STRING pFormat)
1775 unsigned char *Mark = pStubMsg->BufferMark;
1776 unsigned rep, count, stride;
1777 unsigned i;
1778 unsigned char *saved_buffer = NULL;
1780 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1782 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1784 if (pStubMsg->PointerBufferMark)
1786 saved_buffer = pStubMsg->Buffer;
1787 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1788 pStubMsg->PointerBufferMark = NULL;
1791 if (*pFormat != RPC_FC_PP) return 0;
1792 pFormat += 2;
1794 while (pFormat[0] != RPC_FC_END) {
1795 switch (pFormat[0]) {
1796 default:
1797 FIXME("unknown repeat type %d\n", pFormat[0]);
1798 case RPC_FC_NO_REPEAT:
1799 rep = 1;
1800 stride = 0;
1801 count = 1;
1802 pFormat += 2;
1803 break;
1804 case RPC_FC_FIXED_REPEAT:
1805 rep = *(const WORD*)&pFormat[2];
1806 stride = *(const WORD*)&pFormat[4];
1807 count = *(const WORD*)&pFormat[8];
1808 pFormat += 10;
1809 break;
1810 case RPC_FC_VARIABLE_REPEAT:
1811 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1812 stride = *(const WORD*)&pFormat[2];
1813 count = *(const WORD*)&pFormat[6];
1814 pFormat += 8;
1815 break;
1817 for (i = 0; i < rep; i++) {
1818 PFORMAT_STRING info = pFormat;
1819 unsigned char *bufbase = Mark + (i * stride);
1820 unsigned u;
1821 for (u=0; u<count; u++,info+=8) {
1822 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1823 PointerMemorySize(pStubMsg, bufptr, info+4);
1826 pFormat += 8 * count;
1829 if (saved_buffer)
1831 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1832 pStubMsg->Buffer = saved_buffer;
1835 return 0;
1838 /***********************************************************************
1839 * EmbeddedPointerFree [internal]
1841 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1842 unsigned char *pMemory,
1843 PFORMAT_STRING pFormat)
1845 unsigned rep, count, stride;
1846 unsigned i;
1848 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1849 if (*pFormat != RPC_FC_PP) return;
1850 pFormat += 2;
1852 while (pFormat[0] != RPC_FC_END) {
1853 switch (pFormat[0]) {
1854 default:
1855 FIXME("unknown repeat type %d\n", pFormat[0]);
1856 case RPC_FC_NO_REPEAT:
1857 rep = 1;
1858 stride = 0;
1859 count = 1;
1860 pFormat += 2;
1861 break;
1862 case RPC_FC_FIXED_REPEAT:
1863 rep = *(const WORD*)&pFormat[2];
1864 stride = *(const WORD*)&pFormat[4];
1865 count = *(const WORD*)&pFormat[8];
1866 pFormat += 10;
1867 break;
1868 case RPC_FC_VARIABLE_REPEAT:
1869 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1870 stride = *(const WORD*)&pFormat[2];
1871 count = *(const WORD*)&pFormat[6];
1872 pFormat += 8;
1873 break;
1875 for (i = 0; i < rep; i++) {
1876 PFORMAT_STRING info = pFormat;
1877 unsigned char *membase = pMemory + (i * stride);
1878 unsigned u;
1880 for (u=0; u<count; u++,info+=8) {
1881 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1882 unsigned char *saved_memory = pStubMsg->Memory;
1884 pStubMsg->Memory = pMemory;
1885 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1886 pStubMsg->Memory = saved_memory;
1889 pFormat += 8 * count;
1893 /***********************************************************************
1894 * NdrPointerMarshall [RPCRT4.@]
1896 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1897 unsigned char *pMemory,
1898 PFORMAT_STRING pFormat)
1900 unsigned char *Buffer;
1902 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1904 /* incremement the buffer here instead of in PointerMarshall,
1905 * as that is used by embedded pointers which already handle the incrementing
1906 * the buffer, and shouldn't write any additional pointer data to the wire */
1907 if (*pFormat != RPC_FC_RP)
1909 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
1910 Buffer = pStubMsg->Buffer;
1911 safe_buffer_increment(pStubMsg, 4);
1913 else
1914 Buffer = pStubMsg->Buffer;
1916 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1918 return NULL;
1921 /***********************************************************************
1922 * NdrPointerUnmarshall [RPCRT4.@]
1924 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1925 unsigned char **ppMemory,
1926 PFORMAT_STRING pFormat,
1927 unsigned char fMustAlloc)
1929 unsigned char *Buffer;
1931 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1933 /* incremement the buffer here instead of in PointerUnmarshall,
1934 * as that is used by embedded pointers which already handle the incrementing
1935 * the buffer, and shouldn't read any additional pointer data from the
1936 * buffer */
1937 if (*pFormat != RPC_FC_RP)
1939 ALIGN_POINTER(pStubMsg->Buffer, 4);
1940 Buffer = pStubMsg->Buffer;
1941 safe_buffer_increment(pStubMsg, 4);
1943 else
1944 Buffer = pStubMsg->Buffer;
1946 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1948 return NULL;
1951 /***********************************************************************
1952 * NdrPointerBufferSize [RPCRT4.@]
1954 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1955 unsigned char *pMemory,
1956 PFORMAT_STRING pFormat)
1958 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1960 /* incremement the buffer length here instead of in PointerBufferSize,
1961 * as that is used by embedded pointers which already handle the buffer
1962 * length, and shouldn't write anything more to the wire */
1963 if (*pFormat != RPC_FC_RP)
1965 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1966 safe_buffer_length_increment(pStubMsg, 4);
1969 PointerBufferSize(pStubMsg, pMemory, pFormat);
1972 /***********************************************************************
1973 * NdrPointerMemorySize [RPCRT4.@]
1975 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1976 PFORMAT_STRING pFormat)
1978 /* unsigned size = *(LPWORD)(pFormat+2); */
1979 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1980 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1981 return 0;
1984 /***********************************************************************
1985 * NdrPointerFree [RPCRT4.@]
1987 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1988 unsigned char *pMemory,
1989 PFORMAT_STRING pFormat)
1991 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1992 PointerFree(pStubMsg, pMemory, pFormat);
1995 /***********************************************************************
1996 * NdrSimpleTypeMarshall [RPCRT4.@]
1998 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1999 unsigned char FormatChar )
2001 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
2004 /***********************************************************************
2005 * NdrSimpleTypeUnmarshall [RPCRT4.@]
2007 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
2008 unsigned char FormatChar )
2010 NdrBaseTypeUnmarshall(pStubMsg, &pMemory, &FormatChar, 0);
2013 /***********************************************************************
2014 * NdrSimpleStructMarshall [RPCRT4.@]
2016 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2017 unsigned char *pMemory,
2018 PFORMAT_STRING pFormat)
2020 unsigned size = *(const WORD*)(pFormat+2);
2021 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2023 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
2025 pStubMsg->BufferMark = pStubMsg->Buffer;
2026 safe_copy_to_buffer(pStubMsg, pMemory, size);
2028 if (pFormat[0] != RPC_FC_STRUCT)
2029 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
2031 return NULL;
2034 /***********************************************************************
2035 * NdrSimpleStructUnmarshall [RPCRT4.@]
2037 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2038 unsigned char **ppMemory,
2039 PFORMAT_STRING pFormat,
2040 unsigned char fMustAlloc)
2042 unsigned size = *(const WORD*)(pFormat+2);
2043 unsigned char *saved_buffer;
2044 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2046 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2048 if (fMustAlloc)
2049 *ppMemory = NdrAllocate(pStubMsg, size);
2050 else
2052 if (!pStubMsg->IsClient && !*ppMemory)
2053 /* for servers, we just point straight into the RPC buffer */
2054 *ppMemory = pStubMsg->Buffer;
2057 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
2058 safe_buffer_increment(pStubMsg, size);
2059 if (pFormat[0] == RPC_FC_PSTRUCT)
2060 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
2062 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2063 if (*ppMemory != saved_buffer)
2064 memcpy(*ppMemory, saved_buffer, size);
2066 return NULL;
2069 /***********************************************************************
2070 * NdrSimpleStructBufferSize [RPCRT4.@]
2072 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2073 unsigned char *pMemory,
2074 PFORMAT_STRING pFormat)
2076 unsigned size = *(const WORD*)(pFormat+2);
2077 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2079 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2081 safe_buffer_length_increment(pStubMsg, size);
2082 if (pFormat[0] != RPC_FC_STRUCT)
2083 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
2086 /***********************************************************************
2087 * NdrSimpleStructMemorySize [RPCRT4.@]
2089 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2090 PFORMAT_STRING pFormat)
2092 unsigned short size = *(const WORD *)(pFormat+2);
2094 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2096 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2097 pStubMsg->MemorySize += size;
2098 safe_buffer_increment(pStubMsg, size);
2100 if (pFormat[0] != RPC_FC_STRUCT)
2101 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
2102 return pStubMsg->MemorySize;
2105 /***********************************************************************
2106 * NdrSimpleStructFree [RPCRT4.@]
2108 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2109 unsigned char *pMemory,
2110 PFORMAT_STRING pFormat)
2112 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2113 if (pFormat[0] != RPC_FC_STRUCT)
2114 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
2118 static unsigned long EmbeddedComplexSize(const MIDL_STUB_MESSAGE *pStubMsg,
2119 PFORMAT_STRING pFormat)
2121 switch (*pFormat) {
2122 case RPC_FC_STRUCT:
2123 case RPC_FC_PSTRUCT:
2124 case RPC_FC_CSTRUCT:
2125 case RPC_FC_BOGUS_STRUCT:
2126 case RPC_FC_SMFARRAY:
2127 case RPC_FC_SMVARRAY:
2128 case RPC_FC_CSTRING:
2129 return *(const WORD*)&pFormat[2];
2130 case RPC_FC_USER_MARSHAL:
2131 return *(const WORD*)&pFormat[4];
2132 case RPC_FC_NON_ENCAPSULATED_UNION:
2133 pFormat += 2;
2134 if (pStubMsg->fHasNewCorrDesc)
2135 pFormat += 6;
2136 else
2137 pFormat += 4;
2139 pFormat += *(const SHORT*)pFormat;
2140 return *(const SHORT*)pFormat;
2141 case RPC_FC_IP:
2142 return sizeof(void *);
2143 case RPC_FC_WSTRING:
2144 return *(const WORD*)&pFormat[2] * 2;
2145 default:
2146 FIXME("unhandled embedded type %02x\n", *pFormat);
2148 return 0;
2152 static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2153 PFORMAT_STRING pFormat)
2155 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
2157 if (!m)
2159 FIXME("no memorysizer for data type=%02x\n", *pFormat);
2160 return 0;
2163 return m(pStubMsg, pFormat);
2167 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2168 unsigned char *pMemory,
2169 PFORMAT_STRING pFormat,
2170 PFORMAT_STRING pPointer)
2172 PFORMAT_STRING desc;
2173 NDR_MARSHALL m;
2174 unsigned long size;
2176 while (*pFormat != RPC_FC_END) {
2177 switch (*pFormat) {
2178 case RPC_FC_BYTE:
2179 case RPC_FC_CHAR:
2180 case RPC_FC_SMALL:
2181 case RPC_FC_USMALL:
2182 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
2183 safe_copy_to_buffer(pStubMsg, pMemory, 1);
2184 pMemory += 1;
2185 break;
2186 case RPC_FC_WCHAR:
2187 case RPC_FC_SHORT:
2188 case RPC_FC_USHORT:
2189 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
2190 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2191 pMemory += 2;
2192 break;
2193 case RPC_FC_LONG:
2194 case RPC_FC_ULONG:
2195 case RPC_FC_ENUM32:
2196 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2197 safe_copy_to_buffer(pStubMsg, pMemory, 4);
2198 pMemory += 4;
2199 break;
2200 case RPC_FC_HYPER:
2201 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2202 safe_copy_to_buffer(pStubMsg, pMemory, 8);
2203 pMemory += 8;
2204 break;
2205 case RPC_FC_POINTER:
2207 unsigned char *saved_buffer;
2208 int pointer_buffer_mark_set = 0;
2209 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
2210 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
2211 saved_buffer = pStubMsg->Buffer;
2212 if (pStubMsg->PointerBufferMark)
2214 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2215 pStubMsg->PointerBufferMark = NULL;
2216 pointer_buffer_mark_set = 1;
2218 else
2219 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2220 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2221 if (pointer_buffer_mark_set)
2223 STD_OVERFLOW_CHECK(pStubMsg);
2224 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2225 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
2227 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2228 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
2229 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2231 pStubMsg->Buffer = saved_buffer + 4;
2233 pPointer += 4;
2234 pMemory += 4;
2235 break;
2237 case RPC_FC_ALIGNM4:
2238 ALIGN_POINTER(pMemory, 4);
2239 break;
2240 case RPC_FC_ALIGNM8:
2241 ALIGN_POINTER(pMemory, 8);
2242 break;
2243 case RPC_FC_STRUCTPAD1:
2244 case RPC_FC_STRUCTPAD2:
2245 case RPC_FC_STRUCTPAD3:
2246 case RPC_FC_STRUCTPAD4:
2247 case RPC_FC_STRUCTPAD5:
2248 case RPC_FC_STRUCTPAD6:
2249 case RPC_FC_STRUCTPAD7:
2250 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2251 break;
2252 case RPC_FC_EMBEDDED_COMPLEX:
2253 pMemory += pFormat[1];
2254 pFormat += 2;
2255 desc = pFormat + *(const SHORT*)pFormat;
2256 size = EmbeddedComplexSize(pStubMsg, desc);
2257 TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory);
2258 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2259 if (m)
2261 /* for some reason interface pointers aren't generated as
2262 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2263 * they still need the derefencing treatment that pointers are
2264 * given */
2265 if (*desc == RPC_FC_IP)
2266 m(pStubMsg, *(unsigned char **)pMemory, desc);
2267 else
2268 m(pStubMsg, pMemory, desc);
2270 else FIXME("no marshaller for embedded type %02x\n", *desc);
2271 pMemory += size;
2272 pFormat += 2;
2273 continue;
2274 case RPC_FC_PAD:
2275 break;
2276 default:
2277 FIXME("unhandled format 0x%02x\n", *pFormat);
2279 pFormat++;
2282 return pMemory;
2285 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2286 unsigned char *pMemory,
2287 PFORMAT_STRING pFormat,
2288 PFORMAT_STRING pPointer)
2290 PFORMAT_STRING desc;
2291 NDR_UNMARSHALL m;
2292 unsigned long size;
2294 while (*pFormat != RPC_FC_END) {
2295 switch (*pFormat) {
2296 case RPC_FC_BYTE:
2297 case RPC_FC_CHAR:
2298 case RPC_FC_SMALL:
2299 case RPC_FC_USMALL:
2300 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2301 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2302 pMemory += 1;
2303 break;
2304 case RPC_FC_WCHAR:
2305 case RPC_FC_SHORT:
2306 case RPC_FC_USHORT:
2307 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2308 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
2309 pMemory += 2;
2310 break;
2311 case RPC_FC_LONG:
2312 case RPC_FC_ULONG:
2313 case RPC_FC_ENUM32:
2314 safe_copy_from_buffer(pStubMsg, pMemory, 4);
2315 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
2316 pMemory += 4;
2317 break;
2318 case RPC_FC_HYPER:
2319 safe_copy_from_buffer(pStubMsg, pMemory, 8);
2320 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2321 pMemory += 8;
2322 break;
2323 case RPC_FC_POINTER:
2325 unsigned char *saved_buffer;
2326 int pointer_buffer_mark_set = 0;
2327 TRACE("pointer => %p\n", pMemory);
2328 ALIGN_POINTER(pStubMsg->Buffer, 4);
2329 saved_buffer = pStubMsg->Buffer;
2330 if (pStubMsg->PointerBufferMark)
2332 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2333 pStubMsg->PointerBufferMark = NULL;
2334 pointer_buffer_mark_set = 1;
2336 else
2337 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2339 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, TRUE);
2340 if (pointer_buffer_mark_set)
2342 STD_OVERFLOW_CHECK(pStubMsg);
2343 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2344 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
2346 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
2347 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
2348 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2350 pStubMsg->Buffer = saved_buffer + 4;
2352 pPointer += 4;
2353 pMemory += 4;
2354 break;
2356 case RPC_FC_ALIGNM4:
2357 ALIGN_POINTER_CLEAR(pMemory, 4);
2358 break;
2359 case RPC_FC_ALIGNM8:
2360 ALIGN_POINTER_CLEAR(pMemory, 8);
2361 break;
2362 case RPC_FC_STRUCTPAD1:
2363 case RPC_FC_STRUCTPAD2:
2364 case RPC_FC_STRUCTPAD3:
2365 case RPC_FC_STRUCTPAD4:
2366 case RPC_FC_STRUCTPAD5:
2367 case RPC_FC_STRUCTPAD6:
2368 case RPC_FC_STRUCTPAD7:
2369 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1);
2370 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2371 break;
2372 case RPC_FC_EMBEDDED_COMPLEX:
2373 pMemory += pFormat[1];
2374 pFormat += 2;
2375 desc = pFormat + *(const SHORT*)pFormat;
2376 size = EmbeddedComplexSize(pStubMsg, desc);
2377 TRACE("embedded complex (size=%ld) => %p\n", size, pMemory);
2378 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
2379 memset(pMemory, 0, size); /* just in case */
2380 if (m)
2382 /* for some reason interface pointers aren't generated as
2383 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2384 * they still need the derefencing treatment that pointers are
2385 * given */
2386 if (*desc == RPC_FC_IP)
2387 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
2388 else
2389 m(pStubMsg, &pMemory, desc, FALSE);
2391 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
2392 pMemory += size;
2393 pFormat += 2;
2394 continue;
2395 case RPC_FC_PAD:
2396 break;
2397 default:
2398 FIXME("unhandled format %d\n", *pFormat);
2400 pFormat++;
2403 return pMemory;
2406 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2407 unsigned char *pMemory,
2408 PFORMAT_STRING pFormat,
2409 PFORMAT_STRING pPointer)
2411 PFORMAT_STRING desc;
2412 NDR_BUFFERSIZE m;
2413 unsigned long size;
2415 while (*pFormat != RPC_FC_END) {
2416 switch (*pFormat) {
2417 case RPC_FC_BYTE:
2418 case RPC_FC_CHAR:
2419 case RPC_FC_SMALL:
2420 case RPC_FC_USMALL:
2421 safe_buffer_length_increment(pStubMsg, 1);
2422 pMemory += 1;
2423 break;
2424 case RPC_FC_WCHAR:
2425 case RPC_FC_SHORT:
2426 case RPC_FC_USHORT:
2427 safe_buffer_length_increment(pStubMsg, 2);
2428 pMemory += 2;
2429 break;
2430 case RPC_FC_LONG:
2431 case RPC_FC_ULONG:
2432 case RPC_FC_ENUM32:
2433 safe_buffer_length_increment(pStubMsg, 4);
2434 pMemory += 4;
2435 break;
2436 case RPC_FC_HYPER:
2437 safe_buffer_length_increment(pStubMsg, 8);
2438 pMemory += 8;
2439 break;
2440 case RPC_FC_POINTER:
2441 if (!pStubMsg->IgnoreEmbeddedPointers)
2443 int saved_buffer_length = pStubMsg->BufferLength;
2444 pStubMsg->BufferLength = pStubMsg->PointerLength;
2445 pStubMsg->PointerLength = 0;
2446 if(!pStubMsg->BufferLength)
2447 ERR("BufferLength == 0??\n");
2448 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
2449 pStubMsg->PointerLength = pStubMsg->BufferLength;
2450 pStubMsg->BufferLength = saved_buffer_length;
2452 safe_buffer_length_increment(pStubMsg, 4);
2453 pPointer += 4;
2454 pMemory += 4;
2455 break;
2456 case RPC_FC_ALIGNM4:
2457 ALIGN_POINTER(pMemory, 4);
2458 break;
2459 case RPC_FC_ALIGNM8:
2460 ALIGN_POINTER(pMemory, 8);
2461 break;
2462 case RPC_FC_STRUCTPAD1:
2463 case RPC_FC_STRUCTPAD2:
2464 case RPC_FC_STRUCTPAD3:
2465 case RPC_FC_STRUCTPAD4:
2466 case RPC_FC_STRUCTPAD5:
2467 case RPC_FC_STRUCTPAD6:
2468 case RPC_FC_STRUCTPAD7:
2469 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2470 break;
2471 case RPC_FC_EMBEDDED_COMPLEX:
2472 pMemory += pFormat[1];
2473 pFormat += 2;
2474 desc = pFormat + *(const SHORT*)pFormat;
2475 size = EmbeddedComplexSize(pStubMsg, desc);
2476 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
2477 if (m)
2479 /* for some reason interface pointers aren't generated as
2480 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2481 * they still need the derefencing treatment that pointers are
2482 * given */
2483 if (*desc == RPC_FC_IP)
2484 m(pStubMsg, *(unsigned char **)pMemory, desc);
2485 else
2486 m(pStubMsg, pMemory, desc);
2488 else FIXME("no buffersizer for embedded type %02x\n", *desc);
2489 pMemory += size;
2490 pFormat += 2;
2491 continue;
2492 case RPC_FC_PAD:
2493 break;
2494 default:
2495 FIXME("unhandled format 0x%02x\n", *pFormat);
2497 pFormat++;
2500 return pMemory;
2503 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
2504 unsigned char *pMemory,
2505 PFORMAT_STRING pFormat,
2506 PFORMAT_STRING pPointer)
2508 PFORMAT_STRING desc;
2509 NDR_FREE m;
2510 unsigned long size;
2512 while (*pFormat != RPC_FC_END) {
2513 switch (*pFormat) {
2514 case RPC_FC_BYTE:
2515 case RPC_FC_CHAR:
2516 case RPC_FC_SMALL:
2517 case RPC_FC_USMALL:
2518 pMemory += 1;
2519 break;
2520 case RPC_FC_WCHAR:
2521 case RPC_FC_SHORT:
2522 case RPC_FC_USHORT:
2523 pMemory += 2;
2524 break;
2525 case RPC_FC_LONG:
2526 case RPC_FC_ULONG:
2527 case RPC_FC_ENUM32:
2528 pMemory += 4;
2529 break;
2530 case RPC_FC_HYPER:
2531 pMemory += 8;
2532 break;
2533 case RPC_FC_POINTER:
2534 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
2535 pPointer += 4;
2536 pMemory += 4;
2537 break;
2538 case RPC_FC_ALIGNM4:
2539 ALIGN_POINTER(pMemory, 4);
2540 break;
2541 case RPC_FC_ALIGNM8:
2542 ALIGN_POINTER(pMemory, 8);
2543 break;
2544 case RPC_FC_STRUCTPAD1:
2545 case RPC_FC_STRUCTPAD2:
2546 case RPC_FC_STRUCTPAD3:
2547 case RPC_FC_STRUCTPAD4:
2548 case RPC_FC_STRUCTPAD5:
2549 case RPC_FC_STRUCTPAD6:
2550 case RPC_FC_STRUCTPAD7:
2551 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2552 break;
2553 case RPC_FC_EMBEDDED_COMPLEX:
2554 pMemory += pFormat[1];
2555 pFormat += 2;
2556 desc = pFormat + *(const SHORT*)pFormat;
2557 size = EmbeddedComplexSize(pStubMsg, desc);
2558 m = NdrFreer[*desc & NDR_TABLE_MASK];
2559 if (m)
2561 /* for some reason interface pointers aren't generated as
2562 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2563 * they still need the derefencing treatment that pointers are
2564 * given */
2565 if (*desc == RPC_FC_IP)
2566 m(pStubMsg, *(unsigned char **)pMemory, desc);
2567 else
2568 m(pStubMsg, pMemory, desc);
2570 pMemory += size;
2571 pFormat += 2;
2572 continue;
2573 case RPC_FC_PAD:
2574 break;
2575 default:
2576 FIXME("unhandled format 0x%02x\n", *pFormat);
2578 pFormat++;
2581 return pMemory;
2584 static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2585 PFORMAT_STRING pFormat)
2587 PFORMAT_STRING desc;
2588 unsigned long size = 0;
2590 while (*pFormat != RPC_FC_END) {
2591 switch (*pFormat) {
2592 case RPC_FC_BYTE:
2593 case RPC_FC_CHAR:
2594 case RPC_FC_SMALL:
2595 case RPC_FC_USMALL:
2596 size += 1;
2597 safe_buffer_increment(pStubMsg, 1);
2598 break;
2599 case RPC_FC_WCHAR:
2600 case RPC_FC_SHORT:
2601 case RPC_FC_USHORT:
2602 size += 2;
2603 safe_buffer_increment(pStubMsg, 2);
2604 break;
2605 case RPC_FC_LONG:
2606 case RPC_FC_ULONG:
2607 case RPC_FC_ENUM32:
2608 size += 4;
2609 safe_buffer_increment(pStubMsg, 4);
2610 break;
2611 case RPC_FC_HYPER:
2612 size += 8;
2613 safe_buffer_increment(pStubMsg, 8);
2614 break;
2615 case RPC_FC_POINTER:
2616 size += 4;
2617 safe_buffer_increment(pStubMsg, 4);
2618 if (!pStubMsg->IgnoreEmbeddedPointers)
2619 FIXME("embedded pointers\n");
2620 break;
2621 case RPC_FC_ALIGNM4:
2622 ALIGN_LENGTH(size, 4);
2623 ALIGN_POINTER(pStubMsg->Buffer, 4);
2624 break;
2625 case RPC_FC_ALIGNM8:
2626 ALIGN_LENGTH(size, 8);
2627 ALIGN_POINTER(pStubMsg->Buffer, 8);
2628 break;
2629 case RPC_FC_STRUCTPAD1:
2630 case RPC_FC_STRUCTPAD2:
2631 case RPC_FC_STRUCTPAD3:
2632 case RPC_FC_STRUCTPAD4:
2633 case RPC_FC_STRUCTPAD5:
2634 case RPC_FC_STRUCTPAD6:
2635 case RPC_FC_STRUCTPAD7:
2636 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2637 break;
2638 case RPC_FC_EMBEDDED_COMPLEX:
2639 size += pFormat[1];
2640 pFormat += 2;
2641 desc = pFormat + *(const SHORT*)pFormat;
2642 size += EmbeddedComplexMemorySize(pStubMsg, desc);
2643 pFormat += 2;
2644 continue;
2645 case RPC_FC_PAD:
2646 break;
2647 default:
2648 FIXME("unhandled format 0x%02x\n", *pFormat);
2650 pFormat++;
2653 return size;
2656 unsigned long ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg,
2657 PFORMAT_STRING pFormat)
2659 PFORMAT_STRING desc;
2660 unsigned long size = 0;
2662 while (*pFormat != RPC_FC_END) {
2663 switch (*pFormat) {
2664 case RPC_FC_BYTE:
2665 case RPC_FC_CHAR:
2666 case RPC_FC_SMALL:
2667 case RPC_FC_USMALL:
2668 size += 1;
2669 break;
2670 case RPC_FC_WCHAR:
2671 case RPC_FC_SHORT:
2672 case RPC_FC_USHORT:
2673 size += 2;
2674 break;
2675 case RPC_FC_LONG:
2676 case RPC_FC_ULONG:
2677 case RPC_FC_ENUM32:
2678 size += 4;
2679 break;
2680 case RPC_FC_HYPER:
2681 size += 8;
2682 break;
2683 case RPC_FC_POINTER:
2684 size += sizeof(void *);
2685 break;
2686 case RPC_FC_ALIGNM4:
2687 ALIGN_LENGTH(size, 4);
2688 break;
2689 case RPC_FC_ALIGNM8:
2690 ALIGN_LENGTH(size, 8);
2691 break;
2692 case RPC_FC_STRUCTPAD1:
2693 case RPC_FC_STRUCTPAD2:
2694 case RPC_FC_STRUCTPAD3:
2695 case RPC_FC_STRUCTPAD4:
2696 case RPC_FC_STRUCTPAD5:
2697 case RPC_FC_STRUCTPAD6:
2698 case RPC_FC_STRUCTPAD7:
2699 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2700 break;
2701 case RPC_FC_EMBEDDED_COMPLEX:
2702 size += pFormat[1];
2703 pFormat += 2;
2704 desc = pFormat + *(const SHORT*)pFormat;
2705 size += EmbeddedComplexSize(pStubMsg, desc);
2706 pFormat += 2;
2707 continue;
2708 case RPC_FC_PAD:
2709 break;
2710 default:
2711 FIXME("unhandled format 0x%02x\n", *pFormat);
2713 pFormat++;
2716 return size;
2719 /***********************************************************************
2720 * NdrComplexStructMarshall [RPCRT4.@]
2722 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2723 unsigned char *pMemory,
2724 PFORMAT_STRING pFormat)
2726 PFORMAT_STRING conf_array = NULL;
2727 PFORMAT_STRING pointer_desc = NULL;
2728 unsigned char *OldMemory = pStubMsg->Memory;
2729 int pointer_buffer_mark_set = 0;
2731 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2733 if (!pStubMsg->PointerBufferMark)
2735 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2736 /* save buffer length */
2737 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2739 /* get the buffer pointer after complex array data, but before
2740 * pointer data */
2741 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
2742 pStubMsg->IgnoreEmbeddedPointers = 1;
2743 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2744 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2746 /* save it for use by embedded pointer code later */
2747 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
2748 TRACE("difference = 0x%x\n", pStubMsg->PointerBufferMark - pStubMsg->Buffer);
2749 pointer_buffer_mark_set = 1;
2751 /* restore the original buffer length */
2752 pStubMsg->BufferLength = saved_buffer_length;
2755 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
2757 pFormat += 4;
2758 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2759 pFormat += 2;
2760 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2761 pFormat += 2;
2763 pStubMsg->Memory = pMemory;
2765 ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
2767 if (conf_array)
2768 NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array);
2770 pStubMsg->Memory = OldMemory;
2772 if (pointer_buffer_mark_set)
2774 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2775 pStubMsg->PointerBufferMark = NULL;
2778 STD_OVERFLOW_CHECK(pStubMsg);
2780 return NULL;
2783 /***********************************************************************
2784 * NdrComplexStructUnmarshall [RPCRT4.@]
2786 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2787 unsigned char **ppMemory,
2788 PFORMAT_STRING pFormat,
2789 unsigned char fMustAlloc)
2791 unsigned size = *(const WORD*)(pFormat+2);
2792 PFORMAT_STRING conf_array = NULL;
2793 PFORMAT_STRING pointer_desc = NULL;
2794 unsigned char *pMemory;
2795 int pointer_buffer_mark_set = 0;
2797 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
2799 if (!pStubMsg->PointerBufferMark)
2801 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2802 /* save buffer pointer */
2803 unsigned char *saved_buffer = pStubMsg->Buffer;
2805 /* get the buffer pointer after complex array data, but before
2806 * pointer data */
2807 pStubMsg->IgnoreEmbeddedPointers = 1;
2808 NdrComplexStructMemorySize(pStubMsg, pFormat);
2809 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2811 /* save it for use by embedded pointer code later */
2812 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2813 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->PointerBufferMark - saved_buffer));
2814 pointer_buffer_mark_set = 1;
2816 /* restore the original buffer */
2817 pStubMsg->Buffer = saved_buffer;
2820 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2822 if (fMustAlloc || !*ppMemory)
2824 *ppMemory = NdrAllocate(pStubMsg, size);
2825 memset(*ppMemory, 0, size);
2828 pFormat += 4;
2829 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2830 pFormat += 2;
2831 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2832 pFormat += 2;
2834 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc);
2836 if (conf_array)
2837 NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc);
2839 if (pointer_buffer_mark_set)
2841 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2842 pStubMsg->PointerBufferMark = NULL;
2845 return NULL;
2848 /***********************************************************************
2849 * NdrComplexStructBufferSize [RPCRT4.@]
2851 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2852 unsigned char *pMemory,
2853 PFORMAT_STRING pFormat)
2855 PFORMAT_STRING conf_array = NULL;
2856 PFORMAT_STRING pointer_desc = NULL;
2857 unsigned char *OldMemory = pStubMsg->Memory;
2858 int pointer_length_set = 0;
2860 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2862 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
2864 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
2866 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
2867 unsigned long saved_buffer_length = pStubMsg->BufferLength;
2869 /* get the buffer length after complex struct data, but before
2870 * pointer data */
2871 pStubMsg->IgnoreEmbeddedPointers = 1;
2872 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
2873 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
2875 /* save it for use by embedded pointer code later */
2876 pStubMsg->PointerLength = pStubMsg->BufferLength;
2877 pointer_length_set = 1;
2878 TRACE("difference = 0x%lx\n", pStubMsg->PointerLength - saved_buffer_length);
2880 /* restore the original buffer length */
2881 pStubMsg->BufferLength = saved_buffer_length;
2884 pFormat += 4;
2885 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2886 pFormat += 2;
2887 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2888 pFormat += 2;
2890 pStubMsg->Memory = pMemory;
2892 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
2894 if (conf_array)
2895 NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array);
2897 pStubMsg->Memory = OldMemory;
2899 if(pointer_length_set)
2901 pStubMsg->BufferLength = pStubMsg->PointerLength;
2902 pStubMsg->PointerLength = 0;
2907 /***********************************************************************
2908 * NdrComplexStructMemorySize [RPCRT4.@]
2910 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2911 PFORMAT_STRING pFormat)
2913 unsigned size = *(const WORD*)(pFormat+2);
2914 PFORMAT_STRING conf_array = NULL;
2915 PFORMAT_STRING pointer_desc = NULL;
2917 TRACE("(%p,%p)\n", pStubMsg, pFormat);
2919 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
2921 pFormat += 4;
2922 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2923 pFormat += 2;
2924 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2925 pFormat += 2;
2927 ComplexStructMemorySize(pStubMsg, pFormat);
2929 if (conf_array)
2930 NdrConformantArrayMemorySize(pStubMsg, conf_array);
2932 return size;
2935 /***********************************************************************
2936 * NdrComplexStructFree [RPCRT4.@]
2938 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
2939 unsigned char *pMemory,
2940 PFORMAT_STRING pFormat)
2942 PFORMAT_STRING conf_array = NULL;
2943 PFORMAT_STRING pointer_desc = NULL;
2944 unsigned char *OldMemory = pStubMsg->Memory;
2946 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2948 pFormat += 4;
2949 if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat;
2950 pFormat += 2;
2951 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
2952 pFormat += 2;
2954 pStubMsg->Memory = pMemory;
2956 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
2958 if (conf_array)
2959 NdrConformantArrayFree(pStubMsg, pMemory, conf_array);
2961 pStubMsg->Memory = OldMemory;
2964 /***********************************************************************
2965 * NdrConformantArrayMarshall [RPCRT4.@]
2967 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2968 unsigned char *pMemory,
2969 PFORMAT_STRING pFormat)
2971 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
2972 unsigned char alignment = pFormat[1] + 1;
2974 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
2975 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
2977 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2979 WriteConformance(pStubMsg);
2981 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
2983 size = safe_multiply(esize, pStubMsg->MaxCount);
2984 pStubMsg->BufferMark = pStubMsg->Buffer;
2985 safe_copy_to_buffer(pStubMsg, pMemory, size);
2987 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
2989 return NULL;
2992 /***********************************************************************
2993 * NdrConformantArrayUnmarshall [RPCRT4.@]
2995 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2996 unsigned char **ppMemory,
2997 PFORMAT_STRING pFormat,
2998 unsigned char fMustAlloc)
3000 DWORD size, esize = *(const WORD*)(pFormat+2);
3001 unsigned char alignment = pFormat[1] + 1;
3002 unsigned char *saved_buffer;
3004 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3005 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3007 pFormat = ReadConformance(pStubMsg, pFormat+4);
3009 size = safe_multiply(esize, pStubMsg->MaxCount);
3010 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3012 if (fMustAlloc)
3013 *ppMemory = NdrAllocate(pStubMsg, size);
3014 else
3016 if (!pStubMsg->IsClient && !*ppMemory)
3017 /* for servers, we just point straight into the RPC buffer */
3018 *ppMemory = pStubMsg->Buffer;
3021 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
3022 safe_buffer_increment(pStubMsg, size);
3023 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
3025 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
3026 if (*ppMemory != saved_buffer)
3027 memcpy(*ppMemory, saved_buffer, size);
3029 return NULL;
3032 /***********************************************************************
3033 * NdrConformantArrayBufferSize [RPCRT4.@]
3035 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3036 unsigned char *pMemory,
3037 PFORMAT_STRING pFormat)
3039 DWORD size, esize = *(const WORD*)(pFormat+2);
3040 unsigned char alignment = pFormat[1] + 1;
3042 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3043 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3045 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3047 SizeConformance(pStubMsg);
3049 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3051 size = safe_multiply(esize, pStubMsg->MaxCount);
3052 /* conformance value plus array */
3053 safe_buffer_length_increment(pStubMsg, size);
3055 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3058 /***********************************************************************
3059 * NdrConformantArrayMemorySize [RPCRT4.@]
3061 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3062 PFORMAT_STRING pFormat)
3064 DWORD size = 0, esize = *(const WORD*)(pFormat+2);
3065 unsigned char alignment = pFormat[1] + 1;
3067 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3068 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3070 pFormat = ReadConformance(pStubMsg, pFormat+4);
3071 size = safe_multiply(esize, pStubMsg->MaxCount);
3072 pStubMsg->MemorySize += size;
3074 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3075 pStubMsg->BufferMark = pStubMsg->Buffer;
3076 safe_buffer_increment(pStubMsg, size);
3078 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3080 return pStubMsg->MemorySize;
3083 /***********************************************************************
3084 * NdrConformantArrayFree [RPCRT4.@]
3086 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3087 unsigned char *pMemory,
3088 PFORMAT_STRING pFormat)
3090 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3091 if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
3093 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3095 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3099 /***********************************************************************
3100 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3102 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
3103 unsigned char* pMemory,
3104 PFORMAT_STRING pFormat )
3106 ULONG bufsize;
3107 unsigned char alignment = pFormat[1] + 1;
3108 DWORD esize = *(const WORD*)(pFormat+2);
3110 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3112 if (pFormat[0] != RPC_FC_CVARRAY)
3114 ERR("invalid format type %x\n", pFormat[0]);
3115 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3116 return NULL;
3119 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3120 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3122 WriteConformance(pStubMsg);
3123 WriteVariance(pStubMsg);
3125 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3127 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3129 pStubMsg->BufferMark = pStubMsg->Buffer;
3130 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
3132 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3134 return NULL;
3138 /***********************************************************************
3139 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
3141 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
3142 unsigned char** ppMemory,
3143 PFORMAT_STRING pFormat,
3144 unsigned char fMustAlloc )
3146 ULONG bufsize, memsize;
3147 unsigned char alignment = pFormat[1] + 1;
3148 DWORD esize = *(const WORD*)(pFormat+2);
3149 unsigned char *saved_buffer;
3150 ULONG offset;
3152 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3154 if (pFormat[0] != RPC_FC_CVARRAY)
3156 ERR("invalid format type %x\n", pFormat[0]);
3157 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3158 return NULL;
3161 pFormat = ReadConformance(pStubMsg, pFormat+4);
3162 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3164 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3166 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3167 memsize = safe_multiply(esize, pStubMsg->MaxCount);
3168 offset = pStubMsg->Offset;
3170 if (!*ppMemory || fMustAlloc)
3171 *ppMemory = NdrAllocate(pStubMsg, memsize);
3172 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
3173 safe_buffer_increment(pStubMsg, bufsize);
3175 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
3177 memcpy(*ppMemory + offset, saved_buffer, bufsize);
3179 return NULL;
3183 /***********************************************************************
3184 * NdrConformantVaryingArrayFree [RPCRT4.@]
3186 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
3187 unsigned char* pMemory,
3188 PFORMAT_STRING pFormat )
3190 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3192 if (pFormat[0] != RPC_FC_CVARRAY)
3194 ERR("invalid format type %x\n", pFormat[0]);
3195 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3196 return;
3199 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3200 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3202 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
3206 /***********************************************************************
3207 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
3209 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
3210 unsigned char* pMemory, PFORMAT_STRING pFormat )
3212 unsigned char alignment = pFormat[1] + 1;
3213 DWORD esize = *(const WORD*)(pFormat+2);
3215 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3217 if (pFormat[0] != RPC_FC_CVARRAY)
3219 ERR("invalid format type %x\n", pFormat[0]);
3220 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3221 return;
3224 /* compute size */
3225 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
3226 /* compute length */
3227 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
3229 SizeConformance(pStubMsg);
3230 SizeVariance(pStubMsg);
3232 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3234 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
3236 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
3240 /***********************************************************************
3241 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
3243 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
3244 PFORMAT_STRING pFormat )
3246 ULONG bufsize, memsize;
3247 unsigned char alignment = pFormat[1] + 1;
3248 DWORD esize = *(const WORD*)(pFormat+2);
3250 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3252 if (pFormat[0] != RPC_FC_CVARRAY)
3254 ERR("invalid format type %x\n", pFormat[0]);
3255 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3256 return pStubMsg->MemorySize;
3259 pFormat = ReadConformance(pStubMsg, pFormat+4);
3260 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3262 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3264 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
3265 memsize = safe_multiply(esize, pStubMsg->MaxCount);
3267 safe_buffer_increment(pStubMsg, bufsize);
3268 pStubMsg->MemorySize += memsize;
3270 EmbeddedPointerMemorySize(pStubMsg, pFormat);
3272 return pStubMsg->MemorySize;
3276 /***********************************************************************
3277 * NdrComplexArrayMarshall [RPCRT4.@]
3279 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3280 unsigned char *pMemory,
3281 PFORMAT_STRING pFormat)
3283 ULONG i, count, def;
3284 BOOL variance_present;
3285 unsigned char alignment;
3286 int pointer_buffer_mark_set = 0;
3288 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3290 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3292 ERR("invalid format type %x\n", pFormat[0]);
3293 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3294 return NULL;
3297 alignment = pFormat[1] + 1;
3299 if (!pStubMsg->PointerBufferMark)
3301 /* save buffer fields that may be changed by buffer sizer functions
3302 * and that may be needed later on */
3303 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3304 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3305 unsigned long saved_max_count = pStubMsg->MaxCount;
3306 unsigned long saved_offset = pStubMsg->Offset;
3307 unsigned long saved_actual_count = pStubMsg->ActualCount;
3309 /* get the buffer pointer after complex array data, but before
3310 * pointer data */
3311 pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart;
3312 pStubMsg->IgnoreEmbeddedPointers = 1;
3313 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3314 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3316 /* save it for use by embedded pointer code later */
3317 pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength;
3318 TRACE("difference = 0x%x\n", pStubMsg->Buffer - pStubMsg->BufferStart);
3319 pointer_buffer_mark_set = 1;
3321 /* restore fields */
3322 pStubMsg->ActualCount = saved_actual_count;
3323 pStubMsg->Offset = saved_offset;
3324 pStubMsg->MaxCount = saved_max_count;
3325 pStubMsg->BufferLength = saved_buffer_length;
3328 def = *(const WORD*)&pFormat[2];
3329 pFormat += 4;
3331 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3332 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3334 variance_present = IsConformanceOrVariancePresent(pFormat);
3335 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3336 TRACE("variance = %d\n", pStubMsg->ActualCount);
3338 WriteConformance(pStubMsg);
3339 if (variance_present)
3340 WriteVariance(pStubMsg);
3342 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3344 count = pStubMsg->ActualCount;
3345 for (i = 0; i < count; i++)
3346 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
3348 STD_OVERFLOW_CHECK(pStubMsg);
3350 if (pointer_buffer_mark_set)
3352 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3353 pStubMsg->PointerBufferMark = NULL;
3356 return NULL;
3359 /***********************************************************************
3360 * NdrComplexArrayUnmarshall [RPCRT4.@]
3362 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3363 unsigned char **ppMemory,
3364 PFORMAT_STRING pFormat,
3365 unsigned char fMustAlloc)
3367 ULONG i, count, size;
3368 unsigned char alignment;
3369 unsigned char *pMemory;
3370 unsigned char *saved_buffer;
3371 int pointer_buffer_mark_set = 0;
3372 int saved_ignore_embedded;
3374 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3376 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3378 ERR("invalid format type %x\n", pFormat[0]);
3379 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3380 return NULL;
3383 alignment = pFormat[1] + 1;
3385 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3386 /* save buffer pointer */
3387 saved_buffer = pStubMsg->Buffer;
3388 /* get the buffer pointer after complex array data, but before
3389 * pointer data */
3390 pStubMsg->IgnoreEmbeddedPointers = 1;
3391 pStubMsg->MemorySize = 0;
3392 NdrComplexArrayMemorySize(pStubMsg, pFormat);
3393 size = pStubMsg->MemorySize;
3394 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3396 TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->Buffer - saved_buffer));
3397 if (!pStubMsg->PointerBufferMark)
3399 /* save it for use by embedded pointer code later */
3400 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3401 pointer_buffer_mark_set = 1;
3403 /* restore the original buffer */
3404 pStubMsg->Buffer = saved_buffer;
3406 pFormat += 4;
3408 pFormat = ReadConformance(pStubMsg, pFormat);
3409 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3411 if (fMustAlloc || !*ppMemory)
3413 *ppMemory = NdrAllocate(pStubMsg, size);
3414 memset(*ppMemory, 0, size);
3417 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3419 pMemory = *ppMemory;
3420 count = pStubMsg->ActualCount;
3421 for (i = 0; i < count; i++)
3422 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL);
3424 if (pointer_buffer_mark_set)
3426 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3427 pStubMsg->PointerBufferMark = NULL;
3430 return NULL;
3433 /***********************************************************************
3434 * NdrComplexArrayBufferSize [RPCRT4.@]
3436 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3437 unsigned char *pMemory,
3438 PFORMAT_STRING pFormat)
3440 ULONG i, count, def;
3441 unsigned char alignment;
3442 BOOL variance_present;
3443 int pointer_length_set = 0;
3445 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3447 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3449 ERR("invalid format type %x\n", pFormat[0]);
3450 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3451 return;
3454 alignment = pFormat[1] + 1;
3456 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3458 /* save buffer fields that may be changed by buffer sizer functions
3459 * and that may be needed later on */
3460 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3461 unsigned long saved_buffer_length = pStubMsg->BufferLength;
3462 unsigned long saved_max_count = pStubMsg->MaxCount;
3463 unsigned long saved_offset = pStubMsg->Offset;
3464 unsigned long saved_actual_count = pStubMsg->ActualCount;
3466 /* get the buffer pointer after complex array data, but before
3467 * pointer data */
3468 pStubMsg->IgnoreEmbeddedPointers = 1;
3469 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3470 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3472 /* save it for use by embedded pointer code later */
3473 pStubMsg->PointerLength = pStubMsg->BufferLength;
3474 pointer_length_set = 1;
3476 /* restore fields */
3477 pStubMsg->ActualCount = saved_actual_count;
3478 pStubMsg->Offset = saved_offset;
3479 pStubMsg->MaxCount = saved_max_count;
3480 pStubMsg->BufferLength = saved_buffer_length;
3482 def = *(const WORD*)&pFormat[2];
3483 pFormat += 4;
3485 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3486 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3487 SizeConformance(pStubMsg);
3489 variance_present = IsConformanceOrVariancePresent(pFormat);
3490 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3491 TRACE("variance = %d\n", pStubMsg->ActualCount);
3493 if (variance_present)
3494 SizeVariance(pStubMsg);
3496 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
3498 count = pStubMsg->ActualCount;
3499 for (i = 0; i < count; i++)
3500 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
3502 if(pointer_length_set)
3504 pStubMsg->BufferLength = pStubMsg->PointerLength;
3505 pStubMsg->PointerLength = 0;
3509 /***********************************************************************
3510 * NdrComplexArrayMemorySize [RPCRT4.@]
3512 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3513 PFORMAT_STRING pFormat)
3515 ULONG i, count, esize, SavedMemorySize, MemorySize;
3516 unsigned char alignment;
3518 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3520 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3522 ERR("invalid format type %x\n", pFormat[0]);
3523 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3524 return 0;
3527 alignment = pFormat[1] + 1;
3529 pFormat += 4;
3531 pFormat = ReadConformance(pStubMsg, pFormat);
3532 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3534 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3536 SavedMemorySize = pStubMsg->MemorySize;
3538 esize = ComplexStructSize(pStubMsg, pFormat);
3540 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
3542 count = pStubMsg->ActualCount;
3543 for (i = 0; i < count; i++)
3544 ComplexStructMemorySize(pStubMsg, pFormat);
3546 pStubMsg->MemorySize = SavedMemorySize;
3548 pStubMsg->MemorySize += MemorySize;
3549 return MemorySize;
3552 /***********************************************************************
3553 * NdrComplexArrayFree [RPCRT4.@]
3555 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3556 unsigned char *pMemory,
3557 PFORMAT_STRING pFormat)
3559 ULONG i, count, def;
3561 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3563 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3565 ERR("invalid format type %x\n", pFormat[0]);
3566 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3567 return;
3570 def = *(const WORD*)&pFormat[2];
3571 pFormat += 4;
3573 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3574 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3576 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3577 TRACE("variance = %d\n", pStubMsg->ActualCount);
3579 count = pStubMsg->ActualCount;
3580 for (i = 0; i < count; i++)
3581 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
3584 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
3585 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
3586 USER_MARSHAL_CB *umcb)
3588 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
3589 pStubMsg->RpcMsg->DataRepresentation);
3590 umcb->pStubMsg = pStubMsg;
3591 umcb->pReserve = NULL;
3592 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
3593 umcb->CBType = cbtype;
3594 umcb->pFormat = pFormat;
3595 umcb->pTypeFormat = NULL /* FIXME */;
3598 #define USER_MARSHAL_PTR_PREFIX \
3599 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
3600 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
3602 /***********************************************************************
3603 * NdrUserMarshalMarshall [RPCRT4.@]
3605 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3606 unsigned char *pMemory,
3607 PFORMAT_STRING pFormat)
3609 unsigned flags = pFormat[1];
3610 unsigned index = *(const WORD*)&pFormat[2];
3611 unsigned char *saved_buffer = NULL;
3612 USER_MARSHAL_CB umcb;
3614 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3615 TRACE("index=%d\n", index);
3617 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
3619 if (flags & USER_MARSHAL_POINTER)
3621 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
3622 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
3623 pStubMsg->Buffer += 4;
3624 if (pStubMsg->PointerBufferMark)
3626 saved_buffer = pStubMsg->Buffer;
3627 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3628 pStubMsg->PointerBufferMark = NULL;
3630 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 8);
3632 else
3633 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, (flags & 0xf) + 1);
3635 pStubMsg->Buffer =
3636 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
3637 &umcb.Flags, pStubMsg->Buffer, pMemory);
3639 if (saved_buffer)
3641 STD_OVERFLOW_CHECK(pStubMsg);
3642 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3643 pStubMsg->Buffer = saved_buffer;
3646 STD_OVERFLOW_CHECK(pStubMsg);
3648 return NULL;
3651 /***********************************************************************
3652 * NdrUserMarshalUnmarshall [RPCRT4.@]
3654 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3655 unsigned char **ppMemory,
3656 PFORMAT_STRING pFormat,
3657 unsigned char fMustAlloc)
3659 unsigned flags = pFormat[1];
3660 unsigned index = *(const WORD*)&pFormat[2];
3661 DWORD memsize = *(const WORD*)&pFormat[4];
3662 unsigned char *saved_buffer = NULL;
3663 USER_MARSHAL_CB umcb;
3665 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3666 TRACE("index=%d\n", index);
3668 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
3670 if (flags & USER_MARSHAL_POINTER)
3672 ALIGN_POINTER(pStubMsg->Buffer, 4);
3673 /* skip pointer prefix */
3674 pStubMsg->Buffer += 4;
3675 if (pStubMsg->PointerBufferMark)
3677 saved_buffer = pStubMsg->Buffer;
3678 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3679 pStubMsg->PointerBufferMark = NULL;
3681 ALIGN_POINTER(pStubMsg->Buffer, 8);
3683 else
3684 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3686 if (fMustAlloc || !*ppMemory)
3687 *ppMemory = NdrAllocate(pStubMsg, memsize);
3689 pStubMsg->Buffer =
3690 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
3691 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
3693 if (saved_buffer)
3695 STD_OVERFLOW_CHECK(pStubMsg);
3696 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3697 pStubMsg->Buffer = saved_buffer;
3700 return NULL;
3703 /***********************************************************************
3704 * NdrUserMarshalBufferSize [RPCRT4.@]
3706 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3707 unsigned char *pMemory,
3708 PFORMAT_STRING pFormat)
3710 unsigned flags = pFormat[1];
3711 unsigned index = *(const WORD*)&pFormat[2];
3712 DWORD bufsize = *(const WORD*)&pFormat[6];
3713 USER_MARSHAL_CB umcb;
3714 unsigned long saved_buffer_length = 0;
3716 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3717 TRACE("index=%d\n", index);
3719 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
3721 if (flags & USER_MARSHAL_POINTER)
3723 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
3724 /* skip pointer prefix */
3725 safe_buffer_length_increment(pStubMsg, 4);
3726 if (pStubMsg->IgnoreEmbeddedPointers)
3727 return;
3728 if (pStubMsg->PointerLength)
3730 saved_buffer_length = pStubMsg->BufferLength;
3731 pStubMsg->BufferLength = pStubMsg->PointerLength;
3732 pStubMsg->PointerLength = 0;
3734 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
3736 else
3737 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
3739 if (bufsize) {
3740 TRACE("size=%d\n", bufsize);
3741 safe_buffer_length_increment(pStubMsg, bufsize);
3743 else
3744 pStubMsg->BufferLength =
3745 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
3746 &umcb.Flags, pStubMsg->BufferLength, pMemory);
3748 if (saved_buffer_length)
3750 pStubMsg->PointerLength = pStubMsg->BufferLength;
3751 pStubMsg->BufferLength = saved_buffer_length;
3756 /***********************************************************************
3757 * NdrUserMarshalMemorySize [RPCRT4.@]
3759 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3760 PFORMAT_STRING pFormat)
3762 unsigned flags = pFormat[1];
3763 unsigned index = *(const WORD*)&pFormat[2];
3764 DWORD memsize = *(const WORD*)&pFormat[4];
3765 DWORD bufsize = *(const WORD*)&pFormat[6];
3767 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3768 TRACE("index=%d\n", index);
3770 pStubMsg->MemorySize += memsize;
3772 if (flags & USER_MARSHAL_POINTER)
3774 ALIGN_POINTER(pStubMsg->Buffer, 4);
3775 /* skip pointer prefix */
3776 pStubMsg->Buffer += 4;
3777 if (pStubMsg->IgnoreEmbeddedPointers)
3778 return pStubMsg->MemorySize;
3779 ALIGN_POINTER(pStubMsg->Buffer, 8);
3781 else
3782 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
3784 if (!bufsize)
3785 FIXME("not implemented for varying buffer size\n");
3787 pStubMsg->Buffer += bufsize;
3789 return pStubMsg->MemorySize;
3792 /***********************************************************************
3793 * NdrUserMarshalFree [RPCRT4.@]
3795 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
3796 unsigned char *pMemory,
3797 PFORMAT_STRING pFormat)
3799 /* unsigned flags = pFormat[1]; */
3800 unsigned index = *(const WORD*)&pFormat[2];
3801 USER_MARSHAL_CB umcb;
3803 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3804 TRACE("index=%d\n", index);
3806 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
3808 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
3809 &umcb.Flags, pMemory);
3812 /***********************************************************************
3813 * NdrClearOutParameters [RPCRT4.@]
3815 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
3816 PFORMAT_STRING pFormat,
3817 void *ArgAddr)
3819 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
3822 /***********************************************************************
3823 * NdrConvert [RPCRT4.@]
3825 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
3827 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
3828 /* FIXME: since this stub doesn't do any converting, the proper behavior
3829 is to raise an exception */
3832 /***********************************************************************
3833 * NdrConvert2 [RPCRT4.@]
3835 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
3837 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
3838 pStubMsg, pFormat, NumberParams);
3839 /* FIXME: since this stub doesn't do any converting, the proper behavior
3840 is to raise an exception */
3843 #include "pshpack1.h"
3844 typedef struct _NDR_CSTRUCT_FORMAT
3846 unsigned char type;
3847 unsigned char alignment;
3848 unsigned short memory_size;
3849 short offset_to_array_description;
3850 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
3851 #include "poppack.h"
3853 /***********************************************************************
3854 * NdrConformantStructMarshall [RPCRT4.@]
3856 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3857 unsigned char *pMemory,
3858 PFORMAT_STRING pFormat)
3860 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3861 PFORMAT_STRING pCArrayFormat;
3862 ULONG esize, bufsize;
3864 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3866 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3867 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3869 ERR("invalid format type %x\n", pCStructFormat->type);
3870 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3871 return NULL;
3874 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3875 pCStructFormat->offset_to_array_description;
3876 if (*pCArrayFormat != RPC_FC_CARRAY)
3878 ERR("invalid array format type %x\n", pCStructFormat->type);
3879 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3880 return NULL;
3882 esize = *(const WORD*)(pCArrayFormat+2);
3884 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
3885 pCArrayFormat + 4, 0);
3887 WriteConformance(pStubMsg);
3889 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3891 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3893 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3894 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
3896 ERR("integer overflow of memory_size %u with bufsize %u\n",
3897 pCStructFormat->memory_size, bufsize);
3898 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3900 /* copy constant sized part of struct */
3901 pStubMsg->BufferMark = pStubMsg->Buffer;
3902 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
3904 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3905 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
3907 return NULL;
3910 /***********************************************************************
3911 * NdrConformantStructUnmarshall [RPCRT4.@]
3913 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3914 unsigned char **ppMemory,
3915 PFORMAT_STRING pFormat,
3916 unsigned char fMustAlloc)
3918 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3919 PFORMAT_STRING pCArrayFormat;
3920 ULONG esize, bufsize;
3921 unsigned char *saved_buffer;
3923 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3925 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3926 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3928 ERR("invalid format type %x\n", pCStructFormat->type);
3929 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3930 return NULL;
3932 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
3933 pCStructFormat->offset_to_array_description;
3934 if (*pCArrayFormat != RPC_FC_CARRAY)
3936 ERR("invalid array format type %x\n", pCStructFormat->type);
3937 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3938 return NULL;
3940 esize = *(const WORD*)(pCArrayFormat+2);
3942 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
3944 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
3946 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
3948 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
3949 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
3951 ERR("integer overflow of memory_size %u with bufsize %u\n",
3952 pCStructFormat->memory_size, bufsize);
3953 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3956 if (fMustAlloc)
3958 SIZE_T size = pCStructFormat->memory_size + bufsize;
3959 *ppMemory = NdrAllocate(pStubMsg, size);
3961 else
3963 if (!pStubMsg->IsClient && !*ppMemory)
3964 /* for servers, we just point straight into the RPC buffer */
3965 *ppMemory = pStubMsg->Buffer;
3968 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
3969 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
3970 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
3971 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
3973 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
3974 if (*ppMemory != saved_buffer)
3975 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
3977 return NULL;
3980 /***********************************************************************
3981 * NdrConformantStructBufferSize [RPCRT4.@]
3983 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3984 unsigned char *pMemory,
3985 PFORMAT_STRING pFormat)
3987 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
3988 PFORMAT_STRING pCArrayFormat;
3989 ULONG esize;
3991 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3993 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
3994 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
3996 ERR("invalid format type %x\n", pCStructFormat->type);
3997 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3998 return;
4000 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4001 pCStructFormat->offset_to_array_description;
4002 if (*pCArrayFormat != RPC_FC_CARRAY)
4004 ERR("invalid array format type %x\n", pCStructFormat->type);
4005 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4006 return;
4008 esize = *(const WORD*)(pCArrayFormat+2);
4010 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
4011 SizeConformance(pStubMsg);
4013 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
4015 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4017 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
4018 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4020 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4021 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4024 /***********************************************************************
4025 * NdrConformantStructMemorySize [RPCRT4.@]
4027 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4028 PFORMAT_STRING pFormat)
4030 FIXME("stub\n");
4031 return 0;
4034 /***********************************************************************
4035 * NdrConformantStructFree [RPCRT4.@]
4037 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4038 unsigned char *pMemory,
4039 PFORMAT_STRING pFormat)
4041 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4042 PFORMAT_STRING pCArrayFormat;
4043 ULONG esize;
4045 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4047 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4048 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4050 ERR("invalid format type %x\n", pCStructFormat->type);
4051 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4052 return;
4055 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4056 pCStructFormat->offset_to_array_description;
4057 if (*pCArrayFormat != RPC_FC_CARRAY)
4059 ERR("invalid array format type %x\n", pCStructFormat->type);
4060 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4061 return;
4063 esize = *(const WORD*)(pCArrayFormat+2);
4065 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4066 pCArrayFormat + 4, 0);
4068 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4070 /* copy constant sized part of struct */
4071 pStubMsg->BufferMark = pStubMsg->Buffer;
4073 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4074 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4077 /***********************************************************************
4078 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4080 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4081 unsigned char *pMemory,
4082 PFORMAT_STRING pFormat)
4084 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4085 PFORMAT_STRING pCVArrayFormat;
4086 ULONG esize, bufsize;
4088 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4090 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4091 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4093 ERR("invalid format type %x\n", pCVStructFormat->type);
4094 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4095 return NULL;
4098 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4099 pCVStructFormat->offset_to_array_description;
4100 switch (*pCVArrayFormat)
4102 case RPC_FC_CVARRAY:
4103 esize = *(const WORD*)(pCVArrayFormat+2);
4105 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4106 pCVArrayFormat + 4, 0);
4107 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4108 pCVArrayFormat, 0);
4109 break;
4110 case RPC_FC_C_CSTRING:
4111 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4112 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4113 esize = sizeof(char);
4114 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4115 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4116 pCVArrayFormat + 2, 0);
4117 else
4118 pStubMsg->MaxCount = pStubMsg->ActualCount;
4119 break;
4120 case RPC_FC_C_WSTRING:
4121 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4122 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4123 esize = sizeof(WCHAR);
4124 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4125 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4126 pCVArrayFormat + 2, 0);
4127 else
4128 pStubMsg->MaxCount = pStubMsg->ActualCount;
4129 break;
4130 default:
4131 ERR("invalid array format type %x\n", *pCVArrayFormat);
4132 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4133 return NULL;
4136 WriteConformance(pStubMsg);
4138 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4140 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4142 /* write constant sized part */
4143 pStubMsg->BufferMark = pStubMsg->Buffer;
4144 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
4146 WriteVariance(pStubMsg);
4148 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4150 /* write array part */
4151 safe_copy_to_buffer(pStubMsg, pMemory + pCVStructFormat->memory_size, bufsize);
4153 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4155 return NULL;
4158 /***********************************************************************
4159 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4161 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4162 unsigned char **ppMemory,
4163 PFORMAT_STRING pFormat,
4164 unsigned char fMustAlloc)
4166 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4167 PFORMAT_STRING pCVArrayFormat;
4168 ULONG esize, bufsize;
4169 unsigned char cvarray_type;
4171 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4173 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4174 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4176 ERR("invalid format type %x\n", pCVStructFormat->type);
4177 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4178 return NULL;
4181 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4182 pCVStructFormat->offset_to_array_description;
4183 cvarray_type = *pCVArrayFormat;
4184 switch (cvarray_type)
4186 case RPC_FC_CVARRAY:
4187 esize = *(const WORD*)(pCVArrayFormat+2);
4188 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
4189 break;
4190 case RPC_FC_C_CSTRING:
4191 esize = sizeof(char);
4192 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4193 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4194 else
4195 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4196 break;
4197 case RPC_FC_C_WSTRING:
4198 esize = sizeof(WCHAR);
4199 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4200 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4201 else
4202 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4203 break;
4204 default:
4205 ERR("invalid array format type %x\n", *pCVArrayFormat);
4206 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4207 return NULL;
4210 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4212 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4214 /* work out how much memory to allocate if we need to do so */
4215 if (!*ppMemory || fMustAlloc)
4217 SIZE_T size = pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
4218 *ppMemory = NdrAllocate(pStubMsg, size);
4221 /* copy the constant data */
4222 pStubMsg->BufferMark = pStubMsg->Buffer;
4223 safe_copy_from_buffer(pStubMsg, *ppMemory, pCVStructFormat->memory_size);
4225 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
4227 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4229 if ((cvarray_type == RPC_FC_C_CSTRING) ||
4230 (cvarray_type == RPC_FC_C_WSTRING))
4232 ULONG i;
4233 /* strings must always have null terminating bytes */
4234 if (bufsize < esize)
4236 ERR("invalid string length of %d\n", pStubMsg->ActualCount);
4237 RpcRaiseException(RPC_S_INVALID_BOUND);
4238 return NULL;
4240 for (i = bufsize - esize; i < bufsize; i++)
4241 if (pStubMsg->Buffer[i] != 0)
4243 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
4244 i, pStubMsg->Buffer[i]);
4245 RpcRaiseException(RPC_S_INVALID_BOUND);
4246 return NULL;
4250 /* copy the array data */
4251 safe_copy_from_buffer(pStubMsg, *ppMemory + pCVStructFormat->memory_size, bufsize);
4253 if (cvarray_type == RPC_FC_C_CSTRING)
4254 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
4255 else if (cvarray_type == RPC_FC_C_WSTRING)
4256 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
4258 EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */);
4260 return NULL;
4263 /***********************************************************************
4264 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
4266 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4267 unsigned char *pMemory,
4268 PFORMAT_STRING pFormat)
4270 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4271 PFORMAT_STRING pCVArrayFormat;
4272 ULONG esize;
4274 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4276 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4277 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4279 ERR("invalid format type %x\n", pCVStructFormat->type);
4280 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4281 return;
4284 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4285 pCVStructFormat->offset_to_array_description;
4286 switch (*pCVArrayFormat)
4288 case RPC_FC_CVARRAY:
4289 esize = *(const WORD*)(pCVArrayFormat+2);
4291 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4292 pCVArrayFormat + 4, 0);
4293 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4294 pCVArrayFormat, 0);
4295 break;
4296 case RPC_FC_C_CSTRING:
4297 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4298 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4299 esize = sizeof(char);
4300 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4301 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4302 pCVArrayFormat + 2, 0);
4303 else
4304 pStubMsg->MaxCount = pStubMsg->ActualCount;
4305 break;
4306 case RPC_FC_C_WSTRING:
4307 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4308 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4309 esize = sizeof(WCHAR);
4310 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4311 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4312 pCVArrayFormat + 2, 0);
4313 else
4314 pStubMsg->MaxCount = pStubMsg->ActualCount;
4315 break;
4316 default:
4317 ERR("invalid array format type %x\n", *pCVArrayFormat);
4318 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4319 return;
4322 SizeConformance(pStubMsg);
4324 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
4326 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4328 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
4329 SizeVariance(pStubMsg);
4330 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4332 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4335 /***********************************************************************
4336 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4338 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4339 PFORMAT_STRING pFormat)
4341 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4342 PFORMAT_STRING pCVArrayFormat;
4343 ULONG esize;
4344 unsigned char cvarray_type;
4346 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4348 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4349 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4351 ERR("invalid format type %x\n", pCVStructFormat->type);
4352 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4353 return 0;
4356 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4357 pCVStructFormat->offset_to_array_description;
4358 cvarray_type = *pCVArrayFormat;
4359 switch (cvarray_type)
4361 case RPC_FC_CVARRAY:
4362 esize = *(const WORD*)(pCVArrayFormat+2);
4363 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4);
4364 break;
4365 case RPC_FC_C_CSTRING:
4366 esize = sizeof(char);
4367 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4368 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4369 else
4370 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4371 break;
4372 case RPC_FC_C_WSTRING:
4373 esize = sizeof(WCHAR);
4374 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4375 pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2);
4376 else
4377 pCVArrayFormat = ReadConformance(pStubMsg, NULL);
4378 break;
4379 default:
4380 ERR("invalid array format type %x\n", *pCVArrayFormat);
4381 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4382 return 0;
4385 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4387 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4389 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4390 pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount);
4391 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4393 pStubMsg->MemorySize += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount);
4395 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4397 return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize;
4400 /***********************************************************************
4401 * NdrConformantVaryingStructFree [RPCRT4.@]
4403 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4404 unsigned char *pMemory,
4405 PFORMAT_STRING pFormat)
4407 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4408 PFORMAT_STRING pCVArrayFormat;
4409 ULONG esize;
4411 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4413 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4414 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4416 ERR("invalid format type %x\n", pCVStructFormat->type);
4417 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4418 return;
4421 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4422 pCVStructFormat->offset_to_array_description;
4423 switch (*pCVArrayFormat)
4425 case RPC_FC_CVARRAY:
4426 esize = *(const WORD*)(pCVArrayFormat+2);
4428 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4429 pCVArrayFormat + 4, 0);
4430 pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4431 pCVArrayFormat, 0);
4432 break;
4433 case RPC_FC_C_CSTRING:
4434 TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size));
4435 pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1;
4436 esize = sizeof(char);
4437 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4438 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4439 pCVArrayFormat + 2, 0);
4440 else
4441 pStubMsg->MaxCount = pStubMsg->ActualCount;
4442 break;
4443 case RPC_FC_C_WSTRING:
4444 TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size));
4445 pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1;
4446 esize = sizeof(WCHAR);
4447 if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED)
4448 pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size,
4449 pCVArrayFormat + 2, 0);
4450 else
4451 pStubMsg->MaxCount = pStubMsg->ActualCount;
4452 break;
4453 default:
4454 ERR("invalid array format type %x\n", *pCVArrayFormat);
4455 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4456 return;
4459 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4461 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4464 #include "pshpack1.h"
4465 typedef struct
4467 unsigned char type;
4468 unsigned char alignment;
4469 unsigned short total_size;
4470 } NDR_SMFARRAY_FORMAT;
4472 typedef struct
4474 unsigned char type;
4475 unsigned char alignment;
4476 unsigned long total_size;
4477 } NDR_LGFARRAY_FORMAT;
4478 #include "poppack.h"
4480 /***********************************************************************
4481 * NdrFixedArrayMarshall [RPCRT4.@]
4483 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4484 unsigned char *pMemory,
4485 PFORMAT_STRING pFormat)
4487 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4488 unsigned long total_size;
4490 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4492 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4493 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4495 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4496 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4497 return NULL;
4500 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4502 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4504 total_size = pSmFArrayFormat->total_size;
4505 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4507 else
4509 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4510 total_size = pLgFArrayFormat->total_size;
4511 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4514 pStubMsg->BufferMark = pStubMsg->Buffer;
4515 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
4517 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4519 return NULL;
4522 /***********************************************************************
4523 * NdrFixedArrayUnmarshall [RPCRT4.@]
4525 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4526 unsigned char **ppMemory,
4527 PFORMAT_STRING pFormat,
4528 unsigned char fMustAlloc)
4530 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4531 unsigned long total_size;
4532 unsigned char *saved_buffer;
4534 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4536 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4537 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4539 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4540 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4541 return NULL;
4544 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4546 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4548 total_size = pSmFArrayFormat->total_size;
4549 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4551 else
4553 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4554 total_size = pLgFArrayFormat->total_size;
4555 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4558 if (fMustAlloc)
4559 *ppMemory = NdrAllocate(pStubMsg, total_size);
4560 else
4562 if (!pStubMsg->IsClient && !*ppMemory)
4563 /* for servers, we just point straight into the RPC buffer */
4564 *ppMemory = pStubMsg->Buffer;
4567 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4568 safe_buffer_increment(pStubMsg, total_size);
4569 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4571 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4572 if (*ppMemory != saved_buffer)
4573 memcpy(*ppMemory, saved_buffer, total_size);
4575 return NULL;
4578 /***********************************************************************
4579 * NdrFixedArrayBufferSize [RPCRT4.@]
4581 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4582 unsigned char *pMemory,
4583 PFORMAT_STRING pFormat)
4585 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4586 unsigned long total_size;
4588 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4590 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4591 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4593 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4594 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4595 return;
4598 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
4600 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4602 total_size = pSmFArrayFormat->total_size;
4603 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4605 else
4607 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4608 total_size = pLgFArrayFormat->total_size;
4609 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4611 safe_buffer_length_increment(pStubMsg, total_size);
4613 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4616 /***********************************************************************
4617 * NdrFixedArrayMemorySize [RPCRT4.@]
4619 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4620 PFORMAT_STRING pFormat)
4622 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4623 ULONG total_size;
4625 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4627 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4628 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4630 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4631 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4632 return 0;
4635 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4637 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4639 total_size = pSmFArrayFormat->total_size;
4640 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4642 else
4644 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4645 total_size = pLgFArrayFormat->total_size;
4646 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4648 pStubMsg->BufferMark = pStubMsg->Buffer;
4649 safe_buffer_increment(pStubMsg, total_size);
4650 pStubMsg->MemorySize += total_size;
4652 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4654 return total_size;
4657 /***********************************************************************
4658 * NdrFixedArrayFree [RPCRT4.@]
4660 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4661 unsigned char *pMemory,
4662 PFORMAT_STRING pFormat)
4664 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4666 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4668 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4669 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4671 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4672 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4673 return;
4676 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4677 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4678 else
4680 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4681 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4684 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4687 /***********************************************************************
4688 * NdrVaryingArrayMarshall [RPCRT4.@]
4690 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4691 unsigned char *pMemory,
4692 PFORMAT_STRING pFormat)
4694 unsigned char alignment;
4695 DWORD elements, esize;
4696 ULONG bufsize;
4698 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4700 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4701 (pFormat[0] != RPC_FC_LGVARRAY))
4703 ERR("invalid format type %x\n", pFormat[0]);
4704 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4705 return NULL;
4708 alignment = pFormat[1] + 1;
4710 if (pFormat[0] == RPC_FC_SMVARRAY)
4712 pFormat += 2;
4713 pFormat += sizeof(WORD);
4714 elements = *(const WORD*)pFormat;
4715 pFormat += sizeof(WORD);
4717 else
4719 pFormat += 2;
4720 pFormat += sizeof(DWORD);
4721 elements = *(const DWORD*)pFormat;
4722 pFormat += sizeof(DWORD);
4725 esize = *(const WORD*)pFormat;
4726 pFormat += sizeof(WORD);
4728 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4729 if ((pStubMsg->ActualCount > elements) ||
4730 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4732 RpcRaiseException(RPC_S_INVALID_BOUND);
4733 return NULL;
4736 WriteVariance(pStubMsg);
4738 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
4740 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4741 pStubMsg->BufferMark = pStubMsg->Buffer;
4742 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
4744 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4746 return NULL;
4749 /***********************************************************************
4750 * NdrVaryingArrayUnmarshall [RPCRT4.@]
4752 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4753 unsigned char **ppMemory,
4754 PFORMAT_STRING pFormat,
4755 unsigned char fMustAlloc)
4757 unsigned char alignment;
4758 DWORD size, elements, esize;
4759 ULONG bufsize;
4760 unsigned char *saved_buffer;
4761 ULONG offset;
4763 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4765 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4766 (pFormat[0] != RPC_FC_LGVARRAY))
4768 ERR("invalid format type %x\n", pFormat[0]);
4769 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4770 return NULL;
4773 alignment = pFormat[1] + 1;
4775 if (pFormat[0] == RPC_FC_SMVARRAY)
4777 pFormat += 2;
4778 size = *(const WORD*)pFormat;
4779 pFormat += sizeof(WORD);
4780 elements = *(const WORD*)pFormat;
4781 pFormat += sizeof(WORD);
4783 else
4785 pFormat += 2;
4786 size = *(const DWORD*)pFormat;
4787 pFormat += sizeof(DWORD);
4788 elements = *(const DWORD*)pFormat;
4789 pFormat += sizeof(DWORD);
4792 esize = *(const WORD*)pFormat;
4793 pFormat += sizeof(WORD);
4795 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4797 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4799 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
4800 offset = pStubMsg->Offset;
4802 if (!*ppMemory || fMustAlloc)
4803 *ppMemory = NdrAllocate(pStubMsg, size);
4804 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4805 safe_buffer_increment(pStubMsg, bufsize);
4807 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4809 memcpy(*ppMemory + offset, saved_buffer, bufsize);
4811 return NULL;
4814 /***********************************************************************
4815 * NdrVaryingArrayBufferSize [RPCRT4.@]
4817 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4818 unsigned char *pMemory,
4819 PFORMAT_STRING pFormat)
4821 unsigned char alignment;
4822 DWORD elements, esize;
4824 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4826 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4827 (pFormat[0] != RPC_FC_LGVARRAY))
4829 ERR("invalid format type %x\n", pFormat[0]);
4830 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4831 return;
4834 alignment = pFormat[1] + 1;
4836 if (pFormat[0] == RPC_FC_SMVARRAY)
4838 pFormat += 2;
4839 pFormat += sizeof(WORD);
4840 elements = *(const WORD*)pFormat;
4841 pFormat += sizeof(WORD);
4843 else
4845 pFormat += 2;
4846 pFormat += sizeof(DWORD);
4847 elements = *(const DWORD*)pFormat;
4848 pFormat += sizeof(DWORD);
4851 esize = *(const WORD*)pFormat;
4852 pFormat += sizeof(WORD);
4854 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4855 if ((pStubMsg->ActualCount > elements) ||
4856 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4858 RpcRaiseException(RPC_S_INVALID_BOUND);
4859 return;
4862 SizeVariance(pStubMsg);
4864 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
4866 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4868 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4871 /***********************************************************************
4872 * NdrVaryingArrayMemorySize [RPCRT4.@]
4874 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4875 PFORMAT_STRING pFormat)
4877 unsigned char alignment;
4878 DWORD size, elements, esize;
4880 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4882 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4883 (pFormat[0] != RPC_FC_LGVARRAY))
4885 ERR("invalid format type %x\n", pFormat[0]);
4886 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4887 return 0;
4890 alignment = pFormat[1] + 1;
4892 if (pFormat[0] == RPC_FC_SMVARRAY)
4894 pFormat += 2;
4895 size = *(const WORD*)pFormat;
4896 pFormat += sizeof(WORD);
4897 elements = *(const WORD*)pFormat;
4898 pFormat += sizeof(WORD);
4900 else
4902 pFormat += 2;
4903 size = *(const DWORD*)pFormat;
4904 pFormat += sizeof(DWORD);
4905 elements = *(const DWORD*)pFormat;
4906 pFormat += sizeof(DWORD);
4909 esize = *(const WORD*)pFormat;
4910 pFormat += sizeof(WORD);
4912 pFormat = ReadVariance(pStubMsg, pFormat, elements);
4914 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4916 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
4917 pStubMsg->MemorySize += size;
4919 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4921 return pStubMsg->MemorySize;
4924 /***********************************************************************
4925 * NdrVaryingArrayFree [RPCRT4.@]
4927 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4928 unsigned char *pMemory,
4929 PFORMAT_STRING pFormat)
4931 unsigned char alignment;
4932 DWORD elements;
4934 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4936 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
4937 (pFormat[0] != RPC_FC_LGVARRAY))
4939 ERR("invalid format type %x\n", pFormat[0]);
4940 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4941 return;
4944 alignment = pFormat[1] + 1;
4946 if (pFormat[0] == RPC_FC_SMVARRAY)
4948 pFormat += 2;
4949 pFormat += sizeof(WORD);
4950 elements = *(const WORD*)pFormat;
4951 pFormat += sizeof(WORD);
4953 else
4955 pFormat += 2;
4956 pFormat += sizeof(DWORD);
4957 elements = *(const DWORD*)pFormat;
4958 pFormat += sizeof(DWORD);
4961 pFormat += sizeof(WORD);
4963 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
4964 if ((pStubMsg->ActualCount > elements) ||
4965 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
4967 RpcRaiseException(RPC_S_INVALID_BOUND);
4968 return;
4971 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4974 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
4976 switch (fc)
4978 case RPC_FC_BYTE:
4979 case RPC_FC_CHAR:
4980 case RPC_FC_SMALL:
4981 case RPC_FC_USMALL:
4982 return *pMemory;
4983 case RPC_FC_WCHAR:
4984 case RPC_FC_SHORT:
4985 case RPC_FC_USHORT:
4986 case RPC_FC_ENUM16:
4987 return *(const USHORT *)pMemory;
4988 case RPC_FC_LONG:
4989 case RPC_FC_ULONG:
4990 case RPC_FC_ENUM32:
4991 return *(const ULONG *)pMemory;
4992 default:
4993 FIXME("Unhandled base type: 0x%02x\n", fc);
4994 return 0;
4998 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
4999 unsigned long discriminant,
5000 PFORMAT_STRING pFormat)
5002 unsigned short num_arms, arm, type;
5004 num_arms = *(const SHORT*)pFormat & 0x0fff;
5005 pFormat += 2;
5006 for(arm = 0; arm < num_arms; arm++)
5008 if(discriminant == *(const ULONG*)pFormat)
5010 pFormat += 4;
5011 break;
5013 pFormat += 6;
5016 type = *(const unsigned short*)pFormat;
5017 TRACE("type %04x\n", type);
5018 if(arm == num_arms) /* default arm extras */
5020 if(type == 0xffff)
5022 ERR("no arm for 0x%lx and no default case\n", discriminant);
5023 RpcRaiseException(RPC_S_INVALID_TAG);
5024 return NULL;
5026 if(type == 0)
5028 TRACE("falling back to empty default case for 0x%lx\n", discriminant);
5029 return NULL;
5032 return pFormat;
5035 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
5037 unsigned short type;
5039 pFormat += 2;
5041 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5042 if(!pFormat)
5043 return NULL;
5045 type = *(const unsigned short*)pFormat;
5046 if((type & 0xff00) == 0x8000)
5048 unsigned char basetype = LOBYTE(type);
5049 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
5051 else
5053 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5054 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
5055 if (m)
5057 unsigned char *saved_buffer = NULL;
5058 int pointer_buffer_mark_set = 0;
5059 switch(*desc)
5061 case RPC_FC_RP:
5062 case RPC_FC_UP:
5063 case RPC_FC_OP:
5064 case RPC_FC_FP:
5065 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
5066 saved_buffer = pStubMsg->Buffer;
5067 if (pStubMsg->PointerBufferMark)
5069 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5070 pStubMsg->PointerBufferMark = NULL;
5071 pointer_buffer_mark_set = 1;
5073 else
5074 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
5076 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
5077 if (pointer_buffer_mark_set)
5079 STD_OVERFLOW_CHECK(pStubMsg);
5080 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5081 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5083 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5084 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5085 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5087 pStubMsg->Buffer = saved_buffer + 4;
5089 break;
5090 default:
5091 m(pStubMsg, pMemory, desc);
5094 else FIXME("no marshaller for embedded type %02x\n", *desc);
5096 return NULL;
5099 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5100 unsigned char **ppMemory,
5101 ULONG discriminant,
5102 PFORMAT_STRING pFormat,
5103 unsigned char fMustAlloc)
5105 unsigned short type;
5107 pFormat += 2;
5109 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5110 if(!pFormat)
5111 return NULL;
5113 type = *(const unsigned short*)pFormat;
5114 if((type & 0xff00) == 0x8000)
5116 unsigned char basetype = LOBYTE(type);
5117 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
5119 else
5121 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5122 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
5123 if (m)
5125 unsigned char *saved_buffer = NULL;
5126 int pointer_buffer_mark_set = 0;
5127 switch(*desc)
5129 case RPC_FC_RP:
5130 case RPC_FC_UP:
5131 case RPC_FC_OP:
5132 case RPC_FC_FP:
5133 **(void***)ppMemory = NULL;
5134 ALIGN_POINTER(pStubMsg->Buffer, 4);
5135 saved_buffer = pStubMsg->Buffer;
5136 if (pStubMsg->PointerBufferMark)
5138 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5139 pStubMsg->PointerBufferMark = NULL;
5140 pointer_buffer_mark_set = 1;
5142 else
5143 pStubMsg->Buffer += 4; /* for pointer ID */
5145 if (saved_buffer + 4 > pStubMsg->BufferEnd)
5147 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5148 saved_buffer, pStubMsg->BufferEnd);
5149 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5152 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
5153 if (pointer_buffer_mark_set)
5155 STD_OVERFLOW_CHECK(pStubMsg);
5156 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5157 pStubMsg->Buffer = saved_buffer + 4;
5159 break;
5160 default:
5161 m(pStubMsg, ppMemory, desc, fMustAlloc);
5164 else FIXME("no marshaller for embedded type %02x\n", *desc);
5166 return NULL;
5169 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
5170 unsigned char *pMemory,
5171 ULONG discriminant,
5172 PFORMAT_STRING pFormat)
5174 unsigned short type;
5176 pFormat += 2;
5178 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5179 if(!pFormat)
5180 return;
5182 type = *(const unsigned short*)pFormat;
5183 if((type & 0xff00) == 0x8000)
5185 unsigned char basetype = LOBYTE(type);
5186 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
5188 else
5190 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5191 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
5192 if (m)
5194 switch(*desc)
5196 case RPC_FC_RP:
5197 case RPC_FC_UP:
5198 case RPC_FC_OP:
5199 case RPC_FC_FP:
5200 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
5201 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
5202 if (!pStubMsg->IgnoreEmbeddedPointers)
5204 int saved_buffer_length = pStubMsg->BufferLength;
5205 pStubMsg->BufferLength = pStubMsg->PointerLength;
5206 pStubMsg->PointerLength = 0;
5207 if(!pStubMsg->BufferLength)
5208 ERR("BufferLength == 0??\n");
5209 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
5210 pStubMsg->PointerLength = pStubMsg->BufferLength;
5211 pStubMsg->BufferLength = saved_buffer_length;
5213 break;
5214 default:
5215 m(pStubMsg, pMemory, desc);
5218 else FIXME("no buffersizer for embedded type %02x\n", *desc);
5222 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
5223 ULONG discriminant,
5224 PFORMAT_STRING pFormat)
5226 unsigned short type, size;
5228 size = *(const unsigned short*)pFormat;
5229 pStubMsg->Memory += size;
5230 pFormat += 2;
5232 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5233 if(!pFormat)
5234 return 0;
5236 type = *(const unsigned short*)pFormat;
5237 if((type & 0xff00) == 0x8000)
5239 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
5241 else
5243 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5244 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
5245 unsigned char *saved_buffer;
5246 if (m)
5248 switch(*desc)
5250 case RPC_FC_RP:
5251 case RPC_FC_UP:
5252 case RPC_FC_OP:
5253 case RPC_FC_FP:
5254 ALIGN_POINTER(pStubMsg->Buffer, 4);
5255 saved_buffer = pStubMsg->Buffer;
5256 safe_buffer_increment(pStubMsg, 4);
5257 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
5258 pStubMsg->MemorySize += 4;
5259 if (!pStubMsg->IgnoreEmbeddedPointers)
5260 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
5261 break;
5262 default:
5263 return m(pStubMsg, desc);
5266 else FIXME("no marshaller for embedded type %02x\n", *desc);
5269 TRACE("size %d\n", size);
5270 return size;
5273 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
5274 unsigned char *pMemory,
5275 ULONG discriminant,
5276 PFORMAT_STRING pFormat)
5278 unsigned short type;
5280 pFormat += 2;
5282 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5283 if(!pFormat)
5284 return;
5286 type = *(const unsigned short*)pFormat;
5287 if((type & 0xff00) != 0x8000)
5289 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5290 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5291 if (m)
5293 switch(*desc)
5295 case RPC_FC_RP:
5296 case RPC_FC_UP:
5297 case RPC_FC_OP:
5298 case RPC_FC_FP:
5299 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5300 break;
5301 default:
5302 m(pStubMsg, pMemory, desc);
5308 /***********************************************************************
5309 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5311 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5312 unsigned char *pMemory,
5313 PFORMAT_STRING pFormat)
5315 unsigned char switch_type;
5316 unsigned char increment;
5317 ULONG switch_value;
5319 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5320 pFormat++;
5322 switch_type = *pFormat & 0xf;
5323 increment = (*pFormat & 0xf0) >> 4;
5324 pFormat++;
5326 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, increment);
5328 switch_value = get_discriminant(switch_type, pMemory);
5329 TRACE("got switch value 0x%x\n", switch_value);
5331 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5332 pMemory += increment;
5334 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5337 /***********************************************************************
5338 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5340 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5341 unsigned char **ppMemory,
5342 PFORMAT_STRING pFormat,
5343 unsigned char fMustAlloc)
5345 unsigned char switch_type;
5346 unsigned char increment;
5347 ULONG switch_value;
5348 unsigned short size;
5349 unsigned char *pMemoryArm;
5351 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5352 pFormat++;
5354 switch_type = *pFormat & 0xf;
5355 increment = (*pFormat & 0xf0) >> 4;
5356 pFormat++;
5358 ALIGN_POINTER(pStubMsg->Buffer, increment);
5359 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5360 TRACE("got switch value 0x%x\n", switch_value);
5362 size = *(const unsigned short*)pFormat + increment;
5363 if(!*ppMemory || fMustAlloc)
5364 *ppMemory = NdrAllocate(pStubMsg, size);
5366 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
5367 pMemoryArm = *ppMemory + increment;
5369 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, fMustAlloc);
5372 /***********************************************************************
5373 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5375 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5376 unsigned char *pMemory,
5377 PFORMAT_STRING pFormat)
5379 unsigned char switch_type;
5380 unsigned char increment;
5381 ULONG switch_value;
5383 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5384 pFormat++;
5386 switch_type = *pFormat & 0xf;
5387 increment = (*pFormat & 0xf0) >> 4;
5388 pFormat++;
5390 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
5391 switch_value = get_discriminant(switch_type, pMemory);
5392 TRACE("got switch value 0x%x\n", switch_value);
5394 /* Add discriminant size */
5395 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
5396 pMemory += increment;
5398 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
5401 /***********************************************************************
5402 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5404 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5405 PFORMAT_STRING pFormat)
5407 unsigned char switch_type;
5408 unsigned char increment;
5409 ULONG switch_value;
5411 switch_type = *pFormat & 0xf;
5412 increment = (*pFormat & 0xf0) >> 4;
5413 pFormat++;
5415 ALIGN_POINTER(pStubMsg->Buffer, increment);
5416 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5417 TRACE("got switch value 0x%x\n", switch_value);
5419 pStubMsg->Memory += increment;
5421 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
5424 /***********************************************************************
5425 * NdrEncapsulatedUnionFree [RPCRT4.@]
5427 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5428 unsigned char *pMemory,
5429 PFORMAT_STRING pFormat)
5431 unsigned char switch_type;
5432 unsigned char increment;
5433 ULONG switch_value;
5435 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5436 pFormat++;
5438 switch_type = *pFormat & 0xf;
5439 increment = (*pFormat & 0xf0) >> 4;
5440 pFormat++;
5442 switch_value = get_discriminant(switch_type, pMemory);
5443 TRACE("got switch value 0x%x\n", switch_value);
5445 pMemory += increment;
5447 return union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
5450 /***********************************************************************
5451 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5453 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5454 unsigned char *pMemory,
5455 PFORMAT_STRING pFormat)
5457 unsigned char switch_type;
5459 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5460 pFormat++;
5462 switch_type = *pFormat;
5463 pFormat++;
5465 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5466 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5467 /* Marshall discriminant */
5468 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5470 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5473 static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
5474 PFORMAT_STRING *ppFormat)
5476 long discriminant = 0;
5478 switch(**ppFormat)
5480 case RPC_FC_BYTE:
5481 case RPC_FC_CHAR:
5482 case RPC_FC_SMALL:
5483 case RPC_FC_USMALL:
5485 UCHAR d;
5486 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5487 discriminant = d;
5488 break;
5490 case RPC_FC_WCHAR:
5491 case RPC_FC_SHORT:
5492 case RPC_FC_USHORT:
5494 USHORT d;
5495 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5496 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5497 discriminant = d;
5498 break;
5500 case RPC_FC_LONG:
5501 case RPC_FC_ULONG:
5503 ULONG d;
5504 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5505 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5506 discriminant = d;
5507 break;
5509 default:
5510 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
5512 (*ppFormat)++;
5514 if (pStubMsg->fHasNewCorrDesc)
5515 *ppFormat += 6;
5516 else
5517 *ppFormat += 4;
5518 return discriminant;
5521 /**********************************************************************
5522 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5524 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5525 unsigned char **ppMemory,
5526 PFORMAT_STRING pFormat,
5527 unsigned char fMustAlloc)
5529 long discriminant;
5530 unsigned short size;
5532 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5533 pFormat++;
5535 /* Unmarshall discriminant */
5536 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5537 TRACE("unmarshalled discriminant %lx\n", discriminant);
5539 pFormat += *(const SHORT*)pFormat;
5541 size = *(const unsigned short*)pFormat;
5543 if(!*ppMemory || fMustAlloc)
5544 *ppMemory = NdrAllocate(pStubMsg, size);
5546 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, fMustAlloc);
5549 /***********************************************************************
5550 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5552 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5553 unsigned char *pMemory,
5554 PFORMAT_STRING pFormat)
5556 unsigned char switch_type;
5558 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5559 pFormat++;
5561 switch_type = *pFormat;
5562 pFormat++;
5564 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5565 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5566 /* Add discriminant size */
5567 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5569 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5572 /***********************************************************************
5573 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
5575 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5576 PFORMAT_STRING pFormat)
5578 ULONG discriminant;
5580 pFormat++;
5581 /* Unmarshall discriminant */
5582 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5583 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
5585 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
5588 /***********************************************************************
5589 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
5591 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5592 unsigned char *pMemory,
5593 PFORMAT_STRING pFormat)
5595 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5596 pFormat++;
5597 pFormat++;
5599 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5600 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5602 return union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5605 /***********************************************************************
5606 * NdrByteCountPointerMarshall [RPCRT4.@]
5608 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5609 unsigned char *pMemory,
5610 PFORMAT_STRING pFormat)
5612 FIXME("stub\n");
5613 return NULL;
5616 /***********************************************************************
5617 * NdrByteCountPointerUnmarshall [RPCRT4.@]
5619 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5620 unsigned char **ppMemory,
5621 PFORMAT_STRING pFormat,
5622 unsigned char fMustAlloc)
5624 FIXME("stub\n");
5625 return NULL;
5628 /***********************************************************************
5629 * NdrByteCountPointerBufferSize [RPCRT4.@]
5631 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5632 unsigned char *pMemory,
5633 PFORMAT_STRING pFormat)
5635 FIXME("stub\n");
5638 /***********************************************************************
5639 * NdrByteCountPointerMemorySize [RPCRT4.@]
5641 ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5642 PFORMAT_STRING pFormat)
5644 FIXME("stub\n");
5645 return 0;
5648 /***********************************************************************
5649 * NdrByteCountPointerFree [RPCRT4.@]
5651 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
5652 unsigned char *pMemory,
5653 PFORMAT_STRING pFormat)
5655 FIXME("stub\n");
5658 /***********************************************************************
5659 * NdrXmitOrRepAsMarshall [RPCRT4.@]
5661 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5662 unsigned char *pMemory,
5663 PFORMAT_STRING pFormat)
5665 FIXME("stub\n");
5666 return NULL;
5669 /***********************************************************************
5670 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
5672 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5673 unsigned char **ppMemory,
5674 PFORMAT_STRING pFormat,
5675 unsigned char fMustAlloc)
5677 FIXME("stub\n");
5678 return NULL;
5681 /***********************************************************************
5682 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
5684 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5685 unsigned char *pMemory,
5686 PFORMAT_STRING pFormat)
5688 FIXME("stub\n");
5691 /***********************************************************************
5692 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
5694 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5695 PFORMAT_STRING pFormat)
5697 FIXME("stub\n");
5698 return 0;
5701 /***********************************************************************
5702 * NdrXmitOrRepAsFree [RPCRT4.@]
5704 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
5705 unsigned char *pMemory,
5706 PFORMAT_STRING pFormat)
5708 FIXME("stub\n");
5711 #include "pshpack1.h"
5712 typedef struct
5714 unsigned char type;
5715 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
5716 ULONG low_value;
5717 ULONG high_value;
5718 } NDR_RANGE;
5719 #include "poppack.h"
5721 /***********************************************************************
5722 * NdrRangeMarshall [internal]
5724 unsigned char *WINAPI NdrRangeMarshall(
5725 PMIDL_STUB_MESSAGE pStubMsg,
5726 unsigned char *pMemory,
5727 PFORMAT_STRING pFormat)
5729 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5730 unsigned char base_type;
5732 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5734 if (pRange->type != RPC_FC_RANGE)
5736 ERR("invalid format type %x\n", pRange->type);
5737 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5738 return NULL;
5741 base_type = pRange->flags_type & 0xf;
5743 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
5746 /***********************************************************************
5747 * NdrRangeUnmarshall
5749 unsigned char *WINAPI NdrRangeUnmarshall(
5750 PMIDL_STUB_MESSAGE pStubMsg,
5751 unsigned char **ppMemory,
5752 PFORMAT_STRING pFormat,
5753 unsigned char fMustAlloc)
5755 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5756 unsigned char base_type;
5758 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5760 if (pRange->type != RPC_FC_RANGE)
5762 ERR("invalid format type %x\n", pRange->type);
5763 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5764 return NULL;
5766 base_type = pRange->flags_type & 0xf;
5768 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
5769 base_type, pRange->low_value, pRange->high_value);
5771 #define RANGE_UNMARSHALL(type, format_spec) \
5772 do \
5774 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5775 if (fMustAlloc || !*ppMemory) \
5776 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5777 if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \
5779 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
5780 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
5781 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
5783 if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \
5784 (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \
5786 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
5787 *(type *)pStubMsg->Buffer, (type)pRange->low_value, \
5788 (type)pRange->high_value); \
5789 RpcRaiseException(RPC_S_INVALID_BOUND); \
5790 return NULL; \
5792 TRACE("*ppMemory: %p\n", *ppMemory); \
5793 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5794 pStubMsg->Buffer += sizeof(type); \
5795 } while (0)
5797 switch(base_type)
5799 case RPC_FC_CHAR:
5800 case RPC_FC_SMALL:
5801 RANGE_UNMARSHALL(UCHAR, "%d");
5802 TRACE("value: 0x%02x\n", **ppMemory);
5803 break;
5804 case RPC_FC_BYTE:
5805 case RPC_FC_USMALL:
5806 RANGE_UNMARSHALL(CHAR, "%u");
5807 TRACE("value: 0x%02x\n", **ppMemory);
5808 break;
5809 case RPC_FC_WCHAR: /* FIXME: valid? */
5810 case RPC_FC_USHORT:
5811 RANGE_UNMARSHALL(USHORT, "%u");
5812 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5813 break;
5814 case RPC_FC_SHORT:
5815 RANGE_UNMARSHALL(SHORT, "%d");
5816 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
5817 break;
5818 case RPC_FC_LONG:
5819 RANGE_UNMARSHALL(LONG, "%d");
5820 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5821 break;
5822 case RPC_FC_ULONG:
5823 RANGE_UNMARSHALL(ULONG, "%u");
5824 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
5825 break;
5826 case RPC_FC_ENUM16:
5827 case RPC_FC_ENUM32:
5828 FIXME("Unhandled enum type\n");
5829 break;
5830 case RPC_FC_ERROR_STATUS_T: /* FIXME: valid? */
5831 case RPC_FC_FLOAT:
5832 case RPC_FC_DOUBLE:
5833 case RPC_FC_HYPER:
5834 default:
5835 ERR("invalid range base type: 0x%02x\n", base_type);
5836 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5839 return NULL;
5842 /***********************************************************************
5843 * NdrRangeBufferSize [internal]
5845 void WINAPI NdrRangeBufferSize(
5846 PMIDL_STUB_MESSAGE pStubMsg,
5847 unsigned char *pMemory,
5848 PFORMAT_STRING pFormat)
5850 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5851 unsigned char base_type;
5853 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5855 if (pRange->type != RPC_FC_RANGE)
5857 ERR("invalid format type %x\n", pRange->type);
5858 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5860 base_type = pRange->flags_type & 0xf;
5862 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
5865 /***********************************************************************
5866 * NdrRangeMemorySize [internal]
5868 ULONG WINAPI NdrRangeMemorySize(
5869 PMIDL_STUB_MESSAGE pStubMsg,
5870 PFORMAT_STRING pFormat)
5872 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
5873 unsigned char base_type;
5875 if (pRange->type != RPC_FC_RANGE)
5877 ERR("invalid format type %x\n", pRange->type);
5878 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5879 return 0;
5881 base_type = pRange->flags_type & 0xf;
5883 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
5886 /***********************************************************************
5887 * NdrRangeFree [internal]
5889 void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
5890 unsigned char *pMemory,
5891 PFORMAT_STRING pFormat)
5893 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5895 /* nothing to do */
5898 /***********************************************************************
5899 * NdrBaseTypeMarshall [internal]
5901 static unsigned char *WINAPI NdrBaseTypeMarshall(
5902 PMIDL_STUB_MESSAGE pStubMsg,
5903 unsigned char *pMemory,
5904 PFORMAT_STRING pFormat)
5906 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
5908 switch(*pFormat)
5910 case RPC_FC_BYTE:
5911 case RPC_FC_CHAR:
5912 case RPC_FC_SMALL:
5913 case RPC_FC_USMALL:
5914 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
5915 TRACE("value: 0x%02x\n", *pMemory);
5916 break;
5917 case RPC_FC_WCHAR:
5918 case RPC_FC_SHORT:
5919 case RPC_FC_USHORT:
5920 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
5921 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
5922 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
5923 break;
5924 case RPC_FC_LONG:
5925 case RPC_FC_ULONG:
5926 case RPC_FC_ERROR_STATUS_T:
5927 case RPC_FC_ENUM32:
5928 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONG));
5929 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
5930 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
5931 break;
5932 case RPC_FC_FLOAT:
5933 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(float));
5934 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
5935 break;
5936 case RPC_FC_DOUBLE:
5937 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(double));
5938 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
5939 break;
5940 case RPC_FC_HYPER:
5941 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONGLONG));
5942 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
5943 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
5944 break;
5945 case RPC_FC_ENUM16:
5946 /* only 16-bits on the wire, so do a sanity check */
5947 if (*(UINT *)pMemory > SHRT_MAX)
5948 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
5949 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
5950 if (pStubMsg->Buffer + sizeof(USHORT) > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5951 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5952 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
5953 pStubMsg->Buffer += sizeof(USHORT);
5954 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
5955 break;
5956 case RPC_FC_IGNORE:
5957 break;
5958 default:
5959 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
5962 /* FIXME: what is the correct return value? */
5963 return NULL;
5966 /***********************************************************************
5967 * NdrBaseTypeUnmarshall [internal]
5969 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
5970 PMIDL_STUB_MESSAGE pStubMsg,
5971 unsigned char **ppMemory,
5972 PFORMAT_STRING pFormat,
5973 unsigned char fMustAlloc)
5975 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
5977 #define BASE_TYPE_UNMARSHALL(type) \
5978 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
5979 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
5981 *ppMemory = pStubMsg->Buffer; \
5982 TRACE("*ppMemory: %p\n", *ppMemory); \
5984 else \
5986 if (fMustAlloc) \
5987 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
5988 TRACE("*ppMemory: %p\n", *ppMemory); \
5989 **(type **)ppMemory = *(type *)pStubMsg->Buffer; \
5991 pStubMsg->Buffer += sizeof(type);
5993 switch(*pFormat)
5995 case RPC_FC_BYTE:
5996 case RPC_FC_CHAR:
5997 case RPC_FC_SMALL:
5998 case RPC_FC_USMALL:
5999 BASE_TYPE_UNMARSHALL(UCHAR);
6000 TRACE("value: 0x%02x\n", **ppMemory);
6001 break;
6002 case RPC_FC_WCHAR:
6003 case RPC_FC_SHORT:
6004 case RPC_FC_USHORT:
6005 BASE_TYPE_UNMARSHALL(USHORT);
6006 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6007 break;
6008 case RPC_FC_LONG:
6009 case RPC_FC_ULONG:
6010 case RPC_FC_ERROR_STATUS_T:
6011 case RPC_FC_ENUM32:
6012 BASE_TYPE_UNMARSHALL(ULONG);
6013 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6014 break;
6015 case RPC_FC_FLOAT:
6016 BASE_TYPE_UNMARSHALL(float);
6017 TRACE("value: %f\n", **(float **)ppMemory);
6018 break;
6019 case RPC_FC_DOUBLE:
6020 BASE_TYPE_UNMARSHALL(double);
6021 TRACE("value: %f\n", **(double **)ppMemory);
6022 break;
6023 case RPC_FC_HYPER:
6024 BASE_TYPE_UNMARSHALL(ULONGLONG);
6025 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
6026 break;
6027 case RPC_FC_ENUM16:
6028 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
6029 if (fMustAlloc || !*ppMemory)
6030 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
6031 if (pStubMsg->Buffer + sizeof(USHORT) > pStubMsg->BufferEnd)
6032 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6033 TRACE("*ppMemory: %p\n", *ppMemory);
6034 /* 16-bits on the wire, but int in memory */
6035 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
6036 pStubMsg->Buffer += sizeof(USHORT);
6037 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6038 break;
6039 case RPC_FC_IGNORE:
6040 break;
6041 default:
6042 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6044 #undef BASE_TYPE_UNMARSHALL
6046 /* FIXME: what is the correct return value? */
6048 return NULL;
6051 /***********************************************************************
6052 * NdrBaseTypeBufferSize [internal]
6054 static void WINAPI NdrBaseTypeBufferSize(
6055 PMIDL_STUB_MESSAGE pStubMsg,
6056 unsigned char *pMemory,
6057 PFORMAT_STRING pFormat)
6059 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6061 switch(*pFormat)
6063 case RPC_FC_BYTE:
6064 case RPC_FC_CHAR:
6065 case RPC_FC_SMALL:
6066 case RPC_FC_USMALL:
6067 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6068 break;
6069 case RPC_FC_WCHAR:
6070 case RPC_FC_SHORT:
6071 case RPC_FC_USHORT:
6072 case RPC_FC_ENUM16:
6073 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
6074 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6075 break;
6076 case RPC_FC_LONG:
6077 case RPC_FC_ULONG:
6078 case RPC_FC_ENUM32:
6079 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
6080 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6081 break;
6082 case RPC_FC_FLOAT:
6083 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
6084 safe_buffer_length_increment(pStubMsg, sizeof(float));
6085 break;
6086 case RPC_FC_DOUBLE:
6087 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
6088 safe_buffer_length_increment(pStubMsg, sizeof(double));
6089 break;
6090 case RPC_FC_HYPER:
6091 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
6092 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6093 break;
6094 case RPC_FC_ERROR_STATUS_T:
6095 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
6096 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6097 break;
6098 case RPC_FC_IGNORE:
6099 break;
6100 default:
6101 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6105 /***********************************************************************
6106 * NdrBaseTypeMemorySize [internal]
6108 static ULONG WINAPI NdrBaseTypeMemorySize(
6109 PMIDL_STUB_MESSAGE pStubMsg,
6110 PFORMAT_STRING pFormat)
6112 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6114 switch(*pFormat)
6116 case RPC_FC_BYTE:
6117 case RPC_FC_CHAR:
6118 case RPC_FC_SMALL:
6119 case RPC_FC_USMALL:
6120 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6121 pStubMsg->MemorySize += sizeof(UCHAR);
6122 return sizeof(UCHAR);
6123 case RPC_FC_WCHAR:
6124 case RPC_FC_SHORT:
6125 case RPC_FC_USHORT:
6126 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6127 pStubMsg->MemorySize += sizeof(USHORT);
6128 return sizeof(USHORT);
6129 case RPC_FC_LONG:
6130 case RPC_FC_ULONG:
6131 case RPC_FC_ENUM32:
6132 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6133 pStubMsg->MemorySize += sizeof(ULONG);
6134 return sizeof(ULONG);
6135 case RPC_FC_FLOAT:
6136 safe_buffer_increment(pStubMsg, sizeof(float));
6137 pStubMsg->MemorySize += sizeof(float);
6138 return sizeof(float);
6139 case RPC_FC_DOUBLE:
6140 safe_buffer_increment(pStubMsg, sizeof(double));
6141 pStubMsg->MemorySize += sizeof(double);
6142 return sizeof(double);
6143 case RPC_FC_HYPER:
6144 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6145 pStubMsg->MemorySize += sizeof(ULONGLONG);
6146 return sizeof(ULONGLONG);
6147 case RPC_FC_ERROR_STATUS_T:
6148 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6149 pStubMsg->MemorySize += sizeof(error_status_t);
6150 return sizeof(error_status_t);
6151 case RPC_FC_ENUM16:
6152 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6153 pStubMsg->MemorySize += sizeof(UINT);
6154 return sizeof(UINT);
6155 case RPC_FC_IGNORE:
6156 pStubMsg->MemorySize += sizeof(void *);
6157 return sizeof(void *);
6158 default:
6159 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6160 return 0;
6164 /***********************************************************************
6165 * NdrBaseTypeFree [internal]
6167 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6168 unsigned char *pMemory,
6169 PFORMAT_STRING pFormat)
6171 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6173 /* nothing to do */
6176 /***********************************************************************
6177 * NdrContextHandleBufferSize [internal]
6179 static void WINAPI NdrContextHandleBufferSize(
6180 PMIDL_STUB_MESSAGE pStubMsg,
6181 unsigned char *pMemory,
6182 PFORMAT_STRING pFormat)
6184 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6186 if (*pFormat != RPC_FC_BIND_CONTEXT)
6188 ERR("invalid format type %x\n", *pFormat);
6189 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6191 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
6192 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6195 /***********************************************************************
6196 * NdrContextHandleMarshall [internal]
6198 static unsigned char *WINAPI NdrContextHandleMarshall(
6199 PMIDL_STUB_MESSAGE pStubMsg,
6200 unsigned char *pMemory,
6201 PFORMAT_STRING pFormat)
6203 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6205 if (*pFormat != RPC_FC_BIND_CONTEXT)
6207 ERR("invalid format type %x\n", *pFormat);
6208 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6210 TRACE("flags: 0x%02x\n", pFormat[1]);
6212 if (pFormat[1] & 0x80)
6213 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
6214 else
6215 NdrClientContextMarshall(pStubMsg, (NDR_CCONTEXT *)pMemory, FALSE);
6217 return NULL;
6220 /***********************************************************************
6221 * NdrContextHandleUnmarshall [internal]
6223 static unsigned char *WINAPI NdrContextHandleUnmarshall(
6224 PMIDL_STUB_MESSAGE pStubMsg,
6225 unsigned char **ppMemory,
6226 PFORMAT_STRING pFormat,
6227 unsigned char fMustAlloc)
6229 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg,
6230 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE");
6232 if (*pFormat != RPC_FC_BIND_CONTEXT)
6234 ERR("invalid format type %x\n", *pFormat);
6235 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6237 TRACE("flags: 0x%02x\n", pFormat[1]);
6239 /* [out]-only or [ret] param */
6240 if ((pFormat[1] & 0x60) == 0x20)
6241 **(NDR_CCONTEXT **)ppMemory = NULL;
6242 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
6244 return NULL;
6247 /***********************************************************************
6248 * NdrClientContextMarshall [RPCRT4.@]
6250 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6251 NDR_CCONTEXT ContextHandle,
6252 int fCheck)
6254 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
6256 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
6258 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6260 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6261 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6262 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6265 /* FIXME: what does fCheck do? */
6266 NDRCContextMarshall(ContextHandle,
6267 pStubMsg->Buffer);
6269 pStubMsg->Buffer += cbNDRContext;
6272 /***********************************************************************
6273 * NdrClientContextUnmarshall [RPCRT4.@]
6275 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6276 NDR_CCONTEXT * pContextHandle,
6277 RPC_BINDING_HANDLE BindHandle)
6279 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
6281 ALIGN_POINTER(pStubMsg->Buffer, 4);
6283 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
6284 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6286 NDRCContextUnmarshall(pContextHandle,
6287 BindHandle,
6288 pStubMsg->Buffer,
6289 pStubMsg->RpcMsg->DataRepresentation);
6291 pStubMsg->Buffer += cbNDRContext;
6294 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6295 NDR_SCONTEXT ContextHandle,
6296 NDR_RUNDOWN RundownRoutine )
6298 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
6300 ALIGN_POINTER(pStubMsg->Buffer, 4);
6302 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6304 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6305 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6306 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6309 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6310 pStubMsg->Buffer, RundownRoutine, NULL,
6311 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6312 pStubMsg->Buffer += cbNDRContext;
6315 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
6317 NDR_SCONTEXT ContextHandle;
6319 TRACE("(%p)\n", pStubMsg);
6321 ALIGN_POINTER(pStubMsg->Buffer, 4);
6323 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6325 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6326 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6327 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6330 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6331 pStubMsg->Buffer,
6332 pStubMsg->RpcMsg->DataRepresentation,
6333 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6334 pStubMsg->Buffer += cbNDRContext;
6336 return ContextHandle;
6339 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
6340 unsigned char* pMemory,
6341 PFORMAT_STRING pFormat)
6343 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
6346 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
6347 PFORMAT_STRING pFormat)
6349 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6350 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6352 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6354 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6355 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6356 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6357 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6358 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6360 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6361 if_id = &sif->InterfaceId;
6364 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
6365 pStubMsg->RpcMsg->DataRepresentation, if_id,
6366 flags);
6369 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6370 NDR_SCONTEXT ContextHandle,
6371 NDR_RUNDOWN RundownRoutine,
6372 PFORMAT_STRING pFormat)
6374 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6375 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6377 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
6379 ALIGN_POINTER(pStubMsg->Buffer, 4);
6381 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6383 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6384 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6385 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6388 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6389 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6390 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6391 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6392 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6394 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6395 if_id = &sif->InterfaceId;
6398 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6399 pStubMsg->Buffer, RundownRoutine, if_id, flags);
6400 pStubMsg->Buffer += cbNDRContext;
6403 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6404 PFORMAT_STRING pFormat)
6406 NDR_SCONTEXT ContextHandle;
6407 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6408 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6410 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6412 ALIGN_POINTER(pStubMsg->Buffer, 4);
6414 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6416 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6417 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6418 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6421 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6422 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6423 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6424 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6425 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6427 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6428 if_id = &sif->InterfaceId;
6431 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6432 pStubMsg->Buffer,
6433 pStubMsg->RpcMsg->DataRepresentation,
6434 if_id, flags);
6435 pStubMsg->Buffer += cbNDRContext;
6437 return ContextHandle;
6440 /***********************************************************************
6441 * NdrCorrelationInitialize [RPCRT4.@]
6443 * Initializes correlation validity checking.
6445 * PARAMS
6446 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6447 * pMemory [I] Pointer to memory to use as a cache.
6448 * CacheSize [I] Size of the memory pointed to by pMemory.
6449 * Flags [I] Reserved. Set to zero.
6451 * RETURNS
6452 * Nothing.
6454 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
6456 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg, pMemory, CacheSize, Flags);
6457 pStubMsg->fHasNewCorrDesc = TRUE;
6460 /***********************************************************************
6461 * NdrCorrelationPass [RPCRT4.@]
6463 * Performs correlation validity checking.
6465 * PARAMS
6466 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6468 * RETURNS
6469 * Nothing.
6471 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
6473 FIXME("(%p): stub\n", pStubMsg);
6476 /***********************************************************************
6477 * NdrCorrelationFree [RPCRT4.@]
6479 * Frees any resources used while unmarshalling parameters that need
6480 * correlation validity checking.
6482 * PARAMS
6483 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6485 * RETURNS
6486 * Nothing.
6488 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
6490 FIXME("(%p): stub\n", pStubMsg);