push e7552b73e75828caa36d732caa646c0c70d8de9d
[wine/hacks.git] / dlls / rpcrt4 / ndr_marshall.c
blob1dfb661cc7d45d00f29c37cc0adab02c9abbb210
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 user marshall functions
30 #include <stdarg.h>
31 #include <stdio.h>
32 #include <string.h>
33 #include <limits.h>
35 #include "windef.h"
36 #include "winbase.h"
37 #include "winerror.h"
39 #include "ndr_misc.h"
40 #include "rpcndr.h"
42 #include "wine/unicode.h"
43 #include "wine/rpcfc.h"
45 #include "wine/debug.h"
47 WINE_DEFAULT_DEBUG_CHANNEL(ole);
49 #if defined(__i386__)
50 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
51 (*((UINT32 *)(pchar)) = (uint32))
53 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
54 (*((UINT32 *)(pchar)))
55 #else
56 /* these would work for i386 too, but less efficient */
57 # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \
58 (*(pchar) = LOBYTE(LOWORD(uint32)), \
59 *((pchar)+1) = HIBYTE(LOWORD(uint32)), \
60 *((pchar)+2) = LOBYTE(HIWORD(uint32)), \
61 *((pchar)+3) = HIBYTE(HIWORD(uint32)))
63 # define LITTLE_ENDIAN_UINT32_READ(pchar) \
64 (MAKELONG( \
65 MAKEWORD(*(pchar), *((pchar)+1)), \
66 MAKEWORD(*((pchar)+2), *((pchar)+3))))
67 #endif
69 #define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \
70 (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \
71 *((pchar)+2) = HIBYTE(LOWORD(uint32)), \
72 *((pchar)+1) = LOBYTE(HIWORD(uint32)), \
73 *(pchar) = HIBYTE(HIWORD(uint32)))
75 #define BIG_ENDIAN_UINT32_READ(pchar) \
76 (MAKELONG( \
77 MAKEWORD(*((pchar)+3), *((pchar)+2)), \
78 MAKEWORD(*((pchar)+1), *(pchar))))
80 #ifdef NDR_LOCAL_IS_BIG_ENDIAN
81 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
82 BIG_ENDIAN_UINT32_WRITE(pchar, uint32)
83 # define NDR_LOCAL_UINT32_READ(pchar) \
84 BIG_ENDIAN_UINT32_READ(pchar)
85 #else
86 # define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \
87 LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32)
88 # define NDR_LOCAL_UINT32_READ(pchar) \
89 LITTLE_ENDIAN_UINT32_READ(pchar)
90 #endif
92 /* _Align must be the desired alignment,
93 * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */
94 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1))
95 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
96 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
97 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
98 #define ALIGN_POINTER_CLEAR(_Ptr, _Align) \
99 do { \
100 memset((_Ptr), 0, ((_Align) - (ULONG_PTR)(_Ptr)) & ((_Align) - 1)); \
101 ALIGN_POINTER(_Ptr, _Align); \
102 } while(0)
104 #define STD_OVERFLOW_CHECK(_Msg) do { \
105 TRACE("buffer=%d/%d\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
106 if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
107 ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
108 } while (0)
110 #define NDR_POINTER_ID_BASE 0x20000
111 #define NDR_POINTER_ID(pStubMsg) (NDR_POINTER_ID_BASE + ((pStubMsg)->UniquePtrCount++) * 4)
112 #define NDR_TABLE_SIZE 128
113 #define NDR_TABLE_MASK 127
115 static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
116 static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
117 static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
118 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
119 static ULONG WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
121 static unsigned char *WINAPI NdrContextHandleMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
122 static void WINAPI NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
123 static unsigned char *WINAPI NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
125 static unsigned char *WINAPI NdrRangeMarshall(PMIDL_STUB_MESSAGE,unsigned char *, PFORMAT_STRING);
126 static void WINAPI NdrRangeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
127 static ULONG WINAPI NdrRangeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
128 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
130 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
132 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
134 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
135 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
136 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
137 NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
138 /* 0x10 */
139 NdrBaseTypeMarshall,
140 /* 0x11 */
141 NdrPointerMarshall, NdrPointerMarshall,
142 NdrPointerMarshall, NdrPointerMarshall,
143 /* 0x15 */
144 NdrSimpleStructMarshall, NdrSimpleStructMarshall,
145 NdrConformantStructMarshall, NdrConformantStructMarshall,
146 NdrConformantVaryingStructMarshall,
147 NdrComplexStructMarshall,
148 /* 0x1b */
149 NdrConformantArrayMarshall,
150 NdrConformantVaryingArrayMarshall,
151 NdrFixedArrayMarshall, NdrFixedArrayMarshall,
152 NdrVaryingArrayMarshall, NdrVaryingArrayMarshall,
153 NdrComplexArrayMarshall,
154 /* 0x22 */
155 NdrConformantStringMarshall, 0, 0,
156 NdrConformantStringMarshall,
157 NdrNonConformantStringMarshall, 0, 0, 0,
158 /* 0x2a */
159 NdrEncapsulatedUnionMarshall,
160 NdrNonEncapsulatedUnionMarshall,
161 NdrByteCountPointerMarshall,
162 NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall,
163 /* 0x2f */
164 NdrInterfacePointerMarshall,
165 /* 0x30 */
166 NdrContextHandleMarshall,
167 /* 0xb1 */
168 0, 0, 0,
169 NdrUserMarshalMarshall,
170 0, 0,
171 /* 0xb7 */
172 NdrRangeMarshall
174 const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
176 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
177 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
178 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
179 NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
180 /* 0x10 */
181 NdrBaseTypeUnmarshall,
182 /* 0x11 */
183 NdrPointerUnmarshall, NdrPointerUnmarshall,
184 NdrPointerUnmarshall, NdrPointerUnmarshall,
185 /* 0x15 */
186 NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall,
187 NdrConformantStructUnmarshall, NdrConformantStructUnmarshall,
188 NdrConformantVaryingStructUnmarshall,
189 NdrComplexStructUnmarshall,
190 /* 0x1b */
191 NdrConformantArrayUnmarshall,
192 NdrConformantVaryingArrayUnmarshall,
193 NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall,
194 NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall,
195 NdrComplexArrayUnmarshall,
196 /* 0x22 */
197 NdrConformantStringUnmarshall, 0, 0,
198 NdrConformantStringUnmarshall,
199 NdrNonConformantStringUnmarshall, 0, 0, 0,
200 /* 0x2a */
201 NdrEncapsulatedUnionUnmarshall,
202 NdrNonEncapsulatedUnionUnmarshall,
203 NdrByteCountPointerUnmarshall,
204 NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall,
205 /* 0x2f */
206 NdrInterfacePointerUnmarshall,
207 /* 0x30 */
208 NdrContextHandleUnmarshall,
209 /* 0xb1 */
210 0, 0, 0,
211 NdrUserMarshalUnmarshall,
212 0, 0,
213 /* 0xb7 */
214 NdrRangeUnmarshall
216 const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
218 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
219 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
220 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
221 NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
222 /* 0x10 */
223 NdrBaseTypeBufferSize,
224 /* 0x11 */
225 NdrPointerBufferSize, NdrPointerBufferSize,
226 NdrPointerBufferSize, NdrPointerBufferSize,
227 /* 0x15 */
228 NdrSimpleStructBufferSize, NdrSimpleStructBufferSize,
229 NdrConformantStructBufferSize, NdrConformantStructBufferSize,
230 NdrConformantVaryingStructBufferSize,
231 NdrComplexStructBufferSize,
232 /* 0x1b */
233 NdrConformantArrayBufferSize,
234 NdrConformantVaryingArrayBufferSize,
235 NdrFixedArrayBufferSize, NdrFixedArrayBufferSize,
236 NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize,
237 NdrComplexArrayBufferSize,
238 /* 0x22 */
239 NdrConformantStringBufferSize, 0, 0,
240 NdrConformantStringBufferSize,
241 NdrNonConformantStringBufferSize, 0, 0, 0,
242 /* 0x2a */
243 NdrEncapsulatedUnionBufferSize,
244 NdrNonEncapsulatedUnionBufferSize,
245 NdrByteCountPointerBufferSize,
246 NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize,
247 /* 0x2f */
248 NdrInterfacePointerBufferSize,
249 /* 0x30 */
250 NdrContextHandleBufferSize,
251 /* 0xb1 */
252 0, 0, 0,
253 NdrUserMarshalBufferSize,
254 0, 0,
255 /* 0xb7 */
256 NdrRangeBufferSize
258 const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
260 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
261 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
262 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
263 NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
264 /* 0x10 */
265 NdrBaseTypeMemorySize,
266 /* 0x11 */
267 NdrPointerMemorySize, NdrPointerMemorySize,
268 NdrPointerMemorySize, NdrPointerMemorySize,
269 /* 0x15 */
270 NdrSimpleStructMemorySize, NdrSimpleStructMemorySize,
271 NdrConformantStructMemorySize, NdrConformantStructMemorySize,
272 NdrConformantVaryingStructMemorySize,
273 NdrComplexStructMemorySize,
274 /* 0x1b */
275 NdrConformantArrayMemorySize,
276 NdrConformantVaryingArrayMemorySize,
277 NdrFixedArrayMemorySize, NdrFixedArrayMemorySize,
278 NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize,
279 NdrComplexArrayMemorySize,
280 /* 0x22 */
281 NdrConformantStringMemorySize, 0, 0,
282 NdrConformantStringMemorySize,
283 NdrNonConformantStringMemorySize, 0, 0, 0,
284 /* 0x2a */
285 NdrEncapsulatedUnionMemorySize,
286 NdrNonEncapsulatedUnionMemorySize,
287 NdrByteCountPointerMemorySize,
288 NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize,
289 /* 0x2f */
290 NdrInterfacePointerMemorySize,
291 /* 0x30 */
293 /* 0xb1 */
294 0, 0, 0,
295 NdrUserMarshalMemorySize,
296 0, 0,
297 /* 0xb7 */
298 NdrRangeMemorySize
300 const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
302 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
303 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
304 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
305 NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
306 /* 0x10 */
307 NdrBaseTypeFree,
308 /* 0x11 */
309 NdrPointerFree, NdrPointerFree,
310 NdrPointerFree, NdrPointerFree,
311 /* 0x15 */
312 NdrSimpleStructFree, NdrSimpleStructFree,
313 NdrConformantStructFree, NdrConformantStructFree,
314 NdrConformantVaryingStructFree,
315 NdrComplexStructFree,
316 /* 0x1b */
317 NdrConformantArrayFree,
318 NdrConformantVaryingArrayFree,
319 NdrFixedArrayFree, NdrFixedArrayFree,
320 NdrVaryingArrayFree, NdrVaryingArrayFree,
321 NdrComplexArrayFree,
322 /* 0x22 */
323 0, 0, 0,
324 0, 0, 0, 0, 0,
325 /* 0x2a */
326 NdrEncapsulatedUnionFree,
327 NdrNonEncapsulatedUnionFree,
329 NdrXmitOrRepAsFree, NdrXmitOrRepAsFree,
330 /* 0x2f */
331 NdrInterfacePointerFree,
332 /* 0x30 */
334 /* 0xb1 */
335 0, 0, 0,
336 NdrUserMarshalFree,
337 0, 0,
338 /* 0xb7 */
339 NdrRangeFree
342 typedef struct _NDR_MEMORY_LIST
344 ULONG magic;
345 ULONG size;
346 ULONG reserved;
347 struct _NDR_MEMORY_LIST *next;
348 } NDR_MEMORY_LIST;
350 #define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L')
352 /***********************************************************************
353 * NdrAllocate [RPCRT4.@]
355 * Allocates a block of memory using pStubMsg->pfnAllocate.
357 * PARAMS
358 * pStubMsg [I/O] MIDL_STUB_MESSAGE structure.
359 * len [I] Size of memory block to allocate.
361 * RETURNS
362 * The memory block of size len that was allocated.
364 * NOTES
365 * The memory block is always 8-byte aligned.
366 * If the function is unable to allocate memory an ERROR_OUTOFMEMORY
367 * exception is raised.
369 void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, SIZE_T len)
371 SIZE_T aligned_len;
372 SIZE_T adjusted_len;
373 void *p;
374 NDR_MEMORY_LIST *mem_list;
376 aligned_len = ALIGNED_LENGTH(len, 8);
377 adjusted_len = aligned_len + sizeof(NDR_MEMORY_LIST);
378 /* check for overflow */
379 if (adjusted_len < len)
381 ERR("overflow of adjusted_len %ld, len %ld\n", adjusted_len, len);
382 RpcRaiseException(RPC_X_BAD_STUB_DATA);
385 p = pStubMsg->pfnAllocate(adjusted_len);
386 if (!p) RpcRaiseException(ERROR_OUTOFMEMORY);
388 mem_list = (NDR_MEMORY_LIST *)((char *)p + aligned_len);
389 mem_list->magic = MEML_MAGIC;
390 mem_list->size = aligned_len;
391 mem_list->reserved = 0;
392 mem_list->next = pStubMsg->pMemoryList;
393 pStubMsg->pMemoryList = mem_list;
395 TRACE("-- %p\n", p);
396 return p;
399 static void NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer)
401 TRACE("(%p, %p)\n", pStubMsg, Pointer);
403 pStubMsg->pfnFree(Pointer);
406 static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat)
408 return (*(const ULONG *)pFormat != -1);
411 static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
413 ALIGN_POINTER(pStubMsg->Buffer, 4);
414 if (pStubMsg->Buffer + 4 > pStubMsg->BufferEnd)
415 RpcRaiseException(RPC_X_BAD_STUB_DATA);
416 pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
417 pStubMsg->Buffer += 4;
418 TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount);
419 if (pStubMsg->fHasNewCorrDesc)
420 return pFormat+6;
421 else
422 return pFormat+4;
425 static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue)
427 if (pFormat && !IsConformanceOrVariancePresent(pFormat))
429 pStubMsg->Offset = 0;
430 pStubMsg->ActualCount = pStubMsg->MaxCount;
431 goto done;
434 ALIGN_POINTER(pStubMsg->Buffer, 4);
435 if (pStubMsg->Buffer + 8 > pStubMsg->BufferEnd)
436 RpcRaiseException(RPC_X_BAD_STUB_DATA);
437 pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
438 pStubMsg->Buffer += 4;
439 TRACE("offset is %d\n", pStubMsg->Offset);
440 pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
441 pStubMsg->Buffer += 4;
442 TRACE("variance is %d\n", pStubMsg->ActualCount);
444 if ((pStubMsg->ActualCount > MaxValue) ||
445 (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue))
447 ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n",
448 pStubMsg->ActualCount, pStubMsg->Offset, MaxValue);
449 RpcRaiseException(RPC_S_INVALID_BOUND);
450 return NULL;
453 done:
454 if (pStubMsg->fHasNewCorrDesc)
455 return pFormat+6;
456 else
457 return pFormat+4;
460 /* writes the conformance value to the buffer */
461 static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg)
463 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
464 if (pStubMsg->Buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
465 RpcRaiseException(RPC_X_BAD_STUB_DATA);
466 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount);
467 pStubMsg->Buffer += 4;
470 /* writes the variance values to the buffer */
471 static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg)
473 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
474 if (pStubMsg->Buffer + 8 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
475 RpcRaiseException(RPC_X_BAD_STUB_DATA);
476 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset);
477 pStubMsg->Buffer += 4;
478 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount);
479 pStubMsg->Buffer += 4;
482 /* requests buffer space for the conformance value */
483 static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg)
485 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
486 if (pStubMsg->BufferLength + 4 < pStubMsg->BufferLength)
487 RpcRaiseException(RPC_X_BAD_STUB_DATA);
488 pStubMsg->BufferLength += 4;
491 /* requests buffer space for the variance values */
492 static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg)
494 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
495 if (pStubMsg->BufferLength + 8 < pStubMsg->BufferLength)
496 RpcRaiseException(RPC_X_BAD_STUB_DATA);
497 pStubMsg->BufferLength += 8;
500 PFORMAT_STRING ComputeConformanceOrVariance(
501 MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
502 PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount)
504 BYTE dtype = pFormat[0] & 0xf;
505 short ofs = *(const short *)&pFormat[2];
506 LPVOID ptr = NULL;
507 DWORD data = 0;
509 if (!IsConformanceOrVariancePresent(pFormat)) {
510 /* null descriptor */
511 *pCount = def;
512 goto finish_conf;
515 switch (pFormat[0] & 0xf0) {
516 case RPC_FC_NORMAL_CONFORMANCE:
517 TRACE("normal conformance, ofs=%d\n", ofs);
518 ptr = pMemory;
519 break;
520 case RPC_FC_POINTER_CONFORMANCE:
521 TRACE("pointer conformance, ofs=%d\n", ofs);
522 ptr = pStubMsg->Memory;
523 break;
524 case RPC_FC_TOP_LEVEL_CONFORMANCE:
525 TRACE("toplevel conformance, ofs=%d\n", ofs);
526 if (pStubMsg->StackTop) {
527 ptr = pStubMsg->StackTop;
529 else {
530 /* -Os mode, *pCount is already set */
531 goto finish_conf;
533 break;
534 case RPC_FC_CONSTANT_CONFORMANCE:
535 data = ofs | ((DWORD)pFormat[1] << 16);
536 TRACE("constant conformance, val=%d\n", data);
537 *pCount = data;
538 goto finish_conf;
539 case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
540 FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
541 if (pStubMsg->StackTop) {
542 ptr = pStubMsg->StackTop;
544 else {
545 /* ? */
546 goto done_conf_grab;
548 break;
549 default:
550 FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0);
553 switch (pFormat[1]) {
554 case RPC_FC_DEREFERENCE:
555 ptr = *(LPVOID*)((char *)ptr + ofs);
556 break;
557 case RPC_FC_CALLBACK:
559 unsigned char *old_stack_top = pStubMsg->StackTop;
560 pStubMsg->StackTop = ptr;
562 /* ofs is index into StubDesc->apfnExprEval */
563 TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
564 pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
566 pStubMsg->StackTop = old_stack_top;
568 /* the callback function always stores the computed value in MaxCount */
569 *pCount = pStubMsg->MaxCount;
570 goto finish_conf;
572 default:
573 ptr = (char *)ptr + ofs;
574 break;
577 switch (dtype) {
578 case RPC_FC_LONG:
579 case RPC_FC_ULONG:
580 data = *(DWORD*)ptr;
581 break;
582 case RPC_FC_SHORT:
583 data = *(SHORT*)ptr;
584 break;
585 case RPC_FC_USHORT:
586 data = *(USHORT*)ptr;
587 break;
588 case RPC_FC_CHAR:
589 case RPC_FC_SMALL:
590 data = *(CHAR*)ptr;
591 break;
592 case RPC_FC_BYTE:
593 case RPC_FC_USMALL:
594 data = *(UCHAR*)ptr;
595 break;
596 default:
597 FIXME("unknown conformance data type %x\n", dtype);
598 goto done_conf_grab;
600 TRACE("dereferenced data type %x at %p, got %d\n", dtype, ptr, data);
602 done_conf_grab:
603 switch (pFormat[1]) {
604 case RPC_FC_DEREFERENCE: /* already handled */
605 case 0: /* no op */
606 *pCount = data;
607 break;
608 case RPC_FC_ADD_1:
609 *pCount = data + 1;
610 break;
611 case RPC_FC_SUB_1:
612 *pCount = data - 1;
613 break;
614 case RPC_FC_MULT_2:
615 *pCount = data * 2;
616 break;
617 case RPC_FC_DIV_2:
618 *pCount = data / 2;
619 break;
620 default:
621 FIXME("unknown conformance op %d\n", pFormat[1]);
622 goto finish_conf;
625 finish_conf:
626 TRACE("resulting conformance is %ld\n", *pCount);
627 if (pStubMsg->fHasNewCorrDesc)
628 return pFormat+6;
629 else
630 return pFormat+4;
633 static inline PFORMAT_STRING SkipConformance(PMIDL_STUB_MESSAGE pStubMsg,
634 PFORMAT_STRING pFormat)
636 if (IsConformanceOrVariancePresent(pFormat))
638 if (pStubMsg->fHasNewCorrDesc)
639 pFormat += 6;
640 else
641 pFormat += 4;
643 return pFormat;
646 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
647 * the result overflows 32-bits */
648 static inline ULONG safe_multiply(ULONG a, ULONG b)
650 ULONGLONG ret = (ULONGLONG)a * b;
651 if (ret > 0xffffffff)
653 RpcRaiseException(RPC_S_INVALID_BOUND);
654 return 0;
656 return ret;
659 static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
661 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
662 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
663 RpcRaiseException(RPC_X_BAD_STUB_DATA);
664 pStubMsg->Buffer += size;
667 static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
669 if (pStubMsg->BufferLength + size < pStubMsg->BufferLength) /* integer overflow of pStubMsg->BufferSize */
671 ERR("buffer length overflow - BufferLength = %u, size = %u\n",
672 pStubMsg->BufferLength, size);
673 RpcRaiseException(RPC_X_BAD_STUB_DATA);
675 pStubMsg->BufferLength += size;
678 /* copies data from the buffer, checking that there is enough data in the buffer
679 * to do so */
680 static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE *pStubMsg, void *p, ULONG size)
682 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
683 (pStubMsg->Buffer + size > pStubMsg->BufferEnd))
685 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
686 pStubMsg->Buffer, pStubMsg->BufferEnd, size);
687 RpcRaiseException(RPC_X_BAD_STUB_DATA);
689 if (p == pStubMsg->Buffer)
690 ERR("pointer is the same as the buffer\n");
691 memcpy(p, pStubMsg->Buffer, size);
692 pStubMsg->Buffer += size;
695 /* copies data to the buffer, checking that there is enough space to do so */
696 static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE *pStubMsg, const void *p, ULONG size)
698 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
699 (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
701 ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
702 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength,
703 size);
704 RpcRaiseException(RPC_X_BAD_STUB_DATA);
706 memcpy(pStubMsg->Buffer, p, size);
707 pStubMsg->Buffer += size;
710 /* verify that string data sitting in the buffer is valid and safe to
711 * unmarshall */
712 static void validate_string_data(MIDL_STUB_MESSAGE *pStubMsg, ULONG bufsize, ULONG esize)
714 ULONG i;
716 /* verify the buffer is safe to access */
717 if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) ||
718 (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd))
720 ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize,
721 pStubMsg->BufferEnd, pStubMsg->Buffer);
722 RpcRaiseException(RPC_X_BAD_STUB_DATA);
725 /* strings must always have null terminating bytes */
726 if (bufsize < esize)
728 ERR("invalid string length of %d\n", bufsize / esize);
729 RpcRaiseException(RPC_S_INVALID_BOUND);
732 for (i = bufsize - esize; i < bufsize; i++)
733 if (pStubMsg->Buffer[i] != 0)
735 ERR("string not null-terminated at byte position %d, data is 0x%x\n",
736 i, pStubMsg->Buffer[i]);
737 RpcRaiseException(RPC_S_INVALID_BOUND);
741 static inline void dump_pointer_attr(unsigned char attr)
743 if (attr & RPC_FC_P_ALLOCALLNODES)
744 TRACE(" RPC_FC_P_ALLOCALLNODES");
745 if (attr & RPC_FC_P_DONTFREE)
746 TRACE(" RPC_FC_P_DONTFREE");
747 if (attr & RPC_FC_P_ONSTACK)
748 TRACE(" RPC_FC_P_ONSTACK");
749 if (attr & RPC_FC_P_SIMPLEPOINTER)
750 TRACE(" RPC_FC_P_SIMPLEPOINTER");
751 if (attr & RPC_FC_P_DEREF)
752 TRACE(" RPC_FC_P_DEREF");
753 TRACE("\n");
756 /***********************************************************************
757 * PointerMarshall [internal]
759 static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
760 unsigned char *Buffer,
761 unsigned char *Pointer,
762 PFORMAT_STRING pFormat)
764 unsigned type = pFormat[0], attr = pFormat[1];
765 PFORMAT_STRING desc;
766 NDR_MARSHALL m;
767 ULONG pointer_id;
768 int pointer_needs_marshaling;
770 TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
771 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
772 pFormat += 2;
773 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
774 else desc = pFormat + *(const SHORT*)pFormat;
776 switch (type) {
777 case RPC_FC_RP: /* ref pointer (always non-null) */
778 if (!Pointer)
780 ERR("NULL ref pointer is not allowed\n");
781 RpcRaiseException(RPC_X_NULL_REF_POINTER);
783 pointer_needs_marshaling = 1;
784 break;
785 case RPC_FC_UP: /* unique pointer */
786 case RPC_FC_OP: /* object pointer - same as unique here */
787 if (Pointer)
788 pointer_needs_marshaling = 1;
789 else
790 pointer_needs_marshaling = 0;
791 pointer_id = Pointer ? NDR_POINTER_ID(pStubMsg) : 0;
792 TRACE("writing 0x%08x to buffer\n", pointer_id);
793 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
794 break;
795 case RPC_FC_FP:
796 pointer_needs_marshaling = !NdrFullPointerQueryPointer(
797 pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id);
798 TRACE("writing 0x%08x to buffer\n", pointer_id);
799 NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id);
800 break;
801 default:
802 FIXME("unhandled ptr type=%02x\n", type);
803 RpcRaiseException(RPC_X_BAD_STUB_DATA);
804 return;
807 TRACE("calling marshaller for type 0x%x\n", (int)*desc);
809 if (pointer_needs_marshaling) {
810 if (attr & RPC_FC_P_DEREF) {
811 Pointer = *(unsigned char**)Pointer;
812 TRACE("deref => %p\n", Pointer);
814 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
815 if (m) m(pStubMsg, Pointer, desc);
816 else FIXME("no marshaller for data type=%02x\n", *desc);
819 STD_OVERFLOW_CHECK(pStubMsg);
822 /***********************************************************************
823 * PointerUnmarshall [internal]
825 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
826 unsigned char *Buffer,
827 unsigned char **pPointer,
828 unsigned char *pSrcPointer,
829 PFORMAT_STRING pFormat,
830 unsigned char fMustAlloc)
832 unsigned type = pFormat[0], attr = pFormat[1];
833 PFORMAT_STRING desc;
834 NDR_UNMARSHALL m;
835 DWORD pointer_id = 0;
836 int pointer_needs_unmarshaling;
838 TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pSrcPointer, pFormat, fMustAlloc);
839 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
840 pFormat += 2;
841 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
842 else desc = pFormat + *(const SHORT*)pFormat;
844 switch (type) {
845 case RPC_FC_RP: /* ref pointer (always non-null) */
846 pointer_needs_unmarshaling = 1;
847 break;
848 case RPC_FC_UP: /* unique pointer */
849 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
850 TRACE("pointer_id is 0x%08x\n", pointer_id);
851 if (pointer_id)
852 pointer_needs_unmarshaling = 1;
853 else {
854 *pPointer = NULL;
855 pointer_needs_unmarshaling = 0;
857 break;
858 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
859 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
860 TRACE("pointer_id is 0x%08x\n", pointer_id);
861 if (!fMustAlloc && pSrcPointer)
863 FIXME("free object pointer %p\n", pSrcPointer);
864 fMustAlloc = TRUE;
866 if (pointer_id)
867 pointer_needs_unmarshaling = 1;
868 else
870 *pPointer = NULL;
871 pointer_needs_unmarshaling = 0;
873 break;
874 case RPC_FC_FP:
875 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
876 TRACE("pointer_id is 0x%08x\n", pointer_id);
877 pointer_needs_unmarshaling = !NdrFullPointerQueryRefId(
878 pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer);
879 break;
880 default:
881 FIXME("unhandled ptr type=%02x\n", type);
882 RpcRaiseException(RPC_X_BAD_STUB_DATA);
883 return;
886 if (pointer_needs_unmarshaling) {
887 unsigned char *base_ptr_val = *pPointer;
888 unsigned char **current_ptr = pPointer;
889 if (pStubMsg->IsClient) {
890 TRACE("client\n");
891 /* if we aren't forcing allocation of memory then try to use the existing
892 * (source) pointer to unmarshall the data into so that [in,out]
893 * parameters behave correctly. it doesn't matter if the parameter is
894 * [out] only since in that case the pointer will be NULL. we force
895 * allocation when the source pointer is NULL here instead of in the type
896 * unmarshalling routine for the benefit of the deref code below */
897 if (!fMustAlloc) {
898 if (pSrcPointer) {
899 TRACE("setting *pPointer to %p\n", pSrcPointer);
900 *pPointer = base_ptr_val = pSrcPointer;
901 } else
902 fMustAlloc = TRUE;
904 } else {
905 TRACE("server\n");
906 /* the memory in a stub is never initialised, so we have to work out here
907 * whether we have to initialise it so we can use the optimisation of
908 * setting the pointer to the buffer, if possible, or set fMustAlloc to
909 * TRUE. */
910 if (attr & RPC_FC_P_DEREF) {
911 fMustAlloc = TRUE;
912 } else {
913 base_ptr_val = NULL;
914 *current_ptr = NULL;
918 if (attr & RPC_FC_P_ALLOCALLNODES)
919 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n");
921 if (attr & RPC_FC_P_DEREF) {
922 if (fMustAlloc) {
923 base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *));
924 *pPointer = base_ptr_val;
925 current_ptr = (unsigned char **)base_ptr_val;
926 } else
927 current_ptr = *(unsigned char***)current_ptr;
928 TRACE("deref => %p\n", current_ptr);
929 if (!fMustAlloc && !*current_ptr) fMustAlloc = TRUE;
931 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
932 if (m) m(pStubMsg, current_ptr, desc, fMustAlloc);
933 else FIXME("no unmarshaller for data type=%02x\n", *desc);
935 if (type == RPC_FC_FP)
936 NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id,
937 base_ptr_val);
940 TRACE("pointer=%p\n", *pPointer);
943 /***********************************************************************
944 * PointerBufferSize [internal]
946 static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
947 unsigned char *Pointer,
948 PFORMAT_STRING pFormat)
950 unsigned type = pFormat[0], attr = pFormat[1];
951 PFORMAT_STRING desc;
952 NDR_BUFFERSIZE m;
953 int pointer_needs_sizing;
954 ULONG pointer_id;
956 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
957 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
958 pFormat += 2;
959 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
960 else desc = pFormat + *(const SHORT*)pFormat;
962 switch (type) {
963 case RPC_FC_RP: /* ref pointer (always non-null) */
964 if (!Pointer)
966 ERR("NULL ref pointer is not allowed\n");
967 RpcRaiseException(RPC_X_NULL_REF_POINTER);
969 break;
970 case RPC_FC_OP:
971 case RPC_FC_UP:
972 /* NULL pointer has no further representation */
973 if (!Pointer)
974 return;
975 break;
976 case RPC_FC_FP:
977 pointer_needs_sizing = !NdrFullPointerQueryPointer(
978 pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id);
979 if (!pointer_needs_sizing)
980 return;
981 break;
982 default:
983 FIXME("unhandled ptr type=%02x\n", type);
984 RpcRaiseException(RPC_X_BAD_STUB_DATA);
985 return;
988 if (attr & RPC_FC_P_DEREF) {
989 Pointer = *(unsigned char**)Pointer;
990 TRACE("deref => %p\n", Pointer);
993 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
994 if (m) m(pStubMsg, Pointer, desc);
995 else FIXME("no buffersizer for data type=%02x\n", *desc);
998 /***********************************************************************
999 * PointerMemorySize [internal]
1001 static ULONG PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1002 unsigned char *Buffer, PFORMAT_STRING pFormat)
1004 unsigned type = pFormat[0], attr = pFormat[1];
1005 PFORMAT_STRING desc;
1006 NDR_MEMORYSIZE m;
1007 DWORD pointer_id = 0;
1008 int pointer_needs_sizing;
1010 TRACE("(%p,%p,%p)\n", pStubMsg, Buffer, pFormat);
1011 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1012 pFormat += 2;
1013 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1014 else desc = pFormat + *(const SHORT*)pFormat;
1016 switch (type) {
1017 case RPC_FC_RP: /* ref pointer (always non-null) */
1018 pointer_needs_sizing = 1;
1019 break;
1020 case RPC_FC_UP: /* unique pointer */
1021 case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
1022 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1023 TRACE("pointer_id is 0x%08x\n", pointer_id);
1024 if (pointer_id)
1025 pointer_needs_sizing = 1;
1026 else
1027 pointer_needs_sizing = 0;
1028 break;
1029 case RPC_FC_FP:
1031 void *pointer;
1032 pointer_id = NDR_LOCAL_UINT32_READ(Buffer);
1033 TRACE("pointer_id is 0x%08x\n", pointer_id);
1034 pointer_needs_sizing = !NdrFullPointerQueryRefId(
1035 pStubMsg->FullPtrXlatTables, pointer_id, 1, &pointer);
1036 break;
1038 default:
1039 FIXME("unhandled ptr type=%02x\n", type);
1040 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1041 return 0;
1044 if (attr & RPC_FC_P_DEREF) {
1045 TRACE("deref\n");
1048 if (pointer_needs_sizing) {
1049 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1050 if (m) m(pStubMsg, desc);
1051 else FIXME("no memorysizer for data type=%02x\n", *desc);
1054 return pStubMsg->MemorySize;
1057 /***********************************************************************
1058 * PointerFree [internal]
1060 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1061 unsigned char *Pointer,
1062 PFORMAT_STRING pFormat)
1064 unsigned type = pFormat[0], attr = pFormat[1];
1065 PFORMAT_STRING desc;
1066 NDR_FREE m;
1067 unsigned char *current_pointer = Pointer;
1069 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1070 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1071 if (attr & RPC_FC_P_DONTFREE) return;
1072 pFormat += 2;
1073 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1074 else desc = pFormat + *(const SHORT*)pFormat;
1076 if (!Pointer) return;
1078 if (type == RPC_FC_FP) {
1079 int pointer_needs_freeing = NdrFullPointerFree(
1080 pStubMsg->FullPtrXlatTables, Pointer);
1081 if (!pointer_needs_freeing)
1082 return;
1085 if (attr & RPC_FC_P_DEREF) {
1086 current_pointer = *(unsigned char**)Pointer;
1087 TRACE("deref => %p\n", current_pointer);
1090 m = NdrFreer[*desc & NDR_TABLE_MASK];
1091 if (m) m(pStubMsg, current_pointer, desc);
1093 /* this check stops us from trying to free buffer memory. we don't have to
1094 * worry about clients, since they won't call this function.
1095 * we don't have to check for the buffer being reallocated because
1096 * BufferStart and BufferEnd won't be reset when allocating memory for
1097 * sending the response. we don't have to check for the new buffer here as
1098 * it won't be used a type memory, only for buffer memory */
1099 if (Pointer >= pStubMsg->BufferStart && Pointer < pStubMsg->BufferEnd)
1100 goto notfree;
1102 if (attr & RPC_FC_P_ONSTACK) {
1103 TRACE("not freeing stack ptr %p\n", Pointer);
1104 return;
1106 TRACE("freeing %p\n", Pointer);
1107 NdrFree(pStubMsg, Pointer);
1108 return;
1109 notfree:
1110 TRACE("not freeing %p\n", Pointer);
1113 /***********************************************************************
1114 * EmbeddedPointerMarshall
1116 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1117 unsigned char *pMemory,
1118 PFORMAT_STRING pFormat)
1120 unsigned char *Mark = pStubMsg->BufferMark;
1121 unsigned rep, count, stride;
1122 unsigned i;
1123 unsigned char *saved_buffer = NULL;
1125 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1127 if (*pFormat != RPC_FC_PP) return NULL;
1128 pFormat += 2;
1130 if (pStubMsg->PointerBufferMark)
1132 saved_buffer = pStubMsg->Buffer;
1133 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1134 pStubMsg->PointerBufferMark = NULL;
1137 while (pFormat[0] != RPC_FC_END) {
1138 switch (pFormat[0]) {
1139 default:
1140 FIXME("unknown repeat type %d\n", pFormat[0]);
1141 case RPC_FC_NO_REPEAT:
1142 rep = 1;
1143 stride = 0;
1144 count = 1;
1145 pFormat += 2;
1146 break;
1147 case RPC_FC_FIXED_REPEAT:
1148 rep = *(const WORD*)&pFormat[2];
1149 stride = *(const WORD*)&pFormat[4];
1150 count = *(const WORD*)&pFormat[8];
1151 pFormat += 10;
1152 break;
1153 case RPC_FC_VARIABLE_REPEAT:
1154 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1155 stride = *(const WORD*)&pFormat[2];
1156 count = *(const WORD*)&pFormat[6];
1157 pFormat += 8;
1158 break;
1160 for (i = 0; i < rep; i++) {
1161 PFORMAT_STRING info = pFormat;
1162 unsigned char *membase = pMemory + (i * stride);
1163 unsigned char *bufbase = Mark + (i * stride);
1164 unsigned u;
1166 for (u=0; u<count; u++,info+=8) {
1167 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1168 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1169 unsigned char *saved_memory = pStubMsg->Memory;
1171 pStubMsg->Memory = pMemory;
1172 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1173 pStubMsg->Memory = saved_memory;
1176 pFormat += 8 * count;
1179 if (saved_buffer)
1181 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1182 pStubMsg->Buffer = saved_buffer;
1185 STD_OVERFLOW_CHECK(pStubMsg);
1187 return NULL;
1190 /***********************************************************************
1191 * EmbeddedPointerUnmarshall
1193 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1194 unsigned char *pDstBuffer,
1195 unsigned char *pSrcMemoryPtrs,
1196 PFORMAT_STRING pFormat,
1197 unsigned char fMustAlloc)
1199 unsigned char *Mark = pStubMsg->BufferMark;
1200 unsigned rep, count, stride;
1201 unsigned i;
1202 unsigned char *saved_buffer = NULL;
1204 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstBuffer, pSrcMemoryPtrs, pFormat, fMustAlloc);
1206 if (*pFormat != RPC_FC_PP) return NULL;
1207 pFormat += 2;
1209 if (pStubMsg->PointerBufferMark)
1211 saved_buffer = pStubMsg->Buffer;
1212 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1213 pStubMsg->PointerBufferMark = NULL;
1216 while (pFormat[0] != RPC_FC_END) {
1217 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1218 switch (pFormat[0]) {
1219 default:
1220 FIXME("unknown repeat type %d\n", pFormat[0]);
1221 case RPC_FC_NO_REPEAT:
1222 rep = 1;
1223 stride = 0;
1224 count = 1;
1225 pFormat += 2;
1226 break;
1227 case RPC_FC_FIXED_REPEAT:
1228 rep = *(const WORD*)&pFormat[2];
1229 stride = *(const WORD*)&pFormat[4];
1230 count = *(const WORD*)&pFormat[8];
1231 pFormat += 10;
1232 break;
1233 case RPC_FC_VARIABLE_REPEAT:
1234 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1235 stride = *(const WORD*)&pFormat[2];
1236 count = *(const WORD*)&pFormat[6];
1237 pFormat += 8;
1238 break;
1240 for (i = 0; i < rep; i++) {
1241 PFORMAT_STRING info = pFormat;
1242 unsigned char *bufdstbase = pDstBuffer + (i * stride);
1243 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride);
1244 unsigned char *bufbase = Mark + (i * stride);
1245 unsigned u;
1247 for (u=0; u<count; u++,info+=8) {
1248 unsigned char **bufdstptr = (unsigned char **)(bufdstbase + *(const SHORT*)&info[2]);
1249 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]);
1250 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1251 PointerUnmarshall(pStubMsg, bufptr, bufdstptr, *memsrcptr, info+4, fMustAlloc);
1254 pFormat += 8 * count;
1257 if (saved_buffer)
1259 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1260 pStubMsg->Buffer = saved_buffer;
1263 return NULL;
1266 /***********************************************************************
1267 * EmbeddedPointerBufferSize
1269 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1270 unsigned char *pMemory,
1271 PFORMAT_STRING pFormat)
1273 unsigned rep, count, stride;
1274 unsigned i;
1275 ULONG saved_buffer_length = 0;
1277 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1279 if (pStubMsg->IgnoreEmbeddedPointers) return;
1281 if (*pFormat != RPC_FC_PP) return;
1282 pFormat += 2;
1284 if (pStubMsg->PointerLength)
1286 saved_buffer_length = pStubMsg->BufferLength;
1287 pStubMsg->BufferLength = pStubMsg->PointerLength;
1288 pStubMsg->PointerLength = 0;
1291 while (pFormat[0] != RPC_FC_END) {
1292 switch (pFormat[0]) {
1293 default:
1294 FIXME("unknown repeat type %d\n", pFormat[0]);
1295 case RPC_FC_NO_REPEAT:
1296 rep = 1;
1297 stride = 0;
1298 count = 1;
1299 pFormat += 2;
1300 break;
1301 case RPC_FC_FIXED_REPEAT:
1302 rep = *(const WORD*)&pFormat[2];
1303 stride = *(const WORD*)&pFormat[4];
1304 count = *(const WORD*)&pFormat[8];
1305 pFormat += 10;
1306 break;
1307 case RPC_FC_VARIABLE_REPEAT:
1308 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1309 stride = *(const WORD*)&pFormat[2];
1310 count = *(const WORD*)&pFormat[6];
1311 pFormat += 8;
1312 break;
1314 for (i = 0; i < rep; i++) {
1315 PFORMAT_STRING info = pFormat;
1316 unsigned char *membase = pMemory + (i * stride);
1317 unsigned u;
1319 for (u=0; u<count; u++,info+=8) {
1320 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1321 unsigned char *saved_memory = pStubMsg->Memory;
1323 pStubMsg->Memory = pMemory;
1324 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1325 pStubMsg->Memory = saved_memory;
1328 pFormat += 8 * count;
1331 if (saved_buffer_length)
1333 pStubMsg->PointerLength = pStubMsg->BufferLength;
1334 pStubMsg->BufferLength = saved_buffer_length;
1338 /***********************************************************************
1339 * EmbeddedPointerMemorySize [internal]
1341 static ULONG EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1342 PFORMAT_STRING pFormat)
1344 unsigned char *Mark = pStubMsg->BufferMark;
1345 unsigned rep, count, stride;
1346 unsigned i;
1347 unsigned char *saved_buffer = NULL;
1349 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1351 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1353 if (pStubMsg->PointerBufferMark)
1355 saved_buffer = pStubMsg->Buffer;
1356 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1357 pStubMsg->PointerBufferMark = NULL;
1360 if (*pFormat != RPC_FC_PP) return 0;
1361 pFormat += 2;
1363 while (pFormat[0] != RPC_FC_END) {
1364 switch (pFormat[0]) {
1365 default:
1366 FIXME("unknown repeat type %d\n", pFormat[0]);
1367 case RPC_FC_NO_REPEAT:
1368 rep = 1;
1369 stride = 0;
1370 count = 1;
1371 pFormat += 2;
1372 break;
1373 case RPC_FC_FIXED_REPEAT:
1374 rep = *(const WORD*)&pFormat[2];
1375 stride = *(const WORD*)&pFormat[4];
1376 count = *(const WORD*)&pFormat[8];
1377 pFormat += 10;
1378 break;
1379 case RPC_FC_VARIABLE_REPEAT:
1380 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1381 stride = *(const WORD*)&pFormat[2];
1382 count = *(const WORD*)&pFormat[6];
1383 pFormat += 8;
1384 break;
1386 for (i = 0; i < rep; i++) {
1387 PFORMAT_STRING info = pFormat;
1388 unsigned char *bufbase = Mark + (i * stride);
1389 unsigned u;
1390 for (u=0; u<count; u++,info+=8) {
1391 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1392 PointerMemorySize(pStubMsg, bufptr, info+4);
1395 pFormat += 8 * count;
1398 if (saved_buffer)
1400 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1401 pStubMsg->Buffer = saved_buffer;
1404 return 0;
1407 /***********************************************************************
1408 * EmbeddedPointerFree [internal]
1410 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1411 unsigned char *pMemory,
1412 PFORMAT_STRING pFormat)
1414 unsigned rep, count, stride;
1415 unsigned i;
1417 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1418 if (*pFormat != RPC_FC_PP) return;
1419 pFormat += 2;
1421 while (pFormat[0] != RPC_FC_END) {
1422 switch (pFormat[0]) {
1423 default:
1424 FIXME("unknown repeat type %d\n", pFormat[0]);
1425 case RPC_FC_NO_REPEAT:
1426 rep = 1;
1427 stride = 0;
1428 count = 1;
1429 pFormat += 2;
1430 break;
1431 case RPC_FC_FIXED_REPEAT:
1432 rep = *(const WORD*)&pFormat[2];
1433 stride = *(const WORD*)&pFormat[4];
1434 count = *(const WORD*)&pFormat[8];
1435 pFormat += 10;
1436 break;
1437 case RPC_FC_VARIABLE_REPEAT:
1438 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1439 stride = *(const WORD*)&pFormat[2];
1440 count = *(const WORD*)&pFormat[6];
1441 pFormat += 8;
1442 break;
1444 for (i = 0; i < rep; i++) {
1445 PFORMAT_STRING info = pFormat;
1446 unsigned char *membase = pMemory + (i * stride);
1447 unsigned u;
1449 for (u=0; u<count; u++,info+=8) {
1450 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1451 unsigned char *saved_memory = pStubMsg->Memory;
1453 pStubMsg->Memory = pMemory;
1454 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1455 pStubMsg->Memory = saved_memory;
1458 pFormat += 8 * count;
1462 /***********************************************************************
1463 * NdrPointerMarshall [RPCRT4.@]
1465 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1466 unsigned char *pMemory,
1467 PFORMAT_STRING pFormat)
1469 unsigned char *Buffer;
1471 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1473 /* Increment the buffer here instead of in PointerMarshall,
1474 * as that is used by embedded pointers which already handle the incrementing
1475 * the buffer, and shouldn't write any additional pointer data to the wire */
1476 if (*pFormat != RPC_FC_RP)
1478 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
1479 Buffer = pStubMsg->Buffer;
1480 safe_buffer_increment(pStubMsg, 4);
1482 else
1483 Buffer = pStubMsg->Buffer;
1485 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1487 return NULL;
1490 /***********************************************************************
1491 * NdrPointerUnmarshall [RPCRT4.@]
1493 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1494 unsigned char **ppMemory,
1495 PFORMAT_STRING pFormat,
1496 unsigned char fMustAlloc)
1498 unsigned char *Buffer;
1500 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1502 if (*pFormat == RPC_FC_RP)
1504 Buffer = pStubMsg->Buffer;
1505 /* Do the NULL ref pointer check here because embedded pointers can be
1506 * NULL if the type the pointer is embedded in was allocated rather than
1507 * being passed in by the client */
1508 if (pStubMsg->IsClient && !*ppMemory)
1510 ERR("NULL ref pointer is not allowed\n");
1511 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1514 else
1516 /* Increment the buffer here instead of in PointerUnmarshall,
1517 * as that is used by embedded pointers which already handle the incrementing
1518 * the buffer, and shouldn't read any additional pointer data from the
1519 * buffer */
1520 ALIGN_POINTER(pStubMsg->Buffer, 4);
1521 Buffer = pStubMsg->Buffer;
1522 safe_buffer_increment(pStubMsg, 4);
1525 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1527 return NULL;
1530 /***********************************************************************
1531 * NdrPointerBufferSize [RPCRT4.@]
1533 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1534 unsigned char *pMemory,
1535 PFORMAT_STRING pFormat)
1537 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1539 /* Increment the buffer length here instead of in PointerBufferSize,
1540 * as that is used by embedded pointers which already handle the buffer
1541 * length, and shouldn't write anything more to the wire */
1542 if (*pFormat != RPC_FC_RP)
1544 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1545 safe_buffer_length_increment(pStubMsg, 4);
1548 PointerBufferSize(pStubMsg, pMemory, pFormat);
1551 /***********************************************************************
1552 * NdrPointerMemorySize [RPCRT4.@]
1554 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1555 PFORMAT_STRING pFormat)
1557 /* unsigned size = *(LPWORD)(pFormat+2); */
1558 FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
1559 PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat);
1560 return 0;
1563 /***********************************************************************
1564 * NdrPointerFree [RPCRT4.@]
1566 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1567 unsigned char *pMemory,
1568 PFORMAT_STRING pFormat)
1570 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1571 PointerFree(pStubMsg, pMemory, pFormat);
1574 /***********************************************************************
1575 * NdrSimpleTypeMarshall [RPCRT4.@]
1577 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1578 unsigned char FormatChar )
1580 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1583 /***********************************************************************
1584 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1586 * Unmarshall a base type.
1588 * NOTES
1589 * Doesn't check that the buffer is long enough before copying, so the caller
1590 * should do this.
1592 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1593 unsigned char FormatChar )
1595 #define BASE_TYPE_UNMARSHALL(type) \
1596 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
1597 TRACE("pMemory: %p\n", pMemory); \
1598 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1599 pStubMsg->Buffer += sizeof(type);
1601 switch(FormatChar)
1603 case RPC_FC_BYTE:
1604 case RPC_FC_CHAR:
1605 case RPC_FC_SMALL:
1606 case RPC_FC_USMALL:
1607 BASE_TYPE_UNMARSHALL(UCHAR);
1608 TRACE("value: 0x%02x\n", *pMemory);
1609 break;
1610 case RPC_FC_WCHAR:
1611 case RPC_FC_SHORT:
1612 case RPC_FC_USHORT:
1613 BASE_TYPE_UNMARSHALL(USHORT);
1614 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
1615 break;
1616 case RPC_FC_LONG:
1617 case RPC_FC_ULONG:
1618 case RPC_FC_ERROR_STATUS_T:
1619 case RPC_FC_ENUM32:
1620 BASE_TYPE_UNMARSHALL(ULONG);
1621 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
1622 break;
1623 case RPC_FC_FLOAT:
1624 BASE_TYPE_UNMARSHALL(float);
1625 TRACE("value: %f\n", *(float *)pMemory);
1626 break;
1627 case RPC_FC_DOUBLE:
1628 BASE_TYPE_UNMARSHALL(double);
1629 TRACE("value: %f\n", *(double *)pMemory);
1630 break;
1631 case RPC_FC_HYPER:
1632 BASE_TYPE_UNMARSHALL(ULONGLONG);
1633 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG *)pMemory));
1634 break;
1635 case RPC_FC_ENUM16:
1636 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
1637 TRACE("pMemory: %p\n", pMemory);
1638 /* 16-bits on the wire, but int in memory */
1639 *(UINT *)pMemory = *(USHORT *)pStubMsg->Buffer;
1640 pStubMsg->Buffer += sizeof(USHORT);
1641 TRACE("value: 0x%08x\n", *(UINT *)pMemory);
1642 break;
1643 case RPC_FC_IGNORE:
1644 break;
1645 default:
1646 FIXME("Unhandled base type: 0x%02x\n", FormatChar);
1648 #undef BASE_TYPE_UNMARSHALL
1651 /***********************************************************************
1652 * NdrSimpleStructMarshall [RPCRT4.@]
1654 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1655 unsigned char *pMemory,
1656 PFORMAT_STRING pFormat)
1658 unsigned size = *(const WORD*)(pFormat+2);
1659 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1661 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
1663 pStubMsg->BufferMark = pStubMsg->Buffer;
1664 safe_copy_to_buffer(pStubMsg, pMemory, size);
1666 if (pFormat[0] != RPC_FC_STRUCT)
1667 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1669 return NULL;
1672 /***********************************************************************
1673 * NdrSimpleStructUnmarshall [RPCRT4.@]
1675 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1676 unsigned char **ppMemory,
1677 PFORMAT_STRING pFormat,
1678 unsigned char fMustAlloc)
1680 unsigned size = *(const WORD*)(pFormat+2);
1681 unsigned char *saved_buffer;
1682 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1684 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1686 if (fMustAlloc)
1687 *ppMemory = NdrAllocate(pStubMsg, size);
1688 else
1690 if (!pStubMsg->IsClient && !*ppMemory)
1691 /* for servers, we just point straight into the RPC buffer */
1692 *ppMemory = pStubMsg->Buffer;
1695 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
1696 safe_buffer_increment(pStubMsg, size);
1697 if (pFormat[0] == RPC_FC_PSTRUCT)
1698 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
1700 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
1701 if (*ppMemory != saved_buffer)
1702 memcpy(*ppMemory, saved_buffer, size);
1704 return NULL;
1707 /***********************************************************************
1708 * NdrSimpleStructBufferSize [RPCRT4.@]
1710 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1711 unsigned char *pMemory,
1712 PFORMAT_STRING pFormat)
1714 unsigned size = *(const WORD*)(pFormat+2);
1715 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1717 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1719 safe_buffer_length_increment(pStubMsg, size);
1720 if (pFormat[0] != RPC_FC_STRUCT)
1721 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1724 /***********************************************************************
1725 * NdrSimpleStructMemorySize [RPCRT4.@]
1727 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1728 PFORMAT_STRING pFormat)
1730 unsigned short size = *(const WORD *)(pFormat+2);
1732 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1734 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1735 pStubMsg->MemorySize += size;
1736 safe_buffer_increment(pStubMsg, size);
1738 if (pFormat[0] != RPC_FC_STRUCT)
1739 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1740 return pStubMsg->MemorySize;
1743 /***********************************************************************
1744 * NdrSimpleStructFree [RPCRT4.@]
1746 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1747 unsigned char *pMemory,
1748 PFORMAT_STRING pFormat)
1750 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1751 if (pFormat[0] != RPC_FC_STRUCT)
1752 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1755 /* Array helpers */
1757 static inline void array_compute_and_size_conformance(
1758 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1759 PFORMAT_STRING pFormat)
1761 switch (fc)
1763 case RPC_FC_CARRAY:
1764 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1765 SizeConformance(pStubMsg);
1766 break;
1767 case RPC_FC_CVARRAY:
1768 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1769 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1770 SizeConformance(pStubMsg);
1771 break;
1772 case RPC_FC_C_CSTRING:
1773 case RPC_FC_C_WSTRING:
1774 if (pFormat[0] == RPC_FC_C_CSTRING)
1776 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1777 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1779 else
1781 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1782 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1785 if (fc == RPC_FC_STRING_SIZED)
1786 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1787 else
1788 pStubMsg->MaxCount = pStubMsg->ActualCount;
1790 SizeConformance(pStubMsg);
1791 break;
1792 default:
1793 ERR("unknown array format 0x%x\n", fc);
1794 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1798 static inline void array_buffer_size(
1799 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1800 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1802 DWORD size;
1803 DWORD esize;
1804 unsigned char alignment;
1806 switch (fc)
1808 case RPC_FC_CARRAY:
1809 esize = *(const WORD*)(pFormat+2);
1810 alignment = pFormat[1] + 1;
1812 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1814 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
1816 size = safe_multiply(esize, pStubMsg->MaxCount);
1817 /* conformance value plus array */
1818 safe_buffer_length_increment(pStubMsg, size);
1820 if (fHasPointers)
1821 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1822 break;
1823 case RPC_FC_CVARRAY:
1824 esize = *(const WORD*)(pFormat+2);
1825 alignment = pFormat[1] + 1;
1827 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1828 pFormat = SkipConformance(pStubMsg, pFormat);
1830 SizeVariance(pStubMsg);
1832 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
1834 size = safe_multiply(esize, pStubMsg->ActualCount);
1835 safe_buffer_length_increment(pStubMsg, size);
1837 if (fHasPointers)
1838 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1839 break;
1840 case RPC_FC_C_CSTRING:
1841 case RPC_FC_C_WSTRING:
1842 if (fc == RPC_FC_C_CSTRING)
1843 esize = 1;
1844 else
1845 esize = 2;
1847 SizeVariance(pStubMsg);
1849 size = safe_multiply(esize, pStubMsg->ActualCount);
1850 safe_buffer_length_increment(pStubMsg, size);
1851 break;
1852 default:
1853 ERR("unknown array format 0x%x\n", fc);
1854 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1858 static inline void array_compute_and_write_conformance(
1859 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1860 PFORMAT_STRING pFormat)
1862 switch (fc)
1864 case RPC_FC_CARRAY:
1865 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1866 WriteConformance(pStubMsg);
1867 break;
1868 case RPC_FC_CVARRAY:
1869 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1870 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1871 WriteConformance(pStubMsg);
1872 break;
1873 case RPC_FC_C_CSTRING:
1874 case RPC_FC_C_WSTRING:
1875 if (fc == RPC_FC_C_CSTRING)
1877 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1878 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1880 else
1882 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1883 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1885 if (pFormat[1] == RPC_FC_STRING_SIZED)
1886 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1887 else
1888 pStubMsg->MaxCount = pStubMsg->ActualCount;
1889 pStubMsg->Offset = 0;
1890 WriteConformance(pStubMsg);
1891 break;
1892 default:
1893 ERR("unknown array format 0x%x\n", fc);
1894 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1898 static inline void array_write_variance_and_marshall(
1899 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1900 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1902 DWORD size;
1903 DWORD esize;
1904 unsigned char alignment;
1906 switch (fc)
1908 case RPC_FC_CARRAY:
1909 esize = *(const WORD*)(pFormat+2);
1910 alignment = pFormat[1] + 1;
1912 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1914 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
1916 size = safe_multiply(esize, pStubMsg->MaxCount);
1917 if (fHasPointers)
1918 pStubMsg->BufferMark = pStubMsg->Buffer;
1919 safe_copy_to_buffer(pStubMsg, pMemory, size);
1921 if (fHasPointers)
1922 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
1923 break;
1924 case RPC_FC_CVARRAY:
1925 esize = *(const WORD*)(pFormat+2);
1926 alignment = pFormat[1] + 1;
1928 /* conformance */
1929 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1930 /* variance */
1931 pFormat = SkipConformance(pStubMsg, pFormat);
1933 WriteVariance(pStubMsg);
1935 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
1937 size = safe_multiply(esize, pStubMsg->ActualCount);
1939 if (fHasPointers)
1940 pStubMsg->BufferMark = pStubMsg->Buffer;
1941 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, size);
1943 if (fHasPointers)
1944 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
1945 break;
1946 case RPC_FC_C_CSTRING:
1947 case RPC_FC_C_WSTRING:
1948 if (fc == RPC_FC_C_CSTRING)
1949 esize = 1;
1950 else
1951 esize = 2;
1953 WriteVariance(pStubMsg);
1955 size = safe_multiply(esize, pStubMsg->ActualCount);
1956 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
1957 break;
1958 default:
1959 ERR("unknown array format 0x%x\n", fc);
1960 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1964 static inline ULONG array_read_conformance(
1965 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
1967 DWORD esize;
1969 switch (fc)
1971 case RPC_FC_CARRAY:
1972 esize = *(const WORD*)(pFormat+2);
1973 pFormat = ReadConformance(pStubMsg, pFormat+4);
1974 return safe_multiply(esize, pStubMsg->MaxCount);
1975 case RPC_FC_CVARRAY:
1976 esize = *(const WORD*)(pFormat+2);
1977 pFormat = ReadConformance(pStubMsg, pFormat+4);
1978 return safe_multiply(esize, pStubMsg->MaxCount);
1979 case RPC_FC_C_CSTRING:
1980 case RPC_FC_C_WSTRING:
1981 if (fc == RPC_FC_C_CSTRING)
1982 esize = 1;
1983 else
1984 esize = 2;
1986 if (pFormat[1] == RPC_FC_STRING_SIZED)
1987 ReadConformance(pStubMsg, pFormat + 2);
1988 else
1989 ReadConformance(pStubMsg, NULL);
1990 return safe_multiply(esize, pStubMsg->MaxCount);
1991 default:
1992 ERR("unknown array format 0x%x\n", fc);
1993 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1997 static inline ULONG array_read_variance_and_unmarshall(
1998 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory,
1999 PFORMAT_STRING pFormat, unsigned char fMustAlloc,
2000 unsigned char fUseBufferMemoryServer, unsigned char fUnmarshall)
2002 ULONG bufsize, memsize;
2003 WORD esize;
2004 unsigned char alignment;
2005 unsigned char *saved_buffer;
2006 ULONG offset;
2008 switch (fc)
2010 case RPC_FC_CARRAY:
2011 esize = *(const WORD*)(pFormat+2);
2012 alignment = pFormat[1] + 1;
2014 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2016 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2018 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2020 if (fUnmarshall)
2022 if (fMustAlloc)
2023 *ppMemory = NdrAllocate(pStubMsg, memsize);
2024 else
2026 if (fUseBufferMemoryServer && !pStubMsg->IsClient && !*ppMemory)
2027 /* for servers, we just point straight into the RPC buffer */
2028 *ppMemory = pStubMsg->Buffer;
2031 saved_buffer = pStubMsg->Buffer;
2032 safe_buffer_increment(pStubMsg, bufsize);
2034 pStubMsg->BufferMark = saved_buffer;
2035 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
2037 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2038 if (*ppMemory != saved_buffer)
2039 memcpy(*ppMemory, saved_buffer, bufsize);
2041 return bufsize;
2042 case RPC_FC_CVARRAY:
2043 esize = *(const WORD*)(pFormat+2);
2044 alignment = pFormat[1] + 1;
2046 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2048 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2050 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2052 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2053 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2055 if (fUnmarshall)
2057 offset = pStubMsg->Offset;
2059 if (!fMustAlloc && !*ppMemory)
2060 fMustAlloc = TRUE;
2061 if (fMustAlloc)
2062 *ppMemory = NdrAllocate(pStubMsg, memsize);
2063 saved_buffer = pStubMsg->Buffer;
2064 safe_buffer_increment(pStubMsg, bufsize);
2066 pStubMsg->BufferMark = saved_buffer;
2067 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat,
2068 fMustAlloc);
2070 memcpy(*ppMemory + offset, saved_buffer, bufsize);
2072 return bufsize;
2073 case RPC_FC_C_CSTRING:
2074 case RPC_FC_C_WSTRING:
2075 if (fc == RPC_FC_C_CSTRING)
2076 esize = 1;
2077 else
2078 esize = 2;
2080 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2082 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2084 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2085 pStubMsg->ActualCount, pStubMsg->MaxCount);
2086 RpcRaiseException(RPC_S_INVALID_BOUND);
2088 if (pStubMsg->Offset)
2090 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2091 RpcRaiseException(RPC_S_INVALID_BOUND);
2094 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2095 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2097 validate_string_data(pStubMsg, bufsize, esize);
2099 if (fUnmarshall)
2101 if (fMustAlloc)
2102 *ppMemory = NdrAllocate(pStubMsg, memsize);
2103 else
2105 if (fUseBufferMemoryServer && !pStubMsg->IsClient &&
2106 !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount))
2107 /* if the data in the RPC buffer is big enough, we just point
2108 * straight into it */
2109 *ppMemory = pStubMsg->Buffer;
2110 else if (!*ppMemory)
2111 *ppMemory = NdrAllocate(pStubMsg, memsize);
2114 if (*ppMemory == pStubMsg->Buffer)
2115 safe_buffer_increment(pStubMsg, bufsize);
2116 else
2117 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2119 if (*pFormat == RPC_FC_C_CSTRING)
2120 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
2121 else
2122 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
2124 return bufsize;
2125 default:
2126 ERR("unknown array format 0x%x\n", fc);
2127 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2131 static inline void array_memory_size(
2132 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat,
2133 unsigned char fHasPointers)
2135 ULONG bufsize, memsize;
2136 DWORD esize;
2137 unsigned char alignment;
2139 switch (fc)
2141 case RPC_FC_CARRAY:
2142 esize = *(const WORD*)(pFormat+2);
2143 alignment = pFormat[1] + 1;
2145 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2147 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2148 pStubMsg->MemorySize += memsize;
2150 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2151 if (fHasPointers)
2152 pStubMsg->BufferMark = pStubMsg->Buffer;
2153 safe_buffer_increment(pStubMsg, bufsize);
2155 if (fHasPointers)
2156 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2157 break;
2158 case RPC_FC_CVARRAY:
2159 esize = *(const WORD*)(pFormat+2);
2160 alignment = pFormat[1] + 1;
2162 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2164 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2166 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2167 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2168 pStubMsg->MemorySize += memsize;
2170 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2171 if (fHasPointers)
2172 pStubMsg->BufferMark = pStubMsg->Buffer;
2173 safe_buffer_increment(pStubMsg, bufsize);
2175 if (fHasPointers)
2176 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2177 break;
2178 case RPC_FC_C_CSTRING:
2179 case RPC_FC_C_WSTRING:
2180 if (fc == RPC_FC_C_CSTRING)
2181 esize = 1;
2182 else
2183 esize = 2;
2185 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2187 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2189 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2190 pStubMsg->ActualCount, pStubMsg->MaxCount);
2191 RpcRaiseException(RPC_S_INVALID_BOUND);
2193 if (pStubMsg->Offset)
2195 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2196 RpcRaiseException(RPC_S_INVALID_BOUND);
2199 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2200 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2202 validate_string_data(pStubMsg, bufsize, esize);
2204 safe_buffer_increment(pStubMsg, bufsize);
2205 pStubMsg->MemorySize += memsize;
2206 break;
2207 default:
2208 ERR("unknown array format 0x%x\n", fc);
2209 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2213 static inline void array_free(
2214 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg,
2215 unsigned char *pMemory, PFORMAT_STRING pFormat, unsigned char fHasPointers)
2217 switch (fc)
2219 case RPC_FC_CARRAY:
2220 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2221 if (fHasPointers)
2222 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2223 break;
2224 case RPC_FC_CVARRAY:
2225 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2226 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2227 if (fHasPointers)
2228 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2229 break;
2230 case RPC_FC_C_CSTRING:
2231 case RPC_FC_C_WSTRING:
2232 /* No embedded pointers so nothing to do */
2233 break;
2234 default:
2235 ERR("unknown array format 0x%x\n", fc);
2236 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2241 * NdrConformantString:
2243 * What MS calls a ConformantString is, in DCE terminology,
2244 * a Varying-Conformant String.
2246 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2247 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2248 * into unmarshalled string)
2249 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2251 * data: CHARTYPE[maxlen]
2253 * ], where CHARTYPE is the appropriate character type (specified externally)
2257 /***********************************************************************
2258 * NdrConformantStringMarshall [RPCRT4.@]
2260 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
2261 unsigned char *pszMessage, PFORMAT_STRING pFormat)
2263 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
2265 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2266 ERR("Unhandled string type: %#x\n", pFormat[0]);
2267 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2270 /* allow compiler to optimise inline function by passing constant into
2271 * these functions */
2272 if (pFormat[0] == RPC_FC_C_CSTRING) {
2273 array_compute_and_write_conformance(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2274 pFormat);
2275 array_write_variance_and_marshall(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2276 pFormat, TRUE /* fHasPointers */);
2277 } else {
2278 array_compute_and_write_conformance(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2279 pFormat);
2280 array_write_variance_and_marshall(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2281 pFormat, TRUE /* fHasPointers */);
2284 return NULL;
2287 /***********************************************************************
2288 * NdrConformantStringBufferSize [RPCRT4.@]
2290 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2291 unsigned char* pMemory, PFORMAT_STRING pFormat)
2293 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2295 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2296 ERR("Unhandled string type: %#x\n", pFormat[0]);
2297 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2300 /* allow compiler to optimise inline function by passing constant into
2301 * these functions */
2302 if (pFormat[0] == RPC_FC_C_CSTRING) {
2303 array_compute_and_size_conformance(RPC_FC_C_CSTRING, pStubMsg, pMemory,
2304 pFormat);
2305 array_buffer_size(RPC_FC_C_CSTRING, pStubMsg, pMemory, pFormat,
2306 TRUE /* fHasPointers */);
2307 } else {
2308 array_compute_and_size_conformance(RPC_FC_C_WSTRING, pStubMsg, pMemory,
2309 pFormat);
2310 array_buffer_size(RPC_FC_C_WSTRING, pStubMsg, pMemory, pFormat,
2311 TRUE /* fHasPointers */);
2315 /************************************************************************
2316 * NdrConformantStringMemorySize [RPCRT4.@]
2318 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2319 PFORMAT_STRING pFormat )
2321 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2323 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2324 ERR("Unhandled string type: %#x\n", pFormat[0]);
2325 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2328 /* allow compiler to optimise inline function by passing constant into
2329 * these functions */
2330 if (pFormat[0] == RPC_FC_C_CSTRING) {
2331 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2332 array_memory_size(RPC_FC_C_CSTRING, pStubMsg, pFormat,
2333 TRUE /* fHasPointers */);
2334 } else {
2335 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2336 array_memory_size(RPC_FC_C_WSTRING, pStubMsg, pFormat,
2337 TRUE /* fHasPointers */);
2340 return pStubMsg->MemorySize;
2343 /************************************************************************
2344 * NdrConformantStringUnmarshall [RPCRT4.@]
2346 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2347 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
2349 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2350 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2352 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2353 ERR("Unhandled string type: %#x\n", *pFormat);
2354 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2357 /* allow compiler to optimise inline function by passing constant into
2358 * these functions */
2359 if (pFormat[0] == RPC_FC_C_CSTRING) {
2360 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2361 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING, pStubMsg, ppMemory,
2362 pFormat, fMustAlloc,
2363 TRUE /* fUseBufferMemoryServer */,
2364 TRUE /* fUnmarshall */);
2365 } else {
2366 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2367 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING, pStubMsg, ppMemory,
2368 pFormat, fMustAlloc,
2369 TRUE /* fUseBufferMemoryServer */,
2370 TRUE /* fUnmarshall */);
2373 return NULL;
2376 /***********************************************************************
2377 * NdrNonConformantStringMarshall [RPCRT4.@]
2379 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2380 unsigned char *pMemory,
2381 PFORMAT_STRING pFormat)
2383 ULONG esize, size, maxsize;
2385 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2387 maxsize = *(USHORT *)&pFormat[2];
2389 if (*pFormat == RPC_FC_CSTRING)
2391 ULONG i;
2392 const char *str = (const char *)pMemory;
2393 for (i = 0; i < maxsize && *str; i++, str++)
2395 TRACE("string=%s\n", debugstr_an(str, i));
2396 pStubMsg->ActualCount = i + 1;
2397 esize = 1;
2399 else if (*pFormat == RPC_FC_WSTRING)
2401 ULONG i;
2402 const WCHAR *str = (const WCHAR *)pMemory;
2403 for (i = 0; i < maxsize && *str; i++, str++)
2405 TRACE("string=%s\n", debugstr_wn(str, i));
2406 pStubMsg->ActualCount = i + 1;
2407 esize = 2;
2409 else
2411 ERR("Unhandled string type: %#x\n", *pFormat);
2412 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2415 pStubMsg->Offset = 0;
2416 WriteVariance(pStubMsg);
2418 size = safe_multiply(esize, pStubMsg->ActualCount);
2419 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
2421 return NULL;
2424 /***********************************************************************
2425 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2427 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2428 unsigned char **ppMemory,
2429 PFORMAT_STRING pFormat,
2430 unsigned char fMustAlloc)
2432 ULONG bufsize, memsize, esize, maxsize;
2434 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2435 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2437 maxsize = *(USHORT *)&pFormat[2];
2439 ReadVariance(pStubMsg, NULL, maxsize);
2440 if (pStubMsg->Offset)
2442 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2443 RpcRaiseException(RPC_S_INVALID_BOUND);
2446 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2447 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2448 else
2450 ERR("Unhandled string type: %#x\n", *pFormat);
2451 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2454 memsize = esize * maxsize;
2455 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2457 validate_string_data(pStubMsg, bufsize, esize);
2459 if (!fMustAlloc && !*ppMemory)
2460 fMustAlloc = TRUE;
2461 if (fMustAlloc)
2462 *ppMemory = NdrAllocate(pStubMsg, memsize);
2464 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2466 if (*pFormat == RPC_FC_CSTRING) {
2467 TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount));
2469 else if (*pFormat == RPC_FC_WSTRING) {
2470 TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount));
2473 return NULL;
2476 /***********************************************************************
2477 * NdrNonConformantStringBufferSize [RPCRT4.@]
2479 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2480 unsigned char *pMemory,
2481 PFORMAT_STRING pFormat)
2483 ULONG esize, maxsize;
2485 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2487 maxsize = *(USHORT *)&pFormat[2];
2489 SizeVariance(pStubMsg);
2491 if (*pFormat == RPC_FC_CSTRING)
2493 ULONG i;
2494 const char *str = (const char *)pMemory;
2495 for (i = 0; i < maxsize && *str; i++, str++)
2497 TRACE("string=%s\n", debugstr_an(str, i));
2498 pStubMsg->ActualCount = i + 1;
2499 esize = 1;
2501 else if (*pFormat == RPC_FC_WSTRING)
2503 ULONG i;
2504 const WCHAR *str = (const WCHAR *)pMemory;
2505 for (i = 0; i < maxsize && *str; i++, str++)
2507 TRACE("string=%s\n", debugstr_wn(str, i));
2508 pStubMsg->ActualCount = i + 1;
2509 esize = 2;
2511 else
2513 ERR("Unhandled string type: %#x\n", *pFormat);
2514 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2517 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
2520 /***********************************************************************
2521 * NdrNonConformantStringMemorySize [RPCRT4.@]
2523 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2524 PFORMAT_STRING pFormat)
2526 ULONG bufsize, memsize, esize, maxsize;
2528 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2530 maxsize = *(USHORT *)&pFormat[2];
2532 ReadVariance(pStubMsg, NULL, maxsize);
2534 if (pStubMsg->Offset)
2536 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2537 RpcRaiseException(RPC_S_INVALID_BOUND);
2540 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2541 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2542 else
2544 ERR("Unhandled string type: %#x\n", *pFormat);
2545 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2548 memsize = esize * maxsize;
2549 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2551 validate_string_data(pStubMsg, bufsize, esize);
2553 safe_buffer_increment(pStubMsg, bufsize);
2554 pStubMsg->MemorySize += memsize;
2556 return pStubMsg->MemorySize;
2559 /* Complex types */
2561 #include "pshpack1.h"
2562 typedef struct
2564 unsigned char type;
2565 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
2566 ULONG low_value;
2567 ULONG high_value;
2568 } NDR_RANGE;
2569 #include "poppack.h"
2571 static ULONG EmbeddedComplexSize(MIDL_STUB_MESSAGE *pStubMsg,
2572 PFORMAT_STRING pFormat)
2574 switch (*pFormat) {
2575 case RPC_FC_STRUCT:
2576 case RPC_FC_PSTRUCT:
2577 case RPC_FC_CSTRUCT:
2578 case RPC_FC_BOGUS_STRUCT:
2579 case RPC_FC_SMFARRAY:
2580 case RPC_FC_SMVARRAY:
2581 case RPC_FC_CSTRING:
2582 return *(const WORD*)&pFormat[2];
2583 case RPC_FC_USER_MARSHAL:
2584 return *(const WORD*)&pFormat[4];
2585 case RPC_FC_RANGE: {
2586 switch (((const NDR_RANGE *)pFormat)->flags_type & 0xf) {
2587 case RPC_FC_BYTE:
2588 case RPC_FC_CHAR:
2589 case RPC_FC_SMALL:
2590 case RPC_FC_USMALL:
2591 return sizeof(UCHAR);
2592 case RPC_FC_WCHAR:
2593 case RPC_FC_SHORT:
2594 case RPC_FC_USHORT:
2595 return sizeof(USHORT);
2596 case RPC_FC_LONG:
2597 case RPC_FC_ULONG:
2598 case RPC_FC_ENUM32:
2599 return sizeof(ULONG);
2600 case RPC_FC_FLOAT:
2601 return sizeof(float);
2602 case RPC_FC_DOUBLE:
2603 return sizeof(double);
2604 case RPC_FC_HYPER:
2605 return sizeof(ULONGLONG);
2606 case RPC_FC_ENUM16:
2607 return sizeof(UINT);
2608 default:
2609 ERR("unknown type 0x%x\n", ((const NDR_RANGE *)pFormat)->flags_type & 0xf);
2610 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2613 case RPC_FC_NON_ENCAPSULATED_UNION:
2614 pFormat += 2;
2615 if (pStubMsg->fHasNewCorrDesc)
2616 pFormat += 6;
2617 else
2618 pFormat += 4;
2620 pFormat += *(const SHORT*)pFormat;
2621 return *(const SHORT*)pFormat;
2622 case RPC_FC_IP:
2623 return sizeof(void *);
2624 case RPC_FC_WSTRING:
2625 return *(const WORD*)&pFormat[2] * 2;
2626 default:
2627 FIXME("unhandled embedded type %02x\n", *pFormat);
2629 return 0;
2633 static ULONG EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2634 PFORMAT_STRING pFormat)
2636 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
2638 if (!m)
2640 FIXME("no memorysizer for data type=%02x\n", *pFormat);
2641 return 0;
2644 return m(pStubMsg, pFormat);
2648 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2649 unsigned char *pMemory,
2650 PFORMAT_STRING pFormat,
2651 PFORMAT_STRING pPointer)
2653 PFORMAT_STRING desc;
2654 NDR_MARSHALL m;
2655 ULONG size;
2657 while (*pFormat != RPC_FC_END) {
2658 switch (*pFormat) {
2659 case RPC_FC_BYTE:
2660 case RPC_FC_CHAR:
2661 case RPC_FC_SMALL:
2662 case RPC_FC_USMALL:
2663 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
2664 safe_copy_to_buffer(pStubMsg, pMemory, 1);
2665 pMemory += 1;
2666 break;
2667 case RPC_FC_WCHAR:
2668 case RPC_FC_SHORT:
2669 case RPC_FC_USHORT:
2670 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
2671 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2672 pMemory += 2;
2673 break;
2674 case RPC_FC_ENUM16:
2675 TRACE("enum16=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2676 if (32767 < *(DWORD*)pMemory)
2677 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2678 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2679 pMemory += 4;
2680 break;
2681 case RPC_FC_LONG:
2682 case RPC_FC_ULONG:
2683 case RPC_FC_ENUM32:
2684 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2685 safe_copy_to_buffer(pStubMsg, pMemory, 4);
2686 pMemory += 4;
2687 break;
2688 case RPC_FC_HYPER:
2689 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2690 safe_copy_to_buffer(pStubMsg, pMemory, 8);
2691 pMemory += 8;
2692 break;
2693 case RPC_FC_POINTER:
2695 unsigned char *saved_buffer;
2696 int pointer_buffer_mark_set = 0;
2697 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
2698 TRACE("pStubMsg->Buffer before %p\n", pStubMsg->Buffer);
2699 if (*pPointer != RPC_FC_RP)
2700 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
2701 saved_buffer = pStubMsg->Buffer;
2702 if (pStubMsg->PointerBufferMark)
2704 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2705 pStubMsg->PointerBufferMark = NULL;
2706 pointer_buffer_mark_set = 1;
2708 else if (*pPointer != RPC_FC_RP)
2709 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2710 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2711 if (pointer_buffer_mark_set)
2713 STD_OVERFLOW_CHECK(pStubMsg);
2714 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2715 pStubMsg->Buffer = saved_buffer;
2716 if (*pPointer != RPC_FC_RP)
2717 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2719 TRACE("pStubMsg->Buffer after %p\n", pStubMsg->Buffer);
2720 pPointer += 4;
2721 pMemory += 4;
2722 break;
2724 case RPC_FC_ALIGNM4:
2725 ALIGN_POINTER(pMemory, 4);
2726 break;
2727 case RPC_FC_ALIGNM8:
2728 ALIGN_POINTER(pMemory, 8);
2729 break;
2730 case RPC_FC_STRUCTPAD1:
2731 case RPC_FC_STRUCTPAD2:
2732 case RPC_FC_STRUCTPAD3:
2733 case RPC_FC_STRUCTPAD4:
2734 case RPC_FC_STRUCTPAD5:
2735 case RPC_FC_STRUCTPAD6:
2736 case RPC_FC_STRUCTPAD7:
2737 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2738 break;
2739 case RPC_FC_EMBEDDED_COMPLEX:
2740 pMemory += pFormat[1];
2741 pFormat += 2;
2742 desc = pFormat + *(const SHORT*)pFormat;
2743 size = EmbeddedComplexSize(pStubMsg, desc);
2744 TRACE("embedded complex (size=%d) <= %p\n", size, pMemory);
2745 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2746 if (m)
2748 /* for some reason interface pointers aren't generated as
2749 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2750 * they still need the derefencing treatment that pointers are
2751 * given */
2752 if (*desc == RPC_FC_IP)
2753 m(pStubMsg, *(unsigned char **)pMemory, desc);
2754 else
2755 m(pStubMsg, pMemory, desc);
2757 else FIXME("no marshaller for embedded type %02x\n", *desc);
2758 pMemory += size;
2759 pFormat += 2;
2760 continue;
2761 case RPC_FC_PAD:
2762 break;
2763 default:
2764 FIXME("unhandled format 0x%02x\n", *pFormat);
2766 pFormat++;
2769 return pMemory;
2772 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2773 unsigned char *pMemory,
2774 PFORMAT_STRING pFormat,
2775 PFORMAT_STRING pPointer,
2776 unsigned char fMustAlloc)
2778 PFORMAT_STRING desc;
2779 NDR_UNMARSHALL m;
2780 ULONG size;
2782 while (*pFormat != RPC_FC_END) {
2783 switch (*pFormat) {
2784 case RPC_FC_BYTE:
2785 case RPC_FC_CHAR:
2786 case RPC_FC_SMALL:
2787 case RPC_FC_USMALL:
2788 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2789 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2790 pMemory += 1;
2791 break;
2792 case RPC_FC_WCHAR:
2793 case RPC_FC_SHORT:
2794 case RPC_FC_USHORT:
2795 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2796 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
2797 pMemory += 2;
2798 break;
2799 case RPC_FC_ENUM16:
2800 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2801 *(DWORD*)pMemory &= 0xffff;
2802 TRACE("enum16=%d => %p\n", *(DWORD*)pMemory, pMemory);
2803 if (32767 < *(DWORD*)pMemory)
2804 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2805 pMemory += 4;
2806 break;
2807 case RPC_FC_LONG:
2808 case RPC_FC_ULONG:
2809 case RPC_FC_ENUM32:
2810 safe_copy_from_buffer(pStubMsg, pMemory, 4);
2811 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
2812 pMemory += 4;
2813 break;
2814 case RPC_FC_HYPER:
2815 safe_copy_from_buffer(pStubMsg, pMemory, 8);
2816 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2817 pMemory += 8;
2818 break;
2819 case RPC_FC_POINTER:
2821 unsigned char *saved_buffer;
2822 int pointer_buffer_mark_set = 0;
2823 TRACE("pointer => %p\n", pMemory);
2824 if (*pPointer != RPC_FC_RP)
2825 ALIGN_POINTER(pStubMsg->Buffer, 4);
2826 saved_buffer = pStubMsg->Buffer;
2827 if (pStubMsg->PointerBufferMark)
2829 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2830 pStubMsg->PointerBufferMark = NULL;
2831 pointer_buffer_mark_set = 1;
2833 else if (*pPointer != RPC_FC_RP)
2834 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2836 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, fMustAlloc);
2837 if (pointer_buffer_mark_set)
2839 STD_OVERFLOW_CHECK(pStubMsg);
2840 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2841 pStubMsg->Buffer = saved_buffer;
2842 if (*pPointer != RPC_FC_RP)
2843 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2845 pPointer += 4;
2846 pMemory += 4;
2847 break;
2849 case RPC_FC_ALIGNM4:
2850 ALIGN_POINTER_CLEAR(pMemory, 4);
2851 break;
2852 case RPC_FC_ALIGNM8:
2853 ALIGN_POINTER_CLEAR(pMemory, 8);
2854 break;
2855 case RPC_FC_STRUCTPAD1:
2856 case RPC_FC_STRUCTPAD2:
2857 case RPC_FC_STRUCTPAD3:
2858 case RPC_FC_STRUCTPAD4:
2859 case RPC_FC_STRUCTPAD5:
2860 case RPC_FC_STRUCTPAD6:
2861 case RPC_FC_STRUCTPAD7:
2862 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1);
2863 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2864 break;
2865 case RPC_FC_EMBEDDED_COMPLEX:
2866 pMemory += pFormat[1];
2867 pFormat += 2;
2868 desc = pFormat + *(const SHORT*)pFormat;
2869 size = EmbeddedComplexSize(pStubMsg, desc);
2870 TRACE("embedded complex (size=%d) => %p\n", size, pMemory);
2871 if (fMustAlloc)
2872 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
2873 * since the type is part of the memory block that is encompassed by
2874 * the whole complex type. Memory is forced to allocate when pointers
2875 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
2876 * clearing the memory we pass in to the unmarshaller */
2877 memset(pMemory, 0, size);
2878 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
2879 if (m)
2881 /* for some reason interface pointers aren't generated as
2882 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2883 * they still need the derefencing treatment that pointers are
2884 * given */
2885 if (*desc == RPC_FC_IP)
2886 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
2887 else
2888 m(pStubMsg, &pMemory, desc, FALSE);
2890 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
2891 pMemory += size;
2892 pFormat += 2;
2893 continue;
2894 case RPC_FC_PAD:
2895 break;
2896 default:
2897 FIXME("unhandled format %d\n", *pFormat);
2899 pFormat++;
2902 return pMemory;
2905 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2906 unsigned char *pMemory,
2907 PFORMAT_STRING pFormat,
2908 PFORMAT_STRING pPointer)
2910 PFORMAT_STRING desc;
2911 NDR_BUFFERSIZE m;
2912 ULONG size;
2914 while (*pFormat != RPC_FC_END) {
2915 switch (*pFormat) {
2916 case RPC_FC_BYTE:
2917 case RPC_FC_CHAR:
2918 case RPC_FC_SMALL:
2919 case RPC_FC_USMALL:
2920 safe_buffer_length_increment(pStubMsg, 1);
2921 pMemory += 1;
2922 break;
2923 case RPC_FC_WCHAR:
2924 case RPC_FC_SHORT:
2925 case RPC_FC_USHORT:
2926 safe_buffer_length_increment(pStubMsg, 2);
2927 pMemory += 2;
2928 break;
2929 case RPC_FC_ENUM16:
2930 safe_buffer_length_increment(pStubMsg, 2);
2931 pMemory += 4;
2932 break;
2933 case RPC_FC_LONG:
2934 case RPC_FC_ULONG:
2935 case RPC_FC_ENUM32:
2936 safe_buffer_length_increment(pStubMsg, 4);
2937 pMemory += 4;
2938 break;
2939 case RPC_FC_HYPER:
2940 safe_buffer_length_increment(pStubMsg, 8);
2941 pMemory += 8;
2942 break;
2943 case RPC_FC_POINTER:
2944 if (!pStubMsg->IgnoreEmbeddedPointers)
2946 int saved_buffer_length = pStubMsg->BufferLength;
2947 pStubMsg->BufferLength = pStubMsg->PointerLength;
2948 pStubMsg->PointerLength = 0;
2949 if(!pStubMsg->BufferLength)
2950 ERR("BufferLength == 0??\n");
2951 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
2952 pStubMsg->PointerLength = pStubMsg->BufferLength;
2953 pStubMsg->BufferLength = saved_buffer_length;
2955 if (*pPointer != RPC_FC_RP)
2957 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
2958 safe_buffer_length_increment(pStubMsg, 4);
2960 pPointer += 4;
2961 pMemory += 4;
2962 break;
2963 case RPC_FC_ALIGNM4:
2964 ALIGN_POINTER(pMemory, 4);
2965 break;
2966 case RPC_FC_ALIGNM8:
2967 ALIGN_POINTER(pMemory, 8);
2968 break;
2969 case RPC_FC_STRUCTPAD1:
2970 case RPC_FC_STRUCTPAD2:
2971 case RPC_FC_STRUCTPAD3:
2972 case RPC_FC_STRUCTPAD4:
2973 case RPC_FC_STRUCTPAD5:
2974 case RPC_FC_STRUCTPAD6:
2975 case RPC_FC_STRUCTPAD7:
2976 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2977 break;
2978 case RPC_FC_EMBEDDED_COMPLEX:
2979 pMemory += pFormat[1];
2980 pFormat += 2;
2981 desc = pFormat + *(const SHORT*)pFormat;
2982 size = EmbeddedComplexSize(pStubMsg, desc);
2983 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
2984 if (m)
2986 /* for some reason interface pointers aren't generated as
2987 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2988 * they still need the derefencing treatment that pointers are
2989 * given */
2990 if (*desc == RPC_FC_IP)
2991 m(pStubMsg, *(unsigned char **)pMemory, desc);
2992 else
2993 m(pStubMsg, pMemory, desc);
2995 else FIXME("no buffersizer for embedded type %02x\n", *desc);
2996 pMemory += size;
2997 pFormat += 2;
2998 continue;
2999 case RPC_FC_PAD:
3000 break;
3001 default:
3002 FIXME("unhandled format 0x%02x\n", *pFormat);
3004 pFormat++;
3007 return pMemory;
3010 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
3011 unsigned char *pMemory,
3012 PFORMAT_STRING pFormat,
3013 PFORMAT_STRING pPointer)
3015 PFORMAT_STRING desc;
3016 NDR_FREE m;
3017 ULONG size;
3019 while (*pFormat != RPC_FC_END) {
3020 switch (*pFormat) {
3021 case RPC_FC_BYTE:
3022 case RPC_FC_CHAR:
3023 case RPC_FC_SMALL:
3024 case RPC_FC_USMALL:
3025 pMemory += 1;
3026 break;
3027 case RPC_FC_WCHAR:
3028 case RPC_FC_SHORT:
3029 case RPC_FC_USHORT:
3030 pMemory += 2;
3031 break;
3032 case RPC_FC_LONG:
3033 case RPC_FC_ULONG:
3034 case RPC_FC_ENUM16:
3035 case RPC_FC_ENUM32:
3036 pMemory += 4;
3037 break;
3038 case RPC_FC_HYPER:
3039 pMemory += 8;
3040 break;
3041 case RPC_FC_POINTER:
3042 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
3043 pPointer += 4;
3044 pMemory += 4;
3045 break;
3046 case RPC_FC_ALIGNM4:
3047 ALIGN_POINTER(pMemory, 4);
3048 break;
3049 case RPC_FC_ALIGNM8:
3050 ALIGN_POINTER(pMemory, 8);
3051 break;
3052 case RPC_FC_STRUCTPAD1:
3053 case RPC_FC_STRUCTPAD2:
3054 case RPC_FC_STRUCTPAD3:
3055 case RPC_FC_STRUCTPAD4:
3056 case RPC_FC_STRUCTPAD5:
3057 case RPC_FC_STRUCTPAD6:
3058 case RPC_FC_STRUCTPAD7:
3059 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3060 break;
3061 case RPC_FC_EMBEDDED_COMPLEX:
3062 pMemory += pFormat[1];
3063 pFormat += 2;
3064 desc = pFormat + *(const SHORT*)pFormat;
3065 size = EmbeddedComplexSize(pStubMsg, desc);
3066 m = NdrFreer[*desc & NDR_TABLE_MASK];
3067 if (m)
3069 /* for some reason interface pointers aren't generated as
3070 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3071 * they still need the derefencing treatment that pointers are
3072 * given */
3073 if (*desc == RPC_FC_IP)
3074 m(pStubMsg, *(unsigned char **)pMemory, desc);
3075 else
3076 m(pStubMsg, pMemory, desc);
3078 pMemory += size;
3079 pFormat += 2;
3080 continue;
3081 case RPC_FC_PAD:
3082 break;
3083 default:
3084 FIXME("unhandled format 0x%02x\n", *pFormat);
3086 pFormat++;
3089 return pMemory;
3092 static ULONG ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3093 PFORMAT_STRING pFormat,
3094 PFORMAT_STRING pPointer)
3096 PFORMAT_STRING desc;
3097 ULONG size = 0;
3099 while (*pFormat != RPC_FC_END) {
3100 switch (*pFormat) {
3101 case RPC_FC_BYTE:
3102 case RPC_FC_CHAR:
3103 case RPC_FC_SMALL:
3104 case RPC_FC_USMALL:
3105 size += 1;
3106 safe_buffer_increment(pStubMsg, 1);
3107 break;
3108 case RPC_FC_WCHAR:
3109 case RPC_FC_SHORT:
3110 case RPC_FC_USHORT:
3111 size += 2;
3112 safe_buffer_increment(pStubMsg, 2);
3113 break;
3114 case RPC_FC_ENUM16:
3115 size += 4;
3116 safe_buffer_increment(pStubMsg, 2);
3117 break;
3118 case RPC_FC_LONG:
3119 case RPC_FC_ULONG:
3120 case RPC_FC_ENUM32:
3121 size += 4;
3122 safe_buffer_increment(pStubMsg, 4);
3123 break;
3124 case RPC_FC_HYPER:
3125 size += 8;
3126 safe_buffer_increment(pStubMsg, 8);
3127 break;
3128 case RPC_FC_POINTER:
3130 unsigned char *saved_buffer;
3131 int pointer_buffer_mark_set = 0;
3132 if (*pPointer != RPC_FC_RP)
3133 ALIGN_POINTER(pStubMsg->Buffer, 4);
3134 saved_buffer = pStubMsg->Buffer;
3135 if (pStubMsg->PointerBufferMark)
3137 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3138 pStubMsg->PointerBufferMark = NULL;
3139 pointer_buffer_mark_set = 1;
3141 else if (*pPointer != RPC_FC_RP)
3142 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3144 if (!pStubMsg->IgnoreEmbeddedPointers)
3145 PointerMemorySize(pStubMsg, saved_buffer, pPointer);
3146 if (pointer_buffer_mark_set)
3148 STD_OVERFLOW_CHECK(pStubMsg);
3149 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3150 pStubMsg->Buffer = saved_buffer;
3151 if (*pPointer != RPC_FC_RP)
3152 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3154 pPointer += 4;
3155 size += 4;
3156 break;
3158 case RPC_FC_ALIGNM4:
3159 ALIGN_LENGTH(size, 4);
3160 break;
3161 case RPC_FC_ALIGNM8:
3162 ALIGN_LENGTH(size, 8);
3163 break;
3164 case RPC_FC_STRUCTPAD1:
3165 case RPC_FC_STRUCTPAD2:
3166 case RPC_FC_STRUCTPAD3:
3167 case RPC_FC_STRUCTPAD4:
3168 case RPC_FC_STRUCTPAD5:
3169 case RPC_FC_STRUCTPAD6:
3170 case RPC_FC_STRUCTPAD7:
3171 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3172 break;
3173 case RPC_FC_EMBEDDED_COMPLEX:
3174 size += pFormat[1];
3175 pFormat += 2;
3176 desc = pFormat + *(const SHORT*)pFormat;
3177 size += EmbeddedComplexMemorySize(pStubMsg, desc);
3178 pFormat += 2;
3179 continue;
3180 case RPC_FC_PAD:
3181 break;
3182 default:
3183 FIXME("unhandled format 0x%02x\n", *pFormat);
3185 pFormat++;
3188 return size;
3191 ULONG ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
3193 PFORMAT_STRING desc;
3194 ULONG size = 0;
3196 while (*pFormat != RPC_FC_END) {
3197 switch (*pFormat) {
3198 case RPC_FC_BYTE:
3199 case RPC_FC_CHAR:
3200 case RPC_FC_SMALL:
3201 case RPC_FC_USMALL:
3202 size += 1;
3203 break;
3204 case RPC_FC_WCHAR:
3205 case RPC_FC_SHORT:
3206 case RPC_FC_USHORT:
3207 size += 2;
3208 break;
3209 case RPC_FC_LONG:
3210 case RPC_FC_ULONG:
3211 case RPC_FC_ENUM16:
3212 case RPC_FC_ENUM32:
3213 size += 4;
3214 break;
3215 case RPC_FC_HYPER:
3216 size += 8;
3217 break;
3218 case RPC_FC_POINTER:
3219 size += sizeof(void *);
3220 break;
3221 case RPC_FC_ALIGNM4:
3222 ALIGN_LENGTH(size, 4);
3223 break;
3224 case RPC_FC_ALIGNM8:
3225 ALIGN_LENGTH(size, 8);
3226 break;
3227 case RPC_FC_STRUCTPAD1:
3228 case RPC_FC_STRUCTPAD2:
3229 case RPC_FC_STRUCTPAD3:
3230 case RPC_FC_STRUCTPAD4:
3231 case RPC_FC_STRUCTPAD5:
3232 case RPC_FC_STRUCTPAD6:
3233 case RPC_FC_STRUCTPAD7:
3234 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3235 break;
3236 case RPC_FC_EMBEDDED_COMPLEX:
3237 size += pFormat[1];
3238 pFormat += 2;
3239 desc = pFormat + *(const SHORT*)pFormat;
3240 size += EmbeddedComplexSize(pStubMsg, desc);
3241 pFormat += 2;
3242 continue;
3243 case RPC_FC_PAD:
3244 break;
3245 default:
3246 FIXME("unhandled format 0x%02x\n", *pFormat);
3248 pFormat++;
3251 return size;
3254 /***********************************************************************
3255 * NdrComplexStructMarshall [RPCRT4.@]
3257 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3258 unsigned char *pMemory,
3259 PFORMAT_STRING pFormat)
3261 PFORMAT_STRING conf_array = NULL;
3262 PFORMAT_STRING pointer_desc = NULL;
3263 unsigned char *OldMemory = pStubMsg->Memory;
3264 int pointer_buffer_mark_set = 0;
3265 ULONG count = 0;
3266 ULONG max_count = 0;
3267 ULONG offset = 0;
3269 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3271 if (!pStubMsg->PointerBufferMark)
3273 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3274 /* save buffer length */
3275 ULONG saved_buffer_length = pStubMsg->BufferLength;
3277 /* get the buffer pointer after complex array data, but before
3278 * pointer data */
3279 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
3280 pStubMsg->IgnoreEmbeddedPointers = 1;
3281 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3282 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3284 /* save it for use by embedded pointer code later */
3285 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
3286 TRACE("difference = 0x%x\n", pStubMsg->PointerBufferMark - pStubMsg->Buffer);
3287 pointer_buffer_mark_set = 1;
3289 /* restore the original buffer length */
3290 pStubMsg->BufferLength = saved_buffer_length;
3293 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
3295 pFormat += 4;
3296 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3297 pFormat += 2;
3298 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3299 pFormat += 2;
3301 pStubMsg->Memory = pMemory;
3303 if (conf_array)
3305 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat);
3306 array_compute_and_write_conformance(conf_array[0], pStubMsg,
3307 pMemory + struct_size, conf_array);
3308 /* these could be changed in ComplexMarshall so save them for later */
3309 max_count = pStubMsg->MaxCount;
3310 count = pStubMsg->ActualCount;
3311 offset = pStubMsg->Offset;
3314 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
3316 if (conf_array)
3318 pStubMsg->MaxCount = max_count;
3319 pStubMsg->ActualCount = count;
3320 pStubMsg->Offset = offset;
3321 array_write_variance_and_marshall(conf_array[0], pStubMsg, pMemory,
3322 conf_array, TRUE /* fHasPointers */);
3325 pStubMsg->Memory = OldMemory;
3327 if (pointer_buffer_mark_set)
3329 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3330 pStubMsg->PointerBufferMark = NULL;
3333 STD_OVERFLOW_CHECK(pStubMsg);
3335 return NULL;
3338 /***********************************************************************
3339 * NdrComplexStructUnmarshall [RPCRT4.@]
3341 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3342 unsigned char **ppMemory,
3343 PFORMAT_STRING pFormat,
3344 unsigned char fMustAlloc)
3346 unsigned size = *(const WORD*)(pFormat+2);
3347 PFORMAT_STRING conf_array = NULL;
3348 PFORMAT_STRING pointer_desc = NULL;
3349 unsigned char *pMemory;
3350 int pointer_buffer_mark_set = 0;
3351 ULONG count = 0;
3352 ULONG max_count = 0;
3353 ULONG offset = 0;
3354 ULONG array_size = 0;
3356 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3358 if (!pStubMsg->PointerBufferMark)
3360 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3361 /* save buffer pointer */
3362 unsigned char *saved_buffer = pStubMsg->Buffer;
3364 /* get the buffer pointer after complex array data, but before
3365 * pointer data */
3366 pStubMsg->IgnoreEmbeddedPointers = 1;
3367 NdrComplexStructMemorySize(pStubMsg, pFormat);
3368 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3370 /* save it for use by embedded pointer code later */
3371 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3372 TRACE("difference = 0x%x\n", pStubMsg->PointerBufferMark - saved_buffer);
3373 pointer_buffer_mark_set = 1;
3375 /* restore the original buffer */
3376 pStubMsg->Buffer = saved_buffer;
3379 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
3381 pFormat += 4;
3382 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3383 pFormat += 2;
3384 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3385 pFormat += 2;
3387 if (conf_array)
3389 array_size = array_read_conformance(conf_array[0], pStubMsg, conf_array);
3390 size += array_size;
3392 /* these could be changed in ComplexMarshall so save them for later */
3393 max_count = pStubMsg->MaxCount;
3394 count = pStubMsg->ActualCount;
3395 offset = pStubMsg->Offset;
3398 if (!fMustAlloc && !*ppMemory)
3399 fMustAlloc = TRUE;
3400 if (fMustAlloc)
3401 *ppMemory = NdrAllocate(pStubMsg, size);
3403 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc);
3405 if (conf_array)
3407 pStubMsg->MaxCount = max_count;
3408 pStubMsg->ActualCount = count;
3409 pStubMsg->Offset = offset;
3410 if (fMustAlloc)
3411 memset(pMemory, 0, array_size);
3412 array_read_variance_and_unmarshall(conf_array[0], pStubMsg, &pMemory,
3413 conf_array, FALSE,
3414 FALSE /* fUseBufferMemoryServer */,
3415 TRUE /* fUnmarshall */);
3418 if (pointer_buffer_mark_set)
3420 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3421 pStubMsg->PointerBufferMark = NULL;
3424 return NULL;
3427 /***********************************************************************
3428 * NdrComplexStructBufferSize [RPCRT4.@]
3430 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3431 unsigned char *pMemory,
3432 PFORMAT_STRING pFormat)
3434 PFORMAT_STRING conf_array = NULL;
3435 PFORMAT_STRING pointer_desc = NULL;
3436 unsigned char *OldMemory = pStubMsg->Memory;
3437 int pointer_length_set = 0;
3438 ULONG count = 0;
3439 ULONG max_count = 0;
3440 ULONG offset = 0;
3442 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3444 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
3446 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3448 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3449 ULONG saved_buffer_length = pStubMsg->BufferLength;
3451 /* get the buffer length after complex struct data, but before
3452 * pointer data */
3453 pStubMsg->IgnoreEmbeddedPointers = 1;
3454 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3455 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3457 /* save it for use by embedded pointer code later */
3458 pStubMsg->PointerLength = pStubMsg->BufferLength;
3459 pointer_length_set = 1;
3460 TRACE("difference = 0x%x\n", pStubMsg->PointerLength - saved_buffer_length);
3462 /* restore the original buffer length */
3463 pStubMsg->BufferLength = saved_buffer_length;
3466 pFormat += 4;
3467 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3468 pFormat += 2;
3469 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3470 pFormat += 2;
3472 pStubMsg->Memory = pMemory;
3474 if (conf_array)
3476 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat);
3477 array_compute_and_size_conformance(conf_array[0], pStubMsg, pMemory + struct_size,
3478 conf_array);
3480 /* these could be changed in ComplexMarshall so save them for later */
3481 max_count = pStubMsg->MaxCount;
3482 count = pStubMsg->ActualCount;
3483 offset = pStubMsg->Offset;
3486 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
3488 if (conf_array)
3490 pStubMsg->MaxCount = max_count;
3491 pStubMsg->ActualCount = count;
3492 pStubMsg->Offset = offset;
3493 array_buffer_size(conf_array[0], pStubMsg, pMemory, conf_array,
3494 TRUE /* fHasPointers */);
3497 pStubMsg->Memory = OldMemory;
3499 if(pointer_length_set)
3501 pStubMsg->BufferLength = pStubMsg->PointerLength;
3502 pStubMsg->PointerLength = 0;
3507 /***********************************************************************
3508 * NdrComplexStructMemorySize [RPCRT4.@]
3510 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3511 PFORMAT_STRING pFormat)
3513 unsigned size = *(const WORD*)(pFormat+2);
3514 PFORMAT_STRING conf_array = NULL;
3515 PFORMAT_STRING pointer_desc = NULL;
3516 ULONG count = 0;
3517 ULONG max_count = 0;
3518 ULONG offset = 0;
3520 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3522 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
3524 pFormat += 4;
3525 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3526 pFormat += 2;
3527 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3528 pFormat += 2;
3530 if (conf_array)
3532 array_read_conformance(conf_array[0], pStubMsg, conf_array);
3534 /* these could be changed in ComplexStructMemorySize so save them for
3535 * later */
3536 max_count = pStubMsg->MaxCount;
3537 count = pStubMsg->ActualCount;
3538 offset = pStubMsg->Offset;
3541 ComplexStructMemorySize(pStubMsg, pFormat, pointer_desc);
3543 if (conf_array)
3545 pStubMsg->MaxCount = max_count;
3546 pStubMsg->ActualCount = count;
3547 pStubMsg->Offset = offset;
3548 array_memory_size(conf_array[0], pStubMsg, conf_array,
3549 TRUE /* fHasPointers */);
3552 return size;
3555 /***********************************************************************
3556 * NdrComplexStructFree [RPCRT4.@]
3558 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3559 unsigned char *pMemory,
3560 PFORMAT_STRING pFormat)
3562 PFORMAT_STRING conf_array = NULL;
3563 PFORMAT_STRING pointer_desc = NULL;
3564 unsigned char *OldMemory = pStubMsg->Memory;
3566 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3568 pFormat += 4;
3569 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3570 pFormat += 2;
3571 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3572 pFormat += 2;
3574 pStubMsg->Memory = pMemory;
3576 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
3578 if (conf_array)
3579 array_free(conf_array[0], pStubMsg, pMemory, conf_array,
3580 TRUE /* fHasPointers */);
3582 pStubMsg->Memory = OldMemory;
3585 /***********************************************************************
3586 * NdrConformantArrayMarshall [RPCRT4.@]
3588 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3589 unsigned char *pMemory,
3590 PFORMAT_STRING pFormat)
3592 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3593 if (pFormat[0] != RPC_FC_CARRAY)
3595 ERR("invalid format = 0x%x\n", pFormat[0]);
3596 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3599 array_compute_and_write_conformance(RPC_FC_CARRAY, pStubMsg, pMemory,
3600 pFormat);
3601 array_write_variance_and_marshall(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3602 TRUE /* fHasPointers */);
3604 return NULL;
3607 /***********************************************************************
3608 * NdrConformantArrayUnmarshall [RPCRT4.@]
3610 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3611 unsigned char **ppMemory,
3612 PFORMAT_STRING pFormat,
3613 unsigned char fMustAlloc)
3615 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3616 if (pFormat[0] != RPC_FC_CARRAY)
3618 ERR("invalid format = 0x%x\n", pFormat[0]);
3619 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3622 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3623 array_read_variance_and_unmarshall(RPC_FC_CARRAY, pStubMsg, ppMemory, pFormat,
3624 fMustAlloc,
3625 TRUE /* fUseBufferMemoryServer */,
3626 TRUE /* fUnmarshall */);
3628 return NULL;
3631 /***********************************************************************
3632 * NdrConformantArrayBufferSize [RPCRT4.@]
3634 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3635 unsigned char *pMemory,
3636 PFORMAT_STRING pFormat)
3638 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3639 if (pFormat[0] != RPC_FC_CARRAY)
3641 ERR("invalid format = 0x%x\n", pFormat[0]);
3642 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3645 array_compute_and_size_conformance(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat);
3646 array_buffer_size(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3647 TRUE /* fHasPointers */);
3650 /***********************************************************************
3651 * NdrConformantArrayMemorySize [RPCRT4.@]
3653 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3654 PFORMAT_STRING pFormat)
3656 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3657 if (pFormat[0] != RPC_FC_CARRAY)
3659 ERR("invalid format = 0x%x\n", pFormat[0]);
3660 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3663 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3664 array_memory_size(RPC_FC_CARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
3666 return pStubMsg->MemorySize;
3669 /***********************************************************************
3670 * NdrConformantArrayFree [RPCRT4.@]
3672 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3673 unsigned char *pMemory,
3674 PFORMAT_STRING pFormat)
3676 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3677 if (pFormat[0] != RPC_FC_CARRAY)
3679 ERR("invalid format = 0x%x\n", pFormat[0]);
3680 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3683 array_free(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3684 TRUE /* fHasPointers */);
3688 /***********************************************************************
3689 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3691 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
3692 unsigned char* pMemory,
3693 PFORMAT_STRING pFormat )
3695 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3697 if (pFormat[0] != RPC_FC_CVARRAY)
3699 ERR("invalid format type %x\n", pFormat[0]);
3700 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3701 return NULL;
3704 array_compute_and_write_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
3705 pFormat);
3706 array_write_variance_and_marshall(RPC_FC_CVARRAY, pStubMsg, pMemory,
3707 pFormat, TRUE /* fHasPointers */);
3709 return NULL;
3713 /***********************************************************************
3714 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
3716 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
3717 unsigned char** ppMemory,
3718 PFORMAT_STRING pFormat,
3719 unsigned char fMustAlloc )
3721 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3723 if (pFormat[0] != RPC_FC_CVARRAY)
3725 ERR("invalid format type %x\n", pFormat[0]);
3726 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3727 return NULL;
3730 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
3731 array_read_variance_and_unmarshall(RPC_FC_CVARRAY, pStubMsg, ppMemory,
3732 pFormat, fMustAlloc,
3733 TRUE /* fUseBufferMemoryServer */,
3734 TRUE /* fUnmarshall */);
3736 return NULL;
3740 /***********************************************************************
3741 * NdrConformantVaryingArrayFree [RPCRT4.@]
3743 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
3744 unsigned char* pMemory,
3745 PFORMAT_STRING pFormat )
3747 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3749 if (pFormat[0] != RPC_FC_CVARRAY)
3751 ERR("invalid format type %x\n", pFormat[0]);
3752 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3753 return;
3756 array_free(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
3757 TRUE /* fHasPointers */);
3761 /***********************************************************************
3762 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
3764 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
3765 unsigned char* pMemory, PFORMAT_STRING pFormat )
3767 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3769 if (pFormat[0] != RPC_FC_CVARRAY)
3771 ERR("invalid format type %x\n", pFormat[0]);
3772 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3773 return;
3776 array_compute_and_size_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
3777 pFormat);
3778 array_buffer_size(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
3779 TRUE /* fHasPointers */);
3783 /***********************************************************************
3784 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
3786 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
3787 PFORMAT_STRING pFormat )
3789 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3791 if (pFormat[0] != RPC_FC_CVARRAY)
3793 ERR("invalid format type %x\n", pFormat[0]);
3794 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3795 return pStubMsg->MemorySize;
3798 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
3799 array_memory_size(RPC_FC_CVARRAY, pStubMsg, pFormat,
3800 TRUE /* fHasPointers */);
3802 return pStubMsg->MemorySize;
3806 /***********************************************************************
3807 * NdrComplexArrayMarshall [RPCRT4.@]
3809 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3810 unsigned char *pMemory,
3811 PFORMAT_STRING pFormat)
3813 ULONG i, count, def;
3814 BOOL variance_present;
3815 unsigned char alignment;
3816 int pointer_buffer_mark_set = 0;
3818 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3820 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3822 ERR("invalid format type %x\n", pFormat[0]);
3823 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3824 return NULL;
3827 alignment = pFormat[1] + 1;
3829 if (!pStubMsg->PointerBufferMark)
3831 /* save buffer fields that may be changed by buffer sizer functions
3832 * and that may be needed later on */
3833 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3834 ULONG saved_buffer_length = pStubMsg->BufferLength;
3835 ULONG_PTR saved_max_count = pStubMsg->MaxCount;
3836 ULONG saved_offset = pStubMsg->Offset;
3837 ULONG saved_actual_count = pStubMsg->ActualCount;
3839 /* get the buffer pointer after complex array data, but before
3840 * pointer data */
3841 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
3842 pStubMsg->IgnoreEmbeddedPointers = 1;
3843 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3844 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3846 /* save it for use by embedded pointer code later */
3847 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
3848 TRACE("difference = 0x%x\n", pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer);
3849 pointer_buffer_mark_set = 1;
3851 /* restore fields */
3852 pStubMsg->ActualCount = saved_actual_count;
3853 pStubMsg->Offset = saved_offset;
3854 pStubMsg->MaxCount = saved_max_count;
3855 pStubMsg->BufferLength = saved_buffer_length;
3858 def = *(const WORD*)&pFormat[2];
3859 pFormat += 4;
3861 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3862 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3864 variance_present = IsConformanceOrVariancePresent(pFormat);
3865 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3866 TRACE("variance = %d\n", pStubMsg->ActualCount);
3868 WriteConformance(pStubMsg);
3869 if (variance_present)
3870 WriteVariance(pStubMsg);
3872 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3874 count = pStubMsg->ActualCount;
3875 for (i = 0; i < count; i++)
3876 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
3878 STD_OVERFLOW_CHECK(pStubMsg);
3880 if (pointer_buffer_mark_set)
3882 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3883 pStubMsg->PointerBufferMark = NULL;
3886 return NULL;
3889 /***********************************************************************
3890 * NdrComplexArrayUnmarshall [RPCRT4.@]
3892 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3893 unsigned char **ppMemory,
3894 PFORMAT_STRING pFormat,
3895 unsigned char fMustAlloc)
3897 ULONG i, count, size;
3898 unsigned char alignment;
3899 unsigned char *pMemory;
3900 unsigned char *saved_buffer;
3901 int pointer_buffer_mark_set = 0;
3902 int saved_ignore_embedded;
3904 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3906 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3908 ERR("invalid format type %x\n", pFormat[0]);
3909 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3910 return NULL;
3913 alignment = pFormat[1] + 1;
3915 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3916 /* save buffer pointer */
3917 saved_buffer = pStubMsg->Buffer;
3918 /* get the buffer pointer after complex array data, but before
3919 * pointer data */
3920 pStubMsg->IgnoreEmbeddedPointers = 1;
3921 pStubMsg->MemorySize = 0;
3922 NdrComplexArrayMemorySize(pStubMsg, pFormat);
3923 size = pStubMsg->MemorySize;
3924 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3926 TRACE("difference = 0x%x\n", pStubMsg->Buffer - saved_buffer);
3927 if (!pStubMsg->PointerBufferMark)
3929 /* save it for use by embedded pointer code later */
3930 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3931 pointer_buffer_mark_set = 1;
3933 /* restore the original buffer */
3934 pStubMsg->Buffer = saved_buffer;
3936 pFormat += 4;
3938 pFormat = ReadConformance(pStubMsg, pFormat);
3939 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3941 if (!fMustAlloc && !*ppMemory)
3942 fMustAlloc = TRUE;
3943 if (fMustAlloc)
3944 *ppMemory = NdrAllocate(pStubMsg, size);
3946 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3948 pMemory = *ppMemory;
3949 count = pStubMsg->ActualCount;
3950 for (i = 0; i < count; i++)
3951 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
3953 if (pointer_buffer_mark_set)
3955 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3956 pStubMsg->PointerBufferMark = NULL;
3959 return NULL;
3962 /***********************************************************************
3963 * NdrComplexArrayBufferSize [RPCRT4.@]
3965 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3966 unsigned char *pMemory,
3967 PFORMAT_STRING pFormat)
3969 ULONG i, count, def;
3970 unsigned char alignment;
3971 BOOL variance_present;
3972 int pointer_length_set = 0;
3974 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3976 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3978 ERR("invalid format type %x\n", pFormat[0]);
3979 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3980 return;
3983 alignment = pFormat[1] + 1;
3985 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3987 /* save buffer fields that may be changed by buffer sizer functions
3988 * and that may be needed later on */
3989 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3990 ULONG saved_buffer_length = pStubMsg->BufferLength;
3991 ULONG_PTR saved_max_count = pStubMsg->MaxCount;
3992 ULONG saved_offset = pStubMsg->Offset;
3993 ULONG saved_actual_count = pStubMsg->ActualCount;
3995 /* get the buffer pointer after complex array data, but before
3996 * pointer data */
3997 pStubMsg->IgnoreEmbeddedPointers = 1;
3998 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3999 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4001 /* save it for use by embedded pointer code later */
4002 pStubMsg->PointerLength = pStubMsg->BufferLength;
4003 pointer_length_set = 1;
4005 /* restore fields */
4006 pStubMsg->ActualCount = saved_actual_count;
4007 pStubMsg->Offset = saved_offset;
4008 pStubMsg->MaxCount = saved_max_count;
4009 pStubMsg->BufferLength = saved_buffer_length;
4011 def = *(const WORD*)&pFormat[2];
4012 pFormat += 4;
4014 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
4015 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
4016 SizeConformance(pStubMsg);
4018 variance_present = IsConformanceOrVariancePresent(pFormat);
4019 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4020 TRACE("variance = %d\n", pStubMsg->ActualCount);
4022 if (variance_present)
4023 SizeVariance(pStubMsg);
4025 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
4027 count = pStubMsg->ActualCount;
4028 for (i = 0; i < count; i++)
4029 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
4031 if(pointer_length_set)
4033 pStubMsg->BufferLength = pStubMsg->PointerLength;
4034 pStubMsg->PointerLength = 0;
4038 /***********************************************************************
4039 * NdrComplexArrayMemorySize [RPCRT4.@]
4041 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4042 PFORMAT_STRING pFormat)
4044 ULONG i, count, esize, SavedMemorySize, MemorySize;
4045 unsigned char alignment;
4047 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4049 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4051 ERR("invalid format type %x\n", pFormat[0]);
4052 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4053 return 0;
4056 alignment = pFormat[1] + 1;
4058 pFormat += 4;
4060 pFormat = ReadConformance(pStubMsg, pFormat);
4061 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
4063 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4065 SavedMemorySize = pStubMsg->MemorySize;
4067 esize = ComplexStructSize(pStubMsg, pFormat);
4069 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
4071 count = pStubMsg->ActualCount;
4072 for (i = 0; i < count; i++)
4073 ComplexStructMemorySize(pStubMsg, pFormat, NULL);
4075 pStubMsg->MemorySize = SavedMemorySize;
4077 pStubMsg->MemorySize += MemorySize;
4078 return MemorySize;
4081 /***********************************************************************
4082 * NdrComplexArrayFree [RPCRT4.@]
4084 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4085 unsigned char *pMemory,
4086 PFORMAT_STRING pFormat)
4088 ULONG i, count, def;
4090 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4092 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4094 ERR("invalid format type %x\n", pFormat[0]);
4095 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4096 return;
4099 def = *(const WORD*)&pFormat[2];
4100 pFormat += 4;
4102 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
4103 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
4105 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4106 TRACE("variance = %d\n", pStubMsg->ActualCount);
4108 count = pStubMsg->ActualCount;
4109 for (i = 0; i < count; i++)
4110 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
4113 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
4114 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
4115 USER_MARSHAL_CB *umcb)
4117 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
4118 pStubMsg->RpcMsg->DataRepresentation);
4119 umcb->pStubMsg = pStubMsg;
4120 umcb->pReserve = NULL;
4121 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
4122 umcb->CBType = cbtype;
4123 umcb->pFormat = pFormat;
4124 umcb->pTypeFormat = NULL /* FIXME */;
4127 #define USER_MARSHAL_PTR_PREFIX \
4128 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4129 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4131 /***********************************************************************
4132 * NdrUserMarshalMarshall [RPCRT4.@]
4134 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4135 unsigned char *pMemory,
4136 PFORMAT_STRING pFormat)
4138 unsigned flags = pFormat[1];
4139 unsigned index = *(const WORD*)&pFormat[2];
4140 unsigned char *saved_buffer = NULL;
4141 USER_MARSHAL_CB umcb;
4143 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4144 TRACE("index=%d\n", index);
4146 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
4148 if (flags & USER_MARSHAL_POINTER)
4150 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
4151 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
4152 pStubMsg->Buffer += 4;
4153 if (pStubMsg->PointerBufferMark)
4155 saved_buffer = pStubMsg->Buffer;
4156 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4157 pStubMsg->PointerBufferMark = NULL;
4159 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 8);
4161 else
4162 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, (flags & 0xf) + 1);
4164 pStubMsg->Buffer =
4165 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
4166 &umcb.Flags, pStubMsg->Buffer, pMemory);
4168 if (saved_buffer)
4170 STD_OVERFLOW_CHECK(pStubMsg);
4171 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4172 pStubMsg->Buffer = saved_buffer;
4175 STD_OVERFLOW_CHECK(pStubMsg);
4177 return NULL;
4180 /***********************************************************************
4181 * NdrUserMarshalUnmarshall [RPCRT4.@]
4183 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4184 unsigned char **ppMemory,
4185 PFORMAT_STRING pFormat,
4186 unsigned char fMustAlloc)
4188 unsigned flags = pFormat[1];
4189 unsigned index = *(const WORD*)&pFormat[2];
4190 DWORD memsize = *(const WORD*)&pFormat[4];
4191 unsigned char *saved_buffer = NULL;
4192 USER_MARSHAL_CB umcb;
4194 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4195 TRACE("index=%d\n", index);
4197 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
4199 if (flags & USER_MARSHAL_POINTER)
4201 ALIGN_POINTER(pStubMsg->Buffer, 4);
4202 /* skip pointer prefix */
4203 pStubMsg->Buffer += 4;
4204 if (pStubMsg->PointerBufferMark)
4206 saved_buffer = pStubMsg->Buffer;
4207 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4208 pStubMsg->PointerBufferMark = NULL;
4210 ALIGN_POINTER(pStubMsg->Buffer, 8);
4212 else
4213 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
4215 if (!fMustAlloc && !*ppMemory)
4216 fMustAlloc = TRUE;
4217 if (fMustAlloc)
4219 *ppMemory = NdrAllocate(pStubMsg, memsize);
4220 memset(*ppMemory, 0, memsize);
4223 pStubMsg->Buffer =
4224 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
4225 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
4227 if (saved_buffer)
4229 STD_OVERFLOW_CHECK(pStubMsg);
4230 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4231 pStubMsg->Buffer = saved_buffer;
4234 return NULL;
4237 /***********************************************************************
4238 * NdrUserMarshalBufferSize [RPCRT4.@]
4240 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4241 unsigned char *pMemory,
4242 PFORMAT_STRING pFormat)
4244 unsigned flags = pFormat[1];
4245 unsigned index = *(const WORD*)&pFormat[2];
4246 DWORD bufsize = *(const WORD*)&pFormat[6];
4247 USER_MARSHAL_CB umcb;
4248 ULONG saved_buffer_length = 0;
4250 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4251 TRACE("index=%d\n", index);
4253 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
4255 if (flags & USER_MARSHAL_POINTER)
4257 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
4258 /* skip pointer prefix */
4259 safe_buffer_length_increment(pStubMsg, 4);
4260 if (pStubMsg->IgnoreEmbeddedPointers)
4261 return;
4262 if (pStubMsg->PointerLength)
4264 saved_buffer_length = pStubMsg->BufferLength;
4265 pStubMsg->BufferLength = pStubMsg->PointerLength;
4266 pStubMsg->PointerLength = 0;
4268 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
4270 else
4271 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
4273 if (bufsize) {
4274 TRACE("size=%d\n", bufsize);
4275 safe_buffer_length_increment(pStubMsg, bufsize);
4277 else
4278 pStubMsg->BufferLength =
4279 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
4280 &umcb.Flags, pStubMsg->BufferLength, pMemory);
4282 if (saved_buffer_length)
4284 pStubMsg->PointerLength = pStubMsg->BufferLength;
4285 pStubMsg->BufferLength = saved_buffer_length;
4290 /***********************************************************************
4291 * NdrUserMarshalMemorySize [RPCRT4.@]
4293 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4294 PFORMAT_STRING pFormat)
4296 unsigned flags = pFormat[1];
4297 unsigned index = *(const WORD*)&pFormat[2];
4298 DWORD memsize = *(const WORD*)&pFormat[4];
4299 DWORD bufsize = *(const WORD*)&pFormat[6];
4301 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4302 TRACE("index=%d\n", index);
4304 pStubMsg->MemorySize += memsize;
4306 if (flags & USER_MARSHAL_POINTER)
4308 ALIGN_POINTER(pStubMsg->Buffer, 4);
4309 /* skip pointer prefix */
4310 pStubMsg->Buffer += 4;
4311 if (pStubMsg->IgnoreEmbeddedPointers)
4312 return pStubMsg->MemorySize;
4313 ALIGN_POINTER(pStubMsg->Buffer, 8);
4315 else
4316 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
4318 if (!bufsize)
4319 FIXME("not implemented for varying buffer size\n");
4321 pStubMsg->Buffer += bufsize;
4323 return pStubMsg->MemorySize;
4326 /***********************************************************************
4327 * NdrUserMarshalFree [RPCRT4.@]
4329 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
4330 unsigned char *pMemory,
4331 PFORMAT_STRING pFormat)
4333 /* unsigned flags = pFormat[1]; */
4334 unsigned index = *(const WORD*)&pFormat[2];
4335 USER_MARSHAL_CB umcb;
4337 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4338 TRACE("index=%d\n", index);
4340 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
4342 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
4343 &umcb.Flags, pMemory);
4346 /***********************************************************************
4347 * NdrGetUserMarshalInfo [RPCRT4.@]
4349 RPC_STATUS RPC_ENTRY NdrGetUserMarshalInfo(ULONG *flags, ULONG level, NDR_USER_MARSHAL_INFO *umi)
4351 USER_MARSHAL_CB *umcb = CONTAINING_RECORD(flags, USER_MARSHAL_CB, Flags);
4353 TRACE("(%p,%u,%p)\n", flags, level, umi);
4355 if (level != 1)
4356 return RPC_S_INVALID_ARG;
4358 memset(&umi->Level1, 0, sizeof(umi->Level1));
4359 umi->InformationLevel = level;
4361 if (umcb->Signature != USER_MARSHAL_CB_SIGNATURE)
4362 return RPC_S_INVALID_ARG;
4364 umi->Level1.pfnAllocate = umcb->pStubMsg->pfnAllocate;
4365 umi->Level1.pfnFree = umcb->pStubMsg->pfnFree;
4366 umi->Level1.pRpcChannelBuffer = umcb->pStubMsg->pRpcChannelBuffer;
4368 switch (umcb->CBType)
4370 case USER_MARSHAL_CB_MARSHALL:
4371 case USER_MARSHAL_CB_UNMARSHALL:
4373 RPC_MESSAGE *msg = umcb->pStubMsg->RpcMsg;
4374 unsigned char *buffer_start = msg->Buffer;
4375 unsigned char *buffer_end =
4376 (unsigned char *)msg->Buffer + msg->BufferLength;
4378 if (umcb->pStubMsg->Buffer < buffer_start ||
4379 umcb->pStubMsg->Buffer > buffer_end)
4380 return ERROR_INVALID_USER_BUFFER;
4382 umi->Level1.Buffer = umcb->pStubMsg->Buffer;
4383 umi->Level1.BufferSize = buffer_end - umcb->pStubMsg->Buffer;
4384 break;
4386 case USER_MARSHAL_CB_BUFFER_SIZE:
4387 case USER_MARSHAL_CB_FREE:
4388 break;
4389 default:
4390 WARN("unrecognised CBType %d\n", umcb->CBType);
4393 return RPC_S_OK;
4396 /***********************************************************************
4397 * NdrClearOutParameters [RPCRT4.@]
4399 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
4400 PFORMAT_STRING pFormat,
4401 void *ArgAddr)
4403 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
4406 /***********************************************************************
4407 * NdrConvert [RPCRT4.@]
4409 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
4411 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
4412 /* FIXME: since this stub doesn't do any converting, the proper behavior
4413 is to raise an exception */
4416 /***********************************************************************
4417 * NdrConvert2 [RPCRT4.@]
4419 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
4421 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4422 pStubMsg, pFormat, NumberParams);
4423 /* FIXME: since this stub doesn't do any converting, the proper behavior
4424 is to raise an exception */
4427 #include "pshpack1.h"
4428 typedef struct _NDR_CSTRUCT_FORMAT
4430 unsigned char type;
4431 unsigned char alignment;
4432 unsigned short memory_size;
4433 short offset_to_array_description;
4434 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
4435 #include "poppack.h"
4437 /***********************************************************************
4438 * NdrConformantStructMarshall [RPCRT4.@]
4440 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4441 unsigned char *pMemory,
4442 PFORMAT_STRING pFormat)
4444 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4445 PFORMAT_STRING pCArrayFormat;
4446 ULONG esize, bufsize;
4448 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4450 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4451 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4453 ERR("invalid format type %x\n", pCStructFormat->type);
4454 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4455 return NULL;
4458 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4459 pCStructFormat->offset_to_array_description;
4460 if (*pCArrayFormat != RPC_FC_CARRAY)
4462 ERR("invalid array format type %x\n", pCStructFormat->type);
4463 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4464 return NULL;
4466 esize = *(const WORD*)(pCArrayFormat+2);
4468 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4469 pCArrayFormat + 4, 0);
4471 WriteConformance(pStubMsg);
4473 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCStructFormat->alignment + 1);
4475 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4477 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4478 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4480 ERR("integer overflow of memory_size %u with bufsize %u\n",
4481 pCStructFormat->memory_size, bufsize);
4482 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4484 /* copy constant sized part of struct */
4485 pStubMsg->BufferMark = pStubMsg->Buffer;
4486 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
4488 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4489 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4491 return NULL;
4494 /***********************************************************************
4495 * NdrConformantStructUnmarshall [RPCRT4.@]
4497 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4498 unsigned char **ppMemory,
4499 PFORMAT_STRING pFormat,
4500 unsigned char fMustAlloc)
4502 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4503 PFORMAT_STRING pCArrayFormat;
4504 ULONG esize, bufsize;
4505 unsigned char *saved_buffer;
4507 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4509 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4510 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4512 ERR("invalid format type %x\n", pCStructFormat->type);
4513 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4514 return NULL;
4516 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4517 pCStructFormat->offset_to_array_description;
4518 if (*pCArrayFormat != RPC_FC_CARRAY)
4520 ERR("invalid array format type %x\n", pCStructFormat->type);
4521 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4522 return NULL;
4524 esize = *(const WORD*)(pCArrayFormat+2);
4526 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
4528 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
4530 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4532 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4533 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4535 ERR("integer overflow of memory_size %u with bufsize %u\n",
4536 pCStructFormat->memory_size, bufsize);
4537 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4540 if (fMustAlloc)
4542 SIZE_T size = pCStructFormat->memory_size + bufsize;
4543 *ppMemory = NdrAllocate(pStubMsg, size);
4545 else
4547 if (!pStubMsg->IsClient && !*ppMemory)
4548 /* for servers, we just point straight into the RPC buffer */
4549 *ppMemory = pStubMsg->Buffer;
4552 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4553 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
4554 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4555 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4557 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4558 if (*ppMemory != saved_buffer)
4559 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
4561 return NULL;
4564 /***********************************************************************
4565 * NdrConformantStructBufferSize [RPCRT4.@]
4567 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4568 unsigned char *pMemory,
4569 PFORMAT_STRING pFormat)
4571 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4572 PFORMAT_STRING pCArrayFormat;
4573 ULONG esize;
4575 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4577 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4578 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4580 ERR("invalid format type %x\n", pCStructFormat->type);
4581 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4582 return;
4584 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4585 pCStructFormat->offset_to_array_description;
4586 if (*pCArrayFormat != RPC_FC_CARRAY)
4588 ERR("invalid array format type %x\n", pCStructFormat->type);
4589 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4590 return;
4592 esize = *(const WORD*)(pCArrayFormat+2);
4594 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
4595 SizeConformance(pStubMsg);
4597 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
4599 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4601 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
4602 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4604 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4605 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4608 /***********************************************************************
4609 * NdrConformantStructMemorySize [RPCRT4.@]
4611 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4612 PFORMAT_STRING pFormat)
4614 FIXME("stub\n");
4615 return 0;
4618 /***********************************************************************
4619 * NdrConformantStructFree [RPCRT4.@]
4621 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4622 unsigned char *pMemory,
4623 PFORMAT_STRING pFormat)
4625 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4626 PFORMAT_STRING pCArrayFormat;
4628 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4630 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4631 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4633 ERR("invalid format type %x\n", pCStructFormat->type);
4634 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4635 return;
4638 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4639 pCStructFormat->offset_to_array_description;
4640 if (*pCArrayFormat != RPC_FC_CARRAY)
4642 ERR("invalid array format type %x\n", pCStructFormat->type);
4643 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4644 return;
4647 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4648 pCArrayFormat + 4, 0);
4650 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4652 /* copy constant sized part of struct */
4653 pStubMsg->BufferMark = pStubMsg->Buffer;
4655 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4656 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4659 /***********************************************************************
4660 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4662 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4663 unsigned char *pMemory,
4664 PFORMAT_STRING pFormat)
4666 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4667 PFORMAT_STRING pCVArrayFormat;
4669 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4671 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4672 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4674 ERR("invalid format type %x\n", pCVStructFormat->type);
4675 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4676 return NULL;
4679 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4680 pCVStructFormat->offset_to_array_description;
4682 array_compute_and_write_conformance(*pCVArrayFormat, pStubMsg,
4683 pMemory + pCVStructFormat->memory_size,
4684 pCVArrayFormat);
4686 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4688 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4690 /* write constant sized part */
4691 pStubMsg->BufferMark = pStubMsg->Buffer;
4692 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
4694 array_write_variance_and_marshall(*pCVArrayFormat, pStubMsg,
4695 pMemory + pCVStructFormat->memory_size,
4696 pCVArrayFormat, FALSE /* fHasPointers */);
4698 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4700 return NULL;
4703 /***********************************************************************
4704 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4706 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4707 unsigned char **ppMemory,
4708 PFORMAT_STRING pFormat,
4709 unsigned char fMustAlloc)
4711 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4712 PFORMAT_STRING pCVArrayFormat;
4713 ULONG memsize, bufsize;
4714 unsigned char *saved_buffer, *saved_array_buffer;
4715 ULONG offset;
4716 unsigned char *array_memory;
4718 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4720 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4721 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4723 ERR("invalid format type %x\n", pCVStructFormat->type);
4724 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4725 return NULL;
4728 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4729 pCVStructFormat->offset_to_array_description;
4731 memsize = array_read_conformance(*pCVArrayFormat, pStubMsg,
4732 pCVArrayFormat);
4734 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4736 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4738 /* work out how much memory to allocate if we need to do so */
4739 if (!fMustAlloc && !*ppMemory)
4740 fMustAlloc = TRUE;
4741 if (fMustAlloc)
4743 SIZE_T size = pCVStructFormat->memory_size + memsize;
4744 *ppMemory = NdrAllocate(pStubMsg, size);
4747 /* mark the start of the constant data */
4748 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4749 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4751 array_memory = *ppMemory + pCVStructFormat->memory_size;
4752 bufsize = array_read_variance_and_unmarshall(*pCVArrayFormat, pStubMsg,
4753 &array_memory, pCVArrayFormat,
4754 FALSE /* fMustAlloc */,
4755 FALSE /* fUseServerBufferMemory */,
4756 FALSE /* fUnmarshall */);
4758 /* save offset in case unmarshalling pointers changes it */
4759 offset = pStubMsg->Offset;
4761 /* mark the start of the array data */
4762 saved_array_buffer = pStubMsg->Buffer;
4763 safe_buffer_increment(pStubMsg, bufsize);
4765 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4767 /* copy the constant data */
4768 memcpy(*ppMemory, saved_buffer, pCVStructFormat->memory_size);
4769 /* copy the array data */
4770 TRACE("copying %p to %p\n", saved_array_buffer, *ppMemory + pCVStructFormat->memory_size);
4771 memcpy(*ppMemory + pCVStructFormat->memory_size + offset,
4772 saved_array_buffer, bufsize);
4774 if (*pCVArrayFormat == RPC_FC_C_CSTRING)
4775 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
4776 else if (*pCVArrayFormat == RPC_FC_C_WSTRING)
4777 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
4779 return NULL;
4782 /***********************************************************************
4783 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
4785 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4786 unsigned char *pMemory,
4787 PFORMAT_STRING pFormat)
4789 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4790 PFORMAT_STRING pCVArrayFormat;
4792 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4794 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4795 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4797 ERR("invalid format type %x\n", pCVStructFormat->type);
4798 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4799 return;
4802 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4803 pCVStructFormat->offset_to_array_description;
4804 array_compute_and_size_conformance(*pCVArrayFormat, pStubMsg,
4805 pMemory + pCVStructFormat->memory_size,
4806 pCVArrayFormat);
4808 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
4810 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4812 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
4814 array_buffer_size(*pCVArrayFormat, pStubMsg,
4815 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
4816 FALSE /* fHasPointers */);
4818 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4821 /***********************************************************************
4822 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4824 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4825 PFORMAT_STRING pFormat)
4827 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4828 PFORMAT_STRING pCVArrayFormat;
4830 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4832 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4833 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4835 ERR("invalid format type %x\n", pCVStructFormat->type);
4836 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4837 return 0;
4840 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4841 pCVStructFormat->offset_to_array_description;
4842 array_read_conformance(*pCVArrayFormat, pStubMsg, pCVArrayFormat);
4844 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4846 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4848 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4849 array_memory_size(*pCVArrayFormat, pStubMsg, pCVArrayFormat,
4850 FALSE /* fHasPointers */);
4852 pStubMsg->MemorySize += pCVStructFormat->memory_size;
4854 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4856 return pStubMsg->MemorySize;
4859 /***********************************************************************
4860 * NdrConformantVaryingStructFree [RPCRT4.@]
4862 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4863 unsigned char *pMemory,
4864 PFORMAT_STRING pFormat)
4866 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4867 PFORMAT_STRING pCVArrayFormat;
4869 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4871 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4872 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4874 ERR("invalid format type %x\n", pCVStructFormat->type);
4875 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4876 return;
4879 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4880 pCVStructFormat->offset_to_array_description;
4881 array_free(*pCVArrayFormat, pStubMsg,
4882 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
4883 FALSE /* fHasPointers */);
4885 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4887 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4890 #include "pshpack1.h"
4891 typedef struct
4893 unsigned char type;
4894 unsigned char alignment;
4895 unsigned short total_size;
4896 } NDR_SMFARRAY_FORMAT;
4898 typedef struct
4900 unsigned char type;
4901 unsigned char alignment;
4902 ULONG total_size;
4903 } NDR_LGFARRAY_FORMAT;
4904 #include "poppack.h"
4906 /***********************************************************************
4907 * NdrFixedArrayMarshall [RPCRT4.@]
4909 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4910 unsigned char *pMemory,
4911 PFORMAT_STRING pFormat)
4913 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4914 ULONG total_size;
4916 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4918 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4919 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4921 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4922 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4923 return NULL;
4926 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4928 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4930 total_size = pSmFArrayFormat->total_size;
4931 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4933 else
4935 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4936 total_size = pLgFArrayFormat->total_size;
4937 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4940 pStubMsg->BufferMark = pStubMsg->Buffer;
4941 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
4943 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4945 return NULL;
4948 /***********************************************************************
4949 * NdrFixedArrayUnmarshall [RPCRT4.@]
4951 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4952 unsigned char **ppMemory,
4953 PFORMAT_STRING pFormat,
4954 unsigned char fMustAlloc)
4956 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4957 ULONG total_size;
4958 unsigned char *saved_buffer;
4960 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4962 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4963 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4965 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4966 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4967 return NULL;
4970 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4972 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4974 total_size = pSmFArrayFormat->total_size;
4975 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4977 else
4979 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4980 total_size = pLgFArrayFormat->total_size;
4981 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4984 if (fMustAlloc)
4985 *ppMemory = NdrAllocate(pStubMsg, total_size);
4986 else
4988 if (!pStubMsg->IsClient && !*ppMemory)
4989 /* for servers, we just point straight into the RPC buffer */
4990 *ppMemory = pStubMsg->Buffer;
4993 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4994 safe_buffer_increment(pStubMsg, total_size);
4995 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4997 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4998 if (*ppMemory != saved_buffer)
4999 memcpy(*ppMemory, saved_buffer, total_size);
5001 return NULL;
5004 /***********************************************************************
5005 * NdrFixedArrayBufferSize [RPCRT4.@]
5007 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5008 unsigned char *pMemory,
5009 PFORMAT_STRING pFormat)
5011 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5012 ULONG total_size;
5014 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5016 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5017 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5019 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5020 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5021 return;
5024 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
5026 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5028 total_size = pSmFArrayFormat->total_size;
5029 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5031 else
5033 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5034 total_size = pLgFArrayFormat->total_size;
5035 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5037 safe_buffer_length_increment(pStubMsg, total_size);
5039 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5042 /***********************************************************************
5043 * NdrFixedArrayMemorySize [RPCRT4.@]
5045 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5046 PFORMAT_STRING pFormat)
5048 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5049 ULONG total_size;
5051 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5053 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5054 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5056 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5057 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5058 return 0;
5061 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5063 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5065 total_size = pSmFArrayFormat->total_size;
5066 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5068 else
5070 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5071 total_size = pLgFArrayFormat->total_size;
5072 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5074 pStubMsg->BufferMark = pStubMsg->Buffer;
5075 safe_buffer_increment(pStubMsg, total_size);
5076 pStubMsg->MemorySize += total_size;
5078 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5080 return total_size;
5083 /***********************************************************************
5084 * NdrFixedArrayFree [RPCRT4.@]
5086 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5087 unsigned char *pMemory,
5088 PFORMAT_STRING pFormat)
5090 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5092 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5094 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5095 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5097 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5098 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5099 return;
5102 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5103 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5104 else
5106 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5107 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5110 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5113 /***********************************************************************
5114 * NdrVaryingArrayMarshall [RPCRT4.@]
5116 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5117 unsigned char *pMemory,
5118 PFORMAT_STRING pFormat)
5120 unsigned char alignment;
5121 DWORD elements, esize;
5122 ULONG bufsize;
5124 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5126 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5127 (pFormat[0] != RPC_FC_LGVARRAY))
5129 ERR("invalid format type %x\n", pFormat[0]);
5130 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5131 return NULL;
5134 alignment = pFormat[1] + 1;
5136 if (pFormat[0] == RPC_FC_SMVARRAY)
5138 pFormat += 2;
5139 pFormat += sizeof(WORD);
5140 elements = *(const WORD*)pFormat;
5141 pFormat += sizeof(WORD);
5143 else
5145 pFormat += 2;
5146 pFormat += sizeof(DWORD);
5147 elements = *(const DWORD*)pFormat;
5148 pFormat += sizeof(DWORD);
5151 esize = *(const WORD*)pFormat;
5152 pFormat += sizeof(WORD);
5154 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5155 if ((pStubMsg->ActualCount > elements) ||
5156 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5158 RpcRaiseException(RPC_S_INVALID_BOUND);
5159 return NULL;
5162 WriteVariance(pStubMsg);
5164 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
5166 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5167 pStubMsg->BufferMark = pStubMsg->Buffer;
5168 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
5170 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5172 return NULL;
5175 /***********************************************************************
5176 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5178 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5179 unsigned char **ppMemory,
5180 PFORMAT_STRING pFormat,
5181 unsigned char fMustAlloc)
5183 unsigned char alignment;
5184 DWORD size, elements, esize;
5185 ULONG bufsize;
5186 unsigned char *saved_buffer;
5187 ULONG offset;
5189 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5191 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5192 (pFormat[0] != RPC_FC_LGVARRAY))
5194 ERR("invalid format type %x\n", pFormat[0]);
5195 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5196 return NULL;
5199 alignment = pFormat[1] + 1;
5201 if (pFormat[0] == RPC_FC_SMVARRAY)
5203 pFormat += 2;
5204 size = *(const WORD*)pFormat;
5205 pFormat += sizeof(WORD);
5206 elements = *(const WORD*)pFormat;
5207 pFormat += sizeof(WORD);
5209 else
5211 pFormat += 2;
5212 size = *(const DWORD*)pFormat;
5213 pFormat += sizeof(DWORD);
5214 elements = *(const DWORD*)pFormat;
5215 pFormat += sizeof(DWORD);
5218 esize = *(const WORD*)pFormat;
5219 pFormat += sizeof(WORD);
5221 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5223 ALIGN_POINTER(pStubMsg->Buffer, alignment);
5225 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5226 offset = pStubMsg->Offset;
5228 if (!fMustAlloc && !*ppMemory)
5229 fMustAlloc = TRUE;
5230 if (fMustAlloc)
5231 *ppMemory = NdrAllocate(pStubMsg, size);
5232 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5233 safe_buffer_increment(pStubMsg, bufsize);
5235 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5237 memcpy(*ppMemory + offset, saved_buffer, bufsize);
5239 return NULL;
5242 /***********************************************************************
5243 * NdrVaryingArrayBufferSize [RPCRT4.@]
5245 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5246 unsigned char *pMemory,
5247 PFORMAT_STRING pFormat)
5249 unsigned char alignment;
5250 DWORD elements, esize;
5252 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5254 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5255 (pFormat[0] != RPC_FC_LGVARRAY))
5257 ERR("invalid format type %x\n", pFormat[0]);
5258 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5259 return;
5262 alignment = pFormat[1] + 1;
5264 if (pFormat[0] == RPC_FC_SMVARRAY)
5266 pFormat += 2;
5267 pFormat += sizeof(WORD);
5268 elements = *(const WORD*)pFormat;
5269 pFormat += sizeof(WORD);
5271 else
5273 pFormat += 2;
5274 pFormat += sizeof(DWORD);
5275 elements = *(const DWORD*)pFormat;
5276 pFormat += sizeof(DWORD);
5279 esize = *(const WORD*)pFormat;
5280 pFormat += sizeof(WORD);
5282 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5283 if ((pStubMsg->ActualCount > elements) ||
5284 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5286 RpcRaiseException(RPC_S_INVALID_BOUND);
5287 return;
5290 SizeVariance(pStubMsg);
5292 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
5294 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5296 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5299 /***********************************************************************
5300 * NdrVaryingArrayMemorySize [RPCRT4.@]
5302 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5303 PFORMAT_STRING pFormat)
5305 unsigned char alignment;
5306 DWORD size, elements, esize;
5308 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5310 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5311 (pFormat[0] != RPC_FC_LGVARRAY))
5313 ERR("invalid format type %x\n", pFormat[0]);
5314 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5315 return 0;
5318 alignment = pFormat[1] + 1;
5320 if (pFormat[0] == RPC_FC_SMVARRAY)
5322 pFormat += 2;
5323 size = *(const WORD*)pFormat;
5324 pFormat += sizeof(WORD);
5325 elements = *(const WORD*)pFormat;
5326 pFormat += sizeof(WORD);
5328 else
5330 pFormat += 2;
5331 size = *(const DWORD*)pFormat;
5332 pFormat += sizeof(DWORD);
5333 elements = *(const DWORD*)pFormat;
5334 pFormat += sizeof(DWORD);
5337 esize = *(const WORD*)pFormat;
5338 pFormat += sizeof(WORD);
5340 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5342 ALIGN_POINTER(pStubMsg->Buffer, alignment);
5344 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5345 pStubMsg->MemorySize += size;
5347 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5349 return pStubMsg->MemorySize;
5352 /***********************************************************************
5353 * NdrVaryingArrayFree [RPCRT4.@]
5355 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5356 unsigned char *pMemory,
5357 PFORMAT_STRING pFormat)
5359 DWORD elements;
5361 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5363 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5364 (pFormat[0] != RPC_FC_LGVARRAY))
5366 ERR("invalid format type %x\n", pFormat[0]);
5367 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5368 return;
5371 if (pFormat[0] == RPC_FC_SMVARRAY)
5373 pFormat += 2;
5374 pFormat += sizeof(WORD);
5375 elements = *(const WORD*)pFormat;
5376 pFormat += sizeof(WORD);
5378 else
5380 pFormat += 2;
5381 pFormat += sizeof(DWORD);
5382 elements = *(const DWORD*)pFormat;
5383 pFormat += sizeof(DWORD);
5386 pFormat += sizeof(WORD);
5388 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5389 if ((pStubMsg->ActualCount > elements) ||
5390 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5392 RpcRaiseException(RPC_S_INVALID_BOUND);
5393 return;
5396 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5399 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
5401 switch (fc)
5403 case RPC_FC_BYTE:
5404 case RPC_FC_CHAR:
5405 case RPC_FC_SMALL:
5406 case RPC_FC_USMALL:
5407 return *pMemory;
5408 case RPC_FC_WCHAR:
5409 case RPC_FC_SHORT:
5410 case RPC_FC_USHORT:
5411 case RPC_FC_ENUM16:
5412 return *(const USHORT *)pMemory;
5413 case RPC_FC_LONG:
5414 case RPC_FC_ULONG:
5415 case RPC_FC_ENUM32:
5416 return *(const ULONG *)pMemory;
5417 default:
5418 FIXME("Unhandled base type: 0x%02x\n", fc);
5419 return 0;
5423 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
5424 ULONG discriminant,
5425 PFORMAT_STRING pFormat)
5427 unsigned short num_arms, arm, type;
5429 num_arms = *(const SHORT*)pFormat & 0x0fff;
5430 pFormat += 2;
5431 for(arm = 0; arm < num_arms; arm++)
5433 if(discriminant == *(const ULONG*)pFormat)
5435 pFormat += 4;
5436 break;
5438 pFormat += 6;
5441 type = *(const unsigned short*)pFormat;
5442 TRACE("type %04x\n", type);
5443 if(arm == num_arms) /* default arm extras */
5445 if(type == 0xffff)
5447 ERR("no arm for 0x%x and no default case\n", discriminant);
5448 RpcRaiseException(RPC_S_INVALID_TAG);
5449 return NULL;
5451 if(type == 0)
5453 TRACE("falling back to empty default case for 0x%x\n", discriminant);
5454 return NULL;
5457 return pFormat;
5460 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
5462 unsigned short type;
5464 pFormat += 2;
5466 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5467 if(!pFormat)
5468 return NULL;
5470 type = *(const unsigned short*)pFormat;
5471 if((type & 0xff00) == 0x8000)
5473 unsigned char basetype = LOBYTE(type);
5474 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
5476 else
5478 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5479 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
5480 if (m)
5482 unsigned char *saved_buffer = NULL;
5483 int pointer_buffer_mark_set = 0;
5484 switch(*desc)
5486 case RPC_FC_RP:
5487 case RPC_FC_UP:
5488 case RPC_FC_OP:
5489 case RPC_FC_FP:
5490 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
5491 saved_buffer = pStubMsg->Buffer;
5492 if (pStubMsg->PointerBufferMark)
5494 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5495 pStubMsg->PointerBufferMark = NULL;
5496 pointer_buffer_mark_set = 1;
5498 else
5499 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
5501 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
5502 if (pointer_buffer_mark_set)
5504 STD_OVERFLOW_CHECK(pStubMsg);
5505 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5506 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5508 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5509 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5510 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5512 pStubMsg->Buffer = saved_buffer + 4;
5514 break;
5515 default:
5516 m(pStubMsg, pMemory, desc);
5519 else FIXME("no marshaller for embedded type %02x\n", *desc);
5521 return NULL;
5524 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5525 unsigned char **ppMemory,
5526 ULONG discriminant,
5527 PFORMAT_STRING pFormat,
5528 unsigned char fMustAlloc)
5530 unsigned short type;
5532 pFormat += 2;
5534 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5535 if(!pFormat)
5536 return NULL;
5538 type = *(const unsigned short*)pFormat;
5539 if((type & 0xff00) == 0x8000)
5541 unsigned char basetype = LOBYTE(type);
5542 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
5544 else
5546 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5547 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
5548 if (m)
5550 unsigned char *saved_buffer = NULL;
5551 int pointer_buffer_mark_set = 0;
5552 switch(*desc)
5554 case RPC_FC_RP:
5555 case RPC_FC_UP:
5556 case RPC_FC_OP:
5557 case RPC_FC_FP:
5558 ALIGN_POINTER(pStubMsg->Buffer, 4);
5559 saved_buffer = pStubMsg->Buffer;
5560 if (pStubMsg->PointerBufferMark)
5562 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5563 pStubMsg->PointerBufferMark = NULL;
5564 pointer_buffer_mark_set = 1;
5566 else
5567 pStubMsg->Buffer += 4; /* for pointer ID */
5569 if (saved_buffer + 4 > pStubMsg->BufferEnd)
5571 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5572 saved_buffer, pStubMsg->BufferEnd);
5573 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5576 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
5577 if (pointer_buffer_mark_set)
5579 STD_OVERFLOW_CHECK(pStubMsg);
5580 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5581 pStubMsg->Buffer = saved_buffer + 4;
5583 break;
5584 default:
5585 m(pStubMsg, ppMemory, desc, fMustAlloc);
5588 else FIXME("no marshaller for embedded type %02x\n", *desc);
5590 return NULL;
5593 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
5594 unsigned char *pMemory,
5595 ULONG discriminant,
5596 PFORMAT_STRING pFormat)
5598 unsigned short type;
5600 pFormat += 2;
5602 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5603 if(!pFormat)
5604 return;
5606 type = *(const unsigned short*)pFormat;
5607 if((type & 0xff00) == 0x8000)
5609 unsigned char basetype = LOBYTE(type);
5610 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
5612 else
5614 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5615 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
5616 if (m)
5618 switch(*desc)
5620 case RPC_FC_RP:
5621 case RPC_FC_UP:
5622 case RPC_FC_OP:
5623 case RPC_FC_FP:
5624 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
5625 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
5626 if (!pStubMsg->IgnoreEmbeddedPointers)
5628 int saved_buffer_length = pStubMsg->BufferLength;
5629 pStubMsg->BufferLength = pStubMsg->PointerLength;
5630 pStubMsg->PointerLength = 0;
5631 if(!pStubMsg->BufferLength)
5632 ERR("BufferLength == 0??\n");
5633 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
5634 pStubMsg->PointerLength = pStubMsg->BufferLength;
5635 pStubMsg->BufferLength = saved_buffer_length;
5637 break;
5638 default:
5639 m(pStubMsg, pMemory, desc);
5642 else FIXME("no buffersizer for embedded type %02x\n", *desc);
5646 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
5647 ULONG discriminant,
5648 PFORMAT_STRING pFormat)
5650 unsigned short type, size;
5652 size = *(const unsigned short*)pFormat;
5653 pStubMsg->Memory += size;
5654 pFormat += 2;
5656 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5657 if(!pFormat)
5658 return 0;
5660 type = *(const unsigned short*)pFormat;
5661 if((type & 0xff00) == 0x8000)
5663 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
5665 else
5667 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5668 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
5669 unsigned char *saved_buffer;
5670 if (m)
5672 switch(*desc)
5674 case RPC_FC_RP:
5675 case RPC_FC_UP:
5676 case RPC_FC_OP:
5677 case RPC_FC_FP:
5678 ALIGN_POINTER(pStubMsg->Buffer, 4);
5679 saved_buffer = pStubMsg->Buffer;
5680 safe_buffer_increment(pStubMsg, 4);
5681 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
5682 pStubMsg->MemorySize += 4;
5683 if (!pStubMsg->IgnoreEmbeddedPointers)
5684 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
5685 break;
5686 default:
5687 return m(pStubMsg, desc);
5690 else FIXME("no marshaller for embedded type %02x\n", *desc);
5693 TRACE("size %d\n", size);
5694 return size;
5697 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
5698 unsigned char *pMemory,
5699 ULONG discriminant,
5700 PFORMAT_STRING pFormat)
5702 unsigned short type;
5704 pFormat += 2;
5706 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5707 if(!pFormat)
5708 return;
5710 type = *(const unsigned short*)pFormat;
5711 if((type & 0xff00) != 0x8000)
5713 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5714 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5715 if (m)
5717 switch(*desc)
5719 case RPC_FC_RP:
5720 case RPC_FC_UP:
5721 case RPC_FC_OP:
5722 case RPC_FC_FP:
5723 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5724 break;
5725 default:
5726 m(pStubMsg, pMemory, desc);
5732 /***********************************************************************
5733 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5735 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5736 unsigned char *pMemory,
5737 PFORMAT_STRING pFormat)
5739 unsigned char switch_type;
5740 unsigned char increment;
5741 ULONG switch_value;
5743 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5744 pFormat++;
5746 switch_type = *pFormat & 0xf;
5747 increment = (*pFormat & 0xf0) >> 4;
5748 pFormat++;
5750 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, increment);
5752 switch_value = get_discriminant(switch_type, pMemory);
5753 TRACE("got switch value 0x%x\n", switch_value);
5755 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5756 pMemory += increment;
5758 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5761 /***********************************************************************
5762 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5764 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5765 unsigned char **ppMemory,
5766 PFORMAT_STRING pFormat,
5767 unsigned char fMustAlloc)
5769 unsigned char switch_type;
5770 unsigned char increment;
5771 ULONG switch_value;
5772 unsigned short size;
5773 unsigned char *pMemoryArm;
5775 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5776 pFormat++;
5778 switch_type = *pFormat & 0xf;
5779 increment = (*pFormat & 0xf0) >> 4;
5780 pFormat++;
5782 ALIGN_POINTER(pStubMsg->Buffer, increment);
5783 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5784 TRACE("got switch value 0x%x\n", switch_value);
5786 size = *(const unsigned short*)pFormat + increment;
5787 if (!fMustAlloc && !*ppMemory)
5788 fMustAlloc = TRUE;
5789 if (fMustAlloc)
5790 *ppMemory = NdrAllocate(pStubMsg, size);
5792 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
5793 * since the arm is part of the memory block that is encompassed by
5794 * the whole union. Memory is forced to allocate when pointers
5795 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
5796 * clearing the memory we pass in to the unmarshaller */
5797 if (fMustAlloc)
5798 memset(*ppMemory, 0, size);
5800 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
5801 pMemoryArm = *ppMemory + increment;
5803 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, FALSE);
5806 /***********************************************************************
5807 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5809 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5810 unsigned char *pMemory,
5811 PFORMAT_STRING pFormat)
5813 unsigned char switch_type;
5814 unsigned char increment;
5815 ULONG switch_value;
5817 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5818 pFormat++;
5820 switch_type = *pFormat & 0xf;
5821 increment = (*pFormat & 0xf0) >> 4;
5822 pFormat++;
5824 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
5825 switch_value = get_discriminant(switch_type, pMemory);
5826 TRACE("got switch value 0x%x\n", switch_value);
5828 /* Add discriminant size */
5829 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
5830 pMemory += increment;
5832 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
5835 /***********************************************************************
5836 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5838 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5839 PFORMAT_STRING pFormat)
5841 unsigned char switch_type;
5842 unsigned char increment;
5843 ULONG switch_value;
5845 switch_type = *pFormat & 0xf;
5846 increment = (*pFormat & 0xf0) >> 4;
5847 pFormat++;
5849 ALIGN_POINTER(pStubMsg->Buffer, increment);
5850 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5851 TRACE("got switch value 0x%x\n", switch_value);
5853 pStubMsg->Memory += increment;
5855 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
5858 /***********************************************************************
5859 * NdrEncapsulatedUnionFree [RPCRT4.@]
5861 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5862 unsigned char *pMemory,
5863 PFORMAT_STRING pFormat)
5865 unsigned char switch_type;
5866 unsigned char increment;
5867 ULONG switch_value;
5869 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5870 pFormat++;
5872 switch_type = *pFormat & 0xf;
5873 increment = (*pFormat & 0xf0) >> 4;
5874 pFormat++;
5876 switch_value = get_discriminant(switch_type, pMemory);
5877 TRACE("got switch value 0x%x\n", switch_value);
5879 pMemory += increment;
5881 union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
5884 /***********************************************************************
5885 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5887 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5888 unsigned char *pMemory,
5889 PFORMAT_STRING pFormat)
5891 unsigned char switch_type;
5893 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5894 pFormat++;
5896 switch_type = *pFormat;
5897 pFormat++;
5899 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5900 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5901 /* Marshall discriminant */
5902 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5904 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5907 static LONG unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
5908 PFORMAT_STRING *ppFormat)
5910 LONG discriminant = 0;
5912 switch(**ppFormat)
5914 case RPC_FC_BYTE:
5915 case RPC_FC_CHAR:
5916 case RPC_FC_SMALL:
5917 case RPC_FC_USMALL:
5919 UCHAR d;
5920 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5921 discriminant = d;
5922 break;
5924 case RPC_FC_WCHAR:
5925 case RPC_FC_SHORT:
5926 case RPC_FC_USHORT:
5928 USHORT d;
5929 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5930 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5931 discriminant = d;
5932 break;
5934 case RPC_FC_LONG:
5935 case RPC_FC_ULONG:
5937 ULONG d;
5938 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5939 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5940 discriminant = d;
5941 break;
5943 default:
5944 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
5946 (*ppFormat)++;
5948 if (pStubMsg->fHasNewCorrDesc)
5949 *ppFormat += 6;
5950 else
5951 *ppFormat += 4;
5952 return discriminant;
5955 /**********************************************************************
5956 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5958 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5959 unsigned char **ppMemory,
5960 PFORMAT_STRING pFormat,
5961 unsigned char fMustAlloc)
5963 LONG discriminant;
5964 unsigned short size;
5966 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5967 pFormat++;
5969 /* Unmarshall discriminant */
5970 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5971 TRACE("unmarshalled discriminant %x\n", discriminant);
5973 pFormat += *(const SHORT*)pFormat;
5975 size = *(const unsigned short*)pFormat;
5977 if (!fMustAlloc && !*ppMemory)
5978 fMustAlloc = TRUE;
5979 if (fMustAlloc)
5980 *ppMemory = NdrAllocate(pStubMsg, size);
5982 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
5983 * since the arm is part of the memory block that is encompassed by
5984 * the whole union. Memory is forced to allocate when pointers
5985 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
5986 * clearing the memory we pass in to the unmarshaller */
5987 if (fMustAlloc)
5988 memset(*ppMemory, 0, size);
5990 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, FALSE);
5993 /***********************************************************************
5994 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
5996 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5997 unsigned char *pMemory,
5998 PFORMAT_STRING pFormat)
6000 unsigned char switch_type;
6002 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6003 pFormat++;
6005 switch_type = *pFormat;
6006 pFormat++;
6008 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6009 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6010 /* Add discriminant size */
6011 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
6013 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6016 /***********************************************************************
6017 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
6019 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6020 PFORMAT_STRING pFormat)
6022 ULONG discriminant;
6024 pFormat++;
6025 /* Unmarshall discriminant */
6026 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6027 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
6029 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
6032 /***********************************************************************
6033 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6035 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
6036 unsigned char *pMemory,
6037 PFORMAT_STRING pFormat)
6039 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6040 pFormat++;
6041 pFormat++;
6043 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6044 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6046 union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6049 /***********************************************************************
6050 * NdrByteCountPointerMarshall [RPCRT4.@]
6052 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6053 unsigned char *pMemory,
6054 PFORMAT_STRING pFormat)
6056 FIXME("stub\n");
6057 return NULL;
6060 /***********************************************************************
6061 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6063 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6064 unsigned char **ppMemory,
6065 PFORMAT_STRING pFormat,
6066 unsigned char fMustAlloc)
6068 FIXME("stub\n");
6069 return NULL;
6072 /***********************************************************************
6073 * NdrByteCountPointerBufferSize [RPCRT4.@]
6075 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6076 unsigned char *pMemory,
6077 PFORMAT_STRING pFormat)
6079 FIXME("stub\n");
6082 /***********************************************************************
6083 * NdrByteCountPointerMemorySize [internal]
6085 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6086 PFORMAT_STRING pFormat)
6088 FIXME("stub\n");
6089 return 0;
6092 /***********************************************************************
6093 * NdrByteCountPointerFree [RPCRT4.@]
6095 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
6096 unsigned char *pMemory,
6097 PFORMAT_STRING pFormat)
6099 FIXME("stub\n");
6102 /***********************************************************************
6103 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6105 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6106 unsigned char *pMemory,
6107 PFORMAT_STRING pFormat)
6109 FIXME("stub\n");
6110 return NULL;
6113 /***********************************************************************
6114 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6116 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6117 unsigned char **ppMemory,
6118 PFORMAT_STRING pFormat,
6119 unsigned char fMustAlloc)
6121 FIXME("stub\n");
6122 return NULL;
6125 /***********************************************************************
6126 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6128 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6129 unsigned char *pMemory,
6130 PFORMAT_STRING pFormat)
6132 FIXME("stub\n");
6135 /***********************************************************************
6136 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6138 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6139 PFORMAT_STRING pFormat)
6141 FIXME("stub\n");
6142 return 0;
6145 /***********************************************************************
6146 * NdrXmitOrRepAsFree [RPCRT4.@]
6148 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
6149 unsigned char *pMemory,
6150 PFORMAT_STRING pFormat)
6152 FIXME("stub\n");
6155 /***********************************************************************
6156 * NdrRangeMarshall [internal]
6158 static unsigned char *WINAPI NdrRangeMarshall(
6159 PMIDL_STUB_MESSAGE pStubMsg,
6160 unsigned char *pMemory,
6161 PFORMAT_STRING pFormat)
6163 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6164 unsigned char base_type;
6166 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6168 if (pRange->type != RPC_FC_RANGE)
6170 ERR("invalid format type %x\n", pRange->type);
6171 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6172 return NULL;
6175 base_type = pRange->flags_type & 0xf;
6177 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
6180 /***********************************************************************
6181 * NdrRangeUnmarshall [RPCRT4.@]
6183 unsigned char *WINAPI NdrRangeUnmarshall(
6184 PMIDL_STUB_MESSAGE pStubMsg,
6185 unsigned char **ppMemory,
6186 PFORMAT_STRING pFormat,
6187 unsigned char fMustAlloc)
6189 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6190 unsigned char base_type;
6192 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6194 if (pRange->type != RPC_FC_RANGE)
6196 ERR("invalid format type %x\n", pRange->type);
6197 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6198 return NULL;
6200 base_type = pRange->flags_type & 0xf;
6202 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6203 base_type, pRange->low_value, pRange->high_value);
6205 #define RANGE_UNMARSHALL(mem_type, wire_type, format_spec) \
6206 do \
6208 ALIGN_POINTER(pStubMsg->Buffer, sizeof(wire_type)); \
6209 if (!fMustAlloc && !*ppMemory) \
6210 fMustAlloc = TRUE; \
6211 if (fMustAlloc) \
6212 *ppMemory = NdrAllocate(pStubMsg, sizeof(mem_type)); \
6213 if (pStubMsg->Buffer + sizeof(wire_type) > pStubMsg->BufferEnd) \
6215 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6216 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6217 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6219 if ((*(wire_type *)pStubMsg->Buffer < (mem_type)pRange->low_value) || \
6220 (*(wire_type *)pStubMsg->Buffer > (mem_type)pRange->high_value)) \
6222 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6223 *(wire_type *)pStubMsg->Buffer, (mem_type)pRange->low_value, \
6224 (mem_type)pRange->high_value); \
6225 RpcRaiseException(RPC_S_INVALID_BOUND); \
6226 return NULL; \
6228 TRACE("*ppMemory: %p\n", *ppMemory); \
6229 **(mem_type **)ppMemory = *(wire_type *)pStubMsg->Buffer; \
6230 pStubMsg->Buffer += sizeof(wire_type); \
6231 } while (0)
6233 switch(base_type)
6235 case RPC_FC_CHAR:
6236 case RPC_FC_SMALL:
6237 RANGE_UNMARSHALL(UCHAR, UCHAR, "%d");
6238 TRACE("value: 0x%02x\n", **ppMemory);
6239 break;
6240 case RPC_FC_BYTE:
6241 case RPC_FC_USMALL:
6242 RANGE_UNMARSHALL(CHAR, CHAR, "%u");
6243 TRACE("value: 0x%02x\n", **ppMemory);
6244 break;
6245 case RPC_FC_WCHAR: /* FIXME: valid? */
6246 case RPC_FC_USHORT:
6247 RANGE_UNMARSHALL(USHORT, USHORT, "%u");
6248 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6249 break;
6250 case RPC_FC_SHORT:
6251 RANGE_UNMARSHALL(SHORT, SHORT, "%d");
6252 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6253 break;
6254 case RPC_FC_LONG:
6255 case RPC_FC_ENUM32:
6256 RANGE_UNMARSHALL(LONG, LONG, "%d");
6257 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6258 break;
6259 case RPC_FC_ULONG:
6260 RANGE_UNMARSHALL(ULONG, ULONG, "%u");
6261 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6262 break;
6263 case RPC_FC_ENUM16:
6264 RANGE_UNMARSHALL(UINT, USHORT, "%u");
6265 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6266 break;
6267 case RPC_FC_FLOAT:
6268 case RPC_FC_DOUBLE:
6269 case RPC_FC_HYPER:
6270 default:
6271 ERR("invalid range base type: 0x%02x\n", base_type);
6272 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6275 return NULL;
6278 /***********************************************************************
6279 * NdrRangeBufferSize [internal]
6281 static void WINAPI NdrRangeBufferSize(
6282 PMIDL_STUB_MESSAGE pStubMsg,
6283 unsigned char *pMemory,
6284 PFORMAT_STRING pFormat)
6286 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6287 unsigned char base_type;
6289 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6291 if (pRange->type != RPC_FC_RANGE)
6293 ERR("invalid format type %x\n", pRange->type);
6294 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6296 base_type = pRange->flags_type & 0xf;
6298 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
6301 /***********************************************************************
6302 * NdrRangeMemorySize [internal]
6304 static ULONG WINAPI NdrRangeMemorySize(
6305 PMIDL_STUB_MESSAGE pStubMsg,
6306 PFORMAT_STRING pFormat)
6308 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6309 unsigned char base_type;
6311 if (pRange->type != RPC_FC_RANGE)
6313 ERR("invalid format type %x\n", pRange->type);
6314 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6315 return 0;
6317 base_type = pRange->flags_type & 0xf;
6319 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
6322 /***********************************************************************
6323 * NdrRangeFree [internal]
6325 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
6326 unsigned char *pMemory,
6327 PFORMAT_STRING pFormat)
6329 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6331 /* nothing to do */
6334 /***********************************************************************
6335 * NdrBaseTypeMarshall [internal]
6337 static unsigned char *WINAPI NdrBaseTypeMarshall(
6338 PMIDL_STUB_MESSAGE pStubMsg,
6339 unsigned char *pMemory,
6340 PFORMAT_STRING pFormat)
6342 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6344 switch(*pFormat)
6346 case RPC_FC_BYTE:
6347 case RPC_FC_CHAR:
6348 case RPC_FC_SMALL:
6349 case RPC_FC_USMALL:
6350 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
6351 TRACE("value: 0x%02x\n", *pMemory);
6352 break;
6353 case RPC_FC_WCHAR:
6354 case RPC_FC_SHORT:
6355 case RPC_FC_USHORT:
6356 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
6357 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
6358 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
6359 break;
6360 case RPC_FC_LONG:
6361 case RPC_FC_ULONG:
6362 case RPC_FC_ERROR_STATUS_T:
6363 case RPC_FC_ENUM32:
6364 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONG));
6365 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
6366 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
6367 break;
6368 case RPC_FC_FLOAT:
6369 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(float));
6370 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
6371 break;
6372 case RPC_FC_DOUBLE:
6373 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(double));
6374 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
6375 break;
6376 case RPC_FC_HYPER:
6377 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONGLONG));
6378 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
6379 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
6380 break;
6381 case RPC_FC_ENUM16:
6382 /* only 16-bits on the wire, so do a sanity check */
6383 if (*(UINT *)pMemory > SHRT_MAX)
6384 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
6385 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
6386 if (pStubMsg->Buffer + sizeof(USHORT) > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6387 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6388 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
6389 pStubMsg->Buffer += sizeof(USHORT);
6390 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
6391 break;
6392 case RPC_FC_IGNORE:
6393 break;
6394 default:
6395 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6398 /* FIXME: what is the correct return value? */
6399 return NULL;
6402 /***********************************************************************
6403 * NdrBaseTypeUnmarshall [internal]
6405 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
6406 PMIDL_STUB_MESSAGE pStubMsg,
6407 unsigned char **ppMemory,
6408 PFORMAT_STRING pFormat,
6409 unsigned char fMustAlloc)
6411 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6413 #define BASE_TYPE_UNMARSHALL(type) \
6414 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6415 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6417 *ppMemory = pStubMsg->Buffer; \
6418 TRACE("*ppMemory: %p\n", *ppMemory); \
6419 safe_buffer_increment(pStubMsg, sizeof(type)); \
6421 else \
6423 if (fMustAlloc) \
6424 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6425 TRACE("*ppMemory: %p\n", *ppMemory); \
6426 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6429 switch(*pFormat)
6431 case RPC_FC_BYTE:
6432 case RPC_FC_CHAR:
6433 case RPC_FC_SMALL:
6434 case RPC_FC_USMALL:
6435 BASE_TYPE_UNMARSHALL(UCHAR);
6436 TRACE("value: 0x%02x\n", **ppMemory);
6437 break;
6438 case RPC_FC_WCHAR:
6439 case RPC_FC_SHORT:
6440 case RPC_FC_USHORT:
6441 BASE_TYPE_UNMARSHALL(USHORT);
6442 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6443 break;
6444 case RPC_FC_LONG:
6445 case RPC_FC_ULONG:
6446 case RPC_FC_ERROR_STATUS_T:
6447 case RPC_FC_ENUM32:
6448 BASE_TYPE_UNMARSHALL(ULONG);
6449 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6450 break;
6451 case RPC_FC_FLOAT:
6452 BASE_TYPE_UNMARSHALL(float);
6453 TRACE("value: %f\n", **(float **)ppMemory);
6454 break;
6455 case RPC_FC_DOUBLE:
6456 BASE_TYPE_UNMARSHALL(double);
6457 TRACE("value: %f\n", **(double **)ppMemory);
6458 break;
6459 case RPC_FC_HYPER:
6460 BASE_TYPE_UNMARSHALL(ULONGLONG);
6461 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
6462 break;
6463 case RPC_FC_ENUM16:
6464 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
6465 if (!fMustAlloc && !*ppMemory)
6466 fMustAlloc = TRUE;
6467 if (fMustAlloc)
6468 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
6469 if (pStubMsg->Buffer + sizeof(USHORT) > pStubMsg->BufferEnd)
6470 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6471 TRACE("*ppMemory: %p\n", *ppMemory);
6472 /* 16-bits on the wire, but int in memory */
6473 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
6474 pStubMsg->Buffer += sizeof(USHORT);
6475 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6476 break;
6477 case RPC_FC_IGNORE:
6478 break;
6479 default:
6480 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6482 #undef BASE_TYPE_UNMARSHALL
6484 /* FIXME: what is the correct return value? */
6486 return NULL;
6489 /***********************************************************************
6490 * NdrBaseTypeBufferSize [internal]
6492 static void WINAPI NdrBaseTypeBufferSize(
6493 PMIDL_STUB_MESSAGE pStubMsg,
6494 unsigned char *pMemory,
6495 PFORMAT_STRING pFormat)
6497 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6499 switch(*pFormat)
6501 case RPC_FC_BYTE:
6502 case RPC_FC_CHAR:
6503 case RPC_FC_SMALL:
6504 case RPC_FC_USMALL:
6505 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6506 break;
6507 case RPC_FC_WCHAR:
6508 case RPC_FC_SHORT:
6509 case RPC_FC_USHORT:
6510 case RPC_FC_ENUM16:
6511 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
6512 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6513 break;
6514 case RPC_FC_LONG:
6515 case RPC_FC_ULONG:
6516 case RPC_FC_ENUM32:
6517 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
6518 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6519 break;
6520 case RPC_FC_FLOAT:
6521 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
6522 safe_buffer_length_increment(pStubMsg, sizeof(float));
6523 break;
6524 case RPC_FC_DOUBLE:
6525 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
6526 safe_buffer_length_increment(pStubMsg, sizeof(double));
6527 break;
6528 case RPC_FC_HYPER:
6529 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
6530 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6531 break;
6532 case RPC_FC_ERROR_STATUS_T:
6533 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
6534 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6535 break;
6536 case RPC_FC_IGNORE:
6537 break;
6538 default:
6539 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6543 /***********************************************************************
6544 * NdrBaseTypeMemorySize [internal]
6546 static ULONG WINAPI NdrBaseTypeMemorySize(
6547 PMIDL_STUB_MESSAGE pStubMsg,
6548 PFORMAT_STRING pFormat)
6550 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6552 switch(*pFormat)
6554 case RPC_FC_BYTE:
6555 case RPC_FC_CHAR:
6556 case RPC_FC_SMALL:
6557 case RPC_FC_USMALL:
6558 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6559 pStubMsg->MemorySize += sizeof(UCHAR);
6560 return sizeof(UCHAR);
6561 case RPC_FC_WCHAR:
6562 case RPC_FC_SHORT:
6563 case RPC_FC_USHORT:
6564 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6565 pStubMsg->MemorySize += sizeof(USHORT);
6566 return sizeof(USHORT);
6567 case RPC_FC_LONG:
6568 case RPC_FC_ULONG:
6569 case RPC_FC_ENUM32:
6570 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6571 pStubMsg->MemorySize += sizeof(ULONG);
6572 return sizeof(ULONG);
6573 case RPC_FC_FLOAT:
6574 safe_buffer_increment(pStubMsg, sizeof(float));
6575 pStubMsg->MemorySize += sizeof(float);
6576 return sizeof(float);
6577 case RPC_FC_DOUBLE:
6578 safe_buffer_increment(pStubMsg, sizeof(double));
6579 pStubMsg->MemorySize += sizeof(double);
6580 return sizeof(double);
6581 case RPC_FC_HYPER:
6582 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6583 pStubMsg->MemorySize += sizeof(ULONGLONG);
6584 return sizeof(ULONGLONG);
6585 case RPC_FC_ERROR_STATUS_T:
6586 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6587 pStubMsg->MemorySize += sizeof(error_status_t);
6588 return sizeof(error_status_t);
6589 case RPC_FC_ENUM16:
6590 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6591 pStubMsg->MemorySize += sizeof(UINT);
6592 return sizeof(UINT);
6593 case RPC_FC_IGNORE:
6594 pStubMsg->MemorySize += sizeof(void *);
6595 return sizeof(void *);
6596 default:
6597 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6598 return 0;
6602 /***********************************************************************
6603 * NdrBaseTypeFree [internal]
6605 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6606 unsigned char *pMemory,
6607 PFORMAT_STRING pFormat)
6609 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6611 /* nothing to do */
6614 /***********************************************************************
6615 * NdrContextHandleBufferSize [internal]
6617 static void WINAPI NdrContextHandleBufferSize(
6618 PMIDL_STUB_MESSAGE pStubMsg,
6619 unsigned char *pMemory,
6620 PFORMAT_STRING pFormat)
6622 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6624 if (*pFormat != RPC_FC_BIND_CONTEXT)
6626 ERR("invalid format type %x\n", *pFormat);
6627 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6629 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
6630 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6633 /***********************************************************************
6634 * NdrContextHandleMarshall [internal]
6636 static unsigned char *WINAPI NdrContextHandleMarshall(
6637 PMIDL_STUB_MESSAGE pStubMsg,
6638 unsigned char *pMemory,
6639 PFORMAT_STRING pFormat)
6641 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6643 if (*pFormat != RPC_FC_BIND_CONTEXT)
6645 ERR("invalid format type %x\n", *pFormat);
6646 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6648 TRACE("flags: 0x%02x\n", pFormat[1]);
6650 if (pFormat[1] & 0x80)
6651 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
6652 else
6653 NdrClientContextMarshall(pStubMsg, pMemory, FALSE);
6655 return NULL;
6658 /***********************************************************************
6659 * NdrContextHandleUnmarshall [internal]
6661 static unsigned char *WINAPI NdrContextHandleUnmarshall(
6662 PMIDL_STUB_MESSAGE pStubMsg,
6663 unsigned char **ppMemory,
6664 PFORMAT_STRING pFormat,
6665 unsigned char fMustAlloc)
6667 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg,
6668 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE");
6670 if (*pFormat != RPC_FC_BIND_CONTEXT)
6672 ERR("invalid format type %x\n", *pFormat);
6673 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6675 TRACE("flags: 0x%02x\n", pFormat[1]);
6677 /* [out]-only or [ret] param */
6678 if ((pFormat[1] & 0x60) == 0x20)
6679 **(NDR_CCONTEXT **)ppMemory = NULL;
6680 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
6682 return NULL;
6685 /***********************************************************************
6686 * NdrClientContextMarshall [RPCRT4.@]
6688 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6689 NDR_CCONTEXT ContextHandle,
6690 int fCheck)
6692 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
6694 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
6696 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6698 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6699 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6700 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6703 /* FIXME: what does fCheck do? */
6704 NDRCContextMarshall(ContextHandle,
6705 pStubMsg->Buffer);
6707 pStubMsg->Buffer += cbNDRContext;
6710 /***********************************************************************
6711 * NdrClientContextUnmarshall [RPCRT4.@]
6713 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6714 NDR_CCONTEXT * pContextHandle,
6715 RPC_BINDING_HANDLE BindHandle)
6717 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
6719 ALIGN_POINTER(pStubMsg->Buffer, 4);
6721 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
6722 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6724 NDRCContextUnmarshall(pContextHandle,
6725 BindHandle,
6726 pStubMsg->Buffer,
6727 pStubMsg->RpcMsg->DataRepresentation);
6729 pStubMsg->Buffer += cbNDRContext;
6732 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6733 NDR_SCONTEXT ContextHandle,
6734 NDR_RUNDOWN RundownRoutine )
6736 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
6738 ALIGN_POINTER(pStubMsg->Buffer, 4);
6740 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6742 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6743 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6744 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6747 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6748 pStubMsg->Buffer, RundownRoutine, NULL,
6749 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6750 pStubMsg->Buffer += cbNDRContext;
6753 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
6755 NDR_SCONTEXT ContextHandle;
6757 TRACE("(%p)\n", pStubMsg);
6759 ALIGN_POINTER(pStubMsg->Buffer, 4);
6761 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6763 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6764 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6765 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6768 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6769 pStubMsg->Buffer,
6770 pStubMsg->RpcMsg->DataRepresentation,
6771 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6772 pStubMsg->Buffer += cbNDRContext;
6774 return ContextHandle;
6777 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
6778 unsigned char* pMemory,
6779 PFORMAT_STRING pFormat)
6781 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
6784 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
6785 PFORMAT_STRING pFormat)
6787 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6788 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6790 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6792 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6793 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6794 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6795 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6796 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6798 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6799 if_id = &sif->InterfaceId;
6802 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
6803 pStubMsg->RpcMsg->DataRepresentation, if_id,
6804 flags);
6807 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6808 NDR_SCONTEXT ContextHandle,
6809 NDR_RUNDOWN RundownRoutine,
6810 PFORMAT_STRING pFormat)
6812 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6813 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6815 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
6817 ALIGN_POINTER(pStubMsg->Buffer, 4);
6819 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6821 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6822 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6823 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6826 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6827 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6828 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6829 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6830 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6832 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6833 if_id = &sif->InterfaceId;
6836 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6837 pStubMsg->Buffer, RundownRoutine, if_id, flags);
6838 pStubMsg->Buffer += cbNDRContext;
6841 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6842 PFORMAT_STRING pFormat)
6844 NDR_SCONTEXT ContextHandle;
6845 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6846 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6848 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6850 ALIGN_POINTER(pStubMsg->Buffer, 4);
6852 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6854 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6855 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6856 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6859 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6860 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6861 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6862 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6863 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6865 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6866 if_id = &sif->InterfaceId;
6869 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6870 pStubMsg->Buffer,
6871 pStubMsg->RpcMsg->DataRepresentation,
6872 if_id, flags);
6873 pStubMsg->Buffer += cbNDRContext;
6875 return ContextHandle;
6878 /***********************************************************************
6879 * NdrCorrelationInitialize [RPCRT4.@]
6881 * Initializes correlation validity checking.
6883 * PARAMS
6884 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6885 * pMemory [I] Pointer to memory to use as a cache.
6886 * CacheSize [I] Size of the memory pointed to by pMemory.
6887 * Flags [I] Reserved. Set to zero.
6889 * RETURNS
6890 * Nothing.
6892 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
6894 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg, pMemory, CacheSize, Flags);
6895 pStubMsg->fHasNewCorrDesc = TRUE;
6898 /***********************************************************************
6899 * NdrCorrelationPass [RPCRT4.@]
6901 * Performs correlation validity checking.
6903 * PARAMS
6904 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6906 * RETURNS
6907 * Nothing.
6909 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
6911 FIXME("(%p): stub\n", pStubMsg);
6914 /***********************************************************************
6915 * NdrCorrelationFree [RPCRT4.@]
6917 * Frees any resources used while unmarshalling parameters that need
6918 * correlation validity checking.
6920 * PARAMS
6921 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6923 * RETURNS
6924 * Nothing.
6926 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
6928 FIXME("(%p): stub\n", pStubMsg);