push 0a0aa53cd365a71ca6121b6df157ca635450378f
[wine/hacks.git] / dlls / rpcrt4 / ndr_marshall.c
blob0d12843d750d785fbf3a536942e9ab31353cb2aa
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", (ULONG)(_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", (ULONG)(_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 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(void*));
1046 pStubMsg->MemorySize += sizeof(void*);
1047 TRACE("deref\n");
1050 if (pointer_needs_sizing) {
1051 m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
1052 if (m) m(pStubMsg, desc);
1053 else FIXME("no memorysizer for data type=%02x\n", *desc);
1056 return pStubMsg->MemorySize;
1059 /***********************************************************************
1060 * PointerFree [internal]
1062 static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1063 unsigned char *Pointer,
1064 PFORMAT_STRING pFormat)
1066 unsigned type = pFormat[0], attr = pFormat[1];
1067 PFORMAT_STRING desc;
1068 NDR_FREE m;
1069 unsigned char *current_pointer = Pointer;
1071 TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
1072 TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
1073 if (attr & RPC_FC_P_DONTFREE) return;
1074 pFormat += 2;
1075 if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
1076 else desc = pFormat + *(const SHORT*)pFormat;
1078 if (!Pointer) return;
1080 if (type == RPC_FC_FP) {
1081 int pointer_needs_freeing = NdrFullPointerFree(
1082 pStubMsg->FullPtrXlatTables, Pointer);
1083 if (!pointer_needs_freeing)
1084 return;
1087 if (attr & RPC_FC_P_DEREF) {
1088 current_pointer = *(unsigned char**)Pointer;
1089 TRACE("deref => %p\n", current_pointer);
1092 m = NdrFreer[*desc & NDR_TABLE_MASK];
1093 if (m) m(pStubMsg, current_pointer, desc);
1095 /* this check stops us from trying to free buffer memory. we don't have to
1096 * worry about clients, since they won't call this function.
1097 * we don't have to check for the buffer being reallocated because
1098 * BufferStart and BufferEnd won't be reset when allocating memory for
1099 * sending the response. we don't have to check for the new buffer here as
1100 * it won't be used a type memory, only for buffer memory */
1101 if (Pointer >= pStubMsg->BufferStart && Pointer < pStubMsg->BufferEnd)
1102 goto notfree;
1104 if (attr & RPC_FC_P_ONSTACK) {
1105 TRACE("not freeing stack ptr %p\n", Pointer);
1106 return;
1108 TRACE("freeing %p\n", Pointer);
1109 NdrFree(pStubMsg, Pointer);
1110 return;
1111 notfree:
1112 TRACE("not freeing %p\n", Pointer);
1115 /***********************************************************************
1116 * EmbeddedPointerMarshall
1118 static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1119 unsigned char *pMemory,
1120 PFORMAT_STRING pFormat)
1122 unsigned char *Mark = pStubMsg->BufferMark;
1123 unsigned rep, count, stride;
1124 unsigned i;
1125 unsigned char *saved_buffer = NULL;
1127 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1129 if (*pFormat != RPC_FC_PP) return NULL;
1130 pFormat += 2;
1132 if (pStubMsg->PointerBufferMark)
1134 saved_buffer = pStubMsg->Buffer;
1135 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1136 pStubMsg->PointerBufferMark = NULL;
1139 while (pFormat[0] != RPC_FC_END) {
1140 switch (pFormat[0]) {
1141 default:
1142 FIXME("unknown repeat type %d\n", pFormat[0]);
1143 case RPC_FC_NO_REPEAT:
1144 rep = 1;
1145 stride = 0;
1146 count = 1;
1147 pFormat += 2;
1148 break;
1149 case RPC_FC_FIXED_REPEAT:
1150 rep = *(const WORD*)&pFormat[2];
1151 stride = *(const WORD*)&pFormat[4];
1152 count = *(const WORD*)&pFormat[8];
1153 pFormat += 10;
1154 break;
1155 case RPC_FC_VARIABLE_REPEAT:
1156 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1157 stride = *(const WORD*)&pFormat[2];
1158 count = *(const WORD*)&pFormat[6];
1159 pFormat += 8;
1160 break;
1162 for (i = 0; i < rep; i++) {
1163 PFORMAT_STRING info = pFormat;
1164 unsigned char *membase = pMemory + (i * stride);
1165 unsigned char *bufbase = Mark + (i * stride);
1166 unsigned u;
1168 for (u=0; u<count; u++,info+=8) {
1169 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1170 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1171 unsigned char *saved_memory = pStubMsg->Memory;
1173 pStubMsg->Memory = pMemory;
1174 PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4);
1175 pStubMsg->Memory = saved_memory;
1178 pFormat += 8 * count;
1181 if (saved_buffer)
1183 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1184 pStubMsg->Buffer = saved_buffer;
1187 STD_OVERFLOW_CHECK(pStubMsg);
1189 return NULL;
1192 /***********************************************************************
1193 * EmbeddedPointerUnmarshall
1195 static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1196 unsigned char *pDstBuffer,
1197 unsigned char *pSrcMemoryPtrs,
1198 PFORMAT_STRING pFormat,
1199 unsigned char fMustAlloc)
1201 unsigned char *Mark = pStubMsg->BufferMark;
1202 unsigned rep, count, stride;
1203 unsigned i;
1204 unsigned char *saved_buffer = NULL;
1206 TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstBuffer, pSrcMemoryPtrs, pFormat, fMustAlloc);
1208 if (*pFormat != RPC_FC_PP) return NULL;
1209 pFormat += 2;
1211 if (pStubMsg->PointerBufferMark)
1213 saved_buffer = pStubMsg->Buffer;
1214 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1215 pStubMsg->PointerBufferMark = NULL;
1218 while (pFormat[0] != RPC_FC_END) {
1219 TRACE("pFormat[0] = 0x%x\n", pFormat[0]);
1220 switch (pFormat[0]) {
1221 default:
1222 FIXME("unknown repeat type %d\n", pFormat[0]);
1223 case RPC_FC_NO_REPEAT:
1224 rep = 1;
1225 stride = 0;
1226 count = 1;
1227 pFormat += 2;
1228 break;
1229 case RPC_FC_FIXED_REPEAT:
1230 rep = *(const WORD*)&pFormat[2];
1231 stride = *(const WORD*)&pFormat[4];
1232 count = *(const WORD*)&pFormat[8];
1233 pFormat += 10;
1234 break;
1235 case RPC_FC_VARIABLE_REPEAT:
1236 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1237 stride = *(const WORD*)&pFormat[2];
1238 count = *(const WORD*)&pFormat[6];
1239 pFormat += 8;
1240 break;
1242 for (i = 0; i < rep; i++) {
1243 PFORMAT_STRING info = pFormat;
1244 unsigned char *bufdstbase = pDstBuffer + (i * stride);
1245 unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride);
1246 unsigned char *bufbase = Mark + (i * stride);
1247 unsigned u;
1249 for (u=0; u<count; u++,info+=8) {
1250 unsigned char **bufdstptr = (unsigned char **)(bufdstbase + *(const SHORT*)&info[2]);
1251 unsigned char **memsrcptr = (unsigned char **)(memsrcbase + *(const SHORT*)&info[0]);
1252 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1253 PointerUnmarshall(pStubMsg, bufptr, bufdstptr, *memsrcptr, info+4, fMustAlloc);
1256 pFormat += 8 * count;
1259 if (saved_buffer)
1261 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1262 pStubMsg->Buffer = saved_buffer;
1265 return NULL;
1268 /***********************************************************************
1269 * EmbeddedPointerBufferSize
1271 static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1272 unsigned char *pMemory,
1273 PFORMAT_STRING pFormat)
1275 unsigned rep, count, stride;
1276 unsigned i;
1277 ULONG saved_buffer_length = 0;
1279 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1281 if (pStubMsg->IgnoreEmbeddedPointers) return;
1283 if (*pFormat != RPC_FC_PP) return;
1284 pFormat += 2;
1286 if (pStubMsg->PointerLength)
1288 saved_buffer_length = pStubMsg->BufferLength;
1289 pStubMsg->BufferLength = pStubMsg->PointerLength;
1290 pStubMsg->PointerLength = 0;
1293 while (pFormat[0] != RPC_FC_END) {
1294 switch (pFormat[0]) {
1295 default:
1296 FIXME("unknown repeat type %d\n", pFormat[0]);
1297 case RPC_FC_NO_REPEAT:
1298 rep = 1;
1299 stride = 0;
1300 count = 1;
1301 pFormat += 2;
1302 break;
1303 case RPC_FC_FIXED_REPEAT:
1304 rep = *(const WORD*)&pFormat[2];
1305 stride = *(const WORD*)&pFormat[4];
1306 count = *(const WORD*)&pFormat[8];
1307 pFormat += 10;
1308 break;
1309 case RPC_FC_VARIABLE_REPEAT:
1310 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1311 stride = *(const WORD*)&pFormat[2];
1312 count = *(const WORD*)&pFormat[6];
1313 pFormat += 8;
1314 break;
1316 for (i = 0; i < rep; i++) {
1317 PFORMAT_STRING info = pFormat;
1318 unsigned char *membase = pMemory + (i * stride);
1319 unsigned u;
1321 for (u=0; u<count; u++,info+=8) {
1322 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1323 unsigned char *saved_memory = pStubMsg->Memory;
1325 pStubMsg->Memory = pMemory;
1326 PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4);
1327 pStubMsg->Memory = saved_memory;
1330 pFormat += 8 * count;
1333 if (saved_buffer_length)
1335 pStubMsg->PointerLength = pStubMsg->BufferLength;
1336 pStubMsg->BufferLength = saved_buffer_length;
1340 /***********************************************************************
1341 * EmbeddedPointerMemorySize [internal]
1343 static ULONG EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1344 PFORMAT_STRING pFormat)
1346 unsigned char *Mark = pStubMsg->BufferMark;
1347 unsigned rep, count, stride;
1348 unsigned i;
1349 unsigned char *saved_buffer = NULL;
1351 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1353 if (pStubMsg->IgnoreEmbeddedPointers) return 0;
1355 if (pStubMsg->PointerBufferMark)
1357 saved_buffer = pStubMsg->Buffer;
1358 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
1359 pStubMsg->PointerBufferMark = NULL;
1362 if (*pFormat != RPC_FC_PP) return 0;
1363 pFormat += 2;
1365 while (pFormat[0] != RPC_FC_END) {
1366 switch (pFormat[0]) {
1367 default:
1368 FIXME("unknown repeat type %d\n", pFormat[0]);
1369 case RPC_FC_NO_REPEAT:
1370 rep = 1;
1371 stride = 0;
1372 count = 1;
1373 pFormat += 2;
1374 break;
1375 case RPC_FC_FIXED_REPEAT:
1376 rep = *(const WORD*)&pFormat[2];
1377 stride = *(const WORD*)&pFormat[4];
1378 count = *(const WORD*)&pFormat[8];
1379 pFormat += 10;
1380 break;
1381 case RPC_FC_VARIABLE_REPEAT:
1382 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1383 stride = *(const WORD*)&pFormat[2];
1384 count = *(const WORD*)&pFormat[6];
1385 pFormat += 8;
1386 break;
1388 for (i = 0; i < rep; i++) {
1389 PFORMAT_STRING info = pFormat;
1390 unsigned char *bufbase = Mark + (i * stride);
1391 unsigned u;
1392 for (u=0; u<count; u++,info+=8) {
1393 unsigned char *bufptr = bufbase + *(const SHORT*)&info[2];
1394 PointerMemorySize(pStubMsg, bufptr, info+4);
1397 pFormat += 8 * count;
1400 if (saved_buffer)
1402 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
1403 pStubMsg->Buffer = saved_buffer;
1406 return 0;
1409 /***********************************************************************
1410 * EmbeddedPointerFree [internal]
1412 static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1413 unsigned char *pMemory,
1414 PFORMAT_STRING pFormat)
1416 unsigned rep, count, stride;
1417 unsigned i;
1419 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1420 if (*pFormat != RPC_FC_PP) return;
1421 pFormat += 2;
1423 while (pFormat[0] != RPC_FC_END) {
1424 switch (pFormat[0]) {
1425 default:
1426 FIXME("unknown repeat type %d\n", pFormat[0]);
1427 case RPC_FC_NO_REPEAT:
1428 rep = 1;
1429 stride = 0;
1430 count = 1;
1431 pFormat += 2;
1432 break;
1433 case RPC_FC_FIXED_REPEAT:
1434 rep = *(const WORD*)&pFormat[2];
1435 stride = *(const WORD*)&pFormat[4];
1436 count = *(const WORD*)&pFormat[8];
1437 pFormat += 10;
1438 break;
1439 case RPC_FC_VARIABLE_REPEAT:
1440 rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount;
1441 stride = *(const WORD*)&pFormat[2];
1442 count = *(const WORD*)&pFormat[6];
1443 pFormat += 8;
1444 break;
1446 for (i = 0; i < rep; i++) {
1447 PFORMAT_STRING info = pFormat;
1448 unsigned char *membase = pMemory + (i * stride);
1449 unsigned u;
1451 for (u=0; u<count; u++,info+=8) {
1452 unsigned char *memptr = membase + *(const SHORT*)&info[0];
1453 unsigned char *saved_memory = pStubMsg->Memory;
1455 pStubMsg->Memory = pMemory;
1456 PointerFree(pStubMsg, *(unsigned char**)memptr, info+4);
1457 pStubMsg->Memory = saved_memory;
1460 pFormat += 8 * count;
1464 /***********************************************************************
1465 * NdrPointerMarshall [RPCRT4.@]
1467 unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1468 unsigned char *pMemory,
1469 PFORMAT_STRING pFormat)
1471 unsigned char *Buffer;
1473 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1475 /* Increment the buffer here instead of in PointerMarshall,
1476 * as that is used by embedded pointers which already handle the incrementing
1477 * the buffer, and shouldn't write any additional pointer data to the wire */
1478 if (*pFormat != RPC_FC_RP)
1480 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
1481 Buffer = pStubMsg->Buffer;
1482 safe_buffer_increment(pStubMsg, 4);
1484 else
1485 Buffer = pStubMsg->Buffer;
1487 PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
1489 return NULL;
1492 /***********************************************************************
1493 * NdrPointerUnmarshall [RPCRT4.@]
1495 unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1496 unsigned char **ppMemory,
1497 PFORMAT_STRING pFormat,
1498 unsigned char fMustAlloc)
1500 unsigned char *Buffer;
1502 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1504 if (*pFormat == RPC_FC_RP)
1506 Buffer = pStubMsg->Buffer;
1507 /* Do the NULL ref pointer check here because embedded pointers can be
1508 * NULL if the type the pointer is embedded in was allocated rather than
1509 * being passed in by the client */
1510 if (pStubMsg->IsClient && !*ppMemory)
1512 ERR("NULL ref pointer is not allowed\n");
1513 RpcRaiseException(RPC_X_NULL_REF_POINTER);
1516 else
1518 /* Increment the buffer here instead of in PointerUnmarshall,
1519 * as that is used by embedded pointers which already handle the incrementing
1520 * the buffer, and shouldn't read any additional pointer data from the
1521 * buffer */
1522 ALIGN_POINTER(pStubMsg->Buffer, 4);
1523 Buffer = pStubMsg->Buffer;
1524 safe_buffer_increment(pStubMsg, 4);
1527 PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc);
1529 return NULL;
1532 /***********************************************************************
1533 * NdrPointerBufferSize [RPCRT4.@]
1535 void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1536 unsigned char *pMemory,
1537 PFORMAT_STRING pFormat)
1539 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1541 /* Increment the buffer length here instead of in PointerBufferSize,
1542 * as that is used by embedded pointers which already handle the buffer
1543 * length, and shouldn't write anything more to the wire */
1544 if (*pFormat != RPC_FC_RP)
1546 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
1547 safe_buffer_length_increment(pStubMsg, 4);
1550 PointerBufferSize(pStubMsg, pMemory, pFormat);
1553 /***********************************************************************
1554 * NdrPointerMemorySize [RPCRT4.@]
1556 ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1557 PFORMAT_STRING pFormat)
1559 unsigned char *Buffer = pStubMsg->Buffer;
1560 if (*pFormat != RPC_FC_RP)
1562 ALIGN_POINTER(pStubMsg->Buffer, 4);
1563 safe_buffer_increment(pStubMsg, 4);
1565 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
1566 return PointerMemorySize(pStubMsg, Buffer, pFormat);
1569 /***********************************************************************
1570 * NdrPointerFree [RPCRT4.@]
1572 void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
1573 unsigned char *pMemory,
1574 PFORMAT_STRING pFormat)
1576 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1577 PointerFree(pStubMsg, pMemory, pFormat);
1580 /***********************************************************************
1581 * NdrSimpleTypeMarshall [RPCRT4.@]
1583 void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1584 unsigned char FormatChar )
1586 NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar);
1589 /***********************************************************************
1590 * NdrSimpleTypeUnmarshall [RPCRT4.@]
1592 * Unmarshall a base type.
1594 * NOTES
1595 * Doesn't check that the buffer is long enough before copying, so the caller
1596 * should do this.
1598 void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
1599 unsigned char FormatChar )
1601 #define BASE_TYPE_UNMARSHALL(type) \
1602 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
1603 TRACE("pMemory: %p\n", pMemory); \
1604 *(type *)pMemory = *(type *)pStubMsg->Buffer; \
1605 pStubMsg->Buffer += sizeof(type);
1607 switch(FormatChar)
1609 case RPC_FC_BYTE:
1610 case RPC_FC_CHAR:
1611 case RPC_FC_SMALL:
1612 case RPC_FC_USMALL:
1613 BASE_TYPE_UNMARSHALL(UCHAR);
1614 TRACE("value: 0x%02x\n", *pMemory);
1615 break;
1616 case RPC_FC_WCHAR:
1617 case RPC_FC_SHORT:
1618 case RPC_FC_USHORT:
1619 BASE_TYPE_UNMARSHALL(USHORT);
1620 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
1621 break;
1622 case RPC_FC_LONG:
1623 case RPC_FC_ULONG:
1624 case RPC_FC_ERROR_STATUS_T:
1625 case RPC_FC_ENUM32:
1626 BASE_TYPE_UNMARSHALL(ULONG);
1627 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
1628 break;
1629 case RPC_FC_FLOAT:
1630 BASE_TYPE_UNMARSHALL(float);
1631 TRACE("value: %f\n", *(float *)pMemory);
1632 break;
1633 case RPC_FC_DOUBLE:
1634 BASE_TYPE_UNMARSHALL(double);
1635 TRACE("value: %f\n", *(double *)pMemory);
1636 break;
1637 case RPC_FC_HYPER:
1638 BASE_TYPE_UNMARSHALL(ULONGLONG);
1639 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG *)pMemory));
1640 break;
1641 case RPC_FC_ENUM16:
1642 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
1643 TRACE("pMemory: %p\n", pMemory);
1644 /* 16-bits on the wire, but int in memory */
1645 *(UINT *)pMemory = *(USHORT *)pStubMsg->Buffer;
1646 pStubMsg->Buffer += sizeof(USHORT);
1647 TRACE("value: 0x%08x\n", *(UINT *)pMemory);
1648 break;
1649 case RPC_FC_IGNORE:
1650 break;
1651 default:
1652 FIXME("Unhandled base type: 0x%02x\n", FormatChar);
1654 #undef BASE_TYPE_UNMARSHALL
1657 /***********************************************************************
1658 * NdrSimpleStructMarshall [RPCRT4.@]
1660 unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
1661 unsigned char *pMemory,
1662 PFORMAT_STRING pFormat)
1664 unsigned size = *(const WORD*)(pFormat+2);
1665 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1667 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
1669 pStubMsg->BufferMark = pStubMsg->Buffer;
1670 safe_copy_to_buffer(pStubMsg, pMemory, size);
1672 if (pFormat[0] != RPC_FC_STRUCT)
1673 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
1675 return NULL;
1678 /***********************************************************************
1679 * NdrSimpleStructUnmarshall [RPCRT4.@]
1681 unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
1682 unsigned char **ppMemory,
1683 PFORMAT_STRING pFormat,
1684 unsigned char fMustAlloc)
1686 unsigned size = *(const WORD*)(pFormat+2);
1687 unsigned char *saved_buffer;
1688 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
1690 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1692 if (fMustAlloc)
1693 *ppMemory = NdrAllocate(pStubMsg, size);
1694 else
1696 if (!pStubMsg->IsClient && !*ppMemory)
1697 /* for servers, we just point straight into the RPC buffer */
1698 *ppMemory = pStubMsg->Buffer;
1701 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
1702 safe_buffer_increment(pStubMsg, size);
1703 if (pFormat[0] == RPC_FC_PSTRUCT)
1704 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc);
1706 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
1707 if (*ppMemory != saved_buffer)
1708 memcpy(*ppMemory, saved_buffer, size);
1710 return NULL;
1713 /***********************************************************************
1714 * NdrSimpleStructBufferSize [RPCRT4.@]
1716 void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
1717 unsigned char *pMemory,
1718 PFORMAT_STRING pFormat)
1720 unsigned size = *(const WORD*)(pFormat+2);
1721 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1723 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
1725 safe_buffer_length_increment(pStubMsg, size);
1726 if (pFormat[0] != RPC_FC_STRUCT)
1727 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4);
1730 /***********************************************************************
1731 * NdrSimpleStructMemorySize [RPCRT4.@]
1733 ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
1734 PFORMAT_STRING pFormat)
1736 unsigned short size = *(const WORD *)(pFormat+2);
1738 TRACE("(%p,%p)\n", pStubMsg, pFormat);
1740 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
1741 pStubMsg->MemorySize += size;
1742 safe_buffer_increment(pStubMsg, size);
1744 if (pFormat[0] != RPC_FC_STRUCT)
1745 EmbeddedPointerMemorySize(pStubMsg, pFormat+4);
1746 return pStubMsg->MemorySize;
1749 /***********************************************************************
1750 * NdrSimpleStructFree [RPCRT4.@]
1752 void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg,
1753 unsigned char *pMemory,
1754 PFORMAT_STRING pFormat)
1756 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
1757 if (pFormat[0] != RPC_FC_STRUCT)
1758 EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4);
1761 /* Array helpers */
1763 static inline void array_compute_and_size_conformance(
1764 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1765 PFORMAT_STRING pFormat)
1767 switch (fc)
1769 case RPC_FC_CARRAY:
1770 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1771 SizeConformance(pStubMsg);
1772 break;
1773 case RPC_FC_CVARRAY:
1774 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1775 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1776 SizeConformance(pStubMsg);
1777 break;
1778 case RPC_FC_C_CSTRING:
1779 case RPC_FC_C_WSTRING:
1780 if (pFormat[0] == RPC_FC_C_CSTRING)
1782 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1783 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1785 else
1787 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1788 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1791 if (fc == RPC_FC_STRING_SIZED)
1792 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1793 else
1794 pStubMsg->MaxCount = pStubMsg->ActualCount;
1796 SizeConformance(pStubMsg);
1797 break;
1798 default:
1799 ERR("unknown array format 0x%x\n", fc);
1800 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1804 static inline void array_buffer_size(
1805 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1806 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1808 DWORD size;
1809 DWORD esize;
1810 unsigned char alignment;
1812 switch (fc)
1814 case RPC_FC_CARRAY:
1815 esize = *(const WORD*)(pFormat+2);
1816 alignment = pFormat[1] + 1;
1818 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1820 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
1822 size = safe_multiply(esize, pStubMsg->MaxCount);
1823 /* conformance value plus array */
1824 safe_buffer_length_increment(pStubMsg, size);
1826 if (fHasPointers)
1827 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1828 break;
1829 case RPC_FC_CVARRAY:
1830 esize = *(const WORD*)(pFormat+2);
1831 alignment = pFormat[1] + 1;
1833 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1834 pFormat = SkipConformance(pStubMsg, pFormat);
1836 SizeVariance(pStubMsg);
1838 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
1840 size = safe_multiply(esize, pStubMsg->ActualCount);
1841 safe_buffer_length_increment(pStubMsg, size);
1843 if (fHasPointers)
1844 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
1845 break;
1846 case RPC_FC_C_CSTRING:
1847 case RPC_FC_C_WSTRING:
1848 if (fc == RPC_FC_C_CSTRING)
1849 esize = 1;
1850 else
1851 esize = 2;
1853 SizeVariance(pStubMsg);
1855 size = safe_multiply(esize, pStubMsg->ActualCount);
1856 safe_buffer_length_increment(pStubMsg, size);
1857 break;
1858 default:
1859 ERR("unknown array format 0x%x\n", fc);
1860 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1864 static inline void array_compute_and_write_conformance(
1865 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1866 PFORMAT_STRING pFormat)
1868 switch (fc)
1870 case RPC_FC_CARRAY:
1871 ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
1872 WriteConformance(pStubMsg);
1873 break;
1874 case RPC_FC_CVARRAY:
1875 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0);
1876 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
1877 WriteConformance(pStubMsg);
1878 break;
1879 case RPC_FC_C_CSTRING:
1880 case RPC_FC_C_WSTRING:
1881 if (fc == RPC_FC_C_CSTRING)
1883 TRACE("string=%s\n", debugstr_a((const char *)pMemory));
1884 pStubMsg->ActualCount = strlen((const char *)pMemory)+1;
1886 else
1888 TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory));
1889 pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1;
1891 if (pFormat[1] == RPC_FC_STRING_SIZED)
1892 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0);
1893 else
1894 pStubMsg->MaxCount = pStubMsg->ActualCount;
1895 pStubMsg->Offset = 0;
1896 WriteConformance(pStubMsg);
1897 break;
1898 default:
1899 ERR("unknown array format 0x%x\n", fc);
1900 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1904 static inline void array_write_variance_and_marshall(
1905 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
1906 PFORMAT_STRING pFormat, unsigned char fHasPointers)
1908 DWORD size;
1909 DWORD esize;
1910 unsigned char alignment;
1912 switch (fc)
1914 case RPC_FC_CARRAY:
1915 esize = *(const WORD*)(pFormat+2);
1916 alignment = pFormat[1] + 1;
1918 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1920 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
1922 size = safe_multiply(esize, pStubMsg->MaxCount);
1923 if (fHasPointers)
1924 pStubMsg->BufferMark = pStubMsg->Buffer;
1925 safe_copy_to_buffer(pStubMsg, pMemory, size);
1927 if (fHasPointers)
1928 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
1929 break;
1930 case RPC_FC_CVARRAY:
1931 esize = *(const WORD*)(pFormat+2);
1932 alignment = pFormat[1] + 1;
1934 /* conformance */
1935 pFormat = SkipConformance(pStubMsg, pFormat + 4);
1936 /* variance */
1937 pFormat = SkipConformance(pStubMsg, pFormat);
1939 WriteVariance(pStubMsg);
1941 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
1943 size = safe_multiply(esize, pStubMsg->ActualCount);
1945 if (fHasPointers)
1946 pStubMsg->BufferMark = pStubMsg->Buffer;
1947 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, size);
1949 if (fHasPointers)
1950 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
1951 break;
1952 case RPC_FC_C_CSTRING:
1953 case RPC_FC_C_WSTRING:
1954 if (fc == RPC_FC_C_CSTRING)
1955 esize = 1;
1956 else
1957 esize = 2;
1959 WriteVariance(pStubMsg);
1961 size = safe_multiply(esize, pStubMsg->ActualCount);
1962 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
1963 break;
1964 default:
1965 ERR("unknown array format 0x%x\n", fc);
1966 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1970 static inline ULONG array_read_conformance(
1971 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
1973 DWORD esize;
1975 switch (fc)
1977 case RPC_FC_CARRAY:
1978 esize = *(const WORD*)(pFormat+2);
1979 pFormat = ReadConformance(pStubMsg, pFormat+4);
1980 return safe_multiply(esize, pStubMsg->MaxCount);
1981 case RPC_FC_CVARRAY:
1982 esize = *(const WORD*)(pFormat+2);
1983 pFormat = ReadConformance(pStubMsg, pFormat+4);
1984 return safe_multiply(esize, pStubMsg->MaxCount);
1985 case RPC_FC_C_CSTRING:
1986 case RPC_FC_C_WSTRING:
1987 if (fc == RPC_FC_C_CSTRING)
1988 esize = 1;
1989 else
1990 esize = 2;
1992 if (pFormat[1] == RPC_FC_STRING_SIZED)
1993 ReadConformance(pStubMsg, pFormat + 2);
1994 else
1995 ReadConformance(pStubMsg, NULL);
1996 return safe_multiply(esize, pStubMsg->MaxCount);
1997 default:
1998 ERR("unknown array format 0x%x\n", fc);
1999 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2003 static inline ULONG array_read_variance_and_unmarshall(
2004 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory,
2005 PFORMAT_STRING pFormat, unsigned char fMustAlloc,
2006 unsigned char fUseBufferMemoryServer, unsigned char fUnmarshall)
2008 ULONG bufsize, memsize;
2009 WORD esize;
2010 unsigned char alignment;
2011 unsigned char *saved_buffer;
2012 ULONG offset;
2014 switch (fc)
2016 case RPC_FC_CARRAY:
2017 esize = *(const WORD*)(pFormat+2);
2018 alignment = pFormat[1] + 1;
2020 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2022 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2024 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2026 if (fUnmarshall)
2028 if (fMustAlloc)
2029 *ppMemory = NdrAllocate(pStubMsg, memsize);
2030 else
2032 if (fUseBufferMemoryServer && !pStubMsg->IsClient && !*ppMemory)
2033 /* for servers, we just point straight into the RPC buffer */
2034 *ppMemory = pStubMsg->Buffer;
2037 saved_buffer = pStubMsg->Buffer;
2038 safe_buffer_increment(pStubMsg, bufsize);
2040 pStubMsg->BufferMark = saved_buffer;
2041 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
2043 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
2044 if (*ppMemory != saved_buffer)
2045 memcpy(*ppMemory, saved_buffer, bufsize);
2047 return bufsize;
2048 case RPC_FC_CVARRAY:
2049 esize = *(const WORD*)(pFormat+2);
2050 alignment = pFormat[1] + 1;
2052 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2054 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2056 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2058 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2059 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2061 if (fUnmarshall)
2063 offset = pStubMsg->Offset;
2065 if (!fMustAlloc && !*ppMemory)
2066 fMustAlloc = TRUE;
2067 if (fMustAlloc)
2068 *ppMemory = NdrAllocate(pStubMsg, memsize);
2069 saved_buffer = pStubMsg->Buffer;
2070 safe_buffer_increment(pStubMsg, bufsize);
2072 pStubMsg->BufferMark = saved_buffer;
2073 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat,
2074 fMustAlloc);
2076 memcpy(*ppMemory + offset, saved_buffer, bufsize);
2078 return bufsize;
2079 case RPC_FC_C_CSTRING:
2080 case RPC_FC_C_WSTRING:
2081 if (fc == RPC_FC_C_CSTRING)
2082 esize = 1;
2083 else
2084 esize = 2;
2086 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2088 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2090 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2091 pStubMsg->ActualCount, pStubMsg->MaxCount);
2092 RpcRaiseException(RPC_S_INVALID_BOUND);
2094 if (pStubMsg->Offset)
2096 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2097 RpcRaiseException(RPC_S_INVALID_BOUND);
2100 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2101 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2103 validate_string_data(pStubMsg, bufsize, esize);
2105 if (fUnmarshall)
2107 if (fMustAlloc)
2108 *ppMemory = NdrAllocate(pStubMsg, memsize);
2109 else
2111 if (fUseBufferMemoryServer && !pStubMsg->IsClient &&
2112 !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount))
2113 /* if the data in the RPC buffer is big enough, we just point
2114 * straight into it */
2115 *ppMemory = pStubMsg->Buffer;
2116 else if (!*ppMemory)
2117 *ppMemory = NdrAllocate(pStubMsg, memsize);
2120 if (*ppMemory == pStubMsg->Buffer)
2121 safe_buffer_increment(pStubMsg, bufsize);
2122 else
2123 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2125 if (*pFormat == RPC_FC_C_CSTRING)
2126 TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
2127 else
2128 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
2130 return bufsize;
2131 default:
2132 ERR("unknown array format 0x%x\n", fc);
2133 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2137 static inline void array_memory_size(
2138 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat,
2139 unsigned char fHasPointers)
2141 ULONG bufsize, memsize;
2142 DWORD esize;
2143 unsigned char alignment;
2145 switch (fc)
2147 case RPC_FC_CARRAY:
2148 esize = *(const WORD*)(pFormat+2);
2149 alignment = pFormat[1] + 1;
2151 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2153 bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount);
2154 pStubMsg->MemorySize += memsize;
2156 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2157 if (fHasPointers)
2158 pStubMsg->BufferMark = pStubMsg->Buffer;
2159 safe_buffer_increment(pStubMsg, bufsize);
2161 if (fHasPointers)
2162 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2163 break;
2164 case RPC_FC_CVARRAY:
2165 esize = *(const WORD*)(pFormat+2);
2166 alignment = pFormat[1] + 1;
2168 pFormat = SkipConformance(pStubMsg, pFormat + 4);
2170 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
2172 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2173 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2174 pStubMsg->MemorySize += memsize;
2176 ALIGN_POINTER(pStubMsg->Buffer, alignment);
2177 if (fHasPointers)
2178 pStubMsg->BufferMark = pStubMsg->Buffer;
2179 safe_buffer_increment(pStubMsg, bufsize);
2181 if (fHasPointers)
2182 EmbeddedPointerMemorySize(pStubMsg, pFormat);
2183 break;
2184 case RPC_FC_C_CSTRING:
2185 case RPC_FC_C_WSTRING:
2186 if (fc == RPC_FC_C_CSTRING)
2187 esize = 1;
2188 else
2189 esize = 2;
2191 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount);
2193 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount))
2195 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n",
2196 pStubMsg->ActualCount, pStubMsg->MaxCount);
2197 RpcRaiseException(RPC_S_INVALID_BOUND);
2199 if (pStubMsg->Offset)
2201 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2202 RpcRaiseException(RPC_S_INVALID_BOUND);
2205 memsize = safe_multiply(esize, pStubMsg->MaxCount);
2206 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2208 validate_string_data(pStubMsg, bufsize, esize);
2210 safe_buffer_increment(pStubMsg, bufsize);
2211 pStubMsg->MemorySize += memsize;
2212 break;
2213 default:
2214 ERR("unknown array format 0x%x\n", fc);
2215 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2219 static inline void array_free(
2220 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg,
2221 unsigned char *pMemory, PFORMAT_STRING pFormat, unsigned char fHasPointers)
2223 switch (fc)
2225 case RPC_FC_CARRAY:
2226 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2227 if (fHasPointers)
2228 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2229 break;
2230 case RPC_FC_CVARRAY:
2231 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
2232 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
2233 if (fHasPointers)
2234 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
2235 break;
2236 case RPC_FC_C_CSTRING:
2237 case RPC_FC_C_WSTRING:
2238 /* No embedded pointers so nothing to do */
2239 break;
2240 default:
2241 ERR("unknown array format 0x%x\n", fc);
2242 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2247 * NdrConformantString:
2249 * What MS calls a ConformantString is, in DCE terminology,
2250 * a Varying-Conformant String.
2252 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
2253 * offset: DWORD (actual string data begins at (offset) CHARTYPE's
2254 * into unmarshalled string)
2255 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
2257 * data: CHARTYPE[maxlen]
2259 * ], where CHARTYPE is the appropriate character type (specified externally)
2263 /***********************************************************************
2264 * NdrConformantStringMarshall [RPCRT4.@]
2266 unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
2267 unsigned char *pszMessage, PFORMAT_STRING pFormat)
2269 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat);
2271 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2272 ERR("Unhandled string type: %#x\n", pFormat[0]);
2273 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2276 /* allow compiler to optimise inline function by passing constant into
2277 * these functions */
2278 if (pFormat[0] == RPC_FC_C_CSTRING) {
2279 array_compute_and_write_conformance(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2280 pFormat);
2281 array_write_variance_and_marshall(RPC_FC_C_CSTRING, pStubMsg, pszMessage,
2282 pFormat, TRUE /* fHasPointers */);
2283 } else {
2284 array_compute_and_write_conformance(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2285 pFormat);
2286 array_write_variance_and_marshall(RPC_FC_C_WSTRING, pStubMsg, pszMessage,
2287 pFormat, TRUE /* fHasPointers */);
2290 return NULL;
2293 /***********************************************************************
2294 * NdrConformantStringBufferSize [RPCRT4.@]
2296 void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2297 unsigned char* pMemory, PFORMAT_STRING pFormat)
2299 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2301 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2302 ERR("Unhandled string type: %#x\n", pFormat[0]);
2303 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2306 /* allow compiler to optimise inline function by passing constant into
2307 * these functions */
2308 if (pFormat[0] == RPC_FC_C_CSTRING) {
2309 array_compute_and_size_conformance(RPC_FC_C_CSTRING, pStubMsg, pMemory,
2310 pFormat);
2311 array_buffer_size(RPC_FC_C_CSTRING, pStubMsg, pMemory, pFormat,
2312 TRUE /* fHasPointers */);
2313 } else {
2314 array_compute_and_size_conformance(RPC_FC_C_WSTRING, pStubMsg, pMemory,
2315 pFormat);
2316 array_buffer_size(RPC_FC_C_WSTRING, pStubMsg, pMemory, pFormat,
2317 TRUE /* fHasPointers */);
2321 /************************************************************************
2322 * NdrConformantStringMemorySize [RPCRT4.@]
2324 ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
2325 PFORMAT_STRING pFormat )
2327 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2329 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2330 ERR("Unhandled string type: %#x\n", pFormat[0]);
2331 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2334 /* allow compiler to optimise inline function by passing constant into
2335 * these functions */
2336 if (pFormat[0] == RPC_FC_C_CSTRING) {
2337 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2338 array_memory_size(RPC_FC_C_CSTRING, pStubMsg, pFormat,
2339 TRUE /* fHasPointers */);
2340 } else {
2341 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2342 array_memory_size(RPC_FC_C_WSTRING, pStubMsg, pFormat,
2343 TRUE /* fHasPointers */);
2346 return pStubMsg->MemorySize;
2349 /************************************************************************
2350 * NdrConformantStringUnmarshall [RPCRT4.@]
2352 unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
2353 unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
2355 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2356 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2358 if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) {
2359 ERR("Unhandled string type: %#x\n", *pFormat);
2360 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2363 /* allow compiler to optimise inline function by passing constant into
2364 * these functions */
2365 if (pFormat[0] == RPC_FC_C_CSTRING) {
2366 array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat);
2367 array_read_variance_and_unmarshall(RPC_FC_C_CSTRING, pStubMsg, ppMemory,
2368 pFormat, fMustAlloc,
2369 TRUE /* fUseBufferMemoryServer */,
2370 TRUE /* fUnmarshall */);
2371 } else {
2372 array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat);
2373 array_read_variance_and_unmarshall(RPC_FC_C_WSTRING, pStubMsg, ppMemory,
2374 pFormat, fMustAlloc,
2375 TRUE /* fUseBufferMemoryServer */,
2376 TRUE /* fUnmarshall */);
2379 return NULL;
2382 /***********************************************************************
2383 * NdrNonConformantStringMarshall [RPCRT4.@]
2385 unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2386 unsigned char *pMemory,
2387 PFORMAT_STRING pFormat)
2389 ULONG esize, size, maxsize;
2391 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2393 maxsize = *(USHORT *)&pFormat[2];
2395 if (*pFormat == RPC_FC_CSTRING)
2397 ULONG i;
2398 const char *str = (const char *)pMemory;
2399 for (i = 0; i < maxsize && *str; i++, str++)
2401 TRACE("string=%s\n", debugstr_an(str, i));
2402 pStubMsg->ActualCount = i + 1;
2403 esize = 1;
2405 else if (*pFormat == RPC_FC_WSTRING)
2407 ULONG i;
2408 const WCHAR *str = (const WCHAR *)pMemory;
2409 for (i = 0; i < maxsize && *str; i++, str++)
2411 TRACE("string=%s\n", debugstr_wn(str, i));
2412 pStubMsg->ActualCount = i + 1;
2413 esize = 2;
2415 else
2417 ERR("Unhandled string type: %#x\n", *pFormat);
2418 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2421 pStubMsg->Offset = 0;
2422 WriteVariance(pStubMsg);
2424 size = safe_multiply(esize, pStubMsg->ActualCount);
2425 safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
2427 return NULL;
2430 /***********************************************************************
2431 * NdrNonConformantStringUnmarshall [RPCRT4.@]
2433 unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2434 unsigned char **ppMemory,
2435 PFORMAT_STRING pFormat,
2436 unsigned char fMustAlloc)
2438 ULONG bufsize, memsize, esize, maxsize;
2440 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
2441 pStubMsg, *ppMemory, pFormat, fMustAlloc);
2443 maxsize = *(USHORT *)&pFormat[2];
2445 ReadVariance(pStubMsg, NULL, maxsize);
2446 if (pStubMsg->Offset)
2448 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2449 RpcRaiseException(RPC_S_INVALID_BOUND);
2452 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2453 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2454 else
2456 ERR("Unhandled string type: %#x\n", *pFormat);
2457 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2460 memsize = esize * maxsize;
2461 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2463 validate_string_data(pStubMsg, bufsize, esize);
2465 if (!fMustAlloc && !*ppMemory)
2466 fMustAlloc = TRUE;
2467 if (fMustAlloc)
2468 *ppMemory = NdrAllocate(pStubMsg, memsize);
2470 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize);
2472 if (*pFormat == RPC_FC_CSTRING) {
2473 TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount));
2475 else if (*pFormat == RPC_FC_WSTRING) {
2476 TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount));
2479 return NULL;
2482 /***********************************************************************
2483 * NdrNonConformantStringBufferSize [RPCRT4.@]
2485 void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2486 unsigned char *pMemory,
2487 PFORMAT_STRING pFormat)
2489 ULONG esize, maxsize;
2491 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat);
2493 maxsize = *(USHORT *)&pFormat[2];
2495 SizeVariance(pStubMsg);
2497 if (*pFormat == RPC_FC_CSTRING)
2499 ULONG i;
2500 const char *str = (const char *)pMemory;
2501 for (i = 0; i < maxsize && *str; i++, str++)
2503 TRACE("string=%s\n", debugstr_an(str, i));
2504 pStubMsg->ActualCount = i + 1;
2505 esize = 1;
2507 else if (*pFormat == RPC_FC_WSTRING)
2509 ULONG i;
2510 const WCHAR *str = (const WCHAR *)pMemory;
2511 for (i = 0; i < maxsize && *str; i++, str++)
2513 TRACE("string=%s\n", debugstr_wn(str, i));
2514 pStubMsg->ActualCount = i + 1;
2515 esize = 2;
2517 else
2519 ERR("Unhandled string type: %#x\n", *pFormat);
2520 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2523 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
2526 /***********************************************************************
2527 * NdrNonConformantStringMemorySize [RPCRT4.@]
2529 ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2530 PFORMAT_STRING pFormat)
2532 ULONG bufsize, memsize, esize, maxsize;
2534 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat);
2536 maxsize = *(USHORT *)&pFormat[2];
2538 ReadVariance(pStubMsg, NULL, maxsize);
2540 if (pStubMsg->Offset)
2542 ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset);
2543 RpcRaiseException(RPC_S_INVALID_BOUND);
2546 if (*pFormat == RPC_FC_CSTRING) esize = 1;
2547 else if (*pFormat == RPC_FC_WSTRING) esize = 2;
2548 else
2550 ERR("Unhandled string type: %#x\n", *pFormat);
2551 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2554 memsize = esize * maxsize;
2555 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
2557 validate_string_data(pStubMsg, bufsize, esize);
2559 safe_buffer_increment(pStubMsg, bufsize);
2560 pStubMsg->MemorySize += memsize;
2562 return pStubMsg->MemorySize;
2565 /* Complex types */
2567 #include "pshpack1.h"
2568 typedef struct
2570 unsigned char type;
2571 unsigned char flags_type; /* flags in upper nibble, type in lower nibble */
2572 ULONG low_value;
2573 ULONG high_value;
2574 } NDR_RANGE;
2575 #include "poppack.h"
2577 static ULONG EmbeddedComplexSize(MIDL_STUB_MESSAGE *pStubMsg,
2578 PFORMAT_STRING pFormat)
2580 switch (*pFormat) {
2581 case RPC_FC_STRUCT:
2582 case RPC_FC_PSTRUCT:
2583 case RPC_FC_CSTRUCT:
2584 case RPC_FC_BOGUS_STRUCT:
2585 case RPC_FC_SMFARRAY:
2586 case RPC_FC_SMVARRAY:
2587 case RPC_FC_CSTRING:
2588 return *(const WORD*)&pFormat[2];
2589 case RPC_FC_USER_MARSHAL:
2590 return *(const WORD*)&pFormat[4];
2591 case RPC_FC_RANGE: {
2592 switch (((const NDR_RANGE *)pFormat)->flags_type & 0xf) {
2593 case RPC_FC_BYTE:
2594 case RPC_FC_CHAR:
2595 case RPC_FC_SMALL:
2596 case RPC_FC_USMALL:
2597 return sizeof(UCHAR);
2598 case RPC_FC_WCHAR:
2599 case RPC_FC_SHORT:
2600 case RPC_FC_USHORT:
2601 return sizeof(USHORT);
2602 case RPC_FC_LONG:
2603 case RPC_FC_ULONG:
2604 case RPC_FC_ENUM32:
2605 return sizeof(ULONG);
2606 case RPC_FC_FLOAT:
2607 return sizeof(float);
2608 case RPC_FC_DOUBLE:
2609 return sizeof(double);
2610 case RPC_FC_HYPER:
2611 return sizeof(ULONGLONG);
2612 case RPC_FC_ENUM16:
2613 return sizeof(UINT);
2614 default:
2615 ERR("unknown type 0x%x\n", ((const NDR_RANGE *)pFormat)->flags_type & 0xf);
2616 RpcRaiseException(RPC_X_BAD_STUB_DATA);
2619 case RPC_FC_NON_ENCAPSULATED_UNION:
2620 pFormat += 2;
2621 if (pStubMsg->fHasNewCorrDesc)
2622 pFormat += 6;
2623 else
2624 pFormat += 4;
2626 pFormat += *(const SHORT*)pFormat;
2627 return *(const SHORT*)pFormat;
2628 case RPC_FC_IP:
2629 return sizeof(void *);
2630 case RPC_FC_WSTRING:
2631 return *(const WORD*)&pFormat[2] * 2;
2632 default:
2633 FIXME("unhandled embedded type %02x\n", *pFormat);
2635 return 0;
2639 static ULONG EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
2640 PFORMAT_STRING pFormat)
2642 NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK];
2644 if (!m)
2646 FIXME("no memorysizer for data type=%02x\n", *pFormat);
2647 return 0;
2650 return m(pStubMsg, pFormat);
2654 static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
2655 unsigned char *pMemory,
2656 PFORMAT_STRING pFormat,
2657 PFORMAT_STRING pPointer)
2659 PFORMAT_STRING desc;
2660 NDR_MARSHALL m;
2661 ULONG size;
2663 while (*pFormat != RPC_FC_END) {
2664 switch (*pFormat) {
2665 case RPC_FC_BYTE:
2666 case RPC_FC_CHAR:
2667 case RPC_FC_SMALL:
2668 case RPC_FC_USMALL:
2669 TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
2670 safe_copy_to_buffer(pStubMsg, pMemory, 1);
2671 pMemory += 1;
2672 break;
2673 case RPC_FC_WCHAR:
2674 case RPC_FC_SHORT:
2675 case RPC_FC_USHORT:
2676 TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
2677 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2678 pMemory += 2;
2679 break;
2680 case RPC_FC_ENUM16:
2681 TRACE("enum16=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2682 if (32767 < *(DWORD*)pMemory)
2683 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2684 safe_copy_to_buffer(pStubMsg, pMemory, 2);
2685 pMemory += 4;
2686 break;
2687 case RPC_FC_LONG:
2688 case RPC_FC_ULONG:
2689 case RPC_FC_ENUM32:
2690 TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
2691 safe_copy_to_buffer(pStubMsg, pMemory, 4);
2692 pMemory += 4;
2693 break;
2694 case RPC_FC_HYPER:
2695 TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2696 safe_copy_to_buffer(pStubMsg, pMemory, 8);
2697 pMemory += 8;
2698 break;
2699 case RPC_FC_POINTER:
2701 unsigned char *saved_buffer;
2702 int pointer_buffer_mark_set = 0;
2703 TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory);
2704 TRACE("pStubMsg->Buffer before %p\n", pStubMsg->Buffer);
2705 if (*pPointer != RPC_FC_RP)
2706 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
2707 saved_buffer = pStubMsg->Buffer;
2708 if (pStubMsg->PointerBufferMark)
2710 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2711 pStubMsg->PointerBufferMark = NULL;
2712 pointer_buffer_mark_set = 1;
2714 else if (*pPointer != RPC_FC_RP)
2715 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2716 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer);
2717 if (pointer_buffer_mark_set)
2719 STD_OVERFLOW_CHECK(pStubMsg);
2720 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2721 pStubMsg->Buffer = saved_buffer;
2722 if (*pPointer != RPC_FC_RP)
2723 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2725 TRACE("pStubMsg->Buffer after %p\n", pStubMsg->Buffer);
2726 pPointer += 4;
2727 pMemory += 4;
2728 break;
2730 case RPC_FC_ALIGNM4:
2731 ALIGN_POINTER(pMemory, 4);
2732 break;
2733 case RPC_FC_ALIGNM8:
2734 ALIGN_POINTER(pMemory, 8);
2735 break;
2736 case RPC_FC_STRUCTPAD1:
2737 case RPC_FC_STRUCTPAD2:
2738 case RPC_FC_STRUCTPAD3:
2739 case RPC_FC_STRUCTPAD4:
2740 case RPC_FC_STRUCTPAD5:
2741 case RPC_FC_STRUCTPAD6:
2742 case RPC_FC_STRUCTPAD7:
2743 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2744 break;
2745 case RPC_FC_EMBEDDED_COMPLEX:
2746 pMemory += pFormat[1];
2747 pFormat += 2;
2748 desc = pFormat + *(const SHORT*)pFormat;
2749 size = EmbeddedComplexSize(pStubMsg, desc);
2750 TRACE("embedded complex (size=%d) <= %p\n", size, pMemory);
2751 m = NdrMarshaller[*desc & NDR_TABLE_MASK];
2752 if (m)
2754 /* for some reason interface pointers aren't generated as
2755 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2756 * they still need the derefencing treatment that pointers are
2757 * given */
2758 if (*desc == RPC_FC_IP)
2759 m(pStubMsg, *(unsigned char **)pMemory, desc);
2760 else
2761 m(pStubMsg, pMemory, desc);
2763 else FIXME("no marshaller for embedded type %02x\n", *desc);
2764 pMemory += size;
2765 pFormat += 2;
2766 continue;
2767 case RPC_FC_PAD:
2768 break;
2769 default:
2770 FIXME("unhandled format 0x%02x\n", *pFormat);
2772 pFormat++;
2775 return pMemory;
2778 static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
2779 unsigned char *pMemory,
2780 PFORMAT_STRING pFormat,
2781 PFORMAT_STRING pPointer,
2782 unsigned char fMustAlloc)
2784 PFORMAT_STRING desc;
2785 NDR_UNMARSHALL m;
2786 ULONG size;
2788 while (*pFormat != RPC_FC_END) {
2789 switch (*pFormat) {
2790 case RPC_FC_BYTE:
2791 case RPC_FC_CHAR:
2792 case RPC_FC_SMALL:
2793 case RPC_FC_USMALL:
2794 safe_copy_from_buffer(pStubMsg, pMemory, 1);
2795 TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory);
2796 pMemory += 1;
2797 break;
2798 case RPC_FC_WCHAR:
2799 case RPC_FC_SHORT:
2800 case RPC_FC_USHORT:
2801 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2802 TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory);
2803 pMemory += 2;
2804 break;
2805 case RPC_FC_ENUM16:
2806 safe_copy_from_buffer(pStubMsg, pMemory, 2);
2807 *(DWORD*)pMemory &= 0xffff;
2808 TRACE("enum16=%d => %p\n", *(DWORD*)pMemory, pMemory);
2809 if (32767 < *(DWORD*)pMemory)
2810 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
2811 pMemory += 4;
2812 break;
2813 case RPC_FC_LONG:
2814 case RPC_FC_ULONG:
2815 case RPC_FC_ENUM32:
2816 safe_copy_from_buffer(pStubMsg, pMemory, 4);
2817 TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
2818 pMemory += 4;
2819 break;
2820 case RPC_FC_HYPER:
2821 safe_copy_from_buffer(pStubMsg, pMemory, 8);
2822 TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
2823 pMemory += 8;
2824 break;
2825 case RPC_FC_POINTER:
2827 unsigned char *saved_buffer;
2828 int pointer_buffer_mark_set = 0;
2829 TRACE("pointer => %p\n", pMemory);
2830 if (*pPointer != RPC_FC_RP)
2831 ALIGN_POINTER(pStubMsg->Buffer, 4);
2832 saved_buffer = pStubMsg->Buffer;
2833 if (pStubMsg->PointerBufferMark)
2835 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
2836 pStubMsg->PointerBufferMark = NULL;
2837 pointer_buffer_mark_set = 1;
2839 else if (*pPointer != RPC_FC_RP)
2840 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2842 PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, fMustAlloc);
2843 if (pointer_buffer_mark_set)
2845 STD_OVERFLOW_CHECK(pStubMsg);
2846 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
2847 pStubMsg->Buffer = saved_buffer;
2848 if (*pPointer != RPC_FC_RP)
2849 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
2851 pPointer += 4;
2852 pMemory += 4;
2853 break;
2855 case RPC_FC_ALIGNM4:
2856 ALIGN_POINTER_CLEAR(pMemory, 4);
2857 break;
2858 case RPC_FC_ALIGNM8:
2859 ALIGN_POINTER_CLEAR(pMemory, 8);
2860 break;
2861 case RPC_FC_STRUCTPAD1:
2862 case RPC_FC_STRUCTPAD2:
2863 case RPC_FC_STRUCTPAD3:
2864 case RPC_FC_STRUCTPAD4:
2865 case RPC_FC_STRUCTPAD5:
2866 case RPC_FC_STRUCTPAD6:
2867 case RPC_FC_STRUCTPAD7:
2868 memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1);
2869 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2870 break;
2871 case RPC_FC_EMBEDDED_COMPLEX:
2872 pMemory += pFormat[1];
2873 pFormat += 2;
2874 desc = pFormat + *(const SHORT*)pFormat;
2875 size = EmbeddedComplexSize(pStubMsg, desc);
2876 TRACE("embedded complex (size=%d) => %p\n", size, pMemory);
2877 if (fMustAlloc)
2878 /* we can't pass fMustAlloc=TRUE into the marshaller for this type
2879 * since the type is part of the memory block that is encompassed by
2880 * the whole complex type. Memory is forced to allocate when pointers
2881 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
2882 * clearing the memory we pass in to the unmarshaller */
2883 memset(pMemory, 0, size);
2884 m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
2885 if (m)
2887 /* for some reason interface pointers aren't generated as
2888 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2889 * they still need the derefencing treatment that pointers are
2890 * given */
2891 if (*desc == RPC_FC_IP)
2892 m(pStubMsg, (unsigned char **)pMemory, desc, FALSE);
2893 else
2894 m(pStubMsg, &pMemory, desc, FALSE);
2896 else FIXME("no unmarshaller for embedded type %02x\n", *desc);
2897 pMemory += size;
2898 pFormat += 2;
2899 continue;
2900 case RPC_FC_PAD:
2901 break;
2902 default:
2903 FIXME("unhandled format %d\n", *pFormat);
2905 pFormat++;
2908 return pMemory;
2911 static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
2912 unsigned char *pMemory,
2913 PFORMAT_STRING pFormat,
2914 PFORMAT_STRING pPointer)
2916 PFORMAT_STRING desc;
2917 NDR_BUFFERSIZE m;
2918 ULONG size;
2920 while (*pFormat != RPC_FC_END) {
2921 switch (*pFormat) {
2922 case RPC_FC_BYTE:
2923 case RPC_FC_CHAR:
2924 case RPC_FC_SMALL:
2925 case RPC_FC_USMALL:
2926 safe_buffer_length_increment(pStubMsg, 1);
2927 pMemory += 1;
2928 break;
2929 case RPC_FC_WCHAR:
2930 case RPC_FC_SHORT:
2931 case RPC_FC_USHORT:
2932 safe_buffer_length_increment(pStubMsg, 2);
2933 pMemory += 2;
2934 break;
2935 case RPC_FC_ENUM16:
2936 safe_buffer_length_increment(pStubMsg, 2);
2937 pMemory += 4;
2938 break;
2939 case RPC_FC_LONG:
2940 case RPC_FC_ULONG:
2941 case RPC_FC_ENUM32:
2942 safe_buffer_length_increment(pStubMsg, 4);
2943 pMemory += 4;
2944 break;
2945 case RPC_FC_HYPER:
2946 safe_buffer_length_increment(pStubMsg, 8);
2947 pMemory += 8;
2948 break;
2949 case RPC_FC_POINTER:
2950 if (!pStubMsg->IgnoreEmbeddedPointers)
2952 int saved_buffer_length = pStubMsg->BufferLength;
2953 pStubMsg->BufferLength = pStubMsg->PointerLength;
2954 pStubMsg->PointerLength = 0;
2955 if(!pStubMsg->BufferLength)
2956 ERR("BufferLength == 0??\n");
2957 PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer);
2958 pStubMsg->PointerLength = pStubMsg->BufferLength;
2959 pStubMsg->BufferLength = saved_buffer_length;
2961 if (*pPointer != RPC_FC_RP)
2963 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
2964 safe_buffer_length_increment(pStubMsg, 4);
2966 pPointer += 4;
2967 pMemory += 4;
2968 break;
2969 case RPC_FC_ALIGNM4:
2970 ALIGN_POINTER(pMemory, 4);
2971 break;
2972 case RPC_FC_ALIGNM8:
2973 ALIGN_POINTER(pMemory, 8);
2974 break;
2975 case RPC_FC_STRUCTPAD1:
2976 case RPC_FC_STRUCTPAD2:
2977 case RPC_FC_STRUCTPAD3:
2978 case RPC_FC_STRUCTPAD4:
2979 case RPC_FC_STRUCTPAD5:
2980 case RPC_FC_STRUCTPAD6:
2981 case RPC_FC_STRUCTPAD7:
2982 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
2983 break;
2984 case RPC_FC_EMBEDDED_COMPLEX:
2985 pMemory += pFormat[1];
2986 pFormat += 2;
2987 desc = pFormat + *(const SHORT*)pFormat;
2988 size = EmbeddedComplexSize(pStubMsg, desc);
2989 m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
2990 if (m)
2992 /* for some reason interface pointers aren't generated as
2993 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
2994 * they still need the derefencing treatment that pointers are
2995 * given */
2996 if (*desc == RPC_FC_IP)
2997 m(pStubMsg, *(unsigned char **)pMemory, desc);
2998 else
2999 m(pStubMsg, pMemory, desc);
3001 else FIXME("no buffersizer for embedded type %02x\n", *desc);
3002 pMemory += size;
3003 pFormat += 2;
3004 continue;
3005 case RPC_FC_PAD:
3006 break;
3007 default:
3008 FIXME("unhandled format 0x%02x\n", *pFormat);
3010 pFormat++;
3013 return pMemory;
3016 static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
3017 unsigned char *pMemory,
3018 PFORMAT_STRING pFormat,
3019 PFORMAT_STRING pPointer)
3021 PFORMAT_STRING desc;
3022 NDR_FREE m;
3023 ULONG size;
3025 while (*pFormat != RPC_FC_END) {
3026 switch (*pFormat) {
3027 case RPC_FC_BYTE:
3028 case RPC_FC_CHAR:
3029 case RPC_FC_SMALL:
3030 case RPC_FC_USMALL:
3031 pMemory += 1;
3032 break;
3033 case RPC_FC_WCHAR:
3034 case RPC_FC_SHORT:
3035 case RPC_FC_USHORT:
3036 pMemory += 2;
3037 break;
3038 case RPC_FC_LONG:
3039 case RPC_FC_ULONG:
3040 case RPC_FC_ENUM16:
3041 case RPC_FC_ENUM32:
3042 pMemory += 4;
3043 break;
3044 case RPC_FC_HYPER:
3045 pMemory += 8;
3046 break;
3047 case RPC_FC_POINTER:
3048 NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer);
3049 pPointer += 4;
3050 pMemory += 4;
3051 break;
3052 case RPC_FC_ALIGNM4:
3053 ALIGN_POINTER(pMemory, 4);
3054 break;
3055 case RPC_FC_ALIGNM8:
3056 ALIGN_POINTER(pMemory, 8);
3057 break;
3058 case RPC_FC_STRUCTPAD1:
3059 case RPC_FC_STRUCTPAD2:
3060 case RPC_FC_STRUCTPAD3:
3061 case RPC_FC_STRUCTPAD4:
3062 case RPC_FC_STRUCTPAD5:
3063 case RPC_FC_STRUCTPAD6:
3064 case RPC_FC_STRUCTPAD7:
3065 pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3066 break;
3067 case RPC_FC_EMBEDDED_COMPLEX:
3068 pMemory += pFormat[1];
3069 pFormat += 2;
3070 desc = pFormat + *(const SHORT*)pFormat;
3071 size = EmbeddedComplexSize(pStubMsg, desc);
3072 m = NdrFreer[*desc & NDR_TABLE_MASK];
3073 if (m)
3075 /* for some reason interface pointers aren't generated as
3076 * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet
3077 * they still need the derefencing treatment that pointers are
3078 * given */
3079 if (*desc == RPC_FC_IP)
3080 m(pStubMsg, *(unsigned char **)pMemory, desc);
3081 else
3082 m(pStubMsg, pMemory, desc);
3084 pMemory += size;
3085 pFormat += 2;
3086 continue;
3087 case RPC_FC_PAD:
3088 break;
3089 default:
3090 FIXME("unhandled format 0x%02x\n", *pFormat);
3092 pFormat++;
3095 return pMemory;
3098 static ULONG ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3099 PFORMAT_STRING pFormat,
3100 PFORMAT_STRING pPointer)
3102 PFORMAT_STRING desc;
3103 ULONG size = 0;
3105 while (*pFormat != RPC_FC_END) {
3106 switch (*pFormat) {
3107 case RPC_FC_BYTE:
3108 case RPC_FC_CHAR:
3109 case RPC_FC_SMALL:
3110 case RPC_FC_USMALL:
3111 size += 1;
3112 safe_buffer_increment(pStubMsg, 1);
3113 break;
3114 case RPC_FC_WCHAR:
3115 case RPC_FC_SHORT:
3116 case RPC_FC_USHORT:
3117 size += 2;
3118 safe_buffer_increment(pStubMsg, 2);
3119 break;
3120 case RPC_FC_ENUM16:
3121 size += 4;
3122 safe_buffer_increment(pStubMsg, 2);
3123 break;
3124 case RPC_FC_LONG:
3125 case RPC_FC_ULONG:
3126 case RPC_FC_ENUM32:
3127 size += 4;
3128 safe_buffer_increment(pStubMsg, 4);
3129 break;
3130 case RPC_FC_HYPER:
3131 size += 8;
3132 safe_buffer_increment(pStubMsg, 8);
3133 break;
3134 case RPC_FC_POINTER:
3136 unsigned char *saved_buffer;
3137 int pointer_buffer_mark_set = 0;
3138 if (*pPointer != RPC_FC_RP)
3139 ALIGN_POINTER(pStubMsg->Buffer, 4);
3140 saved_buffer = pStubMsg->Buffer;
3141 if (pStubMsg->PointerBufferMark)
3143 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3144 pStubMsg->PointerBufferMark = NULL;
3145 pointer_buffer_mark_set = 1;
3147 else if (*pPointer != RPC_FC_RP)
3148 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3150 if (!pStubMsg->IgnoreEmbeddedPointers)
3151 PointerMemorySize(pStubMsg, saved_buffer, pPointer);
3152 if (pointer_buffer_mark_set)
3154 STD_OVERFLOW_CHECK(pStubMsg);
3155 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3156 pStubMsg->Buffer = saved_buffer;
3157 if (*pPointer != RPC_FC_RP)
3158 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
3160 pPointer += 4;
3161 size += 4;
3162 break;
3164 case RPC_FC_ALIGNM4:
3165 ALIGN_LENGTH(size, 4);
3166 break;
3167 case RPC_FC_ALIGNM8:
3168 ALIGN_LENGTH(size, 8);
3169 break;
3170 case RPC_FC_STRUCTPAD1:
3171 case RPC_FC_STRUCTPAD2:
3172 case RPC_FC_STRUCTPAD3:
3173 case RPC_FC_STRUCTPAD4:
3174 case RPC_FC_STRUCTPAD5:
3175 case RPC_FC_STRUCTPAD6:
3176 case RPC_FC_STRUCTPAD7:
3177 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3178 break;
3179 case RPC_FC_EMBEDDED_COMPLEX:
3180 size += pFormat[1];
3181 pFormat += 2;
3182 desc = pFormat + *(const SHORT*)pFormat;
3183 size += EmbeddedComplexMemorySize(pStubMsg, desc);
3184 pFormat += 2;
3185 continue;
3186 case RPC_FC_PAD:
3187 break;
3188 default:
3189 FIXME("unhandled format 0x%02x\n", *pFormat);
3191 pFormat++;
3194 return size;
3197 ULONG ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
3199 PFORMAT_STRING desc;
3200 ULONG size = 0;
3202 while (*pFormat != RPC_FC_END) {
3203 switch (*pFormat) {
3204 case RPC_FC_BYTE:
3205 case RPC_FC_CHAR:
3206 case RPC_FC_SMALL:
3207 case RPC_FC_USMALL:
3208 size += 1;
3209 break;
3210 case RPC_FC_WCHAR:
3211 case RPC_FC_SHORT:
3212 case RPC_FC_USHORT:
3213 size += 2;
3214 break;
3215 case RPC_FC_LONG:
3216 case RPC_FC_ULONG:
3217 case RPC_FC_ENUM16:
3218 case RPC_FC_ENUM32:
3219 size += 4;
3220 break;
3221 case RPC_FC_HYPER:
3222 size += 8;
3223 break;
3224 case RPC_FC_POINTER:
3225 size += sizeof(void *);
3226 break;
3227 case RPC_FC_ALIGNM4:
3228 ALIGN_LENGTH(size, 4);
3229 break;
3230 case RPC_FC_ALIGNM8:
3231 ALIGN_LENGTH(size, 8);
3232 break;
3233 case RPC_FC_STRUCTPAD1:
3234 case RPC_FC_STRUCTPAD2:
3235 case RPC_FC_STRUCTPAD3:
3236 case RPC_FC_STRUCTPAD4:
3237 case RPC_FC_STRUCTPAD5:
3238 case RPC_FC_STRUCTPAD6:
3239 case RPC_FC_STRUCTPAD7:
3240 size += *pFormat - RPC_FC_STRUCTPAD1 + 1;
3241 break;
3242 case RPC_FC_EMBEDDED_COMPLEX:
3243 size += pFormat[1];
3244 pFormat += 2;
3245 desc = pFormat + *(const SHORT*)pFormat;
3246 size += EmbeddedComplexSize(pStubMsg, desc);
3247 pFormat += 2;
3248 continue;
3249 case RPC_FC_PAD:
3250 break;
3251 default:
3252 FIXME("unhandled format 0x%02x\n", *pFormat);
3254 pFormat++;
3257 return size;
3260 /***********************************************************************
3261 * NdrComplexStructMarshall [RPCRT4.@]
3263 unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3264 unsigned char *pMemory,
3265 PFORMAT_STRING pFormat)
3267 PFORMAT_STRING conf_array = NULL;
3268 PFORMAT_STRING pointer_desc = NULL;
3269 unsigned char *OldMemory = pStubMsg->Memory;
3270 int pointer_buffer_mark_set = 0;
3271 ULONG count = 0;
3272 ULONG max_count = 0;
3273 ULONG offset = 0;
3275 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3277 if (!pStubMsg->PointerBufferMark)
3279 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3280 /* save buffer length */
3281 ULONG saved_buffer_length = pStubMsg->BufferLength;
3283 /* get the buffer pointer after complex array data, but before
3284 * pointer data */
3285 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
3286 pStubMsg->IgnoreEmbeddedPointers = 1;
3287 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3288 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3290 /* save it for use by embedded pointer code later */
3291 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
3292 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - pStubMsg->Buffer));
3293 pointer_buffer_mark_set = 1;
3295 /* restore the original buffer length */
3296 pStubMsg->BufferLength = saved_buffer_length;
3299 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1);
3301 pFormat += 4;
3302 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3303 pFormat += 2;
3304 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3305 pFormat += 2;
3307 pStubMsg->Memory = pMemory;
3309 if (conf_array)
3311 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat);
3312 array_compute_and_write_conformance(conf_array[0], pStubMsg,
3313 pMemory + struct_size, conf_array);
3314 /* these could be changed in ComplexMarshall so save them for later */
3315 max_count = pStubMsg->MaxCount;
3316 count = pStubMsg->ActualCount;
3317 offset = pStubMsg->Offset;
3320 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc);
3322 if (conf_array)
3324 pStubMsg->MaxCount = max_count;
3325 pStubMsg->ActualCount = count;
3326 pStubMsg->Offset = offset;
3327 array_write_variance_and_marshall(conf_array[0], pStubMsg, pMemory,
3328 conf_array, TRUE /* fHasPointers */);
3331 pStubMsg->Memory = OldMemory;
3333 if (pointer_buffer_mark_set)
3335 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3336 pStubMsg->PointerBufferMark = NULL;
3339 STD_OVERFLOW_CHECK(pStubMsg);
3341 return NULL;
3344 /***********************************************************************
3345 * NdrComplexStructUnmarshall [RPCRT4.@]
3347 unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3348 unsigned char **ppMemory,
3349 PFORMAT_STRING pFormat,
3350 unsigned char fMustAlloc)
3352 unsigned size = *(const WORD*)(pFormat+2);
3353 PFORMAT_STRING conf_array = NULL;
3354 PFORMAT_STRING pointer_desc = NULL;
3355 unsigned char *pMemory;
3356 int pointer_buffer_mark_set = 0;
3357 ULONG count = 0;
3358 ULONG max_count = 0;
3359 ULONG offset = 0;
3360 ULONG array_size = 0;
3362 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3364 if (!pStubMsg->PointerBufferMark)
3366 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3367 /* save buffer pointer */
3368 unsigned char *saved_buffer = pStubMsg->Buffer;
3370 /* get the buffer pointer after complex array data, but before
3371 * pointer data */
3372 pStubMsg->IgnoreEmbeddedPointers = 1;
3373 NdrComplexStructMemorySize(pStubMsg, pFormat);
3374 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3376 /* save it for use by embedded pointer code later */
3377 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3378 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - saved_buffer));
3379 pointer_buffer_mark_set = 1;
3381 /* restore the original buffer */
3382 pStubMsg->Buffer = saved_buffer;
3385 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
3387 pFormat += 4;
3388 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3389 pFormat += 2;
3390 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3391 pFormat += 2;
3393 if (conf_array)
3395 array_size = array_read_conformance(conf_array[0], pStubMsg, conf_array);
3396 size += array_size;
3398 /* these could be changed in ComplexMarshall so save them for later */
3399 max_count = pStubMsg->MaxCount;
3400 count = pStubMsg->ActualCount;
3401 offset = pStubMsg->Offset;
3404 if (!fMustAlloc && !*ppMemory)
3405 fMustAlloc = TRUE;
3406 if (fMustAlloc)
3407 *ppMemory = NdrAllocate(pStubMsg, size);
3409 pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc);
3411 if (conf_array)
3413 pStubMsg->MaxCount = max_count;
3414 pStubMsg->ActualCount = count;
3415 pStubMsg->Offset = offset;
3416 if (fMustAlloc)
3417 memset(pMemory, 0, array_size);
3418 array_read_variance_and_unmarshall(conf_array[0], pStubMsg, &pMemory,
3419 conf_array, FALSE,
3420 FALSE /* fUseBufferMemoryServer */,
3421 TRUE /* fUnmarshall */);
3424 if (pointer_buffer_mark_set)
3426 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3427 pStubMsg->PointerBufferMark = NULL;
3430 return NULL;
3433 /***********************************************************************
3434 * NdrComplexStructBufferSize [RPCRT4.@]
3436 void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3437 unsigned char *pMemory,
3438 PFORMAT_STRING pFormat)
3440 PFORMAT_STRING conf_array = NULL;
3441 PFORMAT_STRING pointer_desc = NULL;
3442 unsigned char *OldMemory = pStubMsg->Memory;
3443 int pointer_length_set = 0;
3444 ULONG count = 0;
3445 ULONG max_count = 0;
3446 ULONG offset = 0;
3448 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3450 ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1);
3452 if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3454 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3455 ULONG saved_buffer_length = pStubMsg->BufferLength;
3457 /* get the buffer length after complex struct data, but before
3458 * pointer data */
3459 pStubMsg->IgnoreEmbeddedPointers = 1;
3460 NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
3461 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3463 /* save it for use by embedded pointer code later */
3464 pStubMsg->PointerLength = pStubMsg->BufferLength;
3465 pointer_length_set = 1;
3466 TRACE("difference = 0x%x\n", pStubMsg->PointerLength - saved_buffer_length);
3468 /* restore the original buffer length */
3469 pStubMsg->BufferLength = saved_buffer_length;
3472 pFormat += 4;
3473 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3474 pFormat += 2;
3475 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3476 pFormat += 2;
3478 pStubMsg->Memory = pMemory;
3480 if (conf_array)
3482 ULONG struct_size = ComplexStructSize(pStubMsg, pFormat);
3483 array_compute_and_size_conformance(conf_array[0], pStubMsg, pMemory + struct_size,
3484 conf_array);
3486 /* these could be changed in ComplexMarshall so save them for later */
3487 max_count = pStubMsg->MaxCount;
3488 count = pStubMsg->ActualCount;
3489 offset = pStubMsg->Offset;
3492 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc);
3494 if (conf_array)
3496 pStubMsg->MaxCount = max_count;
3497 pStubMsg->ActualCount = count;
3498 pStubMsg->Offset = offset;
3499 array_buffer_size(conf_array[0], pStubMsg, pMemory, conf_array,
3500 TRUE /* fHasPointers */);
3503 pStubMsg->Memory = OldMemory;
3505 if(pointer_length_set)
3507 pStubMsg->BufferLength = pStubMsg->PointerLength;
3508 pStubMsg->PointerLength = 0;
3513 /***********************************************************************
3514 * NdrComplexStructMemorySize [RPCRT4.@]
3516 ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3517 PFORMAT_STRING pFormat)
3519 unsigned size = *(const WORD*)(pFormat+2);
3520 PFORMAT_STRING conf_array = NULL;
3521 PFORMAT_STRING pointer_desc = NULL;
3522 ULONG count = 0;
3523 ULONG max_count = 0;
3524 ULONG offset = 0;
3526 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3528 ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
3530 pFormat += 4;
3531 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3532 pFormat += 2;
3533 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3534 pFormat += 2;
3536 if (conf_array)
3538 array_read_conformance(conf_array[0], pStubMsg, conf_array);
3540 /* these could be changed in ComplexStructMemorySize so save them for
3541 * later */
3542 max_count = pStubMsg->MaxCount;
3543 count = pStubMsg->ActualCount;
3544 offset = pStubMsg->Offset;
3547 ComplexStructMemorySize(pStubMsg, pFormat, pointer_desc);
3549 if (conf_array)
3551 pStubMsg->MaxCount = max_count;
3552 pStubMsg->ActualCount = count;
3553 pStubMsg->Offset = offset;
3554 array_memory_size(conf_array[0], pStubMsg, conf_array,
3555 TRUE /* fHasPointers */);
3558 return size;
3561 /***********************************************************************
3562 * NdrComplexStructFree [RPCRT4.@]
3564 void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg,
3565 unsigned char *pMemory,
3566 PFORMAT_STRING pFormat)
3568 PFORMAT_STRING conf_array = NULL;
3569 PFORMAT_STRING pointer_desc = NULL;
3570 unsigned char *OldMemory = pStubMsg->Memory;
3572 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3574 pFormat += 4;
3575 if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat;
3576 pFormat += 2;
3577 if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat;
3578 pFormat += 2;
3580 pStubMsg->Memory = pMemory;
3582 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc);
3584 if (conf_array)
3585 array_free(conf_array[0], pStubMsg, pMemory, conf_array,
3586 TRUE /* fHasPointers */);
3588 pStubMsg->Memory = OldMemory;
3591 /***********************************************************************
3592 * NdrConformantArrayMarshall [RPCRT4.@]
3594 unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3595 unsigned char *pMemory,
3596 PFORMAT_STRING pFormat)
3598 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3599 if (pFormat[0] != RPC_FC_CARRAY)
3601 ERR("invalid format = 0x%x\n", pFormat[0]);
3602 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3605 array_compute_and_write_conformance(RPC_FC_CARRAY, pStubMsg, pMemory,
3606 pFormat);
3607 array_write_variance_and_marshall(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3608 TRUE /* fHasPointers */);
3610 return NULL;
3613 /***********************************************************************
3614 * NdrConformantArrayUnmarshall [RPCRT4.@]
3616 unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3617 unsigned char **ppMemory,
3618 PFORMAT_STRING pFormat,
3619 unsigned char fMustAlloc)
3621 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3622 if (pFormat[0] != RPC_FC_CARRAY)
3624 ERR("invalid format = 0x%x\n", pFormat[0]);
3625 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3628 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3629 array_read_variance_and_unmarshall(RPC_FC_CARRAY, pStubMsg, ppMemory, pFormat,
3630 fMustAlloc,
3631 TRUE /* fUseBufferMemoryServer */,
3632 TRUE /* fUnmarshall */);
3634 return NULL;
3637 /***********************************************************************
3638 * NdrConformantArrayBufferSize [RPCRT4.@]
3640 void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3641 unsigned char *pMemory,
3642 PFORMAT_STRING pFormat)
3644 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3645 if (pFormat[0] != RPC_FC_CARRAY)
3647 ERR("invalid format = 0x%x\n", pFormat[0]);
3648 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3651 array_compute_and_size_conformance(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat);
3652 array_buffer_size(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3653 TRUE /* fHasPointers */);
3656 /***********************************************************************
3657 * NdrConformantArrayMemorySize [RPCRT4.@]
3659 ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
3660 PFORMAT_STRING pFormat)
3662 TRACE("(%p,%p)\n", pStubMsg, pFormat);
3663 if (pFormat[0] != RPC_FC_CARRAY)
3665 ERR("invalid format = 0x%x\n", pFormat[0]);
3666 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3669 array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat);
3670 array_memory_size(RPC_FC_CARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
3672 return pStubMsg->MemorySize;
3675 /***********************************************************************
3676 * NdrConformantArrayFree [RPCRT4.@]
3678 void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
3679 unsigned char *pMemory,
3680 PFORMAT_STRING pFormat)
3682 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3683 if (pFormat[0] != RPC_FC_CARRAY)
3685 ERR("invalid format = 0x%x\n", pFormat[0]);
3686 RpcRaiseException(RPC_X_BAD_STUB_DATA);
3689 array_free(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat,
3690 TRUE /* fHasPointers */);
3694 /***********************************************************************
3695 * NdrConformantVaryingArrayMarshall [RPCRT4.@]
3697 unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg,
3698 unsigned char* pMemory,
3699 PFORMAT_STRING pFormat )
3701 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3703 if (pFormat[0] != RPC_FC_CVARRAY)
3705 ERR("invalid format type %x\n", pFormat[0]);
3706 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3707 return NULL;
3710 array_compute_and_write_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
3711 pFormat);
3712 array_write_variance_and_marshall(RPC_FC_CVARRAY, pStubMsg, pMemory,
3713 pFormat, TRUE /* fHasPointers */);
3715 return NULL;
3719 /***********************************************************************
3720 * NdrConformantVaryingArrayUnmarshall [RPCRT4.@]
3722 unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg,
3723 unsigned char** ppMemory,
3724 PFORMAT_STRING pFormat,
3725 unsigned char fMustAlloc )
3727 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3729 if (pFormat[0] != RPC_FC_CVARRAY)
3731 ERR("invalid format type %x\n", pFormat[0]);
3732 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3733 return NULL;
3736 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
3737 array_read_variance_and_unmarshall(RPC_FC_CVARRAY, pStubMsg, ppMemory,
3738 pFormat, fMustAlloc,
3739 TRUE /* fUseBufferMemoryServer */,
3740 TRUE /* fUnmarshall */);
3742 return NULL;
3746 /***********************************************************************
3747 * NdrConformantVaryingArrayFree [RPCRT4.@]
3749 void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
3750 unsigned char* pMemory,
3751 PFORMAT_STRING pFormat )
3753 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3755 if (pFormat[0] != RPC_FC_CVARRAY)
3757 ERR("invalid format type %x\n", pFormat[0]);
3758 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3759 return;
3762 array_free(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
3763 TRUE /* fHasPointers */);
3767 /***********************************************************************
3768 * NdrConformantVaryingArrayBufferSize [RPCRT4.@]
3770 void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg,
3771 unsigned char* pMemory, PFORMAT_STRING pFormat )
3773 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
3775 if (pFormat[0] != RPC_FC_CVARRAY)
3777 ERR("invalid format type %x\n", pFormat[0]);
3778 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3779 return;
3782 array_compute_and_size_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory,
3783 pFormat);
3784 array_buffer_size(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat,
3785 TRUE /* fHasPointers */);
3789 /***********************************************************************
3790 * NdrConformantVaryingArrayMemorySize [RPCRT4.@]
3792 ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg,
3793 PFORMAT_STRING pFormat )
3795 TRACE("(%p, %p)\n", pStubMsg, pFormat);
3797 if (pFormat[0] != RPC_FC_CVARRAY)
3799 ERR("invalid format type %x\n", pFormat[0]);
3800 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3801 return pStubMsg->MemorySize;
3804 array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat);
3805 array_memory_size(RPC_FC_CVARRAY, pStubMsg, pFormat,
3806 TRUE /* fHasPointers */);
3808 return pStubMsg->MemorySize;
3812 /***********************************************************************
3813 * NdrComplexArrayMarshall [RPCRT4.@]
3815 unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
3816 unsigned char *pMemory,
3817 PFORMAT_STRING pFormat)
3819 ULONG i, count, def;
3820 BOOL variance_present;
3821 unsigned char alignment;
3822 int pointer_buffer_mark_set = 0;
3824 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3826 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3828 ERR("invalid format type %x\n", pFormat[0]);
3829 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3830 return NULL;
3833 alignment = pFormat[1] + 1;
3835 if (!pStubMsg->PointerBufferMark)
3837 /* save buffer fields that may be changed by buffer sizer functions
3838 * and that may be needed later on */
3839 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3840 ULONG saved_buffer_length = pStubMsg->BufferLength;
3841 ULONG_PTR saved_max_count = pStubMsg->MaxCount;
3842 ULONG saved_offset = pStubMsg->Offset;
3843 ULONG saved_actual_count = pStubMsg->ActualCount;
3845 /* get the buffer pointer after complex array data, but before
3846 * pointer data */
3847 pStubMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer;
3848 pStubMsg->IgnoreEmbeddedPointers = 1;
3849 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
3850 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3852 /* save it for use by embedded pointer code later */
3853 pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength;
3854 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer));
3855 pointer_buffer_mark_set = 1;
3857 /* restore fields */
3858 pStubMsg->ActualCount = saved_actual_count;
3859 pStubMsg->Offset = saved_offset;
3860 pStubMsg->MaxCount = saved_max_count;
3861 pStubMsg->BufferLength = saved_buffer_length;
3864 def = *(const WORD*)&pFormat[2];
3865 pFormat += 4;
3867 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
3868 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
3870 variance_present = IsConformanceOrVariancePresent(pFormat);
3871 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
3872 TRACE("variance = %d\n", pStubMsg->ActualCount);
3874 WriteConformance(pStubMsg);
3875 if (variance_present)
3876 WriteVariance(pStubMsg);
3878 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
3880 count = pStubMsg->ActualCount;
3881 for (i = 0; i < count; i++)
3882 pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
3884 STD_OVERFLOW_CHECK(pStubMsg);
3886 if (pointer_buffer_mark_set)
3888 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3889 pStubMsg->PointerBufferMark = NULL;
3892 return NULL;
3895 /***********************************************************************
3896 * NdrComplexArrayUnmarshall [RPCRT4.@]
3898 unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
3899 unsigned char **ppMemory,
3900 PFORMAT_STRING pFormat,
3901 unsigned char fMustAlloc)
3903 ULONG i, count, size;
3904 unsigned char alignment;
3905 unsigned char *pMemory;
3906 unsigned char *saved_buffer;
3907 int pointer_buffer_mark_set = 0;
3908 int saved_ignore_embedded;
3910 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
3912 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3914 ERR("invalid format type %x\n", pFormat[0]);
3915 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3916 return NULL;
3919 alignment = pFormat[1] + 1;
3921 saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3922 /* save buffer pointer */
3923 saved_buffer = pStubMsg->Buffer;
3924 /* get the buffer pointer after complex array data, but before
3925 * pointer data */
3926 pStubMsg->IgnoreEmbeddedPointers = 1;
3927 pStubMsg->MemorySize = 0;
3928 NdrComplexArrayMemorySize(pStubMsg, pFormat);
3929 size = pStubMsg->MemorySize;
3930 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
3932 TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - saved_buffer));
3933 if (!pStubMsg->PointerBufferMark)
3935 /* save it for use by embedded pointer code later */
3936 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
3937 pointer_buffer_mark_set = 1;
3939 /* restore the original buffer */
3940 pStubMsg->Buffer = saved_buffer;
3942 pFormat += 4;
3944 pFormat = ReadConformance(pStubMsg, pFormat);
3945 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
3947 if (!fMustAlloc && !*ppMemory)
3948 fMustAlloc = TRUE;
3949 if (fMustAlloc)
3950 *ppMemory = NdrAllocate(pStubMsg, size);
3952 ALIGN_POINTER(pStubMsg->Buffer, alignment);
3954 pMemory = *ppMemory;
3955 count = pStubMsg->ActualCount;
3956 for (i = 0; i < count; i++)
3957 pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
3959 if (pointer_buffer_mark_set)
3961 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
3962 pStubMsg->PointerBufferMark = NULL;
3965 return NULL;
3968 /***********************************************************************
3969 * NdrComplexArrayBufferSize [RPCRT4.@]
3971 void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
3972 unsigned char *pMemory,
3973 PFORMAT_STRING pFormat)
3975 ULONG i, count, def;
3976 unsigned char alignment;
3977 BOOL variance_present;
3978 int pointer_length_set = 0;
3980 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
3982 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
3984 ERR("invalid format type %x\n", pFormat[0]);
3985 RpcRaiseException(RPC_S_INTERNAL_ERROR);
3986 return;
3989 alignment = pFormat[1] + 1;
3991 if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
3993 /* save buffer fields that may be changed by buffer sizer functions
3994 * and that may be needed later on */
3995 int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
3996 ULONG saved_buffer_length = pStubMsg->BufferLength;
3997 ULONG_PTR saved_max_count = pStubMsg->MaxCount;
3998 ULONG saved_offset = pStubMsg->Offset;
3999 ULONG saved_actual_count = pStubMsg->ActualCount;
4001 /* get the buffer pointer after complex array data, but before
4002 * pointer data */
4003 pStubMsg->IgnoreEmbeddedPointers = 1;
4004 NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat);
4005 pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
4007 /* save it for use by embedded pointer code later */
4008 pStubMsg->PointerLength = pStubMsg->BufferLength;
4009 pointer_length_set = 1;
4011 /* restore fields */
4012 pStubMsg->ActualCount = saved_actual_count;
4013 pStubMsg->Offset = saved_offset;
4014 pStubMsg->MaxCount = saved_max_count;
4015 pStubMsg->BufferLength = saved_buffer_length;
4017 def = *(const WORD*)&pFormat[2];
4018 pFormat += 4;
4020 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
4021 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
4022 SizeConformance(pStubMsg);
4024 variance_present = IsConformanceOrVariancePresent(pFormat);
4025 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4026 TRACE("variance = %d\n", pStubMsg->ActualCount);
4028 if (variance_present)
4029 SizeVariance(pStubMsg);
4031 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
4033 count = pStubMsg->ActualCount;
4034 for (i = 0; i < count; i++)
4035 pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
4037 if(pointer_length_set)
4039 pStubMsg->BufferLength = pStubMsg->PointerLength;
4040 pStubMsg->PointerLength = 0;
4044 /***********************************************************************
4045 * NdrComplexArrayMemorySize [RPCRT4.@]
4047 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4048 PFORMAT_STRING pFormat)
4050 ULONG i, count, esize, SavedMemorySize, MemorySize;
4051 unsigned char alignment;
4053 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4055 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4057 ERR("invalid format type %x\n", pFormat[0]);
4058 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4059 return 0;
4062 alignment = pFormat[1] + 1;
4064 pFormat += 4;
4066 pFormat = ReadConformance(pStubMsg, pFormat);
4067 pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
4069 ALIGN_POINTER(pStubMsg->Buffer, alignment);
4071 SavedMemorySize = pStubMsg->MemorySize;
4073 esize = ComplexStructSize(pStubMsg, pFormat);
4075 MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
4077 count = pStubMsg->ActualCount;
4078 for (i = 0; i < count; i++)
4079 ComplexStructMemorySize(pStubMsg, pFormat, NULL);
4081 pStubMsg->MemorySize = SavedMemorySize;
4083 pStubMsg->MemorySize += MemorySize;
4084 return MemorySize;
4087 /***********************************************************************
4088 * NdrComplexArrayFree [RPCRT4.@]
4090 void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
4091 unsigned char *pMemory,
4092 PFORMAT_STRING pFormat)
4094 ULONG i, count, def;
4096 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4098 if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
4100 ERR("invalid format type %x\n", pFormat[0]);
4101 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4102 return;
4105 def = *(const WORD*)&pFormat[2];
4106 pFormat += 4;
4108 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
4109 TRACE("conformance = %ld\n", pStubMsg->MaxCount);
4111 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
4112 TRACE("variance = %d\n", pStubMsg->ActualCount);
4114 count = pStubMsg->ActualCount;
4115 for (i = 0; i < count; i++)
4116 pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
4119 static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg,
4120 USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat,
4121 USER_MARSHAL_CB *umcb)
4123 umcb->Flags = MAKELONG(pStubMsg->dwDestContext,
4124 pStubMsg->RpcMsg->DataRepresentation);
4125 umcb->pStubMsg = pStubMsg;
4126 umcb->pReserve = NULL;
4127 umcb->Signature = USER_MARSHAL_CB_SIGNATURE;
4128 umcb->CBType = cbtype;
4129 umcb->pFormat = pFormat;
4130 umcb->pTypeFormat = NULL /* FIXME */;
4133 #define USER_MARSHAL_PTR_PREFIX \
4134 ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \
4135 ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
4137 /***********************************************************************
4138 * NdrUserMarshalMarshall [RPCRT4.@]
4140 unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4141 unsigned char *pMemory,
4142 PFORMAT_STRING pFormat)
4144 unsigned flags = pFormat[1];
4145 unsigned index = *(const WORD*)&pFormat[2];
4146 unsigned char *saved_buffer = NULL;
4147 USER_MARSHAL_CB umcb;
4149 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4150 TRACE("index=%d\n", index);
4152 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb);
4154 if (flags & USER_MARSHAL_POINTER)
4156 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
4157 NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX);
4158 pStubMsg->Buffer += 4;
4159 if (pStubMsg->PointerBufferMark)
4161 saved_buffer = pStubMsg->Buffer;
4162 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4163 pStubMsg->PointerBufferMark = NULL;
4165 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 8);
4167 else
4168 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, (flags & 0xf) + 1);
4170 pStubMsg->Buffer =
4171 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall(
4172 &umcb.Flags, pStubMsg->Buffer, pMemory);
4174 if (saved_buffer)
4176 STD_OVERFLOW_CHECK(pStubMsg);
4177 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4178 pStubMsg->Buffer = saved_buffer;
4181 STD_OVERFLOW_CHECK(pStubMsg);
4183 return NULL;
4186 /***********************************************************************
4187 * NdrUserMarshalUnmarshall [RPCRT4.@]
4189 unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4190 unsigned char **ppMemory,
4191 PFORMAT_STRING pFormat,
4192 unsigned char fMustAlloc)
4194 unsigned flags = pFormat[1];
4195 unsigned index = *(const WORD*)&pFormat[2];
4196 DWORD memsize = *(const WORD*)&pFormat[4];
4197 unsigned char *saved_buffer = NULL;
4198 USER_MARSHAL_CB umcb;
4200 TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4201 TRACE("index=%d\n", index);
4203 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb);
4205 if (flags & USER_MARSHAL_POINTER)
4207 ALIGN_POINTER(pStubMsg->Buffer, 4);
4208 /* skip pointer prefix */
4209 pStubMsg->Buffer += 4;
4210 if (pStubMsg->PointerBufferMark)
4212 saved_buffer = pStubMsg->Buffer;
4213 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
4214 pStubMsg->PointerBufferMark = NULL;
4216 ALIGN_POINTER(pStubMsg->Buffer, 8);
4218 else
4219 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
4221 if (!fMustAlloc && !*ppMemory)
4222 fMustAlloc = TRUE;
4223 if (fMustAlloc)
4225 *ppMemory = NdrAllocate(pStubMsg, memsize);
4226 memset(*ppMemory, 0, memsize);
4229 pStubMsg->Buffer =
4230 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall(
4231 &umcb.Flags, pStubMsg->Buffer, *ppMemory);
4233 if (saved_buffer)
4235 STD_OVERFLOW_CHECK(pStubMsg);
4236 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
4237 pStubMsg->Buffer = saved_buffer;
4240 return NULL;
4243 /***********************************************************************
4244 * NdrUserMarshalBufferSize [RPCRT4.@]
4246 void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4247 unsigned char *pMemory,
4248 PFORMAT_STRING pFormat)
4250 unsigned flags = pFormat[1];
4251 unsigned index = *(const WORD*)&pFormat[2];
4252 DWORD bufsize = *(const WORD*)&pFormat[6];
4253 USER_MARSHAL_CB umcb;
4254 ULONG saved_buffer_length = 0;
4256 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4257 TRACE("index=%d\n", index);
4259 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb);
4261 if (flags & USER_MARSHAL_POINTER)
4263 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
4264 /* skip pointer prefix */
4265 safe_buffer_length_increment(pStubMsg, 4);
4266 if (pStubMsg->IgnoreEmbeddedPointers)
4267 return;
4268 if (pStubMsg->PointerLength)
4270 saved_buffer_length = pStubMsg->BufferLength;
4271 pStubMsg->BufferLength = pStubMsg->PointerLength;
4272 pStubMsg->PointerLength = 0;
4274 ALIGN_LENGTH(pStubMsg->BufferLength, 8);
4276 else
4277 ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1);
4279 if (bufsize) {
4280 TRACE("size=%d\n", bufsize);
4281 safe_buffer_length_increment(pStubMsg, bufsize);
4283 else
4284 pStubMsg->BufferLength =
4285 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize(
4286 &umcb.Flags, pStubMsg->BufferLength, pMemory);
4288 if (saved_buffer_length)
4290 pStubMsg->PointerLength = pStubMsg->BufferLength;
4291 pStubMsg->BufferLength = saved_buffer_length;
4296 /***********************************************************************
4297 * NdrUserMarshalMemorySize [RPCRT4.@]
4299 ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4300 PFORMAT_STRING pFormat)
4302 unsigned flags = pFormat[1];
4303 unsigned index = *(const WORD*)&pFormat[2];
4304 DWORD memsize = *(const WORD*)&pFormat[4];
4305 DWORD bufsize = *(const WORD*)&pFormat[6];
4307 TRACE("(%p,%p)\n", pStubMsg, pFormat);
4308 TRACE("index=%d\n", index);
4310 pStubMsg->MemorySize += memsize;
4312 if (flags & USER_MARSHAL_POINTER)
4314 ALIGN_POINTER(pStubMsg->Buffer, 4);
4315 /* skip pointer prefix */
4316 pStubMsg->Buffer += 4;
4317 if (pStubMsg->IgnoreEmbeddedPointers)
4318 return pStubMsg->MemorySize;
4319 ALIGN_POINTER(pStubMsg->Buffer, 8);
4321 else
4322 ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1);
4324 if (!bufsize)
4325 FIXME("not implemented for varying buffer size\n");
4327 pStubMsg->Buffer += bufsize;
4329 return pStubMsg->MemorySize;
4332 /***********************************************************************
4333 * NdrUserMarshalFree [RPCRT4.@]
4335 void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg,
4336 unsigned char *pMemory,
4337 PFORMAT_STRING pFormat)
4339 /* unsigned flags = pFormat[1]; */
4340 unsigned index = *(const WORD*)&pFormat[2];
4341 USER_MARSHAL_CB umcb;
4343 TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
4344 TRACE("index=%d\n", index);
4346 UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb);
4348 pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree(
4349 &umcb.Flags, pMemory);
4352 /***********************************************************************
4353 * NdrGetUserMarshalInfo [RPCRT4.@]
4355 RPC_STATUS RPC_ENTRY NdrGetUserMarshalInfo(ULONG *flags, ULONG level, NDR_USER_MARSHAL_INFO *umi)
4357 USER_MARSHAL_CB *umcb = CONTAINING_RECORD(flags, USER_MARSHAL_CB, Flags);
4359 TRACE("(%p,%u,%p)\n", flags, level, umi);
4361 if (level != 1)
4362 return RPC_S_INVALID_ARG;
4364 memset(&umi->Level1, 0, sizeof(umi->Level1));
4365 umi->InformationLevel = level;
4367 if (umcb->Signature != USER_MARSHAL_CB_SIGNATURE)
4368 return RPC_S_INVALID_ARG;
4370 umi->Level1.pfnAllocate = umcb->pStubMsg->pfnAllocate;
4371 umi->Level1.pfnFree = umcb->pStubMsg->pfnFree;
4372 umi->Level1.pRpcChannelBuffer = umcb->pStubMsg->pRpcChannelBuffer;
4374 switch (umcb->CBType)
4376 case USER_MARSHAL_CB_MARSHALL:
4377 case USER_MARSHAL_CB_UNMARSHALL:
4379 RPC_MESSAGE *msg = umcb->pStubMsg->RpcMsg;
4380 unsigned char *buffer_start = msg->Buffer;
4381 unsigned char *buffer_end =
4382 (unsigned char *)msg->Buffer + msg->BufferLength;
4384 if (umcb->pStubMsg->Buffer < buffer_start ||
4385 umcb->pStubMsg->Buffer > buffer_end)
4386 return ERROR_INVALID_USER_BUFFER;
4388 umi->Level1.Buffer = umcb->pStubMsg->Buffer;
4389 umi->Level1.BufferSize = buffer_end - umcb->pStubMsg->Buffer;
4390 break;
4392 case USER_MARSHAL_CB_BUFFER_SIZE:
4393 case USER_MARSHAL_CB_FREE:
4394 break;
4395 default:
4396 WARN("unrecognised CBType %d\n", umcb->CBType);
4399 return RPC_S_OK;
4402 /***********************************************************************
4403 * NdrClearOutParameters [RPCRT4.@]
4405 void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg,
4406 PFORMAT_STRING pFormat,
4407 void *ArgAddr)
4409 FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr);
4412 /***********************************************************************
4413 * NdrConvert [RPCRT4.@]
4415 void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat )
4417 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat);
4418 /* FIXME: since this stub doesn't do any converting, the proper behavior
4419 is to raise an exception */
4422 /***********************************************************************
4423 * NdrConvert2 [RPCRT4.@]
4425 void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams )
4427 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n",
4428 pStubMsg, pFormat, NumberParams);
4429 /* FIXME: since this stub doesn't do any converting, the proper behavior
4430 is to raise an exception */
4433 #include "pshpack1.h"
4434 typedef struct _NDR_CSTRUCT_FORMAT
4436 unsigned char type;
4437 unsigned char alignment;
4438 unsigned short memory_size;
4439 short offset_to_array_description;
4440 } NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT;
4441 #include "poppack.h"
4443 /***********************************************************************
4444 * NdrConformantStructMarshall [RPCRT4.@]
4446 unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4447 unsigned char *pMemory,
4448 PFORMAT_STRING pFormat)
4450 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4451 PFORMAT_STRING pCArrayFormat;
4452 ULONG esize, bufsize;
4454 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4456 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4457 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4459 ERR("invalid format type %x\n", pCStructFormat->type);
4460 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4461 return NULL;
4464 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4465 pCStructFormat->offset_to_array_description;
4466 if (*pCArrayFormat != RPC_FC_CARRAY)
4468 ERR("invalid array format type %x\n", pCStructFormat->type);
4469 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4470 return NULL;
4472 esize = *(const WORD*)(pCArrayFormat+2);
4474 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4475 pCArrayFormat + 4, 0);
4477 WriteConformance(pStubMsg);
4479 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCStructFormat->alignment + 1);
4481 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4483 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4484 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4486 ERR("integer overflow of memory_size %u with bufsize %u\n",
4487 pCStructFormat->memory_size, bufsize);
4488 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4490 /* copy constant sized part of struct */
4491 pStubMsg->BufferMark = pStubMsg->Buffer;
4492 safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
4494 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4495 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4497 return NULL;
4500 /***********************************************************************
4501 * NdrConformantStructUnmarshall [RPCRT4.@]
4503 unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4504 unsigned char **ppMemory,
4505 PFORMAT_STRING pFormat,
4506 unsigned char fMustAlloc)
4508 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4509 PFORMAT_STRING pCArrayFormat;
4510 ULONG esize, bufsize;
4511 unsigned char *saved_buffer;
4513 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4515 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4516 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4518 ERR("invalid format type %x\n", pCStructFormat->type);
4519 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4520 return NULL;
4522 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4523 pCStructFormat->offset_to_array_description;
4524 if (*pCArrayFormat != RPC_FC_CARRAY)
4526 ERR("invalid array format type %x\n", pCStructFormat->type);
4527 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4528 return NULL;
4530 esize = *(const WORD*)(pCArrayFormat+2);
4532 pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4);
4534 ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1);
4536 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4538 bufsize = safe_multiply(esize, pStubMsg->MaxCount);
4539 if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */
4541 ERR("integer overflow of memory_size %u with bufsize %u\n",
4542 pCStructFormat->memory_size, bufsize);
4543 RpcRaiseException(RPC_X_BAD_STUB_DATA);
4546 if (fMustAlloc)
4548 SIZE_T size = pCStructFormat->memory_size + bufsize;
4549 *ppMemory = NdrAllocate(pStubMsg, size);
4551 else
4553 if (!pStubMsg->IsClient && !*ppMemory)
4554 /* for servers, we just point straight into the RPC buffer */
4555 *ppMemory = pStubMsg->Buffer;
4558 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4559 safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize);
4560 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4561 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4563 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
4564 if (*ppMemory != saved_buffer)
4565 memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize);
4567 return NULL;
4570 /***********************************************************************
4571 * NdrConformantStructBufferSize [RPCRT4.@]
4573 void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4574 unsigned char *pMemory,
4575 PFORMAT_STRING pFormat)
4577 const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4578 PFORMAT_STRING pCArrayFormat;
4579 ULONG esize;
4581 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4583 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4584 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4586 ERR("invalid format type %x\n", pCStructFormat->type);
4587 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4588 return;
4590 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4591 pCStructFormat->offset_to_array_description;
4592 if (*pCArrayFormat != RPC_FC_CARRAY)
4594 ERR("invalid array format type %x\n", pCStructFormat->type);
4595 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4596 return;
4598 esize = *(const WORD*)(pCArrayFormat+2);
4600 pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0);
4601 SizeConformance(pStubMsg);
4603 ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1);
4605 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4607 safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size);
4608 safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize));
4610 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4611 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4614 /***********************************************************************
4615 * NdrConformantStructMemorySize [RPCRT4.@]
4617 ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4618 PFORMAT_STRING pFormat)
4620 FIXME("stub\n");
4621 return 0;
4624 /***********************************************************************
4625 * NdrConformantStructFree [RPCRT4.@]
4627 void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4628 unsigned char *pMemory,
4629 PFORMAT_STRING pFormat)
4631 const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat;
4632 PFORMAT_STRING pCArrayFormat;
4634 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4636 pFormat += sizeof(NDR_CSTRUCT_FORMAT);
4637 if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
4639 ERR("invalid format type %x\n", pCStructFormat->type);
4640 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4641 return;
4644 pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description +
4645 pCStructFormat->offset_to_array_description;
4646 if (*pCArrayFormat != RPC_FC_CARRAY)
4648 ERR("invalid array format type %x\n", pCStructFormat->type);
4649 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4650 return;
4653 ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size,
4654 pCArrayFormat + 4, 0);
4656 TRACE("memory_size = %d\n", pCStructFormat->memory_size);
4658 /* copy constant sized part of struct */
4659 pStubMsg->BufferMark = pStubMsg->Buffer;
4661 if (pCStructFormat->type == RPC_FC_CPSTRUCT)
4662 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4665 /***********************************************************************
4666 * NdrConformantVaryingStructMarshall [RPCRT4.@]
4668 unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4669 unsigned char *pMemory,
4670 PFORMAT_STRING pFormat)
4672 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4673 PFORMAT_STRING pCVArrayFormat;
4675 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4677 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4678 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4680 ERR("invalid format type %x\n", pCVStructFormat->type);
4681 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4682 return NULL;
4685 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4686 pCVStructFormat->offset_to_array_description;
4688 array_compute_and_write_conformance(*pCVArrayFormat, pStubMsg,
4689 pMemory + pCVStructFormat->memory_size,
4690 pCVArrayFormat);
4692 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4694 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4696 /* write constant sized part */
4697 pStubMsg->BufferMark = pStubMsg->Buffer;
4698 safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
4700 array_write_variance_and_marshall(*pCVArrayFormat, pStubMsg,
4701 pMemory + pCVStructFormat->memory_size,
4702 pCVArrayFormat, FALSE /* fHasPointers */);
4704 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4706 return NULL;
4709 /***********************************************************************
4710 * NdrConformantVaryingStructUnmarshall [RPCRT4.@]
4712 unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4713 unsigned char **ppMemory,
4714 PFORMAT_STRING pFormat,
4715 unsigned char fMustAlloc)
4717 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4718 PFORMAT_STRING pCVArrayFormat;
4719 ULONG memsize, bufsize;
4720 unsigned char *saved_buffer, *saved_array_buffer;
4721 ULONG offset;
4722 unsigned char *array_memory;
4724 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4726 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4727 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4729 ERR("invalid format type %x\n", pCVStructFormat->type);
4730 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4731 return NULL;
4734 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4735 pCVStructFormat->offset_to_array_description;
4737 memsize = array_read_conformance(*pCVArrayFormat, pStubMsg,
4738 pCVArrayFormat);
4740 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4742 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4744 /* work out how much memory to allocate if we need to do so */
4745 if (!fMustAlloc && !*ppMemory)
4746 fMustAlloc = TRUE;
4747 if (fMustAlloc)
4749 SIZE_T size = pCVStructFormat->memory_size + memsize;
4750 *ppMemory = NdrAllocate(pStubMsg, size);
4753 /* mark the start of the constant data */
4754 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
4755 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4757 array_memory = *ppMemory + pCVStructFormat->memory_size;
4758 bufsize = array_read_variance_and_unmarshall(*pCVArrayFormat, pStubMsg,
4759 &array_memory, pCVArrayFormat,
4760 FALSE /* fMustAlloc */,
4761 FALSE /* fUseServerBufferMemory */,
4762 FALSE /* fUnmarshall */);
4764 /* save offset in case unmarshalling pointers changes it */
4765 offset = pStubMsg->Offset;
4767 /* mark the start of the array data */
4768 saved_array_buffer = pStubMsg->Buffer;
4769 safe_buffer_increment(pStubMsg, bufsize);
4771 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
4773 /* copy the constant data */
4774 memcpy(*ppMemory, saved_buffer, pCVStructFormat->memory_size);
4775 /* copy the array data */
4776 TRACE("copying %p to %p\n", saved_array_buffer, *ppMemory + pCVStructFormat->memory_size);
4777 memcpy(*ppMemory + pCVStructFormat->memory_size + offset,
4778 saved_array_buffer, bufsize);
4780 if (*pCVArrayFormat == RPC_FC_C_CSTRING)
4781 TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size)));
4782 else if (*pCVArrayFormat == RPC_FC_C_WSTRING)
4783 TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size)));
4785 return NULL;
4788 /***********************************************************************
4789 * NdrConformantVaryingStructBufferSize [RPCRT4.@]
4791 void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
4792 unsigned char *pMemory,
4793 PFORMAT_STRING pFormat)
4795 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4796 PFORMAT_STRING pCVArrayFormat;
4798 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4800 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4801 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4803 ERR("invalid format type %x\n", pCVStructFormat->type);
4804 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4805 return;
4808 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4809 pCVStructFormat->offset_to_array_description;
4810 array_compute_and_size_conformance(*pCVArrayFormat, pStubMsg,
4811 pMemory + pCVStructFormat->memory_size,
4812 pCVArrayFormat);
4814 ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1);
4816 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4818 safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size);
4820 array_buffer_size(*pCVArrayFormat, pStubMsg,
4821 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
4822 FALSE /* fHasPointers */);
4824 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
4827 /***********************************************************************
4828 * NdrConformantVaryingStructMemorySize [RPCRT4.@]
4830 ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
4831 PFORMAT_STRING pFormat)
4833 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4834 PFORMAT_STRING pCVArrayFormat;
4836 TRACE("(%p, %p)\n", pStubMsg, pFormat);
4838 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4839 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4841 ERR("invalid format type %x\n", pCVStructFormat->type);
4842 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4843 return 0;
4846 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4847 pCVStructFormat->offset_to_array_description;
4848 array_read_conformance(*pCVArrayFormat, pStubMsg, pCVArrayFormat);
4850 ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1);
4852 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4854 safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size);
4855 array_memory_size(*pCVArrayFormat, pStubMsg, pCVArrayFormat,
4856 FALSE /* fHasPointers */);
4858 pStubMsg->MemorySize += pCVStructFormat->memory_size;
4860 EmbeddedPointerMemorySize(pStubMsg, pFormat);
4862 return pStubMsg->MemorySize;
4865 /***********************************************************************
4866 * NdrConformantVaryingStructFree [RPCRT4.@]
4868 void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg,
4869 unsigned char *pMemory,
4870 PFORMAT_STRING pFormat)
4872 const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat;
4873 PFORMAT_STRING pCVArrayFormat;
4875 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4877 pFormat += sizeof(NDR_CVSTRUCT_FORMAT);
4878 if (pCVStructFormat->type != RPC_FC_CVSTRUCT)
4880 ERR("invalid format type %x\n", pCVStructFormat->type);
4881 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4882 return;
4885 pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description +
4886 pCVStructFormat->offset_to_array_description;
4887 array_free(*pCVArrayFormat, pStubMsg,
4888 pMemory + pCVStructFormat->memory_size, pCVArrayFormat,
4889 FALSE /* fHasPointers */);
4891 TRACE("memory_size = %d\n", pCVStructFormat->memory_size);
4893 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
4896 #include "pshpack1.h"
4897 typedef struct
4899 unsigned char type;
4900 unsigned char alignment;
4901 unsigned short total_size;
4902 } NDR_SMFARRAY_FORMAT;
4904 typedef struct
4906 unsigned char type;
4907 unsigned char alignment;
4908 ULONG total_size;
4909 } NDR_LGFARRAY_FORMAT;
4910 #include "poppack.h"
4912 /***********************************************************************
4913 * NdrFixedArrayMarshall [RPCRT4.@]
4915 unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
4916 unsigned char *pMemory,
4917 PFORMAT_STRING pFormat)
4919 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4920 ULONG total_size;
4922 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
4924 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4925 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4927 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4928 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4929 return NULL;
4932 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4934 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4936 total_size = pSmFArrayFormat->total_size;
4937 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4939 else
4941 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4942 total_size = pLgFArrayFormat->total_size;
4943 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4946 pStubMsg->BufferMark = pStubMsg->Buffer;
4947 safe_copy_to_buffer(pStubMsg, pMemory, total_size);
4949 pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
4951 return NULL;
4954 /***********************************************************************
4955 * NdrFixedArrayUnmarshall [RPCRT4.@]
4957 unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
4958 unsigned char **ppMemory,
4959 PFORMAT_STRING pFormat,
4960 unsigned char fMustAlloc)
4962 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
4963 ULONG total_size;
4964 unsigned char *saved_buffer;
4966 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
4968 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
4969 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
4971 ERR("invalid format type %x\n", pSmFArrayFormat->type);
4972 RpcRaiseException(RPC_S_INTERNAL_ERROR);
4973 return NULL;
4976 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
4978 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
4980 total_size = pSmFArrayFormat->total_size;
4981 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
4983 else
4985 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
4986 total_size = pLgFArrayFormat->total_size;
4987 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
4990 if (fMustAlloc)
4991 *ppMemory = NdrAllocate(pStubMsg, total_size);
4992 else
4994 if (!pStubMsg->IsClient && !*ppMemory)
4995 /* for servers, we just point straight into the RPC buffer */
4996 *ppMemory = pStubMsg->Buffer;
4999 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5000 safe_buffer_increment(pStubMsg, total_size);
5001 pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5003 TRACE("copying %p to %p\n", saved_buffer, *ppMemory);
5004 if (*ppMemory != saved_buffer)
5005 memcpy(*ppMemory, saved_buffer, total_size);
5007 return NULL;
5010 /***********************************************************************
5011 * NdrFixedArrayBufferSize [RPCRT4.@]
5013 void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5014 unsigned char *pMemory,
5015 PFORMAT_STRING pFormat)
5017 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5018 ULONG total_size;
5020 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5022 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5023 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5025 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5026 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5027 return;
5030 ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1);
5032 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5034 total_size = pSmFArrayFormat->total_size;
5035 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5037 else
5039 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5040 total_size = pLgFArrayFormat->total_size;
5041 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5043 safe_buffer_length_increment(pStubMsg, total_size);
5045 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5048 /***********************************************************************
5049 * NdrFixedArrayMemorySize [RPCRT4.@]
5051 ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5052 PFORMAT_STRING pFormat)
5054 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5055 ULONG total_size;
5057 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5059 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5060 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5062 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5063 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5064 return 0;
5067 ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1);
5069 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5071 total_size = pSmFArrayFormat->total_size;
5072 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5074 else
5076 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5077 total_size = pLgFArrayFormat->total_size;
5078 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5080 pStubMsg->BufferMark = pStubMsg->Buffer;
5081 safe_buffer_increment(pStubMsg, total_size);
5082 pStubMsg->MemorySize += total_size;
5084 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5086 return total_size;
5089 /***********************************************************************
5090 * NdrFixedArrayFree [RPCRT4.@]
5092 void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5093 unsigned char *pMemory,
5094 PFORMAT_STRING pFormat)
5096 const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat;
5098 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5100 if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) &&
5101 (pSmFArrayFormat->type != RPC_FC_LGFARRAY))
5103 ERR("invalid format type %x\n", pSmFArrayFormat->type);
5104 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5105 return;
5108 if (pSmFArrayFormat->type == RPC_FC_SMFARRAY)
5109 pFormat = (const unsigned char *)(pSmFArrayFormat + 1);
5110 else
5112 const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat;
5113 pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
5116 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5119 /***********************************************************************
5120 * NdrVaryingArrayMarshall [RPCRT4.@]
5122 unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5123 unsigned char *pMemory,
5124 PFORMAT_STRING pFormat)
5126 unsigned char alignment;
5127 DWORD elements, esize;
5128 ULONG bufsize;
5130 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5132 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5133 (pFormat[0] != RPC_FC_LGVARRAY))
5135 ERR("invalid format type %x\n", pFormat[0]);
5136 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5137 return NULL;
5140 alignment = pFormat[1] + 1;
5142 if (pFormat[0] == RPC_FC_SMVARRAY)
5144 pFormat += 2;
5145 pFormat += sizeof(WORD);
5146 elements = *(const WORD*)pFormat;
5147 pFormat += sizeof(WORD);
5149 else
5151 pFormat += 2;
5152 pFormat += sizeof(DWORD);
5153 elements = *(const DWORD*)pFormat;
5154 pFormat += sizeof(DWORD);
5157 esize = *(const WORD*)pFormat;
5158 pFormat += sizeof(WORD);
5160 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5161 if ((pStubMsg->ActualCount > elements) ||
5162 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5164 RpcRaiseException(RPC_S_INVALID_BOUND);
5165 return NULL;
5168 WriteVariance(pStubMsg);
5170 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment);
5172 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5173 pStubMsg->BufferMark = pStubMsg->Buffer;
5174 safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
5176 EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
5178 return NULL;
5181 /***********************************************************************
5182 * NdrVaryingArrayUnmarshall [RPCRT4.@]
5184 unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5185 unsigned char **ppMemory,
5186 PFORMAT_STRING pFormat,
5187 unsigned char fMustAlloc)
5189 unsigned char alignment;
5190 DWORD size, elements, esize;
5191 ULONG bufsize;
5192 unsigned char *saved_buffer;
5193 ULONG offset;
5195 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5197 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5198 (pFormat[0] != RPC_FC_LGVARRAY))
5200 ERR("invalid format type %x\n", pFormat[0]);
5201 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5202 return NULL;
5205 alignment = pFormat[1] + 1;
5207 if (pFormat[0] == RPC_FC_SMVARRAY)
5209 pFormat += 2;
5210 size = *(const WORD*)pFormat;
5211 pFormat += sizeof(WORD);
5212 elements = *(const WORD*)pFormat;
5213 pFormat += sizeof(WORD);
5215 else
5217 pFormat += 2;
5218 size = *(const DWORD*)pFormat;
5219 pFormat += sizeof(DWORD);
5220 elements = *(const DWORD*)pFormat;
5221 pFormat += sizeof(DWORD);
5224 esize = *(const WORD*)pFormat;
5225 pFormat += sizeof(WORD);
5227 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5229 ALIGN_POINTER(pStubMsg->Buffer, alignment);
5231 bufsize = safe_multiply(esize, pStubMsg->ActualCount);
5232 offset = pStubMsg->Offset;
5234 if (!fMustAlloc && !*ppMemory)
5235 fMustAlloc = TRUE;
5236 if (fMustAlloc)
5237 *ppMemory = NdrAllocate(pStubMsg, size);
5238 saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer;
5239 safe_buffer_increment(pStubMsg, bufsize);
5241 EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc);
5243 memcpy(*ppMemory + offset, saved_buffer, bufsize);
5245 return NULL;
5248 /***********************************************************************
5249 * NdrVaryingArrayBufferSize [RPCRT4.@]
5251 void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5252 unsigned char *pMemory,
5253 PFORMAT_STRING pFormat)
5255 unsigned char alignment;
5256 DWORD elements, esize;
5258 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5260 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5261 (pFormat[0] != RPC_FC_LGVARRAY))
5263 ERR("invalid format type %x\n", pFormat[0]);
5264 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5265 return;
5268 alignment = pFormat[1] + 1;
5270 if (pFormat[0] == RPC_FC_SMVARRAY)
5272 pFormat += 2;
5273 pFormat += sizeof(WORD);
5274 elements = *(const WORD*)pFormat;
5275 pFormat += sizeof(WORD);
5277 else
5279 pFormat += 2;
5280 pFormat += sizeof(DWORD);
5281 elements = *(const DWORD*)pFormat;
5282 pFormat += sizeof(DWORD);
5285 esize = *(const WORD*)pFormat;
5286 pFormat += sizeof(WORD);
5288 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5289 if ((pStubMsg->ActualCount > elements) ||
5290 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5292 RpcRaiseException(RPC_S_INVALID_BOUND);
5293 return;
5296 SizeVariance(pStubMsg);
5298 ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
5300 safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5302 EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
5305 /***********************************************************************
5306 * NdrVaryingArrayMemorySize [RPCRT4.@]
5308 ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5309 PFORMAT_STRING pFormat)
5311 unsigned char alignment;
5312 DWORD size, elements, esize;
5314 TRACE("(%p, %p)\n", pStubMsg, pFormat);
5316 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5317 (pFormat[0] != RPC_FC_LGVARRAY))
5319 ERR("invalid format type %x\n", pFormat[0]);
5320 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5321 return 0;
5324 alignment = pFormat[1] + 1;
5326 if (pFormat[0] == RPC_FC_SMVARRAY)
5328 pFormat += 2;
5329 size = *(const WORD*)pFormat;
5330 pFormat += sizeof(WORD);
5331 elements = *(const WORD*)pFormat;
5332 pFormat += sizeof(WORD);
5334 else
5336 pFormat += 2;
5337 size = *(const DWORD*)pFormat;
5338 pFormat += sizeof(DWORD);
5339 elements = *(const DWORD*)pFormat;
5340 pFormat += sizeof(DWORD);
5343 esize = *(const WORD*)pFormat;
5344 pFormat += sizeof(WORD);
5346 pFormat = ReadVariance(pStubMsg, pFormat, elements);
5348 ALIGN_POINTER(pStubMsg->Buffer, alignment);
5350 safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount));
5351 pStubMsg->MemorySize += size;
5353 EmbeddedPointerMemorySize(pStubMsg, pFormat);
5355 return pStubMsg->MemorySize;
5358 /***********************************************************************
5359 * NdrVaryingArrayFree [RPCRT4.@]
5361 void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg,
5362 unsigned char *pMemory,
5363 PFORMAT_STRING pFormat)
5365 DWORD elements;
5367 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5369 if ((pFormat[0] != RPC_FC_SMVARRAY) &&
5370 (pFormat[0] != RPC_FC_LGVARRAY))
5372 ERR("invalid format type %x\n", pFormat[0]);
5373 RpcRaiseException(RPC_S_INTERNAL_ERROR);
5374 return;
5377 if (pFormat[0] == RPC_FC_SMVARRAY)
5379 pFormat += 2;
5380 pFormat += sizeof(WORD);
5381 elements = *(const WORD*)pFormat;
5382 pFormat += sizeof(WORD);
5384 else
5386 pFormat += 2;
5387 pFormat += sizeof(DWORD);
5388 elements = *(const DWORD*)pFormat;
5389 pFormat += sizeof(DWORD);
5392 pFormat += sizeof(WORD);
5394 pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
5395 if ((pStubMsg->ActualCount > elements) ||
5396 (pStubMsg->ActualCount + pStubMsg->Offset > elements))
5398 RpcRaiseException(RPC_S_INVALID_BOUND);
5399 return;
5402 EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
5405 static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
5407 switch (fc)
5409 case RPC_FC_BYTE:
5410 case RPC_FC_CHAR:
5411 case RPC_FC_SMALL:
5412 case RPC_FC_USMALL:
5413 return *pMemory;
5414 case RPC_FC_WCHAR:
5415 case RPC_FC_SHORT:
5416 case RPC_FC_USHORT:
5417 case RPC_FC_ENUM16:
5418 return *(const USHORT *)pMemory;
5419 case RPC_FC_LONG:
5420 case RPC_FC_ULONG:
5421 case RPC_FC_ENUM32:
5422 return *(const ULONG *)pMemory;
5423 default:
5424 FIXME("Unhandled base type: 0x%02x\n", fc);
5425 return 0;
5429 static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg,
5430 ULONG discriminant,
5431 PFORMAT_STRING pFormat)
5433 unsigned short num_arms, arm, type;
5435 num_arms = *(const SHORT*)pFormat & 0x0fff;
5436 pFormat += 2;
5437 for(arm = 0; arm < num_arms; arm++)
5439 if(discriminant == *(const ULONG*)pFormat)
5441 pFormat += 4;
5442 break;
5444 pFormat += 6;
5447 type = *(const unsigned short*)pFormat;
5448 TRACE("type %04x\n", type);
5449 if(arm == num_arms) /* default arm extras */
5451 if(type == 0xffff)
5453 ERR("no arm for 0x%x and no default case\n", discriminant);
5454 RpcRaiseException(RPC_S_INVALID_TAG);
5455 return NULL;
5457 if(type == 0)
5459 TRACE("falling back to empty default case for 0x%x\n", discriminant);
5460 return NULL;
5463 return pFormat;
5466 static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat)
5468 unsigned short type;
5470 pFormat += 2;
5472 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5473 if(!pFormat)
5474 return NULL;
5476 type = *(const unsigned short*)pFormat;
5477 if((type & 0xff00) == 0x8000)
5479 unsigned char basetype = LOBYTE(type);
5480 return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype);
5482 else
5484 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5485 NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK];
5486 if (m)
5488 unsigned char *saved_buffer = NULL;
5489 int pointer_buffer_mark_set = 0;
5490 switch(*desc)
5492 case RPC_FC_RP:
5493 case RPC_FC_UP:
5494 case RPC_FC_OP:
5495 case RPC_FC_FP:
5496 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
5497 saved_buffer = pStubMsg->Buffer;
5498 if (pStubMsg->PointerBufferMark)
5500 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5501 pStubMsg->PointerBufferMark = NULL;
5502 pointer_buffer_mark_set = 1;
5504 else
5505 safe_buffer_increment(pStubMsg, 4); /* for pointer ID */
5507 PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc);
5508 if (pointer_buffer_mark_set)
5510 STD_OVERFLOW_CHECK(pStubMsg);
5511 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5512 if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
5514 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5515 saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
5516 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5518 pStubMsg->Buffer = saved_buffer + 4;
5520 break;
5521 default:
5522 m(pStubMsg, pMemory, desc);
5525 else FIXME("no marshaller for embedded type %02x\n", *desc);
5527 return NULL;
5530 static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5531 unsigned char **ppMemory,
5532 ULONG discriminant,
5533 PFORMAT_STRING pFormat,
5534 unsigned char fMustAlloc)
5536 unsigned short type;
5538 pFormat += 2;
5540 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5541 if(!pFormat)
5542 return NULL;
5544 type = *(const unsigned short*)pFormat;
5545 if((type & 0xff00) == 0x8000)
5547 unsigned char basetype = LOBYTE(type);
5548 return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE);
5550 else
5552 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5553 NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
5554 if (m)
5556 unsigned char *saved_buffer = NULL;
5557 int pointer_buffer_mark_set = 0;
5558 switch(*desc)
5560 case RPC_FC_RP:
5561 case RPC_FC_UP:
5562 case RPC_FC_OP:
5563 case RPC_FC_FP:
5564 ALIGN_POINTER(pStubMsg->Buffer, 4);
5565 saved_buffer = pStubMsg->Buffer;
5566 if (pStubMsg->PointerBufferMark)
5568 pStubMsg->Buffer = pStubMsg->PointerBufferMark;
5569 pStubMsg->PointerBufferMark = NULL;
5570 pointer_buffer_mark_set = 1;
5572 else
5573 pStubMsg->Buffer += 4; /* for pointer ID */
5575 if (saved_buffer + 4 > pStubMsg->BufferEnd)
5577 ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n",
5578 saved_buffer, pStubMsg->BufferEnd);
5579 RpcRaiseException(RPC_X_BAD_STUB_DATA);
5582 PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc);
5583 if (pointer_buffer_mark_set)
5585 STD_OVERFLOW_CHECK(pStubMsg);
5586 pStubMsg->PointerBufferMark = pStubMsg->Buffer;
5587 pStubMsg->Buffer = saved_buffer + 4;
5589 break;
5590 default:
5591 m(pStubMsg, ppMemory, desc, fMustAlloc);
5594 else FIXME("no marshaller for embedded type %02x\n", *desc);
5596 return NULL;
5599 static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg,
5600 unsigned char *pMemory,
5601 ULONG discriminant,
5602 PFORMAT_STRING pFormat)
5604 unsigned short type;
5606 pFormat += 2;
5608 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5609 if(!pFormat)
5610 return;
5612 type = *(const unsigned short*)pFormat;
5613 if((type & 0xff00) == 0x8000)
5615 unsigned char basetype = LOBYTE(type);
5616 NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype);
5618 else
5620 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5621 NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK];
5622 if (m)
5624 switch(*desc)
5626 case RPC_FC_RP:
5627 case RPC_FC_UP:
5628 case RPC_FC_OP:
5629 case RPC_FC_FP:
5630 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
5631 safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */
5632 if (!pStubMsg->IgnoreEmbeddedPointers)
5634 int saved_buffer_length = pStubMsg->BufferLength;
5635 pStubMsg->BufferLength = pStubMsg->PointerLength;
5636 pStubMsg->PointerLength = 0;
5637 if(!pStubMsg->BufferLength)
5638 ERR("BufferLength == 0??\n");
5639 PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc);
5640 pStubMsg->PointerLength = pStubMsg->BufferLength;
5641 pStubMsg->BufferLength = saved_buffer_length;
5643 break;
5644 default:
5645 m(pStubMsg, pMemory, desc);
5648 else FIXME("no buffersizer for embedded type %02x\n", *desc);
5652 static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg,
5653 ULONG discriminant,
5654 PFORMAT_STRING pFormat)
5656 unsigned short type, size;
5658 size = *(const unsigned short*)pFormat;
5659 pStubMsg->Memory += size;
5660 pFormat += 2;
5662 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5663 if(!pFormat)
5664 return 0;
5666 type = *(const unsigned short*)pFormat;
5667 if((type & 0xff00) == 0x8000)
5669 return NdrBaseTypeMemorySize(pStubMsg, pFormat);
5671 else
5673 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5674 NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK];
5675 unsigned char *saved_buffer;
5676 if (m)
5678 switch(*desc)
5680 case RPC_FC_RP:
5681 case RPC_FC_UP:
5682 case RPC_FC_OP:
5683 case RPC_FC_FP:
5684 ALIGN_POINTER(pStubMsg->Buffer, 4);
5685 saved_buffer = pStubMsg->Buffer;
5686 safe_buffer_increment(pStubMsg, 4);
5687 ALIGN_LENGTH(pStubMsg->MemorySize, 4);
5688 pStubMsg->MemorySize += 4;
5689 if (!pStubMsg->IgnoreEmbeddedPointers)
5690 PointerMemorySize(pStubMsg, saved_buffer, pFormat);
5691 break;
5692 default:
5693 return m(pStubMsg, desc);
5696 else FIXME("no marshaller for embedded type %02x\n", *desc);
5699 TRACE("size %d\n", size);
5700 return size;
5703 static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg,
5704 unsigned char *pMemory,
5705 ULONG discriminant,
5706 PFORMAT_STRING pFormat)
5708 unsigned short type;
5710 pFormat += 2;
5712 pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat);
5713 if(!pFormat)
5714 return;
5716 type = *(const unsigned short*)pFormat;
5717 if((type & 0xff00) != 0x8000)
5719 PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat;
5720 NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK];
5721 if (m)
5723 switch(*desc)
5725 case RPC_FC_RP:
5726 case RPC_FC_UP:
5727 case RPC_FC_OP:
5728 case RPC_FC_FP:
5729 PointerFree(pStubMsg, *(unsigned char **)pMemory, desc);
5730 break;
5731 default:
5732 m(pStubMsg, pMemory, desc);
5738 /***********************************************************************
5739 * NdrEncapsulatedUnionMarshall [RPCRT4.@]
5741 unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5742 unsigned char *pMemory,
5743 PFORMAT_STRING pFormat)
5745 unsigned char switch_type;
5746 unsigned char increment;
5747 ULONG switch_value;
5749 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5750 pFormat++;
5752 switch_type = *pFormat & 0xf;
5753 increment = (*pFormat & 0xf0) >> 4;
5754 pFormat++;
5756 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, increment);
5758 switch_value = get_discriminant(switch_type, pMemory);
5759 TRACE("got switch value 0x%x\n", switch_value);
5761 NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type);
5762 pMemory += increment;
5764 return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat);
5767 /***********************************************************************
5768 * NdrEncapsulatedUnionUnmarshall [RPCRT4.@]
5770 unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5771 unsigned char **ppMemory,
5772 PFORMAT_STRING pFormat,
5773 unsigned char fMustAlloc)
5775 unsigned char switch_type;
5776 unsigned char increment;
5777 ULONG switch_value;
5778 unsigned short size;
5779 unsigned char *pMemoryArm;
5781 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5782 pFormat++;
5784 switch_type = *pFormat & 0xf;
5785 increment = (*pFormat & 0xf0) >> 4;
5786 pFormat++;
5788 ALIGN_POINTER(pStubMsg->Buffer, increment);
5789 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5790 TRACE("got switch value 0x%x\n", switch_value);
5792 size = *(const unsigned short*)pFormat + increment;
5793 if (!fMustAlloc && !*ppMemory)
5794 fMustAlloc = TRUE;
5795 if (fMustAlloc)
5796 *ppMemory = NdrAllocate(pStubMsg, size);
5798 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
5799 * since the arm is part of the memory block that is encompassed by
5800 * the whole union. Memory is forced to allocate when pointers
5801 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
5802 * clearing the memory we pass in to the unmarshaller */
5803 if (fMustAlloc)
5804 memset(*ppMemory, 0, size);
5806 NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE);
5807 pMemoryArm = *ppMemory + increment;
5809 return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, FALSE);
5812 /***********************************************************************
5813 * NdrEncapsulatedUnionBufferSize [RPCRT4.@]
5815 void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
5816 unsigned char *pMemory,
5817 PFORMAT_STRING pFormat)
5819 unsigned char switch_type;
5820 unsigned char increment;
5821 ULONG switch_value;
5823 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5824 pFormat++;
5826 switch_type = *pFormat & 0xf;
5827 increment = (*pFormat & 0xf0) >> 4;
5828 pFormat++;
5830 ALIGN_LENGTH(pStubMsg->BufferLength, increment);
5831 switch_value = get_discriminant(switch_type, pMemory);
5832 TRACE("got switch value 0x%x\n", switch_value);
5834 /* Add discriminant size */
5835 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type);
5836 pMemory += increment;
5838 union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat);
5841 /***********************************************************************
5842 * NdrEncapsulatedUnionMemorySize [RPCRT4.@]
5844 ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
5845 PFORMAT_STRING pFormat)
5847 unsigned char switch_type;
5848 unsigned char increment;
5849 ULONG switch_value;
5851 switch_type = *pFormat & 0xf;
5852 increment = (*pFormat & 0xf0) >> 4;
5853 pFormat++;
5855 ALIGN_POINTER(pStubMsg->Buffer, increment);
5856 switch_value = get_discriminant(switch_type, pStubMsg->Buffer);
5857 TRACE("got switch value 0x%x\n", switch_value);
5859 pStubMsg->Memory += increment;
5861 return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat);
5864 /***********************************************************************
5865 * NdrEncapsulatedUnionFree [RPCRT4.@]
5867 void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
5868 unsigned char *pMemory,
5869 PFORMAT_STRING pFormat)
5871 unsigned char switch_type;
5872 unsigned char increment;
5873 ULONG switch_value;
5875 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5876 pFormat++;
5878 switch_type = *pFormat & 0xf;
5879 increment = (*pFormat & 0xf0) >> 4;
5880 pFormat++;
5882 switch_value = get_discriminant(switch_type, pMemory);
5883 TRACE("got switch value 0x%x\n", switch_value);
5885 pMemory += increment;
5887 union_arm_free(pStubMsg, pMemory, switch_value, pFormat);
5890 /***********************************************************************
5891 * NdrNonEncapsulatedUnionMarshall [RPCRT4.@]
5893 unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg,
5894 unsigned char *pMemory,
5895 PFORMAT_STRING pFormat)
5897 unsigned char switch_type;
5899 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
5900 pFormat++;
5902 switch_type = *pFormat;
5903 pFormat++;
5905 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
5906 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
5907 /* Marshall discriminant */
5908 NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
5910 return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
5913 static LONG unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg,
5914 PFORMAT_STRING *ppFormat)
5916 LONG discriminant = 0;
5918 switch(**ppFormat)
5920 case RPC_FC_BYTE:
5921 case RPC_FC_CHAR:
5922 case RPC_FC_SMALL:
5923 case RPC_FC_USMALL:
5925 UCHAR d;
5926 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5927 discriminant = d;
5928 break;
5930 case RPC_FC_WCHAR:
5931 case RPC_FC_SHORT:
5932 case RPC_FC_USHORT:
5934 USHORT d;
5935 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
5936 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5937 discriminant = d;
5938 break;
5940 case RPC_FC_LONG:
5941 case RPC_FC_ULONG:
5943 ULONG d;
5944 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
5945 safe_copy_from_buffer(pStubMsg, &d, sizeof(d));
5946 discriminant = d;
5947 break;
5949 default:
5950 FIXME("Unhandled base type: 0x%02x\n", **ppFormat);
5952 (*ppFormat)++;
5954 if (pStubMsg->fHasNewCorrDesc)
5955 *ppFormat += 6;
5956 else
5957 *ppFormat += 4;
5958 return discriminant;
5961 /**********************************************************************
5962 * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@]
5964 unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
5965 unsigned char **ppMemory,
5966 PFORMAT_STRING pFormat,
5967 unsigned char fMustAlloc)
5969 LONG discriminant;
5970 unsigned short size;
5972 TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
5973 pFormat++;
5975 /* Unmarshall discriminant */
5976 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
5977 TRACE("unmarshalled discriminant %x\n", discriminant);
5979 pFormat += *(const SHORT*)pFormat;
5981 size = *(const unsigned short*)pFormat;
5983 if (!fMustAlloc && !*ppMemory)
5984 fMustAlloc = TRUE;
5985 if (fMustAlloc)
5986 *ppMemory = NdrAllocate(pStubMsg, size);
5988 /* we can't pass fMustAlloc=TRUE into the marshaller for the arm
5989 * since the arm is part of the memory block that is encompassed by
5990 * the whole union. Memory is forced to allocate when pointers
5991 * are set to NULL, so we emulate that part of fMustAlloc=TRUE by
5992 * clearing the memory we pass in to the unmarshaller */
5993 if (fMustAlloc)
5994 memset(*ppMemory, 0, size);
5996 return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, FALSE);
5999 /***********************************************************************
6000 * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@]
6002 void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6003 unsigned char *pMemory,
6004 PFORMAT_STRING pFormat)
6006 unsigned char switch_type;
6008 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6009 pFormat++;
6011 switch_type = *pFormat;
6012 pFormat++;
6014 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6015 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6016 /* Add discriminant size */
6017 NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type);
6019 union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6022 /***********************************************************************
6023 * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@]
6025 ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6026 PFORMAT_STRING pFormat)
6028 ULONG discriminant;
6030 pFormat++;
6031 /* Unmarshall discriminant */
6032 discriminant = unmarshall_discriminant(pStubMsg, &pFormat);
6033 TRACE("unmarshalled discriminant 0x%x\n", discriminant);
6035 return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat);
6038 /***********************************************************************
6039 * NdrNonEncapsulatedUnionFree [RPCRT4.@]
6041 void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg,
6042 unsigned char *pMemory,
6043 PFORMAT_STRING pFormat)
6045 TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
6046 pFormat++;
6047 pFormat++;
6049 pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0);
6050 TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount);
6052 union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat);
6055 /***********************************************************************
6056 * NdrByteCountPointerMarshall [RPCRT4.@]
6058 unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6059 unsigned char *pMemory,
6060 PFORMAT_STRING pFormat)
6062 FIXME("stub\n");
6063 return NULL;
6066 /***********************************************************************
6067 * NdrByteCountPointerUnmarshall [RPCRT4.@]
6069 unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6070 unsigned char **ppMemory,
6071 PFORMAT_STRING pFormat,
6072 unsigned char fMustAlloc)
6074 FIXME("stub\n");
6075 return NULL;
6078 /***********************************************************************
6079 * NdrByteCountPointerBufferSize [RPCRT4.@]
6081 void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6082 unsigned char *pMemory,
6083 PFORMAT_STRING pFormat)
6085 FIXME("stub\n");
6088 /***********************************************************************
6089 * NdrByteCountPointerMemorySize [internal]
6091 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6092 PFORMAT_STRING pFormat)
6094 FIXME("stub\n");
6095 return 0;
6098 /***********************************************************************
6099 * NdrByteCountPointerFree [RPCRT4.@]
6101 void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg,
6102 unsigned char *pMemory,
6103 PFORMAT_STRING pFormat)
6105 FIXME("stub\n");
6108 /***********************************************************************
6109 * NdrXmitOrRepAsMarshall [RPCRT4.@]
6111 unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6112 unsigned char *pMemory,
6113 PFORMAT_STRING pFormat)
6115 FIXME("stub\n");
6116 return NULL;
6119 /***********************************************************************
6120 * NdrXmitOrRepAsUnmarshall [RPCRT4.@]
6122 unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6123 unsigned char **ppMemory,
6124 PFORMAT_STRING pFormat,
6125 unsigned char fMustAlloc)
6127 FIXME("stub\n");
6128 return NULL;
6131 /***********************************************************************
6132 * NdrXmitOrRepAsBufferSize [RPCRT4.@]
6134 void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
6135 unsigned char *pMemory,
6136 PFORMAT_STRING pFormat)
6138 FIXME("stub\n");
6141 /***********************************************************************
6142 * NdrXmitOrRepAsMemorySize [RPCRT4.@]
6144 ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
6145 PFORMAT_STRING pFormat)
6147 FIXME("stub\n");
6148 return 0;
6151 /***********************************************************************
6152 * NdrXmitOrRepAsFree [RPCRT4.@]
6154 void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
6155 unsigned char *pMemory,
6156 PFORMAT_STRING pFormat)
6158 FIXME("stub\n");
6161 /***********************************************************************
6162 * NdrRangeMarshall [internal]
6164 static unsigned char *WINAPI NdrRangeMarshall(
6165 PMIDL_STUB_MESSAGE pStubMsg,
6166 unsigned char *pMemory,
6167 PFORMAT_STRING pFormat)
6169 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6170 unsigned char base_type;
6172 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6174 if (pRange->type != RPC_FC_RANGE)
6176 ERR("invalid format type %x\n", pRange->type);
6177 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6178 return NULL;
6181 base_type = pRange->flags_type & 0xf;
6183 return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type);
6186 /***********************************************************************
6187 * NdrRangeUnmarshall [RPCRT4.@]
6189 unsigned char *WINAPI NdrRangeUnmarshall(
6190 PMIDL_STUB_MESSAGE pStubMsg,
6191 unsigned char **ppMemory,
6192 PFORMAT_STRING pFormat,
6193 unsigned char fMustAlloc)
6195 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6196 unsigned char base_type;
6198 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6200 if (pRange->type != RPC_FC_RANGE)
6202 ERR("invalid format type %x\n", pRange->type);
6203 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6204 return NULL;
6206 base_type = pRange->flags_type & 0xf;
6208 TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n",
6209 base_type, pRange->low_value, pRange->high_value);
6211 #define RANGE_UNMARSHALL(mem_type, wire_type, format_spec) \
6212 do \
6214 ALIGN_POINTER(pStubMsg->Buffer, sizeof(wire_type)); \
6215 if (!fMustAlloc && !*ppMemory) \
6216 fMustAlloc = TRUE; \
6217 if (fMustAlloc) \
6218 *ppMemory = NdrAllocate(pStubMsg, sizeof(mem_type)); \
6219 if (pStubMsg->Buffer + sizeof(wire_type) > pStubMsg->BufferEnd) \
6221 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \
6222 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \
6223 RpcRaiseException(RPC_X_BAD_STUB_DATA); \
6225 if ((*(wire_type *)pStubMsg->Buffer < (mem_type)pRange->low_value) || \
6226 (*(wire_type *)pStubMsg->Buffer > (mem_type)pRange->high_value)) \
6228 ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \
6229 *(wire_type *)pStubMsg->Buffer, (mem_type)pRange->low_value, \
6230 (mem_type)pRange->high_value); \
6231 RpcRaiseException(RPC_S_INVALID_BOUND); \
6232 return NULL; \
6234 TRACE("*ppMemory: %p\n", *ppMemory); \
6235 **(mem_type **)ppMemory = *(wire_type *)pStubMsg->Buffer; \
6236 pStubMsg->Buffer += sizeof(wire_type); \
6237 } while (0)
6239 switch(base_type)
6241 case RPC_FC_CHAR:
6242 case RPC_FC_SMALL:
6243 RANGE_UNMARSHALL(UCHAR, UCHAR, "%d");
6244 TRACE("value: 0x%02x\n", **ppMemory);
6245 break;
6246 case RPC_FC_BYTE:
6247 case RPC_FC_USMALL:
6248 RANGE_UNMARSHALL(CHAR, CHAR, "%u");
6249 TRACE("value: 0x%02x\n", **ppMemory);
6250 break;
6251 case RPC_FC_WCHAR: /* FIXME: valid? */
6252 case RPC_FC_USHORT:
6253 RANGE_UNMARSHALL(USHORT, USHORT, "%u");
6254 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6255 break;
6256 case RPC_FC_SHORT:
6257 RANGE_UNMARSHALL(SHORT, SHORT, "%d");
6258 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6259 break;
6260 case RPC_FC_LONG:
6261 case RPC_FC_ENUM32:
6262 RANGE_UNMARSHALL(LONG, LONG, "%d");
6263 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6264 break;
6265 case RPC_FC_ULONG:
6266 RANGE_UNMARSHALL(ULONG, ULONG, "%u");
6267 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6268 break;
6269 case RPC_FC_ENUM16:
6270 RANGE_UNMARSHALL(UINT, USHORT, "%u");
6271 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6272 break;
6273 case RPC_FC_FLOAT:
6274 case RPC_FC_DOUBLE:
6275 case RPC_FC_HYPER:
6276 default:
6277 ERR("invalid range base type: 0x%02x\n", base_type);
6278 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6281 return NULL;
6284 /***********************************************************************
6285 * NdrRangeBufferSize [internal]
6287 static void WINAPI NdrRangeBufferSize(
6288 PMIDL_STUB_MESSAGE pStubMsg,
6289 unsigned char *pMemory,
6290 PFORMAT_STRING pFormat)
6292 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6293 unsigned char base_type;
6295 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6297 if (pRange->type != RPC_FC_RANGE)
6299 ERR("invalid format type %x\n", pRange->type);
6300 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6302 base_type = pRange->flags_type & 0xf;
6304 NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type);
6307 /***********************************************************************
6308 * NdrRangeMemorySize [internal]
6310 static ULONG WINAPI NdrRangeMemorySize(
6311 PMIDL_STUB_MESSAGE pStubMsg,
6312 PFORMAT_STRING pFormat)
6314 NDR_RANGE *pRange = (NDR_RANGE *)pFormat;
6315 unsigned char base_type;
6317 if (pRange->type != RPC_FC_RANGE)
6319 ERR("invalid format type %x\n", pRange->type);
6320 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6321 return 0;
6323 base_type = pRange->flags_type & 0xf;
6325 return NdrBaseTypeMemorySize(pStubMsg, &base_type);
6328 /***********************************************************************
6329 * NdrRangeFree [internal]
6331 static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg,
6332 unsigned char *pMemory,
6333 PFORMAT_STRING pFormat)
6335 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6337 /* nothing to do */
6340 /***********************************************************************
6341 * NdrBaseTypeMarshall [internal]
6343 static unsigned char *WINAPI NdrBaseTypeMarshall(
6344 PMIDL_STUB_MESSAGE pStubMsg,
6345 unsigned char *pMemory,
6346 PFORMAT_STRING pFormat)
6348 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6350 switch(*pFormat)
6352 case RPC_FC_BYTE:
6353 case RPC_FC_CHAR:
6354 case RPC_FC_SMALL:
6355 case RPC_FC_USMALL:
6356 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
6357 TRACE("value: 0x%02x\n", *pMemory);
6358 break;
6359 case RPC_FC_WCHAR:
6360 case RPC_FC_SHORT:
6361 case RPC_FC_USHORT:
6362 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
6363 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
6364 TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
6365 break;
6366 case RPC_FC_LONG:
6367 case RPC_FC_ULONG:
6368 case RPC_FC_ERROR_STATUS_T:
6369 case RPC_FC_ENUM32:
6370 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONG));
6371 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
6372 TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
6373 break;
6374 case RPC_FC_FLOAT:
6375 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(float));
6376 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
6377 break;
6378 case RPC_FC_DOUBLE:
6379 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(double));
6380 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
6381 break;
6382 case RPC_FC_HYPER:
6383 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONGLONG));
6384 safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
6385 TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
6386 break;
6387 case RPC_FC_ENUM16:
6388 /* only 16-bits on the wire, so do a sanity check */
6389 if (*(UINT *)pMemory > SHRT_MAX)
6390 RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
6391 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT));
6392 if (pStubMsg->Buffer + sizeof(USHORT) > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6393 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6394 *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
6395 pStubMsg->Buffer += sizeof(USHORT);
6396 TRACE("value: 0x%04x\n", *(UINT *)pMemory);
6397 break;
6398 case RPC_FC_IGNORE:
6399 break;
6400 default:
6401 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6404 /* FIXME: what is the correct return value? */
6405 return NULL;
6408 /***********************************************************************
6409 * NdrBaseTypeUnmarshall [internal]
6411 static unsigned char *WINAPI NdrBaseTypeUnmarshall(
6412 PMIDL_STUB_MESSAGE pStubMsg,
6413 unsigned char **ppMemory,
6414 PFORMAT_STRING pFormat,
6415 unsigned char fMustAlloc)
6417 TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
6419 #define BASE_TYPE_UNMARSHALL(type) \
6420 ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \
6421 if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
6423 *ppMemory = pStubMsg->Buffer; \
6424 TRACE("*ppMemory: %p\n", *ppMemory); \
6425 safe_buffer_increment(pStubMsg, sizeof(type)); \
6427 else \
6429 if (fMustAlloc) \
6430 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
6431 TRACE("*ppMemory: %p\n", *ppMemory); \
6432 safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
6435 switch(*pFormat)
6437 case RPC_FC_BYTE:
6438 case RPC_FC_CHAR:
6439 case RPC_FC_SMALL:
6440 case RPC_FC_USMALL:
6441 BASE_TYPE_UNMARSHALL(UCHAR);
6442 TRACE("value: 0x%02x\n", **ppMemory);
6443 break;
6444 case RPC_FC_WCHAR:
6445 case RPC_FC_SHORT:
6446 case RPC_FC_USHORT:
6447 BASE_TYPE_UNMARSHALL(USHORT);
6448 TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
6449 break;
6450 case RPC_FC_LONG:
6451 case RPC_FC_ULONG:
6452 case RPC_FC_ERROR_STATUS_T:
6453 case RPC_FC_ENUM32:
6454 BASE_TYPE_UNMARSHALL(ULONG);
6455 TRACE("value: 0x%08x\n", **(ULONG **)ppMemory);
6456 break;
6457 case RPC_FC_FLOAT:
6458 BASE_TYPE_UNMARSHALL(float);
6459 TRACE("value: %f\n", **(float **)ppMemory);
6460 break;
6461 case RPC_FC_DOUBLE:
6462 BASE_TYPE_UNMARSHALL(double);
6463 TRACE("value: %f\n", **(double **)ppMemory);
6464 break;
6465 case RPC_FC_HYPER:
6466 BASE_TYPE_UNMARSHALL(ULONGLONG);
6467 TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
6468 break;
6469 case RPC_FC_ENUM16:
6470 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
6471 if (!fMustAlloc && !*ppMemory)
6472 fMustAlloc = TRUE;
6473 if (fMustAlloc)
6474 *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
6475 if (pStubMsg->Buffer + sizeof(USHORT) > pStubMsg->BufferEnd)
6476 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6477 TRACE("*ppMemory: %p\n", *ppMemory);
6478 /* 16-bits on the wire, but int in memory */
6479 **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
6480 pStubMsg->Buffer += sizeof(USHORT);
6481 TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
6482 break;
6483 case RPC_FC_IGNORE:
6484 break;
6485 default:
6486 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6488 #undef BASE_TYPE_UNMARSHALL
6490 /* FIXME: what is the correct return value? */
6492 return NULL;
6495 /***********************************************************************
6496 * NdrBaseTypeBufferSize [internal]
6498 static void WINAPI NdrBaseTypeBufferSize(
6499 PMIDL_STUB_MESSAGE pStubMsg,
6500 unsigned char *pMemory,
6501 PFORMAT_STRING pFormat)
6503 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6505 switch(*pFormat)
6507 case RPC_FC_BYTE:
6508 case RPC_FC_CHAR:
6509 case RPC_FC_SMALL:
6510 case RPC_FC_USMALL:
6511 safe_buffer_length_increment(pStubMsg, sizeof(UCHAR));
6512 break;
6513 case RPC_FC_WCHAR:
6514 case RPC_FC_SHORT:
6515 case RPC_FC_USHORT:
6516 case RPC_FC_ENUM16:
6517 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT));
6518 safe_buffer_length_increment(pStubMsg, sizeof(USHORT));
6519 break;
6520 case RPC_FC_LONG:
6521 case RPC_FC_ULONG:
6522 case RPC_FC_ENUM32:
6523 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG));
6524 safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
6525 break;
6526 case RPC_FC_FLOAT:
6527 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float));
6528 safe_buffer_length_increment(pStubMsg, sizeof(float));
6529 break;
6530 case RPC_FC_DOUBLE:
6531 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double));
6532 safe_buffer_length_increment(pStubMsg, sizeof(double));
6533 break;
6534 case RPC_FC_HYPER:
6535 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG));
6536 safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG));
6537 break;
6538 case RPC_FC_ERROR_STATUS_T:
6539 ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t));
6540 safe_buffer_length_increment(pStubMsg, sizeof(error_status_t));
6541 break;
6542 case RPC_FC_IGNORE:
6543 break;
6544 default:
6545 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6549 /***********************************************************************
6550 * NdrBaseTypeMemorySize [internal]
6552 static ULONG WINAPI NdrBaseTypeMemorySize(
6553 PMIDL_STUB_MESSAGE pStubMsg,
6554 PFORMAT_STRING pFormat)
6556 TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat);
6558 switch(*pFormat)
6560 case RPC_FC_BYTE:
6561 case RPC_FC_CHAR:
6562 case RPC_FC_SMALL:
6563 case RPC_FC_USMALL:
6564 safe_buffer_increment(pStubMsg, sizeof(UCHAR));
6565 pStubMsg->MemorySize += sizeof(UCHAR);
6566 return sizeof(UCHAR);
6567 case RPC_FC_WCHAR:
6568 case RPC_FC_SHORT:
6569 case RPC_FC_USHORT:
6570 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
6571 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6572 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(USHORT));
6573 pStubMsg->MemorySize += sizeof(USHORT);
6574 return sizeof(USHORT);
6575 case RPC_FC_LONG:
6576 case RPC_FC_ULONG:
6577 case RPC_FC_ENUM32:
6578 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
6579 safe_buffer_increment(pStubMsg, sizeof(ULONG));
6580 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(ULONG));
6581 pStubMsg->MemorySize += sizeof(ULONG);
6582 return sizeof(ULONG);
6583 case RPC_FC_FLOAT:
6584 ALIGN_POINTER(pStubMsg->Buffer, sizeof(float));
6585 safe_buffer_increment(pStubMsg, sizeof(float));
6586 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(float));
6587 pStubMsg->MemorySize += sizeof(float);
6588 return sizeof(float);
6589 case RPC_FC_DOUBLE:
6590 ALIGN_POINTER(pStubMsg->Buffer, sizeof(double));
6591 safe_buffer_increment(pStubMsg, sizeof(double));
6592 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(double));
6593 pStubMsg->MemorySize += sizeof(double);
6594 return sizeof(double);
6595 case RPC_FC_HYPER:
6596 ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG));
6597 safe_buffer_increment(pStubMsg, sizeof(ULONGLONG));
6598 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(ULONGLONG));
6599 pStubMsg->MemorySize += sizeof(ULONGLONG);
6600 return sizeof(ULONGLONG);
6601 case RPC_FC_ERROR_STATUS_T:
6602 ALIGN_POINTER(pStubMsg->Buffer, sizeof(error_status_t));
6603 safe_buffer_increment(pStubMsg, sizeof(error_status_t));
6604 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(error_status_t));
6605 pStubMsg->MemorySize += sizeof(error_status_t);
6606 return sizeof(error_status_t);
6607 case RPC_FC_ENUM16:
6608 ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
6609 safe_buffer_increment(pStubMsg, sizeof(USHORT));
6610 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(UINT));
6611 pStubMsg->MemorySize += sizeof(UINT);
6612 return sizeof(UINT);
6613 case RPC_FC_IGNORE:
6614 ALIGN_LENGTH(pStubMsg->MemorySize, sizeof(void *));
6615 pStubMsg->MemorySize += sizeof(void *);
6616 return sizeof(void *);
6617 default:
6618 FIXME("Unhandled base type: 0x%02x\n", *pFormat);
6619 return 0;
6623 /***********************************************************************
6624 * NdrBaseTypeFree [internal]
6626 static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
6627 unsigned char *pMemory,
6628 PFORMAT_STRING pFormat)
6630 TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6632 /* nothing to do */
6635 /***********************************************************************
6636 * NdrContextHandleBufferSize [internal]
6638 static void WINAPI NdrContextHandleBufferSize(
6639 PMIDL_STUB_MESSAGE pStubMsg,
6640 unsigned char *pMemory,
6641 PFORMAT_STRING pFormat)
6643 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6645 if (*pFormat != RPC_FC_BIND_CONTEXT)
6647 ERR("invalid format type %x\n", *pFormat);
6648 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6650 ALIGN_LENGTH(pStubMsg->BufferLength, 4);
6651 safe_buffer_length_increment(pStubMsg, cbNDRContext);
6654 /***********************************************************************
6655 * NdrContextHandleMarshall [internal]
6657 static unsigned char *WINAPI NdrContextHandleMarshall(
6658 PMIDL_STUB_MESSAGE pStubMsg,
6659 unsigned char *pMemory,
6660 PFORMAT_STRING pFormat)
6662 TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
6664 if (*pFormat != RPC_FC_BIND_CONTEXT)
6666 ERR("invalid format type %x\n", *pFormat);
6667 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6669 TRACE("flags: 0x%02x\n", pFormat[1]);
6671 if (pFormat[1] & 0x80)
6672 NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE);
6673 else
6674 NdrClientContextMarshall(pStubMsg, pMemory, FALSE);
6676 return NULL;
6679 /***********************************************************************
6680 * NdrContextHandleUnmarshall [internal]
6682 static unsigned char *WINAPI NdrContextHandleUnmarshall(
6683 PMIDL_STUB_MESSAGE pStubMsg,
6684 unsigned char **ppMemory,
6685 PFORMAT_STRING pFormat,
6686 unsigned char fMustAlloc)
6688 TRACE("pStubMsg %p, ppMemory %p, pFormat %p, fMustAlloc %s\n", pStubMsg,
6689 ppMemory, pFormat, fMustAlloc ? "TRUE": "FALSE");
6691 if (*pFormat != RPC_FC_BIND_CONTEXT)
6693 ERR("invalid format type %x\n", *pFormat);
6694 RpcRaiseException(RPC_S_INTERNAL_ERROR);
6696 TRACE("flags: 0x%02x\n", pFormat[1]);
6698 /* [out]-only or [ret] param */
6699 if ((pFormat[1] & 0x60) == 0x20)
6700 **(NDR_CCONTEXT **)ppMemory = NULL;
6701 NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle);
6703 return NULL;
6706 /***********************************************************************
6707 * NdrClientContextMarshall [RPCRT4.@]
6709 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6710 NDR_CCONTEXT ContextHandle,
6711 int fCheck)
6713 TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck);
6715 ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4);
6717 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6719 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6720 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6721 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6724 /* FIXME: what does fCheck do? */
6725 NDRCContextMarshall(ContextHandle,
6726 pStubMsg->Buffer);
6728 pStubMsg->Buffer += cbNDRContext;
6731 /***********************************************************************
6732 * NdrClientContextUnmarshall [RPCRT4.@]
6734 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6735 NDR_CCONTEXT * pContextHandle,
6736 RPC_BINDING_HANDLE BindHandle)
6738 TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle);
6740 ALIGN_POINTER(pStubMsg->Buffer, 4);
6742 if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd)
6743 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6745 NDRCContextUnmarshall(pContextHandle,
6746 BindHandle,
6747 pStubMsg->Buffer,
6748 pStubMsg->RpcMsg->DataRepresentation);
6750 pStubMsg->Buffer += cbNDRContext;
6753 void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6754 NDR_SCONTEXT ContextHandle,
6755 NDR_RUNDOWN RundownRoutine )
6757 TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine);
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 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6769 pStubMsg->Buffer, RundownRoutine, NULL,
6770 RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6771 pStubMsg->Buffer += cbNDRContext;
6774 NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
6776 NDR_SCONTEXT ContextHandle;
6778 TRACE("(%p)\n", pStubMsg);
6780 ALIGN_POINTER(pStubMsg->Buffer, 4);
6782 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6784 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6785 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6786 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6789 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6790 pStubMsg->Buffer,
6791 pStubMsg->RpcMsg->DataRepresentation,
6792 NULL, RPC_CONTEXT_HANDLE_DEFAULT_FLAGS);
6793 pStubMsg->Buffer += cbNDRContext;
6795 return ContextHandle;
6798 void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
6799 unsigned char* pMemory,
6800 PFORMAT_STRING pFormat)
6802 FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
6805 NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
6806 PFORMAT_STRING pFormat)
6808 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6809 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6811 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6813 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6814 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6815 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6816 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6817 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6819 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6820 if_id = &sif->InterfaceId;
6823 return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL,
6824 pStubMsg->RpcMsg->DataRepresentation, if_id,
6825 flags);
6828 void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
6829 NDR_SCONTEXT ContextHandle,
6830 NDR_RUNDOWN RundownRoutine,
6831 PFORMAT_STRING pFormat)
6833 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6834 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6836 TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
6838 ALIGN_POINTER(pStubMsg->Buffer, 4);
6840 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6842 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6843 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6844 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6847 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6848 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6849 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6850 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6851 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6853 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6854 if_id = &sif->InterfaceId;
6857 NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle,
6858 pStubMsg->Buffer, RundownRoutine, if_id, flags);
6859 pStubMsg->Buffer += cbNDRContext;
6862 NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
6863 PFORMAT_STRING pFormat)
6865 NDR_SCONTEXT ContextHandle;
6866 RPC_SYNTAX_IDENTIFIER *if_id = NULL;
6867 ULONG flags = RPC_CONTEXT_HANDLE_DEFAULT_FLAGS;
6869 TRACE("(%p, %p)\n", pStubMsg, pFormat);
6871 ALIGN_POINTER(pStubMsg->Buffer, 4);
6873 if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
6875 ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n",
6876 pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength);
6877 RpcRaiseException(RPC_X_BAD_STUB_DATA);
6880 if (pFormat[1] & NDR_CONTEXT_HANDLE_SERIALIZE)
6881 flags |= RPC_CONTEXT_HANDLE_SERIALIZE;
6882 if (pFormat[1] & NDR_CONTEXT_HANDLE_NO_SERIALIZE)
6883 flags |= RPC_CONTEXT_HANDLE_DONT_SERIALIZE;
6884 if (pFormat[1] & NDR_STRICT_CONTEXT_HANDLE)
6886 RPC_SERVER_INTERFACE *sif = pStubMsg->StubDesc->RpcInterfaceInformation;
6887 if_id = &sif->InterfaceId;
6890 ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle,
6891 pStubMsg->Buffer,
6892 pStubMsg->RpcMsg->DataRepresentation,
6893 if_id, flags);
6894 pStubMsg->Buffer += cbNDRContext;
6896 return ContextHandle;
6899 /***********************************************************************
6900 * NdrCorrelationInitialize [RPCRT4.@]
6902 * Initializes correlation validity checking.
6904 * PARAMS
6905 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6906 * pMemory [I] Pointer to memory to use as a cache.
6907 * CacheSize [I] Size of the memory pointed to by pMemory.
6908 * Flags [I] Reserved. Set to zero.
6910 * RETURNS
6911 * Nothing.
6913 void WINAPI NdrCorrelationInitialize(PMIDL_STUB_MESSAGE pStubMsg, void *pMemory, ULONG CacheSize, ULONG Flags)
6915 FIXME("(%p, %p, %d, 0x%x): stub\n", pStubMsg, pMemory, CacheSize, Flags);
6916 pStubMsg->fHasNewCorrDesc = TRUE;
6919 /***********************************************************************
6920 * NdrCorrelationPass [RPCRT4.@]
6922 * Performs correlation validity checking.
6924 * PARAMS
6925 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6927 * RETURNS
6928 * Nothing.
6930 void WINAPI NdrCorrelationPass(PMIDL_STUB_MESSAGE pStubMsg)
6932 FIXME("(%p): stub\n", pStubMsg);
6935 /***********************************************************************
6936 * NdrCorrelationFree [RPCRT4.@]
6938 * Frees any resources used while unmarshalling parameters that need
6939 * correlation validity checking.
6941 * PARAMS
6942 * pStubMsg [I] MIDL_STUB_MESSAGE used during unmarshalling.
6944 * RETURNS
6945 * Nothing.
6947 void WINAPI NdrCorrelationFree(PMIDL_STUB_MESSAGE pStubMsg)
6949 FIXME("(%p): stub\n", pStubMsg);